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文件格式的头部。