操作系统与网络实现 之二十三(甲)

键盘中断

 

boot.asm

[BITS 16]                                                   ;编译成16位的指令

[ORG 0x7C00]

jmp                 main

 

read_kernelloader:                                          ;读入 kernelloader 程序

  push              es

 

  .rkl:

  mov               ax , 0x1000                             ;kernelloader.bin 所在的段基址           

  mov               es , ax

  mov               bx , 0                                  ;写入到内存0x1000:0000

  mov               ah , 2

  mov               dl , 0                                  ;驱动器号

  mov               ch , 0                                  ;磁道

  mov               cl , 2                                  ; 2个扇区开始

  mov               al , 2                                  ;读入扇区数,每个扇区为 512B

  int               0x13 

  jc                .rkl

 

  pop               es

  ret

 

main:                                                       ;主程序         

  mov               ax , 0x0                                ;boot.asm 程序的段基址

  mov               ds , ax

 

  call              read_kernelloader                       ;读入 kernelloader 程序 

 

  jmp dword         0x1000:0                                ;跳转到 kernelloader 处执行

times 510-($-$$) db 0

db 0x55

db 0xAA

 

kernelloader.asm

[BITS 16]  

jmp                 main

 

gdt_entries   equ    3         ;共有三个段描述符:null,os code32,os data32

 

pe            equ    1         ;bit PE in CR0

null          equ    0h

os_code32_sel equ    8h        ;1,gdt,rpl=00

os_data32_sel equ    10h    ;2,gdt,rpl=00

VESA:        times 256 db 0    ;分配一块区域存放 vesa 返回的信息,大小256,我们只需要其中的一个32位值

pdescr      times 6 db 0

gdt_table    times (gdt_entries*8) db 0

 

set_video_mode:                              ;设置显卡模式

  push              es

 

  ;设置显卡模式

  mov               ax , 0x4f02

  mov               bx , 0x4114             ;800X600 ( 5:6:5 ) 16位色

  int               0x10

  ;取得该模式下显存线性地址

  mov               bx , 0x1000

  mov               es , bx

  mov               di , VESA  ;es:di指向256空间,int 10h将在此填写数据

  mov               ax , 0x4f01

  mov               cx , 0x114

  int               0x10

  ;40个字节开始存有显存地址0xe0000000,将此地址再存入指定的地址0x10050,占四个字节

  mov               eax , [ es:VESA + 40 ]

  ;将此地址再存入指定的地址0x10050,因为实际运行中,在0x10040-0x10120都没有填入数据,都是可以利用的

  mov               [ es:0x50 ] , eax            ;es:bx 0x1000:0050=0x10050 内容为 0xe0000000

  pop               es

  ret

read_charpic:                          ;读入字库及图片

  push              es

  mov               ah , 2              ;磁盘读

  mov               dl , 0              ;驱动器号

  .rc1:

  mov               bx , 0x1000         ;asc16 所在的段基址           

  mov               es , bx

  mov               bx , 0x0400          ;写入到内存0x1000:0400 物理地址=0x10400

  mov               dh , 0               ;磁头

  mov               ch , 0               ;磁道

  mov               cl , 4               ;开始扇区

  mov               al , 15              ;读入扇区数,每个扇区为 512B

  int               0x13   

  jc                .rc1

 

  add               bx , 15*512           ;读入地址增加

  mov               di , 6                ;读入磁道数

  mov               dh , 1                ;磁头

  mov               ch , 0                ;磁道 

  call              readtrack

 

  .rc2:

  mov               ah , 2               ;磁盘读 

  mov               dh , 1               ;磁头

  mov               ch , 3               ;磁道

  mov               cl , 1               ;开始扇区

  mov               al , 3               ;读入扇区数,每个扇区为 512B

  int               0x13   

  jc                .rc2

