Boot sequence:
BIOS -> Boot loader -> Kernel image
1. 为何执行的第一条指令地址总是0x000ffff0?
这和intel如何设计8088处理器有关,在实模式下,cpu可访问的地址空间只有16位,也就是1M大小,BIOS是被固定在物理地址0x000f0000~0x000fffff,这样就能保证第一条指令总是在BIOS中执行。
2. Boot loader
一个sector是512bytes,BIOS会把第一个可启动的512bytes的boot sector放在0x7c00~ 0x7dff,也就是说bootloader只有512bytes的空间可以用。
看看它都做了什么:
in Boot.S
a. 运行在实模式下,初始化各段,栈指针。
b. Enable A20.
c. load gdt, 启用保护模式,就可以开始使用32位地址4G内存
d. 跳转到cmain
in main.c
e. load kernel image, 应该是elf格式的。
3. Kernel: 描述一下printf.c& console.c之间的关系,console.c提供了什么样的接口?这个接口printf.c是怎么用的?
console.c 提供了一个cputchar()的接口.
4. Run the following code.
unsigned int i =0x00646c72;
cprintf("H%x Wo%s", 57616, &i);
Whatis the output? Explain how this output is arrived out in thestep-by-step
manner of the previousexercise.
************************************************************************************
错误答案:He110Wo0xf010efec [The addr of 0x00646c72, should be (%ebp)-c ]
************************************************************************************
He110 World 《0x00646c72被解析成字符串,并且由于是littleendian,所以从后往前打,0x72= r, 0x6c = l, 0x64 = r》
5. In the following code, what is going to be printed after 'y='?(note: the
answer is not a specific value.) Why does thishappen?
cprintf("x=%d y=%d", 3);
内存溢出,它访问的是一个不确定的内存空间
x=3 y=-267325460
6. Determine where the kernel initializes its stack, and exactlywhere in memory its stack is located. How does the kernel reservespace for its stack? And at which "end" of this reservedarea is the stack pointer initialized to point to?
step by step的运行,第一个callfunction后的esp指向0xf010eff8,所以猜测栈的初始地址在这个位置+ 8 = 0xf010f000。以下程序也证明如此:
# Set the stackpointer
movl $(bootstacktop),%esp
f0100033: bc 00 f0 10 f0 mov $0xf010f000,%esp
kernel用什么办法来保存空间还不清楚~~~印象里Linux是4k/8k.
7. To become familiar with the C calling conventions on the x86,find the address of the test_backtrace function inobj/kern/kernel.asm, set a breakpoint there in Bochs, and examinewhat happens each time it gets called after the kernel starts. Thereare two
ways you can set this breakpoint: with the b command and aphysical address, or with the vb command, a segment selector (use 8for the code segment), and a virtual address.
How many 32-bitwords does each recursive nesting level of test_backtrace push on thestack, and what are thosewords?
每次有8个32bit的字被压栈,分别代表上个函数的栈地址,参数x,putch()的调用地址等。
0x0010ef2c <bogus+ 0>: 0xf0100069 0x00000000 0x00000001 0xf010ef68
0x0010ef3c<bogus+ 16>: 0x00000000 0xf0100954 0x00000002 0xf010ef68
0x0010ef4c<bogus+ 32>: 0xf0100069 0x00000001 0x00000002 0xf010ef88
0x0010ef5c<bogus+ 48>: 0x00000000 0xf0100954 0x00000003 0xf010ef88
0x0010ef6c<bogus+ 64>: 0xf0100069 0x00000002 0x00000003 0xf010efa8
0x0010ef7c<bogus+ 80>: 0x00000000 0xf0100954 0x00000004 0xf010efa8
0x0010ef8c<bogus+ 96>: 0xf0100069 0x00000003 0x00000004 0x00000000
0x0010ef9c<bogus+ 112>: 0x00000000 0x00010094 0x00000005 0xf010efc8
0x0010efac <bogus+ 128>: 0xf0100069 0x00000004 0x00000005 0x00000000
0x0010efbc<bogus+ 144>: 0x00000000 0x00000000 0x00010094 0xf010eff8
stack top: +-------------------------------(low memory) +-----------last EBP------------(current SP) +------------EIP----------------(RET addr) +------------arg0--------------- +------------arg1--------------- +……----------------------------(high memory)
8. Complete the mon_backtrace
mon_backtrace(int argc, char **argv, struct Trapframe *tf)
{
63 inti;
64 uint32_t ebp = read_ebp();
65 cprintf("Stack backtrace:\n");
66 // The key of args is print the every single byte of (ebp) -ebp
67 while(ebp != 0) {
68 cprintf("ebp %x eip %x args ", ebp,*(int*)(ebp+4));
69 for (i = 1; i < 5; i++) {
70 if (*(int*)ebp != ((ebp + i*4))){
71 cprintf("%08x ",*(int*)((ebp+4)+i*4));
72 } else break;
73 }
74 cprintf("\n");
75 ebp = (*(int*)(ebp));
76 }
77 return 0;
}
Stack backtrace:
ebp f010ef08 eip f0100087 args 0000000000000000 00000000 00000000 f01009f4 00000001 f010ef48
ebpf010ef28 eip f0100069 args 00000000 00000001 f010ef68 00000000f01009f4 00000002 f010ef68
ebp f010ef48 eip f0100069 args00000001 00000002 f010ef88 00000000 f01009f4 00000003 f010ef88
ebpf010ef68 eip f0100069 args 00000002 00000003 f010efa8 00000000f01009f4 00000004 f010efa8
ebp f010ef88 eip f0100069 args00000003 00000004 00000000 00000000 00010094 00000005 f010efc8
ebpf010efa8 eip f0100069 args 00000004 00000005 00000000 0000000000000000 00010094 f010eff8
ebp f010efc8 eip f0100144 args00000005 00000003 f010efec 00000004 00000000 00000000 0000000000646c72 00000000 00000000 00000000
ebp f010eff8 eip f010003d args 00000000 00000000 0000ffff 10cf9b000000ffff 10cf9300 f0000017 00000010 32311b00 36353433 3039383709083d2d 72657771 69757974 5d5b706f 7361000a 68676664 3b6c6b6a5c006027