xv6启动源码阅读


最近在学习MIT的6.828操作系统课程,课程地址:

https://pdos.csail.mit.edu/6.828/2016/ 。6.828的课程自带了一个简单的基于unix的操作系统。打算写几篇阅读这个操作系统源码的文章。这是第一篇,主要讲解启动时候的主要操作。


一 bootloader的汇编代码部分

       我们知道,在计算机启动的时候,首先执行的代码是主板上的BIOS(Basic Input Output System).BIOS所做的主要是一些硬件自检的工作。在这些工作做完之后,它会从启动盘里读取第一扇区的512字节数据到内存中,这512字节实际上就是我们熟知的bootloader.在导入完之后,BIOS就会把CPU的控制权给bootloader.BIOS会把bootloader导入到地址0x7c00开始的地方,然后把PC指针设成此地址,以完成跳转。下面让我们看看bootloader的汇编部分代码:

.code16 # Assemble for 16−bit mode
.globl start
start:
cli # BIOS enabled interrupts; disable

 # Zero data segment registers DS, ES, and SS.
xorw %ax,%ax # Set %ax to zero
movw %ax,%ds # −> Data Segment
movw %ax,%es # −> Extra Segment
movw %ax,%ss # −> Stack Segment

.code16的意思是此段代码是16位的代码。为了保证向后的兼容性,在刚启动的时候,执行的是16位的代码。32位的代码要等到32位被使能之后才可以执行。

        BIOS在执行的时候会打开中断,但这是BIOS已经不在执行了,所以它的中断向量表之类的也就不在起作用了,bootloader此时应当关闭中断,在合适的时机再将中断打开。

               下面几条语句的用意是清掉段寄存器。在xv6中,我们有虚拟地址,逻辑地址,线性地址和物理地址的概念。虚拟地址的概念相信熟悉分页机制的肯定都知道。在进程中,指令操作的往往都不是实际的物理地址,因为这样会带来很多问题:安全问题,共享问题等等。所以用分页机制来做下转换,程序操作的都是虚拟地址,而这些虚拟地址都是不变的,操作系统负责将虚拟地址映射到实际的物理地址上,同样的虚拟地址在不同的时刻可能对应不同的物理地址。

         在x86指令架构中,虚拟地址通常是用逻辑地址来表示的,虚拟地址通常保存成这样的形式segment:offset,每条地址处在一个段中,segment是该段的基地址,各个地址相对于段基址的偏移被存在offset里面。程序中出现的实际上只有offset,硬件自动通过通过segment和offset算出线性地址,线性地址再经过页表等一系列处理得到实际的物理地址。

       在刚进入bootloader的时候,硬件处于实模式,在此模式下,只能使用16位的寄存器,但是真正可寻址的范围是20位地址,也就是1M的地址空间,硬件通过把segment左移四位然后加上offset的方式来得到线性地址,因为这时分页模式还没有打开,所以得到的就是实际的物理地址。

实模式下物理地址计算方式:segment >> 4 + offset.

        %ds, %es,%ss实际上存放的就是各个段的基地址(segment),其中ds代表数据段,es代表扩展段,ss代表堆栈段。在BIOS的时候可能会用到这些寄存器,在这里把寄存器清0.

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

       在上述计算物理地址的过程中,用到了两个16位的寄存器,那么两个寄存器的最大值都是0xffff,所以得到的物理地址的最大值应该是是0xffff0+0xffff = 0x10ffef,这个地址实际上是有21位的,但是在实模式下,8086/8088寻址地址实际上只有20位,这也就意味着最高位是无效的,得到的地址实际上是0xffef.

     但是在intel更高架构的处理器上(如80286),地址线总数是多余20位的,所以这21位是有效的,这就导致了在8086和80286在实模式下行为不一致。为了使行为一致,IBM采用了这样一种方法:当键盘控制器的输入为低时,清掉A21这位,只有键盘控制器的输入为高时,这一位才有效。具体的情形可以参考这篇文章:http://www.techbulo.com/703.html

     当然,在这里我们需要离开实模式了,所以我们要确保键盘控制器输出为高,以保证在80286以

  • 8
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值