博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Linux内核_实验三:跟踪分析Linux内核的启动过程
阅读量:5060 次
发布时间:2019-06-12

本文共 2031 字,大约阅读时间需要 6 分钟。

郑斌    《Linux内核分析》MOOC课程

该文章为课程的第三个实验记录及分析。

 

实验指导:

1.使用实验楼的虚拟机打开shell

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

内核启动完成后进入程序,支持三个命令help、version和quit,您也可以添加更多的命令.

2.使用gdb跟踪调试内核

qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -s -S # 关于-s和-S选项的说明: -S freeze CPU at startup (use ’c’ to start execution) -s shorthand for -gdb tcp::1234 若不想使用1234端口,则可以使用-gdb tcp:xxxx来取代-s选项

另开一个shell窗口

gdb(gdb)file linux-3.18.6/vmlinux # 在gdb界面中targe remote之前加载符号表 (gdb)target remote:1234 # 建立gdb和gdbserver之间的连接,按c 让qemu上的Linux继续运行 (gdb)break start_kernel # 断点的设置可以在target remote之前,也可以在之后

 

实验环境:在中进行。

 

实验步骤:

打开shell,进入到LinuxKernel目录,通过qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img命令

运行对应的内核程序。

这里的  -initrd  rootfs.img的作用是指明根文件系统。  

 

可以看到menu程序已经启动。在这里支持help、version、quit共3个命令。分别为查看帮助,查看版本,和退出功能。

 

下面通过gdb调试来跟踪分心Linux内核的启动过程。

通过命令qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -s -S 。

参数-S的作用是在开始的时候,CPU初始化之前冻结CPU

参数-s 的作用是创建gdbserver,对应 tcp的1234号端口。若不想使用1234端口,则可以使用-gdb tcp:xxxx来取代-s选项。

 

file linux-3.18.6/vmlinux     这是一个带debug信息的内核。该命令加载符号集

target remote:1234       建立gdbgdbserver之间的连接。

 

然后通过break设置断点,按c然程序继续执行到断点。按list可以查看断点附近的代码。

 

我们查看的内核代码。这里有很多个文件目录。

其中arch包括了所支持的多种CPU体系结构,这里我们只关心里面的x86文件夹就好了。

其他还有如drivers为驱动相关代码。fs为文件系统相关内核代码,ipc是进程相关代码,mm是存储管理代码,net是和网络相关的内核代码等等。

init为初始化相关的模块,在init/main.c/start_kernel中之后开始C代码的操作系统初始化,最后执行第一个用户态进程init。。

在start_kernel函数中可以看到很多_init相关函数,涉及到操作系统启动相关的多种初始化操作。

这里的init_task为相当于0号进程的pcb。   还有();为进程调度相关初始化。();为中断相关的内核代码。等等。

这里看到start_kernel 最后一句 rest_init().

当操作系统为空闲时,就会执行这个idle程序。

 

总结:

浅入的学习了xLinux内核的启动过程。

学习了gdb的操作使用。

x86 CPU启动的第一个动作CS:EIP=FFFF:0000H(换算为物理地址为000FFFF0H,因为16位CPU有20根地址线),即BIOS程序的位置。BIOS例行程序检测完硬件并完成相应的初始化之后就会寻找可引导介质,找到后把引导程序加载到指定内存区域后,就把控制权交给了引导程序。引导程序BootLoader开始负责操作系统初始化,然后起动操作系统。启动操作系统时一般会指定kernel、initrd和root所在的分区和目录。内核启动过程包括start_kernel之前和之后,之前全部是做初始化的汇编指令,之后开始C代码的操作系统初始化,最后执行第一个用户态进程init。一般分两阶段启动,先是利用initrd的内存文件系统,然后切换到硬盘文件系统继续启动。

 

参考资料:课程学习文档视频以及互联网资料。

转载于:https://www.cnblogs.com/terrry/articles/4354695.html

你可能感兴趣的文章
CPU,寄存器,一缓二缓.... RAM ROM 外部存储器等简介
查看>>
windows下编译FreeSwitch
查看>>
git .gitignore 文件不起作用
查看>>
Alan Turing的纪录片观后感
查看>>
c#自定义控件中的事件处理
查看>>
App.config自定义节点读取
查看>>
unity3d根据手机串号和二维码做正版验证
查看>>
二十六、Android WebView缓存
查看>>
django Models 常用的字段和参数
查看>>
linux -- 嵌入式linux下wifi无线网卡驱动
查看>>
SVN使用教程总结
查看>>
SQL中varchar和nvarchar有什么区别?
查看>>
OpenCV矩阵运算总结
查看>>
Java Build Practice 4:Extend and Invoke Ant API
查看>>
[转] Transformer图解
查看>>
FreeBSD方式安装 MAC OSX
查看>>
Linux 根文件系统制作
查看>>
IOS--沙盒机制
查看>>
My.Ioc 的性能
查看>>
使用 JointCode.Shuttle 访问任意 AppDomain 的服务
查看>>