ucore lab1结合原理的实现

本文详细介绍了计算机从硬件启动到加载bootloader的过程,包括关闭中断、设置A20地址线、初始化GDT、开启保护模式等步骤。接着讲解了如何加载内核代码,并初始化IDT,特别是用户态与内核态转换的重点,涉及到栈的变化和中断处理机制。
摘要由CSDN通过智能技术生成

首先,从计算机硬件启动开始说起,开始启动的时候,CPU产生一个RESET,设定一些处理器,从ROM的0Xfffffff0开始执行,进行POST(上电自检),初始化硬件设备,紧接着搜索操作系统来启动,在这个过程中试图访问磁盘的第一个扇区也称为引导扇区(512个字节),只要能找到一个有效的磁盘,那就将这个扇区拷贝到内存0x00007c00开始的位置,跳转,加载这个扇区的代码,也就是bootloader

在这个阶段,我们需要做的最主要的有3部,为载入内核的代码做好准备。首先bootloader开始的时候需要关闭中断,设置代码从地址递增的方向执行,对8042键盘进行读写操作,置位A20地址线(为了兼容8086遗留下来的原因),使得在保护模式的时候,21位地址不会一直为0.接着我们需要加载GDTR(GDT的大小和基地址),初始化全局描述符表。最后通过置位Cr0寄存器的PE位开启保护模式,然后通过段选择子跳转到内核代码开始的位置设置DS,ES,FS,GS,SS,以及BIOS的数据栈位0-0x7c00(ebp:0,esp:0x7c00).

关中断,初始化寄存器,然后使能了A20。

.globl start
start:
.code16                                             # Assemble for 16-bit mode
    cli                                             # Disable interrupts
    cld                                             # String operations increment

    xorw %ax, %ax                                   # Segment number zero
    movw %ax, %ds                                   # -> Data Segment
    movw %ax, %es                                   # -> Extra Segment
    movw %ax, %ss                                   # -> Stack Segment
seta20.1:
    inb $0x64, %al                                  # Wait for not busy(8042 input buffer empty).
    testb $0x2, %al
    jnz seta20.1

    movb $0xd1, %al                                 # 对0x64写入0xd1
    outb %al, $0x64                                 # 0xd1 means: write data to 8042's P2 port

seta20.2:
    inb $0x64, %al                                  # Wait for not busy(8042 input buffer empty).
    testb $0x2, %al
    jnz seta20.2

    movb $0xdf, %al                                 # 对0x60写入0xdf使能了A20
    outb %al, $0x60                                 # 0xdf = 11011111, means set P2's A20 bit(the 1 bit) to 1
.p2align 2                                          # force 4 byte alignment
gdt:    #标识符  表示地址
    SEG_NULLASM                                     # null seg    第一段永远为0  不用的
    SEG_ASM(STA_X|STA_R, 0x0, 0xffffffff)           # code seg for bootloader and kernel
    SEG_ASM(STA_W, 0x0, 0xffffffff)                 # data seg for bootloader and kernel

gdtdesc:					    # GDTR寄存器  用lgdt加载
    .word 0x17                                      # sizeof(gdt) - 1
    .long gdt                                       # address gdt 

通过SEG_ASM设置全局描述符,这里只是简单的为内核的代码加载初始化GDT而已。


                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值