;开始0x20000 

  mov               ah , 2               ;磁盘读

  mov               dl , 0               ;驱动器号

  .rc3:

  mov               bx , 0x2000          ;所在的段基址           

  mov               es , bx

  mov               bx , 0x0000          ;写入到内存物理地址0x20000

  mov               dh , 1               ;磁头

  mov               ch , 3               ;磁道

  mov               cl , 4               ;开始扇区

  mov               al , 15              ;读入扇区数,每个扇区为 512B

  int               0x13   

  jc                .rc3

 

  add               bx , 15*512           ;读入地址增加

 

  mov               di , 6               ;读入磁道数

  mov               dh , 0               ;磁头

  mov               ch , 4               ;磁道

  call              readtrack

 

  .rc4:

  mov               ah , 2               ;磁盘读

  mov               dh , 0               ;磁头

  mov               ch , 7               ;磁道

  mov               cl , 1               ;开始扇区

  mov               al , 5               ;读入扇区数,每个扇区为 512B

  int               0x13   

  jc                .rc4

 

;开始0x30000 

  mov               ah , 2               ;磁盘读

  mov               dl , 0               ;驱动器号

  .rc5:

  mov               bx , 0x3000           ;所在的段基址           

  mov               es , bx

  mov               bx , 0x0000           ;写入到内存物理地址0x30000

  mov               dh , 0               ;磁头

  mov               ch , 7               ;磁道

  mov               cl , 6               ;开始扇区

  mov               al , 13              ;读入扇区数,每个扇区为 512B

  int               0x13   

  jc                .rc5

 

  add               bx , 13*512            ;读入地址增加

 

  mov               di , 6               ;读入磁道数

  mov               dh , 1               ;磁头

  mov               ch , 7               ;磁道

  call              readtrack

 

  .rc6:

  mov               ah , 2               ;磁盘读

  mov               dh , 1               ;磁头

  mov               ch , 10               ;磁道

  mov               cl , 1               ;开始扇区

  mov               al , 7               ;读入扇区数,每个扇区为 512B

  int               0x13   

  jc                .rc6 

 

;开始0x40000 

  mov               ah , 2               ;磁盘读

  mov               dl , 0               ;驱动器号

  .rc7:

  mov               bx , 0x4000          ;所在的段基址           

  mov               es , bx

  mov               bx , 0x0000          ;写入到内存物理地址0x40000

  mov               dh , 1               ;磁头

  mov               ch , 10              ;磁道

  mov               cl , 8               ;开始扇区

  mov               al , 11              ;读入扇区数,每个扇区为 512B

  int               0x13   

  jc                .rc7

 

  add               bx , 11*512          ;读入地址增加

 

  mov               di , 6               ;读入磁道数

  mov               dh , 0               ;磁头

  mov               ch , 11              ;磁道

  call              readtrack

 

  .rc8:

  mov               ah , 2               ;磁盘读

  mov               dh , 0               ;磁头

  mov               ch , 14              ;磁道

  mov               cl , 1               ;开始扇区

  mov               al , 9               ;读入扇区数,每个扇区为 512B

  int               0x13   

  jc                .rc8

 

;开始0x50000 

  mov               ah , 2               ;磁盘读

  mov               dl , 0               ;驱动器号

  .rc9:

  mov               bx , 0x5000          ;所在的段基址           

  mov               es , bx

  mov               bx , 0x0000          ;写入到内存物理地址0x50000

  mov               dh , 0               ;磁头

  mov               ch , 14              ;磁道

  mov               cl , 10              ;开始扇区

  mov               al , 9               ;读入扇区数,每个扇区为 512B

  int               0x13   

  jc                .rc9

 

  add               bx , 9*512            ;读入地址增加

 

  mov               di , 6               ;读入磁道数

  mov               dh , 1               ;磁头

  mov               ch , 14              ;磁道

  call              readtrack

 

  .rc10:

  mov               ah , 2               ;磁盘读

  mov               dh , 1               ;磁头

  mov               ch , 17              ;磁道

  mov               cl , 1               ;开始扇区

  mov               al , 11              ;读入扇区数,每个扇区为 512B

  int               0x13   

  jc                .rc10

 

;开始0x60000 

  mov               ah , 2               ;磁盘读

  mov               dl , 0               ;驱动器号

  .rc11:

  mov               bx , 0x6000          ;所在的段基址           

  mov               es , bx

  mov               bx , 0x0000          ;写入到内存物理地址0x60000

  mov               dh , 1               ;磁头

  mov               ch , 17              ;磁道

  mov               cl , 12               ;开始扇区

  mov               al , 7                ;读入扇区数,每个扇区为 512B

  int               0x13   

  jc                .rc11

 

  add               bx , 7*512            ;读入地址增加

 

  mov               di , 6               ;读入磁道数

  mov               dh , 0               ;磁头

  mov               ch , 18              ;磁道

  call              readtrack

 

  .rc12:

  mov               ah , 2               ;磁盘读

  mov               dh , 0               ;磁头

  mov               ch , 21              ;磁道

  mov               cl , 1               ;开始扇区

  mov               al , 13              ;读入扇区数,每个扇区为 512B

  int               0x13   

  jc               .rc12

 

