init创建getty,等用户输入用户名和密码,输入完成后调用login程序进行核对密码,如果正确就读取/etc/passwd文件,读取这个用户的指定的shell并启动它。
2) ssh登录
系统调用sshd程序,取代getty和login,之后启动shell。
3) 图形界面登录
init进程调用显示管理器,Gnome图形界面对应为gdm,然后输入用户名、密码,如果密码正确就启动用户会话。
到这里系统就启动起来了!说了这么多,现在我们来玩点好玩的!!!!!!简单熟悉一下linux的启动!!!!!!!!!!!首先要准备一个ubuntu系统最好13.04或者12.04都得,可以是虚拟机(最好是在虚拟机上操作!因为我因为这个小实验而重装了一遍真机系统!当时不懂啊!惨。。。。。。。。。)。
1:进入系统,在主文件夹(方便)新建一个c语言文件并且命名为init.c,输入---->最简单的c语言程序helloworld,不这是最伟大的c语言程序!
main(){
printf("helloworld!\n");
}
之后不用说就是编译啦。打开终端(ctrl + alt + t)执行这条指令:gcc --static -o init init.c 这样init文件就准备好了!猜到我想做什���了吗。。?哈哈我们继续!!
2:将上文提到过的/sbin/init 文件备份执行这条指令:sudo cp /sbin/init /sbin/init.bak 备份成init.bak 文件
将原来的init 文件删除,执行指令:sudo rm /sbin/init
好了,下一步就将我们的helloworld init复制到/sbin/录目下!执行指令: sudo mv init /sbin/ 这条指令之前要注意你终端当前的路径与init的路径是不是相同,要不不能成功的!!
3:这样就做好了!!!我们果断重启!这样在启动中我们看到了我们的 helloworld!唉。。它停哪里了!!那是肯定的,上文介绍了init的作用,你换了,不能启动是正常的啦。。思考下,到这里内核处于什么状态。?这里其实内核基本已经初始化完成了!就剩下进程的生成与子系统的初始化了。在init_post()函数的最尾会查找init的路径,如果找不到就崩溃。而且会试图建立一个交互式的shell(/bin/sh)来代替找不到的init,让用户可以修复这种错误、重新启动。
4:现在我们来恢复我们的系统!刚才在 2 中的步骤不会让你白做的!重新启动系统,并在一开始就按着左Shift (我以前的系统是不用的,不知道以前对grub.cfg做了什么坏事!!),系统会自动检测到这个信号的,这样会出现下面图中的界面。(建议去看看grub2的特性!):
按下e,进行编辑,按键盘右下角 向下的按键,在linux 这一行的最尾(quiet)前面加入----> init=/sbin/init.bak ,按下 ctrl + x 启动系统。如图:
如果一切没有错,那么你肯定能成功地重新启动系统!如果看到登录界面,那么恭喜你,你已经在漫漫人生路上走了一趟了!
好了,到这里本文要讲的知识已经讲完了。下面我们一起来思考一下我在这其中遇到的没有解决的问题,请大神们指教!
问题: 首先我的实验是在虚拟机上做的,原本我以为init是跟内核的压缩文件有关,所以用3.8.0-19 内核进去系统将init删了,这样3.8.0-19内核肯定启动不了内核。我用3.8.0-27内核进去系统,同样不能进去。。还是出现伟大的helloworld!这样看 init跟vmlinux等 在boot里的文件无关了!那么init关机后会被保存在哪里!?还有一个最重要的!我重新装了一遍系统(虚拟机的),这是没有3.8.0-27内核的,我将我真机的3.8.0-27的内核文件(/boot 里的vmlinuz文件等)放到虚拟机的/boot/文件夹里,重新启动系统,发现分辨率变了,光标不灵活(可能是分辨率的关系!),屏幕大小感觉是原来的两倍。这是为什么呢?
ps:本文挺长!如果你有疑问请提出来,交流交流,学习学习!如果你知道上面的问题的原因,那么请大神留几句话共小弟学习学习!