6.828学习笔记 Boot Loader

Boot Loader

在前面说过BIOS完成初始化PCI和各种设备后,会寻找bootable device,如硬盘,CD-ROM等。然后BIOS从磁盘中读取boot loader。 

软盘和硬盘都会被分割成512 byte的区域,叫做sectors。sector是磁盘最小的交换粒度:每次读写操作必须大于等于一个sector,并分配在sector的边界上。如果一个disk是可启动的,第一个扇区就叫做boot sector,因为这是用于存放boot loader的代码的地方。BIOS找到bootalbe软盘或者硬盘,就加载512byte的boot sector至内存物理地址0x7c00到0x7dff的地方,然后使用jum指令条状至CS:IP to 0000:7c00,将控制权交给 boot loader. 这个地址是任意的,但是对于pc来说是固定,并且标准化了的。boot loader用汇编写于boot/boot.S和c语言写在C语言 boot/main.c。

Boot loader主要有两个功能。第一是将处理器从real mode切换至32-bit protected mode.因为只有在这个模式下软件可以进入所有在内存中超过1MB的处理器物理地址。该保护模式在PC Assembly Language中的第1.2.7和1.2.8中有介绍。(https://pdos.csail.mit.edu/6.828/2017/readings/pcasm-book.pdf) segmented address转换至物理地址在保护模式中有区别,并且transition offsets是32位而不是16位。第二,boot loader借助x86的特殊I/O指令,通过进入IDE disk device register从硬盘中读取内核。在IDE hard drive controller" section on the 6.828 reference page有相关介绍.

exercise 3:在地址0x7c00设置断点,在此处boot sector被加载。追踪在boot/boot.S的代码,使用源代码和反汇编出来的obj/boot/boot.asm来追查所在的位置。

Take a look at the lab tools guide, especially the section on GDB commands. Even if you're familiar with GDB, this includes some esoteric GDB commands that are useful for OS work.并使用GDB中x/i命令以反汇编boot loader中的指令顺序,并对比原来的boot loader源代码obj/boot/boot.asm和GDB。追踪在boot/main.c中的bootmain()函数,再接着进入readsect()。确认具体的符合每一个readsect()中的汇编指令。追踪剩下的readsect()并返回bootmain(),然后确认用于读取剩下内核sector的for循环的开始和结束。查找循环结束后的代码,设置断点。然后执行知道boot loader结束。

 

posted @ 2017-10-29 22:27  zz刚  阅读(799)  评论(0编辑  收藏  举报