一.实验
使用自己的Linux系统环境搭建MenuOS
1、首先按照以下命令,下载内核源码,解压并编译:
mkdir LinuxKernel
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
2、制作根文件目录,打包镜像文件:
mkdir rootfs
git clone https://github.com/mengning/menu.git
cd menu
gcc -pthread -o init linktable.c menu.c test.c -m32 -static
cd ../rootfs
cp ../menu/init ./
find . | cpio -o -Hnewc |gzip -9 > ../rootfs.img
其中cp ../menu/init ./
把init复制到rootfs目录下,init为一号进程是第一个用户态进程。复制完成后使用cpio方式,将rootfs目录下的文件打包,生成rootfs.img镜像文件。
3、启动不带调试信息的Linux内核和MenuOS:
输入qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img
即可启动MenuOS。
4、重新编译Linux内核:
输入make menuconfig
即可打开配置界面。按顺序选择Kernel hacking ---> Compile-time checks and compiler options ---> [*] Compile the kernel with debug info
完成后退出界面,输入make命令就完成了Linux内核的配置编译。
5、跟踪调试Linux内核的启动过程:
(1)先使用如下命令启动内核qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -S -s
;
(2)再打开一个窗口,启动gdb,加载内核建立连接;
(3)使用break命令在“start_kernel”函数处设置断点,按“c”继续执行即可运行到断点处。
start_kernel()代码部分:
start_kernel()相当于C语言中的main函数,是一切的起点。
(4)在rest_init函数处设置断点
通过断点的设置,可以看到rest_init函数在start_kernel的尾部进行了调用。
rest_init()代码部分:
rest_init是0号进程,它创建了1号进程init和其他的一些服务进程。
二.遇到的问题和解决方法
1、在make menuconfig时遇到下图中的错误,通过命令sudo apt-get install libncurses5-dev
下载缺少的文件后解决了这一问题。
2、在运行qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img
命令时,出现了下图的错误,重新下载qemu后还是出现错误。
通过询问同学学习到了解决的方法,可以用如下建立连接的命令,找到qemu文件
sudo ln -s /usr/bin/qemu-system-i386 /usr/bin/qemu
在这之前,还需要使用sudo apt install qemu-system-i386
命令先下载qemu-system-i386文件。运行成功后即可成功执行: