1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217
| #include "../include/linux/config.h"
INITSEG = DEF_INITSEG SYSSEG = DEF_SYSSEG SETUPSEG= DEF_SETUPSEG
.globl begtext,begdata,begbss,endtext,enddata,endbss .text begtext: .data begdata: .bss begbss: .text
entry start start: mov ax,#INITSEG mov ds,ax !int 0x15功能0x88取得扩展内存存在0x90002处 mov ah,#0x88 int 0x15 mov [2],ax
!0x12功能,获取EGA配置信息 mov ah,#0x12 mov bl,#0x10 int 0x10 mov [8],ax mov [10],bx mov [12],cx ! mov ax,#0x5019 cmp bl,#0x10 je novga call chsvga novga: mov [14],ax mov ah,#0x03 xor bh,bh int 0x10 mov [0],dx !取显卡当前显示模式 mov ah,#0x0f int 0x10 mov [4],bx mov [6],ax
!取第一个硬盘的参数 mov ax,#0x0000 mov ds,ax lds si,[4*0x41] !中断向量表中参数表地址hd0 mov ax,#INITSEG mov es,ax mov di,#0x0080 !存放到0x9000:0080 mov cx,#0x10 rep movsb !hd1参数表地址 mov ax,#0x0000 mov ds,ax lds si,[4*0x46] mov ax,#INITSEG mov es,ax mov di,#0x0090 mov cx,#0x10 rep movsb !检查系统是否有第2个硬盘 mov ax,#0x1500 mov dl,#0x81 !驱动器号0x81第一个硬盘 int 0x13 jc no_disk1 cmp ah,#3 !是否是硬盘 je is_disk1 no_disk1: mov ax,#INITSEG !第2个存储介质不存在, mov es,ax mov di,#0x0090 mov cx,#0x10 mov ax,#0x00 rep stosb is_disk1: cli !禁止外部中断 !首先将system移动到从内存地址0x0000开始 mov ax,#0x0000 cld do_move: mov es,ax add ax,#0x1000 cmp ax,#0x9000 jz end_move mov ds,ax !初始化为0x1000:0x0 sub di,di sub si,si mov cx,#0x8000 ! rep movsw jmp do_move
!加载段描述符 end_move: mov ax,#SETUPSEG mov ds,ax !指向本程序 lidt idt_48 !加载IDT寄存器 lgdt gdt_48 !加载GDT寄存器
!开启A20地址线 call empty_8042 !键盘芯片,等待输入缓冲区为空 mov al,#0xD1 out #0x64,al call empty_8042 mov al,#0xDF out #0x60,al call empty_8042 !
!主片端口0x20,0x21,从片端口0xA0-0xA1, mov al,#0x11 out #0x20,al !ICW1=0x11 .word 0x00eb,0x00eb out #0xA0,al !从片 .word 0x00eb,0x00eb !Liux系统硬件中断从0x20开始 mov al,#0x20 out #0x21,al !ICW2=0x20(对应中断号从0x20开始 .word 0x00eb,0x00eb mov al,#0x28 out #0xA1,al !从片ICW2 .word 0x00eb,0x00eb mov al,#0x04 !主片ICW3=0x04 out #0x21,al ! .word 0x00eb,0x00eb mov al,#0x02 out #0xA1,al !从片ICW3
.word 0x00eb,0x00eb mov al,#0x01 out #0x21,al !主片ICW4=0x01
.word 0x00eb,0x00eb out #0xA1,al !从片ICW4 .word 0x00eb,0x00eb mov al,#0xFF !屏蔽所有的中断(主+从 out #0x21,al .word 0x00eb,0x00eb out #0xA1,al
!修改cr0,进入保护模式 mov ax,#0x0001 lmsw ax jmpi 0,8 !第一个段选择子=代码段描述符 !从上面开始机器去执行system中的代码 !当输入缓冲器为空时,执行写命令,(键盘控制器的端口作为与A20地址线, empty_8042: .word 0x00eb,0x00eb in al,#0x64 !读取AT键盘控制器状态寄存器 test al,#2 ! jnz empty_8042 ret !显示卡部分未写
gdt: .word 0,0,0,0 !内核代码段选择符0x08 .word 0x07FF .word 0x0000 .word 0x9A00 .word 0x00C0 !内核数据段 0x10 .word 0x07FF .word 0x0000 .word 0x9200 .word 0x00C0 idt_48: .word 0 .word 0,0 gdt_48: .word 0x800 .word 512+gdt,0x9 !0x9000:512+gdt
msg1: .ascii "Press <RETURN> to see SVGA-modes available or any other key to continue." db 0x0d,0x0a,0x0a,0x00 msg2: .ascii "Mode: COLSxROWS:" db 0x0d,0x0a,0x0a,0x00 msg3: .ascii "Choose mode by pressing the corresponding number." db 0x0d,0x0a,0x00
!显卡特征数据串 idati: .ascii "761295520" idcandt: .byte 0xa5 idgenoa: .byte 0x77,0x00,0x66,0x99 idparadise: .ascii "VGA=" !..................
.text endtext: .data enddata: .bss endbss:
|