作业3:构造一个简单的Linux系统MenuOS 20135115臧文君
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了作业3:构造一个简单的Linux系统MenuOS 20135115臧文君相关的知识,希望对你有一定的参考价值。
构造一个简单的Linux系统MenuOS
注:作者:臧文君,原创作品转载请注明出处,《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000
一、Linux内核源代码介绍
1、根目录
arch/x86目录下的代码是我们重点关注的,arch中包括支持不同CPU的源代码。
init目录下包含内核启动相关的代码,如main.c(start_kernel函数相当于普通C程序的main函数,是Linux内核初始化的起点)。
ipc:进程间通信
kernel:Linux内核的核心代码
关注readme文件
二、构造一个简单的Linux系统MenuOS
<步骤指导>
1、在实验楼环境下:
cd LinuxKernel/
qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img
即可启动内核,完成后进入menu程序,支持三个命令help、version和quit。
2、使用自己的Linux系统环境搭建MenuOS的过程
# 下载内核源代码编译内核
cd ~/LinuxKernel/
wget https://www.kernel.org/pub/linux/kernel/v3.x/linux-3.18.6.tar.xz
xz -d linux-3.18.6.tar.xz
tar -xvf linux-3.18.6.tar(解压)
cd linux-3.18.6
make i386_defconfig
make # 一般要编译很长时间,少则20分钟多则数小时
# 制作根文件系统
cd ~/LinuxKernel/
mkdir rootfs
git clone https://github.com/mengning/menu.git # 如果被墙,可以使用附件menu.zip
cd menu
gcc -o init linktable.c menu.c test.c -m32 -static –lpthread(init是第一个用户态进程,是1号进程,采用的是静态编译的方式)
cd ../rootfs
cp ../menu/init ./
find . | cpio -o -Hnewc |gzip -9 > ../rootfs.img(img镜像文件)
# 启动MenuOS系统
cd ~/LinuxKernel/
qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img
3、重新配置编译Linux使之携带调试信息
(1)在原来配置的基础上,make menuconfig选中如下选项重新配置Linux,使之携带调试信息
kernel hacking—>
[*] compile the kernel with debug info
(2)make重新编译(时间较长)
4、使用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界面中target remote之前加载符号表 file home/shiyanlou/LinuxKernel/vmlinux
(gdb)target remote:1234 # 建立gdb和gdbserver之间的连接,按c 让qemu上的Linux继续运行
(gdb)break start_kernel # 断点的设置可以在target remote之前,也可以在之后
三、跟踪调试Linux内核的启动过程
1、之前内核启动被冻结,断点设置完成后,打C回车可以恢复启动。
命令:(gdb)list查看断点前后的代码
在rest_init()前设置断点:break rest_init(),再按C运行,list查看代码。
2、简单分析一下start_kernel
在init目录下的main.c中
全局变量init_task,即手工创建的PCB,0号进程即最终的idle进程。
不管分析内核的哪一部分都会涉及到start_kernel。
trap_init();初始化中断向量
例:set_system_trap_gate(SYSCALL VECTOR,&system_call)系统陷阱门(系统调用)
mm_init();内存管理模块
sched_init();系统调度模块
start_kernel中的最后一句:rest_init();在start_kernel从内核一启动就一直存在,是0号进程。
0号进程创建了1号进程kernel_init。
当系统没有进程需要执行时就调度到idle进程。
道生一,一生二,二生三,三生万物。
实验报告:
1、cd home/YL/menu/rootfs,启动linux内核:qemu-system-x86_64 -kernel /boot/vmlinuz-4.3.0-kali1-amd64 -initrd ../rootfs.img
注:find . | cpio -o -Hnewc | gzip -9 > ../rootfs.img将当前目录下的所有文件打包压缩生成img镜像文件
2、qemu-system-x86_64 -kernel /boot/vmlinuz-4.3.0-kali1-amd64 -initrd ../rootfs.img -s -S,启动linux内核,停在起始部位,设置断点进行调试。
3、重新开一个终端窗口,输入gdb,可以使用help命令查看可选择的命令。
4、在gdb界面中target remote之前加载符号表:先切换到usr/src/linux-source-4.4路径下,然后输入命令file vmlinux。再建立gdb和gdbserver之间的连接:target remote:1234。
5、在start_kernel前设置断点:break start_kernel,按c 让qemu上的Linux继续运行
总结:
这次实验是构造一个简单的linux系统MenuOS,使用老师已经配置好的虚拟机,做起来比较方便,但因为linux内核的版本不同以及配置的原因,所以在命令的使用上与网课中介绍的有一些差别,主要是路径的不同,在理解了各个命令中参数的含义后,命令使用起来会比较容易,实验也能顺利的进行。
在课上的巩固讲解中,我了解到linux内核启动的三要素是:kernel,initrd和root所在分区。对于内核启动,最重要的命令就是:qemu-system-x86_64 -kernel /boot/vmlinuz-4.3.0-kali1-amd64 -initrd ../rootfs.img。在之后的gdb调试过程中,要注意路径!
以上是关于作业3:构造一个简单的Linux系统MenuOS 20135115臧文君的主要内容,如果未能解决你的问题,请参考以下文章
Linux内核分析——构造一个简单的Linux系统MenuOS
20135327郭皓--Linux内核分析第三周 构造一个简单的Linux系统MenuOS