跟踪分析Linux内核的启动过程(start_kernel到init进程启动)

SA16225055  冯金明

原创作品转载请注明出处

《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000

实验内容

1、内核启动并进入menu

输入命令为:
cd LinuxKernel/
qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img


2、GDB调试查看kernel启动流程

使用GDB跟踪调试内核:
先关闭原先的窗口,输入以下的命令:
qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -s -S
打开另一个shell窗口,用于GDB调试:
输入以下命令:
gdb
(gdb)file linux-3.18.6/vmlinux
(gdb)target remote:1234
(gdb)break start_kernel

可以按着这个步骤一步一步调试查看整个kernel启动的过程。

start_kernel到init进程启动过程详解

查看Linux内核源码,在/init/main.c中可以查看start_kernel()函数的相关内容,可以看到其中有一系列的init函数,可以看出start_kernel是一些模块的初始化,比如init_IRQ()函数为中断向量初始化; tick_init()为时钟初始化等等。

初始化完成后,则会调用rest_init(),此函数创建了1号进程(第一个用户态的进程)和2号进程(内核态的祖先),其中包括了pid1的kernel_init以及kthreadd。同时,此函数在执行的后期还将自己变为idle进程,此进程为一个while(1)的loop。

kernel_init调用run_init_process,至此启动文件根目录的/init程序,pid1的init就开始执行了。
借用一张分析得很到位的进程图:

idle进程、1号进程

rest_init()函数可以算是在运行最后的初始化工作,其中就包括创建1号进程以及第一个内核进程等操作。创建完成后,则使用do_fork()来创建新的进程。pid是会进行一个累加的。内核线程调用cpu_startup_entry,再调用其中的cpu_idel_loop函数进入循环,此即为0号进程。
从rest_init开始,Linux开始产生进程,在rest_init中,通过init_task产生pid=0的进程,即0号进程(idle进程),它是内核状态下的进程;在rest_init函数中,内核通过kernel_init创建1号进程,它是第一个用户态进程。关于init_task(也就是idle),当运行队列中没有别的就绪进程时,init_task(也就是idle)将会被调用,它的核心是一个while(1)循环,在循环中它将会调用schedule函数以便在运行队列中有新进程加入时切换到该新进程上。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值