Chinaunix首页 | 论坛 | 博客
  • 博客访问: 267955
  • 博文数量: 45
  • 博客积分: 1618
  • 博客等级: 上尉
  • 技术积分: 530
  • 用 户 组: 普通用户
  • 注册时间: 2010-09-11 10:13
文章分类

全部博文(45)

文章存档

2012年(1)

2011年(25)

2010年(19)

我的朋友

分类:

2010-10-10 21:19:19

1、关中断,标记位IF设为0。设置串处理从低地址向高地址处理(SI、DI增大),即DF为0

cli
cld

2、相关寄存器清零,堆栈寄存器设置为0x7c00开始

xorw    %ax,%ax            # Segment number zero
movw    %ax,%ds            # -> Data Segment
movw    %ax,%es            # -> Extra Segment
movw    %ax,%ss            # -> Stack Segment
# 设置堆栈指针, 从0x7c00
向下,start是该段代码的起始标号,即0x7c00
movw    $start,%sp

3、A20地址线:从80286开始,系统出现了一种新的机制,被称为保护模式。到了80386,保护模式得到了进一步的完善和发展,并且对于80386以后的芯片,保护模式的变化就非常小了。在保护模式下,如果A20 Gate被禁止,则可以访问的内存只能是奇数1M段,即1M,3M,5M…,也就是00000-FFFFF, 200000-2FFFFF,300000-3FFFFF…。如果A20 Gate被打开,则可以访问的内存则是连续的。而实模式要想访问1M以上的内存也要打开,所以A20 Gate无论如何都要打开的打开A20 Gate,从理论上讲,打开A20 Gate的方法是通过设置8042芯片输出端口(64h)的2nd-bit,但事实上,当你向8042芯片输出端口进行写操作的时候,在键盘缓冲区中,或许还有别的数据尚未处理,因此你必须首先处理这些数据。

seta20.1:    inb    $0x64,%al        # 获取状态 in al,0x64
        testb    $0x2,%al        # Busy? test al,0x02
        jnz    seta20.1        # Yes 占用则跳转
        movb    $0xd1,%al        # Command: Write
        outb    %al,$0x64        # output port
seta20.2:    inb    $0x64,%al        # Get status
        testb    $0x2,%al        # Busy?
        jnz    seta20.2        # Yes
        movb    $0xdf,%al        # Enable
        outb    %al,$0x60        # A20 ROM BASIC 入口

4、装载全局描述符,并设置cr0(PE位设置为1)进入使系统进入保护模式

real_to_prot:    cli            # 现在还不能允许中断
                    # 我们还没有设置中断描述符表

        lgdt    gdtdesc        #  加载全局描述符
        movl    %cr0, %eax    # 打开保护模式 cr0为控制寄存器,还有 cr1 cr2 cr3
        orl    $CR0_PE_ON, %eax   #.set CR0_PE_ON,0x1
        movl    %eax, %cr0

5、接下来系统进入32位的保护模式,进行了一个关键跳转

.set PROT_MODE_CSEG,0x8        # code segment selector
.set PROT_MODE_DSEG,0x10 # data segment selector
ljmp    $PROT_MODE_CSEG, $protcseg

注意PROT_MODE_CSEG为段选择子,段选择子的格式如下

所以对于PROT_MODE_CSEG定义为0x8而言,就是选择第一个代码段,也即是当前执行的代码段,同样$protcseg也即是当前代码里面的$protcset处,程序也就跳入了32位的保护模式进行运行
6、下面是一些寄存器的初始化,并跳入c代码运行

        movw    $PROT_MODE_DSEG, %ax    # Our data segment selector
        movw    %ax, %ds        # -> DS: Data Segment
        movw    %ax, %es        # -> ES: Extra Segment
        movw    %ax, %fs        # -> FS
        movw    %ax, %gs        # -> GS
        movw    %ax, %ss        # -> SS: Stack Segment
    
        call cmain            # finish the boot load from C.


阅读(1651) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~