github項目的地址
參考前面一部分
ucore–可讀ELF格式文件的baby bootloader–proj2-第一部分
https://blog.csdn.net/sgy1993/article/details/89277000
之前實現的功能只能讀取到內存裏面,但是因爲沒有相應的鏡像,也沒有相應的跳轉代碼
這一部分我們加上了可以生成內核鏡像的Makefile
下面看一下Makefile裏面是怎麼生成的kernel鏡像呢?
+ cc kern/init/init.c
gcc -Ikern/init/ -fno-builtin -Wall -ggdb3 -m32 -nostdinc -fno-stack-protector -Ilibs/ -Ikern/driver -c kern/init/init.c -o obj/kern/init/init.o
+ ld bin/kernel
ld -m elf_i386 -Ttext 0x100000 -e kern_init -o bin/kernel obj/kern/init/init.o
可以看出來kernel可執行文件是這麼生成的
-Ttext 表示代碼段的鏈接地址, 這裏鏈接地址和加載地址是一致的,所以在虛擬地址 0x100000,就是內核代碼應該運行的地方。
關於鏈接地址和加載地址的介紹
https://blog.csdn.net/sgy1993/article/details/89281964
然後我們把內核可執行文件放進了ucore.img的第2個磁盤分區當中
dd if=bin/kernel of=bin/ucore.img seek=1 conv=notrunc
我們可以以二進制的格式打開這個文件看一下,
首先是kernel文件
然後我們打開ucore.img 文件,我們看 0x200偏移的地方是不是存放內核的地方。
你可以發現確實是一樣的。
然後我們調試一下程序,看一看內核鏡像是否被加載到0x100000的地方
看一下我們的bootmain函數
void
bootmain(void) {
// read the 1st page off disk
readseg((uintptr_t)ELFHDR, SECTSIZE * 8, 0);
// is this a valid ELF?
if (ELFHDR->e_magic != ELF_MAGIC) {
cons_putc('E');
}
cons_putc('O');
/* do nothing */
while (1);
}
如果拷貝到那個地方,就不會打印E,結果確實沒有打印E,打印了一個O
我們通過gdb 調試查看一下結果
(gdb) x /16x 0x100000
0x100000: 0x7f 0x45 0x4c 0x46 0x01 0x01 0x01 0x00
0x100008: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
(gdb)
可以和上面那張kernel的圖片進行對比,會發現數據是一樣的。確實拷貝進去了。
這個地方讀取的並不是kernel整個鏡像,而是elf文件格式的頭部。