-
Notifications
You must be signed in to change notification settings - Fork 227
/
loader.asm
90 lines (82 loc) · 1.86 KB
/
loader.asm
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
use16
org 0x7c00
boot:
; initialize segment registers
xor ax, ax
mov ds, ax
mov es, ax
mov ss, ax
; initialize stack
mov sp, 0x7bfe
; load rust code into 0x7e00 so we can jump to it later
mov ah, 2 ; read
mov al, 24 ; 24 sectors (12 KiB)
mov ch, 0 ; cylinder & 0xff
mov cl, 2 ; sector | ((cylinder >> 2) & 0xc0)
mov dh, 0 ; head
mov bx, 0x7e00 ; read buffer
int 0x13
jc error
; load protected mode GDT and a null IDT (we don't need interrupts)
cli
lgdt [gdtr]
lidt [idtr]
; set protected mode bit of cr0
mov eax, cr0
or eax, 1
mov cr0, eax
; far jump to load CS with 32 bit segment
jmp 0x08:protected_mode
error:
mov si, .msg
.loop:
lodsb
or al, al
jz .done
mov ah, 0x0e
int 0x10
jmp .loop
.done:
jmp $
.msg db "could not read disk", 0
protected_mode:
use32
; load all the other segments with 32 bit data segments
mov eax, 0x10
mov ds, eax
mov es, eax
mov fs, eax
mov gs, eax
mov ss, eax
; set up stack
mov esp, 0x7bfc
; jump into rust
call 0x7e00
jmp $
gdtr:
dw (gdt_end - gdt) + 1 ; size
dd gdt ; offset
idtr:
dw 0
dd 0
gdt:
; null entry
dq 0
; code entry
dw 0xffff ; limit 0:15
dw 0x0000 ; base 0:15
db 0x00 ; base 16:23
db 0b10011010 ; access byte - code
db 0x4f ; flags/(limit 16:19). flag is set to 32 bit protected mode
db 0x00 ; base 24:31
; data entry
dw 0xffff ; limit 0:15
dw 0x0000 ; base 0:15
db 0x00 ; base 16:23
db 0b10010010 ; access byte - data
db 0x4f ; flags/(limit 16:19). flag is set to 32 bit protected mode
db 0x00 ; base 24:31
gdt_end:
times 510-($-$$) db 0
db 0x55
db 0xaa