实验来源:https://github.com/mengning/menu
一、环境配置
安装qemu
sudo apt-get install qemu
sudo ln -s /usr/bin/qemu-system-i386 /usr/bin/qemu
下载内核源代码编译内核
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 -j4
制作根文件系统
cd ~/LinuxKernel/
mkdir rootfs
git clone https://github.com/mengning/menu.git
cd menu
gcc -m32 -static linktable.c menu.c test.c -o init -lpthread
cd ../rootfs
cp ../menu/init ./
find . | cpio -o -Hnewc | gzip -9 > ../rootfs.img
启动MenuOS系统
cd ~/LinuxKernel/
qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img
二、调试内核
重新配置编译Linux使之携带调试信息
make menuconfig
kernel hacking—>
Compile-time checks and compiler options --->
[*]compile the kernel with debug info
使用gdb跟踪调试内核
qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -s -S
# 关于-s和-S选项的说明:
# -S freeze CPU atstartup(use ’c’ to start execution)
# -s shorthandfor-gdb tcp::1234
若不想使用1234端口,则可以使用-gdb tcp:xxxx来取代-s选项
gdb连接qemu
另开一个shell窗口,
cd linux-3.18.6/ # 必须在该目录下执行gdb才能找到源代码
gdb
(gdb)file vmlinux # 在gdb界面中targe remote之前加载符号表
(gdb)target remote:1234 # 建立gdb和gdbserver之间的连接,按c 让qemu上的Linux继续运行
(gdb)breakstart_kernel # 断点的设置可以在target remote之前,也可以在之后
(gdb)tui enable # 打开源码(同 layout src)
(gdb)tui reg all # 运行过程中查看寄存器值
(gdb) n # 单步执行
(gdb)s # 单步执行并进入函数
(gdb)finish # 结束当前函数
三、问题及解决方案
1. 编译内核
error: linux/compiler-gcc5.h: 没有那个文件或目录
error: linux/compiler-gcc5.h: not such file or directory
gcc版本问题
直接复制源码同目录下的compiler-gcc4.h文件并改名为compiler-gcc5.h
cp include/linux/compiler-gcc4.h include/linux/compiler-gcc5.h
2. 调试内核
make menuconfig错误
recipe for target 'menuconfig' failed
安装依赖库
sudo apt-get install ncurses-dev
终端显示太小
scripts/kconfig/mconf Kconfig
Your display is too small to run Menuconfig!
It must be at least 19 lines by 80 columns.
scripts/kconfig/Makefile:24: recipe for target 'menuconfig' failed
make[1]: *** [menuconfig] Error 1
Makefile:541: recipe for target 'menuconfig' failed
make: *** [menuconfig] Error 2
直接将终端最大化
3. 编译menu失败
64位deepin环境下执行
gcc -m32 -static linktable.c menu.c test.c -o init -lpthread 失败
In file included from /usr/include/stdio.h:27:0,
from linktable.c:23:
/usr/include/features.h:364:25: fatal error: sys/cdefs.h: 没有那个文件或目录 # include
安装32位库
sudo apt-get purge libc6-dev
sudo apt-get install libc6-dev
sudo apt-get install libc6-dev-i386
在其他的教程中编译menu的命令不同,可能会有几种错误
(1)gcc-o init linktable.c menu.c test.c-m32-static–lpthread
gcc: error: –lpthread: 没有那个文件或目录
gcc: error: –lpthread: Not such file or directory
测试将 -m32 -static 放置到 gcc 后面即可
(2)gcc -m32 -static -lpthread linktable.c menu.c test.c -o init
static undefined reference to `pthread_mutex_lock'
测试将 -lpthrread 放到命令最后面即可
(3)gcc -m32 -static-libgfortran -lpthread linktable.c menu.c test.c -o init
用这条指令能够编译过去,但是实际运行起来到不了menuos
显示: panic - not syncing: No working init found.
修改指令,一定要是静态编译,将-lpthread放在最后面
gcc -m32 -static linktable.c menu.c test.c -o init -lpthread
如果文章内容对您有帮助,麻烦您为我点个赞,谢谢!