Blob
1 [cpu 286]2 [bits 16]4 %include "macros.inc"6 struc TSS7 .link: resw 1 ; +0x008 .sp0: resw 1 ; +0x029 .ss0: resw 1 ; +0x0410 .sp1: resw 1 ; +0x0611 .ss1: resw 1 ; +0x0812 .sp2: resw 1 ; +0x0a13 .ss2: resw 1 ; +0x0c14 .ip: resw 1 ; +0x0e15 .flags: resw 1 ; +0x1016 .ax: resw 1 ; +0x1217 .cx: resw 1 ; +0x1418 .dx: resw 1 ; +0x1619 .bx: resw 1 ; +0x1820 .sp: resw 1 ; +0x1a21 .bp: resw 1 ; +0x1c22 .si: resw 1 ; +0x1e23 .di: resw 1 ; +0x2024 .es: resw 1 ; +0x2225 .cs: resw 1 ; +0x2426 .ss: resw 1 ; +0x2627 .ds: resw 1 ; +0x2828 .ldtr: resw 1 ; +0x2a29 .size: ; +0x2c30 endstruc32 section .text33 extern floppy_init34 global _entry35 global putchar36 global puts37 global puthexb38 global puthexw39 global panic40 _entry:41 pop dx42 mov byte [bootdrv], dl44 ; copy user task into 0x2000:045 mov ax, 0x200046 mov es, ax47 xor di, di48 lea si, [user]49 lea cx, [user.end - user]50 rep movsb52 ; clear screen53 mov bx, 0xb80054 mov es, bx55 xor di, di56 mov ax, (' ' | (0x07 << 8))57 mov cx, (80 * 25 * 2)58 rep stosw60 ; get size of conventional memory (below 640K)61 int 0x1262 mov word [convmem], ax64 ; get size of extended memory (above 1M)65 mov ah, 0x8866 int 0x1567 jc .noxm68 mov word [highmem], ax70 .noxm:71 ; NOTE: BIOS cannot be accessed from here72 cli74 ; disable keyboard75 call .wait76 mov al, 0xAD77 out 0x64, al79 ; read from input80 call .wait81 mov al, 0xD082 out 0x64, al83 call .wait284 in al, 0x6085 mov bl, al87 ; write to output88 call .wait89 mov al,0xD190 out 0x64,al91 call .wait92 mov al, bl93 or al, 2 ; enable A20 line94 out 0x60, al96 ; enable keyboard97 call .wait98 mov al, 0xAE99 out 0x64, al100 call .wait101 jmp .setup103 .wait:104 in al,0x64105 test al, 2106 jnz .wait107 ret110 .wait2:111 in al,0x64112 test al,1113 jz .wait2114 ret116 .setup:117 lidt [idtr]118 lgdt [gdtr]119 smsw ax120 or ax, 1121 lmsw ax122 jmp (gdt.text - gdt):.reloadcs124 .reloadcs:125 lea sp, [stack]126 lea ax, [gdt.data - gdt]127 mov ds, ax128 mov es, ax129 mov ss, ax131 ; initialize PIC132 outb_slow 0x20, 0x11 ; Start the initialization routine (in cascae mode)133 outb_slow 0xA0, 0x11134 outb_slow 0x21, 0x20 ; Master PIC IRQ offset135 outb_slow 0xA1, 0x28 ; Slave PIC IRQ offset136 outb_slow 0x21, 4 ; Tell the master PIC that there is a slave PIC at IRQ2137 outb_slow 0xA1, 2 ; Tell the slave PIC it's cascade identity138 outb_slow 0x21, 1 ; Use the 8086-mode (and not the 8088 mode)139 outb_slow 0xA1, 1140 outb_slow 0x21, 0xfe ; Set the IRQ masks141 outb_slow 0xA1, 0xff143 ; initialize IDT144 mov al, 0x20145 mov ah, 0x86146 lea dx, [i_timer]147 call set_irq148 mov al, 0x80149 mov ah, 0xe6150 lea dx, [i_sys]151 call set_irq153 lea bp, [convmsg]154 call puts155 mov ax, word [convmem]156 call puthexw157 lea bp, [kbmsg]158 call puts160 lea bp, [xmmsg]161 call puts162 mov ax, word [highmem]163 call puthexw164 lea bp, [kbmsg]165 call puts167 call floppy_init169 ; set up TSS170 mov word [tss + TSS.link], 0171 mov word [tss + TSS.sp0], stack172 mov word [tss + TSS.ss0], (gdt.data - gdt)174 ; load TSS into TR175 lea ax, [gdt.tss - gdt]176 ltr ax178 ; load LDT179 lea ax, [gdt.ldt - gdt]180 lldt ax182 ; enter userspace, TODO: enter ring 3183 mov ax, 0x0f ; LDT .data184 mov ds, ax185 mov es, ax186 push 0x17 ; ss (LDT .stack)187 push 0xfffe ; sp188 push 0x202 ; flags (EI | 0x02)189 push 0x07 ; cs (LDT .text)190 push 0 ; ip191 iret193 i_timer:194 pusha195 push ds196 push es198 mov ax, (gdt.data - gdt)199 mov ds, ax200 mov es, ax202 mov al, '.'203 call putchar205 outb 0x20, 0x20206 pop es207 pop ds208 popa209 iret211 ; ds:si - from212 ; es:di - to213 ; cx - count214 copy_from_user:215 rep movsb216 ret218 i_sys: ; syscall interrupt (0x80)219 push ds220 push es222 ; load kernel .data into es223 push ax224 mov ax, (gdt.data - gdt)225 mov es, ax226 pop ax228 test ax, ax229 jz .print231 ; invalid interrupt232 mov ax, -1233 jmp .ret236 .print:237 push cx238 mov si, bx239 lea di, [ubuf]240 ; TODO: check that cx < sizeof(ubuf)241 call copy_from_user242 pop bx243 mov byte [ubuf + bx], 0245 ; load kernel .data into ds & es246 lea ax, [gdt.data - gdt]247 mov ds, ax248 mov es, ax250 lea bp, [ubuf]251 call puts252 xor ax, ax253 jmp .ret255 .ret:256 pop es257 pop ds258 iret260 ; al - num261 ; ah - attr262 ; dx - offset263 set_irq:264 xor bh, bh265 mov bl, al266 shl bx, 3267 lea bx, [idt + bx]268 mov word [bx + 0], dx269 mov word [bx + 2], (gdt.text - gdt)270 mov byte [bx + 4], 0x00271 mov byte [bx + 5], ah272 mov word [bx + 6], 0273 ret275 error:276 cli277 lea bp, [errstr]278 call puts279 hlt280 jmp $282 ; ax - value283 puthexw:284 push ax285 mov al, ah286 call puthexb287 pop ax288 jmp puthexb290 ; al - value291 puthexb:292 push ax293 shr al, 4294 call puthexch295 pop ax296 and al, 0xf297 jmp puthexch299 ; al - hex digit300 puthexch:301 cmp al, 10302 jae .hex303 add al, '0'304 jmp putchar306 .hex:307 add al, 'a' - 10308 jmp putchar310 ; al - char311 writech:312 lea bx, [gdt.vid - gdt]313 mov es, bx315 xor ch, ch316 xor dh, dh317 mov cl, byte [posx]318 mov dl, byte [posy]320 cmp al, 10 ; '\n'321 je .nl323 imul bx, dx, 80324 add bx, cx325 shl bx, 1326 mov byte [es:bx], al328 inc cl329 cmp cl, 80330 je .nl331 mov byte [posx], cl332 ret334 .nl:335 mov byte [posx], 0336 inc dl338 cmp dl, 25339 je .scroll340 mov byte [posy], dl341 ret343 .scroll:344 push ds345 mov ax, 0x18346 mov ds, ax348 cld349 xor di, di350 mov si, 160351 mov cx, 80 * 24352 rep movsw354 pop ds356 mov di, 80 * 24 * 2357 mov cx, 80358 mov ax, (' ' | (0x07 << 8))359 rep stosw360 mov byte [posy], 24361 ret363 ; al - ch364 putchar:365 call writech366 jmp update_cursor368 ; bp - str369 puts:370 mov al, byte [ds:bp]371 inc bp372 test al, al373 jz update_cursor375 call writech376 jmp puts378 update_cursor:379 mov dx, 0x3D4380 mov al, 0x0f381 out dx, al383 mov bx, word [posy]384 imul bx, 80385 add bx, word [posx]387 inc dx ; 0x3D5388 mov al, bl389 out dx, al391 dec dx ; 0x3D4392 mov al, 0x0E393 out dx, al395 inc dx ; 0x3D5396 mov al, bh397 out dx, al398 ret400 ; bp - str401 panic:402 call puts404 .halt:405 cli406 hlt407 jmp .halt409 section .rodata410 user:411 incbin "user.bin"412 .end:413 hello:414 db "Hello World", 10, 0415 errstr:416 db "Error", 10, 0417 convmsg:418 db "Conventional memory: 0x", 0419 xmmsg:420 db "Extended memory: 0x", 0421 kbmsg:422 db " KB", 10, 0424 align 2425 idtr:426 dw idt.end - idt - 1427 dd idt + 0x10000429 align 2430 gdtr:431 dw gdt.end - gdt - 1432 dd gdt + 0x10000435 section .data436 gdt:437 dq 0439 .text: ; 0x08 - kernel code440 dw 0xffff441 dw 0x0000442 db 0x01443 db 0x9A444 dw 0x0000446 .data: ; 0x10 - kernel data447 dw 0xffff448 dw 0x0000449 db 0x01450 db 0x92451 dw 0x0000453 .vid: ; 0x18 - video memory454 dw 4000455 dw 0x8000456 db 0x0b457 db 0x92458 dw 0x0000460 .tss: ; 0x20 - TSS461 dw TSS.size462 dw tss463 db 0x01464 db 0x81465 dw 0x0000467 .ldt: ; 0x28 - LDT468 dw (ldt.end - ldt)469 dw ldt470 db 0x01471 db 0x82472 dw 0x0000473 .end:475 ldt:476 .text: ; 0x07 - user code477 dw 0xffff478 dw 0x0000479 db 0x02480 db 0xfa481 dw 0x0000483 .data: ; 0x0f - user data484 dw 0xffff485 dw 0x0000486 db 0x02487 db 0xf2488 dw 0x0000490 .stack: ; 0x17 - user stack491 dw 0xffff492 dw 0x0000493 db 0x03494 db 0xf2495 dw 0x0000496 .end:498 section .bss499 ubuf:500 resb 256501 posx:502 resw 1503 posy:504 resw 1505 bootdrv:506 resb 1507 convmem:508 resw 1 ; in kilobytes509 highmem:510 resw 1 ; in kilobytes511 idt:512 resq 256513 .end:514 resb 512515 stack:516 tss:517 resb TSS.size