7358
Snapshot: first draft of a boot image that switches to 32-bit mode as quickly as possible (~70 bytes) Doesn't work yet. Gets stuck in an infinite reset loop.
This commit is contained in:
parent
70bb19100e
commit
9b5b8471ca
|
@ -0,0 +1,121 @@
|
|||
# Bootable image demonstrating printing to screen in 32-bit mode.
|
||||
# Must have exactly 512 bytes.
|
||||
#
|
||||
# To convert to a disk image:
|
||||
# ./bootstrap run apps/hex < apps/bos/32bit.hex > boot.bin
|
||||
# To run:
|
||||
# qemu-system-i386 boot.bin
|
||||
# Or:
|
||||
# bochs -f apps/bos/bochsrc # bochsrc loads boot.bin
|
||||
#
|
||||
# Expected output inside emulator:
|
||||
# H
|
||||
|
||||
## 16-bit entry point
|
||||
|
||||
# Boot image starts executing at address 0x7c00,
|
||||
# and so occupies [0x7c00, 0x7e00).
|
||||
# We don't read or write the stack before we get to 32-bit mode.
|
||||
|
||||
# 00:
|
||||
fa
|
||||
0f 01 16 # lgdt 00/mod/indirect 010/subop 110/rm32/TODO
|
||||
2c 7c # *gdt_descriptor
|
||||
0f 20 c0 # eax <- cr0
|
||||
66 83 c8 01 # eax <- or 0x1
|
||||
0f 22 c0 # cr0 <- eax
|
||||
ea 32 7c 08 00 # far jump to CODE_SEG:initialize_32bit_mode (TODO: why the 08? something to do with segment selector; only first 16 bits are used in the jump address)
|
||||
|
||||
## GDT: 3 records of 8 bytes each
|
||||
|
||||
# 14:
|
||||
# gdt_start:
|
||||
# gdt_null: mandatory null descriptor
|
||||
00 00 00 00 00 00 00 00
|
||||
# gdt_code: (offset 8 from gdt_start)
|
||||
ff ff # limit[0:16]
|
||||
00 00 00 # base[0:24]
|
||||
9a # 1/present 00/privilege 1/descriptor type = 1001b
|
||||
# 1/code 0/conforming 1/readable 0/accessed = 1010b
|
||||
cf # 1/granularity 1/32-bit 0/64-bit-segment 0/AVL = 1100b
|
||||
# limit[16:20] = 1111b
|
||||
00 # base[24:32]
|
||||
# gdt_data: (offset 16 from gdt_start)
|
||||
ff ff # limit[0:16]
|
||||
00 00 00 # base[0:24]
|
||||
92 # 1/present 00/privilege 1/descriptor type = 1001b
|
||||
# 0/data 0/conforming 1/readable 0/accessed = 0010b
|
||||
cf # same as gdt_code
|
||||
00 # base[24:32]
|
||||
# gdt_end:
|
||||
|
||||
# 2c:
|
||||
# gdt_descriptor:
|
||||
17 00 # final index of gdt = gdt_end - gdt_start - 1
|
||||
14 7c 00 00 # start = gdt_start
|
||||
|
||||
## 32-bit code from this point (still some instructions not in SubX)
|
||||
|
||||
# 32:
|
||||
# initialize_32bit_mode:
|
||||
66 b8 10 00 # ax <- offset 16 from gdt_start
|
||||
8e d8 # ds <- ax
|
||||
8e d0 # ss <- ax
|
||||
8e c0 # es <- ax
|
||||
8e e0 # fs <- ax
|
||||
8e e8 # gs <- ax
|
||||
# 40:
|
||||
e9 0a 00 00 00 # jump to 0x7c50, leaving some extra padding
|
||||
|
||||
# padding
|
||||
# 45:
|
||||
00 00 00 00 00 00 00 00 00 00
|
||||
|
||||
## 'application' SubX code: print one character to top-left of screen
|
||||
|
||||
# 50:
|
||||
# *0xb8000 <- 0x0f48
|
||||
c7 # opcode
|
||||
# modrm
|
||||
05 # 00/mod/indirect 000/subop/copy 101/rm32/use-disp32
|
||||
# disp32
|
||||
00 80 0b 00
|
||||
# imm32
|
||||
48 # 'H'
|
||||
0f # white on black
|
||||
00 00
|
||||
|
||||
e9 fd ff # loop forever
|
||||
|
||||
# more padding to 512 bytes
|
||||
00 00 00
|
||||
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
|
||||
55 aa # final 2 bytes: boot sector marker
|
||||
|
||||
# vim:ft=subx
|
|
@ -0,0 +1,87 @@
|
|||
## 16-bit code
|
||||
|
||||
# Entry:
|
||||
00:
|
||||
bd 00 90 # bp <- 0x9000
|
||||
89 ec # sp <- bp
|
||||
|
||||
bb 8f 7c # bx <- MSG_REAL_MODE
|
||||
e8 38 00 # call print_string
|
||||
|
||||
e8 02 00 # call switch_to_pm
|
||||
eb fe # jump $ (should never get here)
|
||||
|
||||
# switch_to_pm:
|
||||
10:
|
||||
fa # cli
|
||||
0f 01 16 3d 7c # lgdt [gdt_descriptor]
|
||||
0f 20 c0 # eax <- cr0
|
||||
66 83 c8 01 # eax <- or 0x1
|
||||
0f 22 c0 # cr0 <- eax
|
||||
20:
|
||||
ea 53 7c 08 00 # jmp CODE_SEG:init_pm
|
||||
|
||||
# gdt_start:
|
||||
# gdt_null: mandatory null descriptor
|
||||
00 00 00 00 00 00 00 00
|
||||
# gdt_code:
|
||||
ff ff 00
|
||||
30:
|
||||
00 00 9a cf 00
|
||||
# gdt_data:
|
||||
ff ff 00 00 00 92 cf 00
|
||||
# gdt_end:
|
||||
|
||||
# gdt_descriptor:
|
||||
3d:
|
||||
17 00 # limit
|
||||
25 7c 00 00 # start
|
||||
|
||||
# print_string:
|
||||
43:
|
||||
60 # pusha
|
||||
b4 0e # ah <- 0x0e
|
||||
# loop:
|
||||
8a 07 # al <- *bx
|
||||
cd 10 # int 10h
|
||||
83 c3 01 # add bx, 1
|
||||
3c 00 # cmp al, 0
|
||||
75 f5 # jne loop
|
||||
61 # popa
|
||||
c3 # ret
|
||||
|
||||
## 32-bit code
|
||||
|
||||
# init_pm:
|
||||
53:
|
||||
66 b8 10 00 # ax <- DATA_SEG
|
||||
8e d8 # ds <- ax
|
||||
8e d0 # ss <- ax
|
||||
8e c0 # es <- ax
|
||||
8e e0 # fs <- ax
|
||||
8e e8 # gs <- ax
|
||||
61:
|
||||
bd 00 00 09 00 # ebp <- 0x90000
|
||||
89 ec # esp <- ebp
|
||||
bb ab 7c 00 00 # ebx <- MSG_PROT_MODE
|
||||
e8 02 00 00 00 # call print_string_pm
|
||||
eb fe # hang
|
||||
|
||||
# print_string_pm:
|
||||
74:
|
||||
60 # pusha
|
||||
ba 00 80 0b 00 8a 03 b4 0f 3c 00
|
||||
80:
|
||||
74 0b 66 89 02 83 c3 01 83 c2 02 eb ed 61 c3 53
|
||||
90:
|
||||
74 61 72 74 65 64 20 69 6e 20 31 36 2d 62 69 74
|
||||
a0:
|
||||
20 52 65 61 6c 20 4d 6f 64 65 00 53 75 63 63 65
|
||||
b0:
|
||||
73 73 66 75 6c 6c 79 20 6c 61 6e 64 65 64 20 69
|
||||
c0:
|
||||
6e 20 33 32 2d 62 69 74 20 50 72 6f 74 65 63 74
|
||||
d0:
|
||||
65 64 20 4d 6f 64 65
|
||||
|
||||
# vim:ft=conf
|
Loading…
Reference in New Issue