免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 708 | 回复: 0
打印 上一主题 下一主题

Linux初时化过程 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-04-15 10:58 |只看该作者 |倒序浏览

      今天用了一个小时的时间把0.11核的初始化程序main.c浏览完了,对Linux的初始化过程有了一个整体上的了解,当然main里面调用了多个初始化子程序,我都暂且没深入进去看,我打算以后看到某个专题的时候再看吧。和以前一样,老规矩,先说一下初始化程序的大概过程,在深入文件具体说一下。
      一、概述
      main.c主程序工作在任务0中, main先物理内存进行划分和分配,然后对各个设备进行初始化,最后创建进程1(init进程),并从进程1的init()运行,进程1的init()会继续进行系统的初始化并再创建一个非交互式shell进程:进程2,在进程2主要是执行rc配置文件,进程2结束后会返回到进程1中,进程1再创建一个shell登陆进程,在这里用户就可以使用Linux的shell命令环境了。
     二、main.c结构
     1)保存根设备号和划分内存:设置高速缓存末地址、物理内存大小、内存主区 开始地址。
     2)硬件初始化:陷阱门、块设备、字符设备、tty、开机时间、调度程序、硬盘等
     3)切换到用户模式,创建进程1,在进程1中从init()开始执行,而进程0处在空闲状态。
     进程1的init()中:
     4)系统调用setup:安装根文件系统设备
     5)打开设备tty0:它对应终端控制台,以读写方式打开作为输入,并再复制两个句柄作为普通输出和错误输出。
     6)创建子shell进程(进程2):创建进程2,在进程2中,关闭输入设备句柄(0),并重新将输入句柄定向到rc,使系统能加载rc文件,最后加载rc文件执行,完成配置工作。而进程1则等待进程2的结束。
     7)建立shell登陆进程:创建新进程,在新进程中,首先关闭三个句柄(0,1,2);然后创建一个会话期,接着重新打开tty0作为输入设备,复制两个句柄作为stdout和stderr;最后加载shell登陆程序。而在进程1中,等待创建进程的结束并开始新一轮的创建新进程的循环。

     以上就是Linux系统初始化的大体过程,在这里需要说明几个问题:
     1)系统调用改作内联函数
      程序中的三个系统调用fork()、pause()和setup()是采用的内联函数的形式而不是进行系统调用。这样做的原因是这样的,因为在创建进程1之前任务0就已经切换到用户模式下了,这个使用的栈是用户栈。进程1创建后,它用的代码和数据是核进程0共享的,也就是说进程1用的栈和进程0用的栈是一个栈,如果在进程1中发生入栈操作,根据内存管理提供的写时复制规则就会引起页面写保护异常,系统就会在物理内存中申请新的页面并将进程0栈中相应的页面复制到进程1新分配的物理页中,这样问题就来了,如果在复制之前进程0用了用户栈,那么复制时,也会把进程0栈的内容复制到进程1的栈中,这样进程1中就会有进程0的多余信息。这样不好。而内联函数就可以解决这个问题,内联函数的调用不会引起用户栈进出栈操作,即使里面的中断指令int会使用栈,但它操作的是核心态栈,核心态栈是独立的,存在于task_struct所在页面,这样就会保证在进程1执行前进程0的用户栈是空的了。
     2)会话期
     上面提到了创建会话期。下面说一下会话期。一个进程调用多个fork()创建多个子进程,这些进程会构成一个进程组,每个组内的进程除了用自己的进程号之外还有它所在组的进程组号(也就是组长的进程号),而会话期则是一个或者多个进程组的集合。用户登陆后所执行的所有程序都属于一个会话期,而登陆shell就是会话期的首进程,也就是控制终端,当他=用户退出登录的时候,系统会结束这会话期的所用进程,这也是会话期的主要用途之一。
     3)用户登录。
     上面的main.c中的init()函数中,直接创建进程运行shell登陆程序,而在实际应用中不是这样的。在实际应用中,在这个地方会执行系统初始化程序init.c,在这个程序根据rc配置信息,为每个允许登陆的终端设备创建一个子进程,并在子进程中运行getty程序,这个程序会在终端上显示登陆信息(用户名密码),用户输入用户信息后,getty被替换成login程序,login程序在验证了用户信息的正确性后,调用shell程序,进入交互式界面。
     4)CMOS信息
     内核需要直接从CMOS中读取时间、内存等信息,读取原理是这样的:系统的信息储存在CMOS的不同偏移处,系统先向CMOS的70地址端口写入偏移地址,在从71数据端口利用int读出数据。



本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u2/63273/showart_537350.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP