linux系统启动过程函数,Linux内核学习第三周 Linux启动过程分析

一.知识点回顾

1.计算机的“三个法宝”:存储程序计算机,中断,函数调用堆栈;

2.操作系统的“两把宝剑”:中断上下文的切换(保存现场和恢复现场),进程上下文的切换。

二.实验内容

1.启动menuos

执行命令   cd LinuxKernel/

qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img

078680f385b38aa7af63df6fe0d94705.png

menuos启动成功。

2.利用gdb跟踪调试内核

另打开一个shell窗口

08dabdfd7dfa20d2d88f5e7414b0aa4d.png

设置断点rest_init()

417536996f926ba240adf5a8e29715f6.png

三.总结

1.start_kernel函数

start_kernel函数完成linux内核的初始化。几乎每个内核部件都是由这个函数进行初始化的。

调用sched_init函数初始化调度程序;

电泳trap_init函数和init_IRQ函数来完成IDT初始化;

调用time_init()函数来初始化系统日期和时间;

调用kernel_thread()函数为进程1创建内核线程,这个内核线程又会创建其他的内核线程并执行。

2init_task进程和idle进程

init_task进程在Linux中属于一个比较特殊的进程,它是内核开发者人为制造出来的,而不是其他进程通过do_fork来完成。Linux在无进程概念的情况下将一直从初始化部分的代码执行到start_kernel,然后再到其最后一个函数调用rest_init。从rest_init开始,Linux开始产生进程,因为init_task是静态制造出来的,pid=0,它试图将从最早的汇编代码一直到start_kernel的执行都纳入到init_task进程上下文中。在rest_init函数中,内核将通过下面的代码产生第一个真正的进程(pid=1):

static noinline void __init_refok rest_init(void)

{

...

kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND);

...

cpu_idle();

}

kernel_init函数最有意思的地方在于它会通过调用kernel_execve来执行根文件系统下的/sbin/init文件(所以此前系统根文件系统必须已经就绪),kernel_execve对用户空间程序/sbin/init的调用发起自int $0x80,这是个从内核空间发起的系统调用,与call_usermodehelper函数本质上是完全一样的。

而此时init_task的任务基本上已经完全结束了,它将沦落为一个idle task,事实上在更早前的sched_init()函数中,通过init_idle(current, smp_processor_id())函数的调用就已经把init_task初始化成了一个idle task,init_idle函数的第一个参数current就是&init_task,在init_idle中将会把init_task加入到cpu的运行队列中,这样当运行队列中没有别的就绪进程时,init_task(也就是idle task)将会被调用,它的核心是一个while(1)循环,在循环中它将会调用schedule函数以便在运行队列中有新进程加入时切换到该新进程上。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值