[转帖]x86多任务內核实例-boot.s_VMware, Unix及操作系统讨论区_Weblogic技术|Tuxedo技术|中间件技术|Oracle论坛|JAVA论坛|Linux/Unix技术|hadoop论坛_联动北方技术论坛  
网站首页 | 关于我们 | 服务中心 | 经验交流 | 公司荣誉 | 成功案例 | 合作伙伴 | 联系我们 |
联动北方-国内领先的云技术服务提供商
»  游客             当前位置:  论坛首页 »  自由讨论区 »  VMware, Unix及操作系统讨论区 »
总帖数
1
每页帖数
101/1页1
返回列表
0
发起投票  发起投票 发新帖子
查看: 3311 | 回复: 0   主题: [转帖]x86多任务內核实例-boot.s        下一篇 
一路向北
注册用户
等级:少校
经验:903
发帖:56
精华:6
注册:2012-12-19
状态:离线
发送短消息息给一路向北 加好友    发送短消息息给一路向北 发消息
发表于: IP:您无权察看 2012-12-21 13:55:39 | [全部帖] [楼主帖] 楼主

!boot.s

!首先利用BIOS中断把内核代码(head代码)加载到内存0x1000处,然后移动到内存0处,

!最后进入保护模式,并跳转到内存0(head代码)开始处继续运行

BOOTSEG = 0X07C0 !引导程序(本程序)被BIOS加载到内存0x7c00处

SYSSEG  = 0X1000 !内核第一步加载到的地址

SYSLEN  = 17 !内核占用的最大磁盘数

entry start

start:

Jmpi go,#BOOTSEG !段间跳转到0x7c0:go处。这指令还会带来加载CS等的段寄存器效果。

go: mov ax,cs !cs现在为0x7c0

mov ds,ax !ds(数据段),ss(堆栈段)段寄存器也都为0x7c0

mov ss,ax !

mov sp,#0x400 !sp栈顶指针为0x400

!加载head代码到 0x1000处,这个代码是利用BIOS中断,从软盘读取数据到内存,

!这里也就说明了,为什么要先移动到0x1000,而不直接移动到0x0,因为现在BIOS中断

!才能从软盘读数据,而先移动到0x1000是为了不覆盖掉BIOS。等移动到0x1000后,就可以

!覆盖BIOS,移动到0x0处了。

load_system:

mov dx,#0x0000 !利用BIOS中断int 0x13功能2从启动盘读取head代码

mov cx,#0x0002 !DH-磁头号;DL驱动器号;CH是10位磁道号的低8位;

mov ax,#SYSSEG !CL的7,6位是磁道号的高2位,其5-0位是起始扇区号

mov es,ax !ES:BX 读入缓冲区位置(0x1000:0x0000).

xor bx,bx !AH-读扇区功能号;AL-需读的扇区数(17)

mov ax,#0x200+SYSLEN !

int 0x13 !

jnc ok_load !

die: jmp die !

!把内核代码移动到内存0开始处,共移动8KB字节(内核长度不超过8KB)

ok_load cli !disable interrupt

mov ax,#SYSSEG !

mov ds,ax !

xor ax,ax !

mov es,ax !

mov cx,#0x1000 !

sub si,si !

sub di,di

rep

movw  ! MOVW:将DS:SI的内容送至ES:DI,是复制过去. 

!加载IDT和GDT基地址寄存器IDTR和GDTR

mov ax, #BOOTSEG

mov ds, ax !数据段DS指向0x7c0

lidt idt_48 !加载IDTR。idt_48定义在后面,2字节表长度,4字节基地址

lgdt gdt_48 !同上

!设置控制寄存器CR0(即机器状态字),进入保护模式,段选择符值8对应GDT表中第2个段描述符

mov ax, #0x0001 !对应保护模式开启位PE(位0)

lmsw ax !加载状态字指令,即将ax放入CR0

jmpi 0,8 !段间跳转,保护模式jmpi这里的8是是相对于GDT表中的位置。我们知道逻辑地址是段选择符(这里的8就是段选择符,对应GDT表的第1项(第0项为空),加上偏移地址。这个要跳转的地址的为GDT表中第一个段描述的中的基地址加上偏移量0).段选择符的0-1位是RPL(请求特权级),2位是TI(1表示在LDT表中,0表示在GDT表中),3-15位是索引值。所以0x08就是表示GDT表中的第一项,且请求特权级为0。

!GDT表定义

gdt .word 0,0,0,0 !第一个段描述符全为空不用,格式参考4.3.4段描述符。



.word 0x07ff !段限长 2048

.word 0x0000 !段基值 0x0

.word 0x9a00 !标识为代码段 可读/可执行

.word 0x00c0 !颗粒度 4KB,结合段限长2048.则此段实际最大长度为8M



.word 0x07ff !略

.word 0x0000 !

.word 0x9200 !

.word 0x00c0 !

!定义idt(中断描述符表),gdt段寄存器值.用来存放GDT表的32位基地址和16为段限长

idt_48: .word 0 ! IDT表长度

.word 0,0 ! IDT表的线性基地址0

gdt_48: .word 0x7ff ! GDT表长度是2048字节,可容纳256个描述项

.word 0x7c00+gdt,0 ! GDT表的线性基地址在0x7c0段的偏移gdt处

.org 510 ! 对齐到510

.word 0xAA55 ! 第512字节(引导扇区最后),为有效标志字节,应为0xAA55




赞(0)    操作        顶端 
总帖数
1
每页帖数
101/1页1
返回列表
发新帖子
请输入验证码: 点击刷新验证码
您需要登录后才可以回帖 登录 | 注册
技术讨论