Question1
在此练习中,大家需要通过静态分析代码来了解:
操作系统镜像文件ucore.img是如何一步一步生成的?(需要比较详细地解释Makefile中每一条相关命令和命令参数的含义,以及说明命令导致的结果)
一个被系统认为是符合规范的硬盘主引导扇区的特征是什么?
结果如下:
> > + cc kern/init/init.c kern/init/init.c:95:1: warning: ‘lab1_switch_test’ defined but not used [-Wunused-function]
> lab1_switch_test(void) { ^~~~~~~~~~~~~~~~
> + cc kern/libs/stdio.c
> + cc kern/libs/readline.c
> + cc kern/debug/panic.c
> + cc kern/debug/kdebug.c kern/debug/kdebug.c:251:1: warning: ‘read_eip’ defined but not used [-Wunused-function] read_eip(void) {
> ^~~~~~~~
> + cc kern/debug/kmonitor.c
> + cc kern/driver/clock.c
> + cc kern/driver/console.c
> + cc kern/driver/picirq.c
> + cc kern/driver/intr.c
> + cc kern/trap/trap.c kern/trap/trap.c:30:26: warning: ‘idt_pd’ defined but not used [-Wunused-variable] static struct pseudodesc
> idt_pd = {
> ^~~~~~ kern/trap/trap.c:14:13: warning: ‘print_ticks’ defined but not used [-Wunused-function] static void
> print_ticks() {
> ^~~~~~~~~~~
> + cc kern/trap/vectors.S
> + cc kern/trap/trapentry.S
> + cc kern/mm/pmm.c
> + cc libs/string.c
> + cc libs/printfmt.c
> + ld bin/kernel
> + cc boot/bootasm.S
> + cc boot/bootmain.c
> + cc tools/sign.c
> + ld bin/bootblock 'obj/bootblock.out' size: 488 bytes build 512 bytes boot sector: 'bin/bootblock' success! 10000+0 records in 10000+0
> records out 5120000 bytes (5.1 MB, 4.9 MiB) copied, 0.0180802 s, 283
> MB/s 1+0 records in 1+0 records out 512 bytes copied, 0.000120725 s,
> 4.2 MB/s 147+1 records in 147+1 records out 75744 bytes (76 kB, 74 KiB) copied, 0.000294345 s, 257 MB/s
一个被系统认为是符合规范的硬盘主引导扇区的特征有以下几点:
1.硬盘的主引导扇区只有512字节。
2.最后两个字节为"0x55aa"
3.466 字节启动代码和64字节的分区表加上两个字节的结束符组成。
Question2
为了熟悉使用qemu和gdb进行的调试工作,我们进行如下的小练习:
1.从CPU加电后执行的第一条指令开始,单步跟踪BIOS的执行。 在初始化位置0x7c00设置实地址断点,测试断点正常。
2.从0x7c00开始跟踪代码运行,将单步跟踪反汇编得到的代码与bootasm.S和 bootblock.asm进行比较。
3.自己找一个bootloader或内核中的代码位置,设置断点并进行测试。
提示:参考附录“启动后第一条执行的指令”,可了解更详细的解释,以及如何单步调试和查看BIOS代码。提示:查看 labcodes_answer/lab1_result/tools/lab1init
文件,用如下命令试试如何调试bootloader第一条指令:$ cd labcodes_answer/lab1_result/ $ make lab1-mon
注意:这里直接编译会报错。
注意到在两个代码中的bootmain.C中发生了修改,这里需要将
unsigned int SECTSIZE = 512 ;
struct elfhdr * ELFHDR = ((struct elfhdr *)0x10000) ; // scratch space
改成:
#define SECTSIZE 512
#define ELFHDR ((struct elfhdr *)0x10000) // scratch space
修改后bootloader编译得到通过,但是继续报错:
> Option “-e” is deprecated and might be removed in a later version of gnome-terminal.
> Use “-- ” to terminate the options and put the command line to execute after it.
> Error constructing proxy for :1.73:/org/gnome/Terminal/Factory0: The connection is closed
> Failed to use specified server: The connection is closed
> Falling back to default server.
> Error constructing proxy for org.gnome.Terminal:/org/gnome/Terminal/Factory0: The connection is
> closed
无奈这里使用手动加载的方法:::
qemu-system-i386 -S -s -hda ucore.img -monitor stdio
然后采用gdb连接调试器::
target remote localhost:1234
gdb无法正确获取当前qemu执行的汇编指令,通过如下配置可以在每次gdb命令行前强制反汇编当前的指令,在gdb命令行或配置文件中添加:
define hook-stop
x/i $pc
end