查看run脚本
cat run
可以看到,使用的内核为: qemu-system-i386 -nographic -kernel $LINUX/arch/i386/boot/bzImage,使用的硬盘为:-initrd rootfs/rootfs.img.gz
如果在启动时加“-s”可以启动调试模式
运行run,进入虚拟机
./run
(退出qume虚拟机:reboot -f)
查看bin文件,如下图,可以看到,只有busybox是有效的二进制可执行文件,其他的都是对busybox的符号链接。
busybox在执行的时候,敲任何命令,结果都是在执行busybox。
退出虚拟机,用调试模式重新打开
再建一个终端操作。
建立符号链接cur指向ubuntu中的内核源码,并查看内核根目录。就不用把大文件放到虚拟机了,速度会受影响。
左边启动虚拟机,等待调试。右边打开gdb调试器,从内核源码里面读取符号。
用gdb连接到qume虚拟机。
target remote localhost:1234
把busybox可执行文件读进来,后面是起始地址。
加断点,这是执行命令解释器时候的入口。
ash_main
再加ls命令的断点。如下图
右侧执行c,左侧即开始运行
显示当前进程的进程号
display $lx_current().pid
查看当前进程是由哪个可执行文件引发的。
继续执行,看到964号进程又执行了命令解释器。可见,启动过程中,ash_main执行了两次,在两个进程中运行的。
用strace查看ls执行的系统调用,新开一个终端。
上面是Ubuntu下执行的系统调用,那么虚拟机的呢,内核版本不一样,故执行的系统调用也不一样。
在系统调用的总控函数位置设置一个断点。b entry_SYSENTER_32
系统调用的实现函数进行跳转的时候,看看是哪个系统调用,也设一个断点
跳转到系统调用实现函数的数组,包含的是系统调用实现函数的入口地址,所以只需要往前走一步,s,就会进入到相应的实现函数,可以看到,第一个实现函数是time
继续执行,走一步到主控函数的入口,再走一步到跳转,再单步执行,重新回到系统调用实现函数。如下图
退出调试,先kill,再quit