ucore--可读ELF格式文件的baby bootloader--proj2-第二部分

github项目的地址

https://github.com/sgy1993/ucore_step_by_myself

参考前面一部分

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

发布了17 篇原创文章 · 获赞 3 · 访问量 3548

猜你喜欢

转载自blog.csdn.net/sgy1993/article/details/89280071
今日推荐