diff options
Diffstat (limited to 'apps')
-rw-r--r-- | apps/boot.bochsrc | 6 | ||||
-rw-r--r-- | apps/boot.hex | 344 | ||||
-rw-r--r-- | apps/bos/3-1.hex | 51 | ||||
-rw-r--r-- | apps/bos/3-2.hex | 65 | ||||
-rw-r--r-- | apps/bos/32bit.hex | 132 | ||||
-rw-r--r-- | apps/bos/4.asm | 143 | ||||
-rw-r--r-- | apps/bos/4.xxd | 87 | ||||
-rw-r--r-- | apps/bos/README.md | 7 | ||||
-rw-r--r-- | apps/bos/bochsrc | 3 | ||||
-rw-r--r-- | apps/bos/print-mem-real-mode.hex | 67 |
10 files changed, 0 insertions, 905 deletions
diff --git a/apps/boot.bochsrc b/apps/boot.bochsrc deleted file mode 100644 index 521e22d9..00000000 --- a/apps/boot.bochsrc +++ /dev/null @@ -1,6 +0,0 @@ -# Configuration for the Bochs x86 CPU emulator to run the output of apps/boot.hex -# See apps/boot.hex for more details. - -ata0-master: type=disk, path="disk.img", mode=flat, cylinders=20, heads=16, spt=63 # 10MB, 512 bytes per sector -boot: disk -log: - diff --git a/apps/boot.hex b/apps/boot.hex deleted file mode 100644 index 8b11dbab..00000000 --- a/apps/boot.hex +++ /dev/null @@ -1,344 +0,0 @@ -# Bootable image that: -# - loads more sectors past the first boot sector (using BIOS primitives) -# - switches to 32-bit mode (giving up access to BIOS primitives) -# - sets up a handler for keyboard events -# - as an example program, prints alphabets to the top-left position on screen (by writing to memory-mapped VGA memory) as they're typed -# -# If the initial load fails, it prints 'D' to the top-left of the screen and -# halts. -# -# To convert to a disk image, first prepare a realistically sized disk image: -# dd if=/dev/zero of=disk.img count=20160 # 512-byte sectors, so 10MB -# Now fill in sectors: -# ./bootstrap run apps/hex < apps/boot.hex > boot.bin -# dd if=boot.bin of=disk.img conv=notrunc -# To run: -# qemu-system-i386 disk.img -# Or: -# bochs -f apps/boot.bochsrc # boot.bochsrc loads disk.img -# -# Since we start out in 16-bit mode, we need instructions SubX doesn't -# support. -# This file contains just lowercase hex bytes and comments. Zero -# error-checking. Make liberal use of: -# - comments documenting expected offsets -# - size checks on the emitted file (currently: 512 bytes) -# - xxd to eyeball that offsets contain expected bytes - -## 16-bit entry point - -# Upon reset, the IBM PC -# loads the first sector (512 bytes) -# from some bootable image (see the boot sector marker at the end of this file) -# to the address range [0x7c00, 0x7e00) - -# offset 00 (address 0x7c00): - # disable interrupts for this initialization - fa # cli - - # initialize segment registers - # this isn't always needed, but the recommendation is to not make assumptions - b8 00 00 # ax <- 0 - 8e d8 # ds <- ax - 8e d0 # ss <- ax - 8e c0 # es <- ax - 8e e0 # fs <- ax - 8e e8 # gs <- ax - - # We don't read or write the stack before we get to 32-bit mode. No function - # calls, so we don't need to initialize the stack. - -# 0e: - # load more sectors from disk - b4 02 # ah <- 2 # read sectors from disk - # dl comes conveniently initialized at boot time with the index of the device being booted - b5 00 # ch <- 0 # cylinder 0 - b6 00 # dh <- 0 # track 0 - b1 02 # cl <- 2 # second sector, 1-based - b0 01 # al <- 1 # number of sectors to read - # address to write sectors to = es:bx = 0x7e00, contiguous with boot segment - bb 00 00 # bx <- 0 - 8e c3 # es <- bx - bb 00 7e # bx <- 0x7e00 - cd 13 # int 13h, BIOS disk service - 0f 82 76 00 # jump-if-carry disk-error - -# 26: - # undo the A20 hack: https://en.wikipedia.org/wiki/A20_line - # this is from https://github.com/mit-pdos/xv6-public/blob/master/bootasm.S - # seta20.1: - e4 64 # al <- port 0x64 - a8 02 # set zf if bit 1 (second-least significant) is not set - 75 fa # if zf not set, goto seta20.1 (-6) - - b0 d1 # al <- 0xd1 - e6 64 # port 0x64 <- al - -# 30: - # seta20.2: - e4 64 # al <- port 0x64 - a8 02 # set zf if bit 1 (second-least significant) is not set - 75 fa # if zf not set, goto seta20.2 (-6) - - b0 df # al <- 0xdf - e6 64 # port 0x64 <- al - -# 3a: - # switch to 32-bit mode - 0f 01 16 # lgdt 00/mod/indirect 010/subop 110/rm/use-disp16 - 80 7c # *gdt_descriptor -# 3f: - 0f 20 c0 # eax <- cr0 - 66 83 c8 01 # eax <- or 0x1 - 0f 22 c0 # cr0 <- eax - ea c0 7c 08 00 # far jump to initialize_32bit_mode after setting cs to the record at offset 8 in the gdt (gdt_code) - -# padding -# 4e: - 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - -## GDT: 3 records of 8 bytes each - -# 60: -# 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: - -# padding -# 78: - 00 00 00 00 00 00 00 00 - -# 80: -# gdt_descriptor: - 17 00 # final index of gdt = gdt_end - gdt_start - 1 - 60 7c 00 00 # start = gdt_start - -# padding -# 85: - 00 00 00 00 00 00 00 00 00 00 - -# 90: -# disk_error: - # print 'D' to top-left of screen to indicate disk error - # *0xb8000 <- 0x0f44 - # bx <- 0xb800 - bb 00 b8 - # ds <- bx - 8e db # 11b/mod 011b/reg/ds 011b/rm/bx - # al <- 'D' - b0 44 - # ah <- 0x0f # white on black - b4 0f - # bx <- 0 - bb 00 00 - # *ds:bx <- ax - 89 07 # 00b/mod/indirect 000b/reg/ax 111b/rm/bx - -e9 fb ff # loop forever - -# padding -# a1: - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - -## 32-bit code from this point (still some instructions not in SubX) - -# c0: -# 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 - - # load interrupt handlers - 0f 01 1d # lidt 00/mod/indirect 011/subop 101/rm32/use-disp32 - 00 7f 00 00 # *idt_descriptor - - # enable keyboard IRQ - b0 fd # al <- 0xfd # enable just IRQ1 - e6 21 # port 0x21 <- al - - # initialization is done; enable interrupts - fb - e9 21 00 00 00 # jump to 0x7d00 - -# padding -# df: - 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - -## 'application' SubX code: print one character to top-left of screen - -# offset 100 (address 0x7d00): -# Entry: - # eax <- *0x7ff4 # random address in second segment containing 'H' - 8b # copy rm32 to r32 - 05 # 00/mod/indirect 000/r32/eax 101/rm32/use-disp32 - # disp32 - f4 7f 00 00 - # *0xb8000 <- eax - 89 # copy r32 to rm32 - 05 # 00/mod/indirect 000/r32/eax 101/rm32/use-disp32 - # disp32 - 00 80 0b 00 - -e9 fb ff ff ff # loop forever - -# padding -# 111: - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - -# 120: -# null interrupt handler: - cf # iret - -# padding -# 121: - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - -# 130: -# keyboard interrupt handler: - # prologue - fa # disable interrupts - 60 # push all registers to stack - # acknowledge interrupt - b0 20 # al <- 0x20 - e6 20 # port 0x20 <- al - # read keyboard status (TODO: why bit 0? Doesn't line up with https://web.archive.org/web/20040604041507/http://panda.cs.ndsu.nodak.edu/~achapwes/PICmicro/keyboard/atkeyboard.html) -#? e4 64 # al <- port 0x64 -#? a8 01 # set zf if bit 0 (least significant) is not set -#? 74 11 # if bit 0 is not set, skip to epilogue - # read keycode into eax - 31 c0 # eax <- xor eax; 11/direct 000/r32/eax 000/rm32/eax - e4 60 # al <- port 0x60 - # map key '1' to ascii; if eax == 2, eax = 0x31 - 3d 02 00 00 00 # compare eax with 0x02 - 75 0b # if not equal, goto epilogue - b8 31 0f 00 00 # eax <- 0x0f31 - # print eax to top-left of screen (*0xb8000) - 89 # copy r32 to rm32 - 05 # 00/mod/indirect 000/r32/eax 101/rm32/use-disp32 - # disp32 - 00 80 0b 00 - # epilogue - 61 # pop all registers - fb # enable interrupts - cf # iret - -# padding -# 14f - 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 - -# final 2 bytes of boot sector -55 aa - -## sector 2 -# not loaded on boot; loaded by load_disk - -# offset 200 (address 0x7e00): interrupt descriptor table -# 32 entries * 8 bytes each = 256 bytes (0x100) -# idt_start: - -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 - -# entry 8: clock - 20 7d # target[0:16] = null interrupt handler - 08 00 # segment selector (gdt_code) - 00 # unused - 8e # 1/p 00/dpl 0 1110/type/32-bit-interrupt-gate - 00 00 # target[16:32] - -# entry 9: keyboard - 30 7d # target[0:16] = keyboard interrupt handler - 08 00 # segment selector (gdt_code) - 00 # unused - 8e # 1/p 00/dpl 0 1110/type/32-bit-interrupt-gate - 00 00 # target[16:32] - -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -# idt_end: - -# offset 300 (address 0x7f00): -# idt_descriptor: - ff 00 # idt_end - idt_start - 1 - 00 7e 00 00 # start = idt_start - -# padding - 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 48 0f 00 00 00 00 00 00 00 00 00 00 # spot the 'H' with attributes -# offset 400 (address 0x8000) - -# vim:ft=conf diff --git a/apps/bos/3-1.hex b/apps/bos/3-1.hex deleted file mode 100644 index 75e10c1f..00000000 --- a/apps/bos/3-1.hex +++ /dev/null @@ -1,51 +0,0 @@ -# Bootable image. -# Boot sector must have exactly 512 bytes. -# 16-bit real mode. -# -# To convert to a disk image: -# ./bootstrap run apps/hex < apps/bos/3-1.hex > boot.bin -# To run: -# qemu-system-i386 boot.bin -# Or: -# bochs -f apps/bos/bochsrc # bochsrc loads boot.bin -# -# Expected output inside emulator: -# Booting from floppy... - -e9 fd ff - -# 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 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 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 - -# vim:ft=subx diff --git a/apps/bos/3-2.hex b/apps/bos/3-2.hex deleted file mode 100644 index a52d2a88..00000000 --- a/apps/bos/3-2.hex +++ /dev/null @@ -1,65 +0,0 @@ -# Bootable image. -# Boot sector must have exactly 512 bytes. -# 16-bit real mode. -# -# To convert to a disk image: -# ./bootstrap run apps/hex < apps/bos/3-2.hex > boot.bin -# To run: -# qemu-system-i386 boot.bin -# Or: -# bochs -f apps/bos/bochsrc # bochsrc loads boot.bin -# -# Expected output inside emulator: -# Hello - -b4 0e # ah <- 0e (teletype output) - -b0 48 # al <- 'H' -cd 10 # int 10h -b0 65 # al <- 'e' -cd 10 # int 10h -b0 6c # al <- 'l' -cd 10 # int 10h -b0 6c # al <- 'l' -cd 10 # int 10h -b0 6f # al <- 'o' -cd 10 # int 10h - -e9 fd ff # loop forever - -# 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 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 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 diff --git a/apps/bos/32bit.hex b/apps/bos/32bit.hex deleted file mode 100644 index e8b1f21a..00000000 --- a/apps/bos/32bit.hex +++ /dev/null @@ -1,132 +0,0 @@ -# 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 # cli # TODO: don't forget to reenable interrupts at some point - 0f 01 16 # lgdt 00/mod/indirect 010/subop 110/rm32/TODO - 80 7c # *gdt_descriptor - 0f 20 c0 # eax <- cr0 - 66 83 c8 01 # eax <- or 0x1 - 0f 22 c0 # cr0 <- eax - ea c0 7c 08 00 # far jump to initialize_32bit_mode after setting cs to the record at offset 8 in the gdt (gdt_code) - -# padding -# 15: - 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - -## GDT: 3 records of 8 bytes each - -# 60: -# 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: - -# padding -# 78: - 00 00 00 00 00 00 00 00 - -# 80: -# gdt_descriptor: - 17 00 # final index of gdt = gdt_end - gdt_start - 1 - 60 7c 00 00 # start = gdt_start - -# padding -# 85: - 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - -## 32-bit code from this point (still some instructions not in SubX) - -# c0: -# 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 - e9 1d 00 00 00 # jump to 0x7cf0 - -# padding -# d3: - 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - -## 'application' SubX code: print one character to top-left of screen - -# f0: -# Entry: - # *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 fb ff ff ff # loop forever - -# padding to 512 bytes - 00 -# 100: -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 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 diff --git a/apps/bos/4.asm b/apps/bos/4.asm deleted file mode 100644 index 71c51d97..00000000 --- a/apps/bos/4.asm +++ /dev/null @@ -1,143 +0,0 @@ -; A boot sector that enters 32-bit protected mode. -; -; To convert to a disk image: -; cd apps/bos -; nasm 4.asm -f bin -o boot.bin -; To run: -; qemu-system-i386 boot.bin -; Or: -; bochs # bochsrc loads boot.bin - -[org 0x7c00] - - mov bp, 0x9000 - mov sp, bp - - mov bx, MSG_REAL_MODE - call print_string - - call switch_to_pm - ; never gets here - - jmp $ - -switch_to_pm: - cli - lgdt [gdt_descriptor] - ; set LSB of CR0 - mov eax, cr0 - or eax, 0x1 - mov cr0, eax - jmp CODE_SEG:init_pm ; Far jump to a new segment containing 32-bit code. - ; This also forces the CPU to flush its cache of - ; prefetched and real-mode decoded instructions. - ; never gets here - -;; === GDT stuff -gdt_start: - -gdt_null: ; the mandatory null descriptor - dd 0x0 ; ’dd’ means define double word (i.e. 4 bytes) - dd 0x0 - -gdt_code: ; the code segment descriptor - ; base=0x0, limit=0xfffff, - ; 1st flags: (present)1 (privilege)00 (descriptor type)1 -> 1001b - ; type flags: (code)1 (conforming)0 (readable)1 (accessed )0 -> 1010b - ; 2nd flags: (granularity)1 (32-bit default)1 (64-bit seg)0 (AVL)0 -> 1100b - dw 0xffff ; Limit (bits 0-15) - dw 0x0 ; Base (bits 0-15) - db 0x0 ; Base (bits 16 -23) - db 10011010b ; 1st flags, type flags - db 11001111b ; 2nd flags, Limit (bits 16-19) - db 0x0 ; Base (bits 24 -31) - -gdt_data: ; the data segment descriptor - ; Same as code segment except for the type flags: - ; type flags: (code)0 (expand down)0 (writable)1 (accessed)0 -> 0010b - dw 0xffff ; Limit (bits 0-15) - dw 0x0 ; Base (bits 0-15) - db 0x0 ; Base (bits 16 -23) - db 10010010b ; 1st flags, type flags - db 11001111b ; 2nd flags, Limit (bits 16-19) - db 0x0 ; Base (bits 24 -31) - -gdt_end: - -gdt_descriptor: - dw gdt_end - gdt_start - 1 ; last valid byte - dd gdt_start - -; some handy constants -CODE_SEG equ gdt_code - gdt_start -DATA_SEG equ gdt_data - gdt_start -;; === end GDT stuff - -;; some 16-bit helpers - -; print string whose address is in bx -print_string: - pusha - mov ah, 0x0e -loop: - mov al, [bx] - int 0x10 - add bx, 1 - cmp al, 0 - jne loop - popa - ret - -;; 32-bit code starts here -[bits 32] - -; Initialise registers and the stack once in PM. -init_pm: - - mov ax, DATA_SEG ; Now in PM, our old segments are meaningless, - mov ds, ax ; so we point our segment registers to the - mov ss, ax ; data selector we defined in our GDT - mov es, ax - mov fs, ax - mov gs, ax - - mov ebp, 0x90000 ; Update our stack position so it is right - mov esp, ebp ; at the top of the free space. - - ;; Protected Mode is now initialized - - mov ebx, MSG_PROT_MODE - call print_string_pm - - ; all done; hang - jmp $ - -; Define some constants -VIDEO_MEMORY equ 0xb8000 -WHITE_ON_BLACK equ 0x0f - -; prints a null -terminated string pointed to by EDX -print_string_pm: - pusha - mov edx, VIDEO_MEMORY ; Set edx to the start of vid mem. -print_string_pm_loop: - mov al, [ebx] ; Store the char at EBX in AL - mov ah, WHITE_ON_BLACK ; Store the attributes in AH - cmp al, 0 ; if (al == 0), at end of string , so - je print_string_pm_done - mov [edx], ax ; Store char and attributes at current - ; character cell. - add ebx , 1 ; Increment EBX to the next char in string. - add edx , 2 ; Move to next character cell in vid mem. - jmp print_string_pm_loop ; loop around to print the next char. -print_string_pm_done: - popa - ret ; Return from the function - -; Global variables -MSG_REAL_MODE db "Started in 16-bit Real Mode", 0 -MSG_PROT_MODE db "Successfully landed in 32-bit Protected Mode", 0 - -; Bootsector padding -times 510-($-$$) db 0 -dw 0xaa55 diff --git a/apps/bos/4.xxd b/apps/bos/4.xxd deleted file mode 100644 index be677134..00000000 --- a/apps/bos/4.xxd +++ /dev/null @@ -1,87 +0,0 @@ -## 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 diff --git a/apps/bos/README.md b/apps/bos/README.md deleted file mode 100644 index 989ebf44..00000000 --- a/apps/bos/README.md +++ /dev/null @@ -1,7 +0,0 @@ -Exercises while reading the incomplete "Writing a simple operating system from -scratch" by Nick Blundell. - https://www.cs.bham.ac.uk/~exr/lectures/opsys/10\_11/lectures/os-dev.pdf - -The name of this directory is a reference to "Bootstrapping a simple compiler -from nothing" by Edmund Grimley-Evans. - https://github.com/certik/bcompiler diff --git a/apps/bos/bochsrc b/apps/bos/bochsrc deleted file mode 100644 index de225b4c..00000000 --- a/apps/bos/bochsrc +++ /dev/null @@ -1,3 +0,0 @@ -ata0-master: type=disk, path="boot.bin", mode=flat, cylinders=1, heads=1, spt=1 -boot: disk -log: - diff --git a/apps/bos/print-mem-real-mode.hex b/apps/bos/print-mem-real-mode.hex deleted file mode 100644 index 5e41d5b3..00000000 --- a/apps/bos/print-mem-real-mode.hex +++ /dev/null @@ -1,67 +0,0 @@ -# Experiment: write to video RAM from 16-bit real mode. And it works. -# -# To convert to a disk image: -# ./bootstrap run apps/hex < apps/bos/print-mem-real-mode.hex > boot.bin -# To run: -# qemu-system-i386 boot.bin -# Or: -# bochs # reads bochsrc, which loads boot.bin - -# - figure 4.1 of https://www.cs.bham.ac.uk/~exr/lectures/opsys/10_11/lectures/os-dev.pdf in protected mode -# edx <- 0xb8000 -# al <- 'H' -# ah <- 0x0f # white on black -# *edx <- ax - -# - translating to real mode -# bx <- 0xb800 -bb 00 b8 -# ds <- bx -8e db # 11b/mod 011b/reg/ds 011b/rm/bx -# al <- 'H' -b0 48 -# ah <- 0x0f # white on black -b4 0f -# bx <- 0 -bb 00 00 -# *ds:bx <- ax -89 07 # 00b/mod/indirect 000b/reg/ax 111b/rm/bx - -e9 fd ff # loop forever - -# 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 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 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 |