linux0.12-7-2

7-2 环境初始化工作

具有登陆系统的功能和多人同时使用系统的能力,通常的系统是在这里或类似地方执行系统环境
初始化程序init.c,而此程序会根据系统/etc/目录中配置文件的设置信息,对系统中支持的每个
终端设备创建子进程,并在子进程中运行终端初始化设置程序agetty(统称getty程序),getty程序
则会在终端上显示用户登陆提示信息"login:"。当用户键入了用户名后,getty被替换成login程序。
login程序在验证了用户输入口令的正确性以后,最终调用shell程序,并进入shell交互工作界面。

init—fork()—>agetty—exec()—>login—exec()—>shell

init进程的主要任务是
(a)根据/etc/rc文件中设置的信息,执行其中设置的命令,
(b)根据/etc/inittab文件中的信息,为每一个允许登陆的终端设备使用fork()创建一个子进程,

并在每个新创建的子进程中运行agetty程序。

©init进程则调用wait(),进入等待子进程结束状态。每当它的一个子进程结束退出,它就会根据wait()

返回的pid号知道是那个对应终端的子进程结束了,因此就会为相应终端设备再创建一个新的子进程,
并在该子进程中重新执行agetty程序。这样,每个被允许的终端设备都始终有一个对应的进程为其等待处理。

(d)当系统关闭时,init负责杀死所有其他的进程,卸载所有的文件系统以及停止处理器的工作,

以及任何它被配置秤要做的工作。

getty程序主要任务设置终端类型、属性、速度和线路规程。
(a)它打开并初始一个tty端口,显示提示信息,并等待用户键入用户名。
(b)该程序只能由超级用户执行。通常,若/etc/issue文本文件存在,则getty会首先显示其中的文本信息,

然后显示登陆提示信息(例如:plinux login:),读取用户键入的登陆明,并执行login程序。

login程序主要用于要求登陆用户输入密码。

(a)根据用户输入的用户名,它从口令文件passwd中取得对应用户的登陆项,
(b)调用getpass()以显示"password:"提示信息,读取用户键入的密码
©使用加密算法对键入的密码进行加密处理,并与口令文件中该用户项中pw_passwd字段作比较。

密码无效

(a)如果用户几次键入的密码均无效,则login程序会以出错1退出执行,表示此次登陆过程失败。
(b)如果存在(d),父进程(进程init)的wait()会返回该退出进程的pid,因此会根据记录下来的信息
再次创建一个子进程,并在该子进程中针对该终端设备再次执行agetty程序,重复上述过程。

密码有效

(a)用户键入的密码正确,则login就会把当前工作目录修改成口令文件指定的该用户的起始工作目录。
(b)并把对该终端设备的访问权限修改成用户读/写和组写,设置进程的组ID。
©利用所得到的信息初始化环境变量信息。
例如:起始目录(HOME=)、使用的shell程序(SHELL=)、用户名(USER=和LOGNAME=)和系统执行程序的
默认路径序列(PATH=)。
(d)显示/etc/motd文件中的文本信息,并检查和显示该用户是否有邮件的信息。
(e)最后login程序改变秤登陆用户的用户ID并执行口令文件中该用户项中指定的shell程序,如bash或csh等。

如果口令文件/etc/passwd中该用户中没有指定使用那个shell程序,系统则会默认的/bin/sh程序。
如果口令文件中也没有为该用户指定用户起始目录的话,系统就会使用默认的根目录/。

shell程序是一个复杂的命令行解释程序,是当用户登陆系统进行交互操作时执行的程序需。

它是用户与计算机进行交互操作的地方。它获取用户输入的信息,然后执行命令。用户可以在
终端上向shell直接进行交互输入,也可以使用shell脚本文件向shell解释程序输入。

在登陆过程中login开始执行shell时,所带参数argv[0]的第一个字符是"-",表示该shell是作为一个登陆shell被执行。
此时该shell程序会根据该字符,执行某些与登陆过程相应的操作。
(a)登陆shell会首先从/etc/profile文件以及.profile文件(若存在的话)读取命令并执行。
(b)如果在进程shell时设置了ENV环境变量,或者在登陆shell的.profile文件中设置了该变量,
则shell下一步会从该变量命名的文件中读取命令并执行。

因此用户应该把每次登陆是都要执行的命令放在.profile文件中,而把每次运行shell都要执行的命令
放在ENV变量指定的文件中。

7-3 本章小结

对于0.12版本内核,通过上面代码分析可知,只要文件系统是一个MINIX文件系统,
并且其中只要包含文件/etc/rc、/bin/sh、/dev/*以及一些目录/etc/、/dev/、
/bin/、/home/、/home/root/,就可以构成一个最简单的根文件系统,让linux运行起来。

1、 对于后续章节的阅读,可以将main.c程序作为一条主线进行,并不需要按章节阅读。
2、 作者强烈希望读者此时能再次复习32位保护模式运行的机制,
详细阅读一下附录中所提供的有关内容,或者参考Intel80X86的有关书籍,
把保护模式下的运行机制彻底弄清楚,然后继续阅读。
3、 如果您按章节顺序地阅读到这里,那么您对Linux系统内核的初始化过程应该已经有
了大致的了解。

问题:“在生成了一些列进程之后,系统是如何分时运行这些进程或者说如何调度这些进程运行的呢?即"轮子"是怎么转起来的呢?”
答案:内核是通过执行sched.c程序中的调度函数schedule()和system_call.s中的定时时钟中断
过程_timer_interrupt来操作的。内核设定每10ms发出一次时钟中断,并在该中断过程中,通过调用
do_timer()函数检查所有进程的当前执行情况来确定进程的下一步状态。

进程在执行过程中由于希望的资源暂时缺乏而临时需要等待一会儿时,它就会在系统调用中通过sleep_on()
类函数间接地调用schedule()函数,将CPU的使用权自愿地移交给别的进程使用。至于系统接下来会运行哪个进程,
则完全由schedule()根据所有进程的当前状态和优先权决定。

对于一直在可运行状态的进程,当时钟中断过程判断出它运行的时间片已被用完时,
就会在do_timer()中执行进程切换操作,该进程的CPU使用权就会被不情愿地剥夺,让给别的进程使用。

调度函数schedule()和时钟中断过程即是下一章中的主题之一。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值