linux0.11学习2之setup

setup.asm上一篇文章中的setup是用于测试的,不是linux中的setup。现在给出linux中的setup的源代码(nasm实现)

;;setup.asm
[section .data]
INITSEG equ 0x9000
SYSSEG equ 0x1000
SETUPSEG equ 0x9020
[section .text]
mov ax,INITSEG   ;将系统数据放到0x90000处
mov ds,ax

mov ah,0x03    ;获取光标的位置
xor bh,bh
int 0x10
mov [0],dx

mov ah,0x88    ;获取扩展内存大小
int 0x15
mov [2],ax

mov ah,0x0f   ;获取显卡当前显示模式
int 0x10
mov [4],bx
mov [6],ax

mov ah,0x12    ;获取EGA/VGA的显示模式及参数
mov bl,0x10
int 0x10
mov [8],ax
mov [10],bx
mov [12],cx

mov ax,0x0000    ;复制第一个硬盘的参数表到0x90080处
mov ds,ax
lds si,[4*0x41]
mov ax,INITSEG
mov es,ax
mov di,0x80
mov cx,0x10
rep
movsb

mov ax,0x0000    ;复制第二个硬盘的参数表到0x90090处
mov ds,ax
lds si,[4*0x46]
mov ax,INITSEG
mov es,ax
mov di,0x90
mov cx,0x10
rep
movsb

mov ax,0x1500 ;检查是否存在第二个硬盘,如果不存在,
mov dl,0x81   ;将0x90090处的第二个硬盘的参数表清零
int 0x13
jc no_disk1
cmp ah,0x3
je is_disk1
no_disk1:
mov ax,INITSEG
mov es,ax
mov di,0x0090
mov cx,0x10
mov ax,0x00
rep
stosb

is_disk1:
;现在要进入保护模式
cli
mov ax,0x0000
cld
             ;首先把system从0x10000处移动到0x00000处

do_move:
mov es,ax
add ax,0x1000
cmp ax,0x9000
jz end_move
mov ds,ax
sub di,di
sub si,si
mov cx,0x8000
rep
movsw
jmp do_move

end_move:
         mov ax,SETUPSEG
         mov ds,ax       ;将idt表,gdt表的信息加载到相应的寄存器
         lidt [idt_48]
         lgdt [gdt_48]

call empty_8042           ;打开A20地址线
mov al,0xD1
out 0x64,al
call empty_8042
mov al,0xDF
out 0x60,al
call empty_8042

mov al,0x11     ;初始化8259,设置ICW1
out 0x20,al
dw 0x00eb,0x00eb
out 0xA0,al
dw 0x00eb,0x00eb

mov al,0x20     ;设置ICW2
out 0x21,al
dw 0x00eb,0x00eb
mov al,0x28
out 0xA1,al
dw 0x00eb,0x00eb

mov al,0x04     ;设置ICW3
out 0x21,al
dw 0x00eb,0x00eb
mov al,0x02
out 0xA1,al
dw 0x00eb,0x00eb

mov al,0x01      ;设置ICW4
out 0x21,al
dw 0x00eb,0x00eb
out 0xA1,al
dw 0x00eb,0x00eb

mov al,0xFF      ;设置OCW1
out 0x21,al
dw 0x00eb,0x00eb
out 0xA1,al

mov ax,0x0001    ;置cr0的第0位为1,表示进入保护模式
lmsw ax

jmp 8:0        ;跳到cs段8,偏移0处,此时已启动保护模式,即0x00000处
               ;system的最开始位置

empty_8042:
dw 0x00eb,0x00eb
in al,0x64
test al,2
jnz empty_8042
ret

gdt:
dw 0,0,0,0   ;第一个描述符,不用

dw 0x07FF    ;code 段的描述符,段长=2048*4096=8M
dw 0x0000    ;base address=0
dw 0x9A00    ;code read/exec
dw 0x00c0    ;granularuty=4096,386

dw 0x07FF    ;data 段的描述符,段长=2048*4096=8M
dw 0x0000    ;base address=0
dw 0x9200    ;data read/write
dw 0x00c0    ;granularuty=4096,386

idt_48:
dw 0
dw 0,0

gdt_48:
dw 0x800
dw 512+gdt,0x9    ;0x90200+gdt




用于测试的system.asm 因为此时不能用bios中断了,所以要改一下system

bits 32
[section .text]
mov ax,cs
mov es,ax
mov ax,0x10
mov gs,ax
mov edi,(80 * 11 + 0)*2 +0xb8000 
mov ah,0Ch
mov al,'f'
mov [gs:edi],ax 

jmp $

把setup.asm和system.asm编译成.bin文件,再按照上一篇文章的方法执行。

结果图:



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值