xv6源码分析(一):BootLoader

    xiaoxiao2021-03-26  12

    BootLoader是操作系统启动时的重要一环,负责从实模式切换到保护模式并且将存在存储设备的操作系统二进制文件读入内存,最后将控制权交给操作系统。

    一、计算机启动时的硬件动作

    PC机上电时运行的第一条指令总是存储在ROM中的BIOS指令,BIOS固件对硬件进行自检然后按照规范总是从磁盘的中的第一个扇区载入程序,并将其放入0x07c00地址处,一般情况下这个便是BootLoader,有些BootLoader较大无法用一个扇区存放,所以一般会分为好几部分,由最初的部分将它们载入到内存,然后将控制权交给BootLoader。

    二、 设置A20地址线

    x86架构的CPU由于考虑到向后兼容性,使得CPU在开始时处于实模式运行状态,只能使用20条地址线,这在现在肯定是无法满足的,通过设置地址线,可以完全使用所有地址线。具体设置过程主要是通过写端口数据来完成,这里就不阐述了,代码如下:

    # Physical address line A20 is tied to zero so that the first PCs # with 2 MB would run software that assumed 1 MB. Undo that. seta20.1: inb $0x64,%al # Wait for not busy testb $0x2,%al jnz seta20.1 movb $0xd1,%al # 0xd1 -> port 0x64 outb %al,$0x64 seta20.2: inb $0x64,%al # Wait for not busy testb $0x2,%al jnz seta20.2 movb $0xdf,%al # 0xdf -> port 0x60 outb %al,$0x60

    三、切换到保护模式

    在保护模式下,cs等段寄存器作为索引值存在的,cs的值作为索引在GDT(全局描述符表)中找到对应的段描述符,段描述符记录着段的起始地址,线性地址便由段起始地址+偏移组成 xv6在BootLoader下首先设置了临时的GDT:

    # Bootstrap GDT .p2align 2 # force 4 byte alignment gdt: SEG_NULLASM # null seg SEG_ASM(STA_X|STA_R, 0x0, 0xffffffff) # code seg SEG_ASM(STA_W, 0x0, 0xffffffff) # data seg gdtdesc: .word (gdtdesc - gdt - 1) # sizeof(gdt) - 1 .long gdt # address gdt

    BootLoader只划分了两个段,一个是0~4G的代码段,可执行,可读,另一个是0~4G的数据段,可写,两个段的起始地址都是0,于是进程中的虚拟地址直接等于线性地址。 GDT准备好了,接下来便可以载入GDT描述符到寄存器并开启保护模式,代码如下:

    # Switch from real to protected mode. Use a bootstrap GDT that makes # virtual addresses map directly to physical addresses so that the # effective memory map doesn't change during the transition. lgdt gdtdesc movl %cr0,
    转载请注明原文地址: https://ju.6miu.com/read-600239.html

    最新回复(0)