;开始0x70000 

  mov               ah , 2               ;磁盘读

  mov               dl , 0               ;驱动器号

  .rc13:

  mov               bx , 0x7000          ;所在的段基址           

  mov               es , bx

  mov               bx , 0x0000           ;写入到内存物理地址0x70000

  mov               dh , 0                ;磁头

  mov               ch , 21               ;磁道

  mov               cl , 14               ;开始扇区

  mov               al , 1                ;读入扇区数,每个扇区为 512B

  int               0x13   

  jc                .rc13

 

  pop es

  ret 

 

;读入几个磁道子程序

;;di  读入的磁道总数

;;dh  磁头

;;ch  开始磁道

readtrack:

  .r_1:

  mov               ah , 2                                  ;;功能号 2 表示读磁盘扇区

  mov               cl , 1                                  ;;启始扇区1扇区

  mov               al , 18                                 ;;读入扇区数

  int               0x13

  jc                .r_1

  add               bx , 18 * 512      ;读入地址增加

  dec               di

  cmp               di , 0

  je                .r_2

 

  xor               dh , 1           ;反转磁头

  cmp               dh , 0           ;这里与磁盘读写独特的规律有关,0.0 1.0 0.1 1.1 0.2 1.2 ......如果反转值为0,磁道数要加1

  jne               .r_1

  inc               ch

  jmp               .r_1

 

  .r_2:

  ret

 

read_kernel:                               ;读入 kernel 程序

  push              es

 

  .rk:

  mov               ax , 0x8000            ;kernel.bin 所在的段基址           

  mov               es , ax

  mov               bx , 0               ;写入到内存0x8000:0000 物理地址=0x80000

  mov               ah , 2

  mov               dl , 0               ;驱动器号

  mov               dh , 0               ;磁头0

  mov               ch , 26              ;磁道

  mov               cl , 1               ;1个扇区开始

  mov               al , 18              ;读入扇区数,每个扇区为 512B

  int               0x13   

  jc                .rk

 

  pop               es

  ret

 

main:

mov ax,1000h

mov ds,ax

;设置显卡模式

call              set_video_mode

;读入 kernel

call              read_kernel

;读入字库及图片

call read_charpic

;打开 A 20 地址线

mov               ax , 0x2401

int               0x15 

;[1]built up GDT table

cli

mov  eax,gdt_table

;item 0:null descriptor,

mov  dword[eax],0

mov  dword[eax+4],0

add  eax,8

;item 1,OS code32 descriptor,

;Base=00000000h,limit=0ffh,G=1,D=1,type=a,dpl=0

mov  word[eax],0ffh

mov  word[eax+2],0

mov  byte[eax+4],00h

mov  byte[eax+5],09ah

mov  byte[eax+6],0c0h

mov  byte[eax+7],00h

add  eax,8

;item 2,OS data32 descriptor

;Base=00000000h,Limit=0fffffh,G=1,D=1,Type=2,DPL=0

mov  word[eax],0ffffh

mov  word[eax+2],0000h

mov  byte[eax+4],00h

mov  byte[eax+5],092h

mov  byte[eax+6],0cfh    ;高四位是G D 0 AVL,此处为1100 = c ,低四位是limit bit 16-19 此处为f

mov  byte[eax+7],00h

add  eax,8

;[2]built false GDT descriptor

mov  word[pdescr+0],(gdt_entries*8)     

mov  dword[pdescr+2],gdt_table+00010000h

lgdt [pdescr]

;[3]enter into protected mode

;刷新CR0

mov eax,cr0

or  eax,pe

mov cr0,eax

jmp flush

flush:

mov ax,os_data32_sel

mov ds,ax

mov es,ax

mov ss,ax

mov fs,ax

mov gs,ax

jmp dword os_code32_sel:0x80000  ;跳转到0x8000:0000保护模式  物理地址0x80000  ->kernel.asm

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值