about summary refs log tree commit diff stats
path: root/apps
diff options
context:
space:
mode:
authorKartik Agaram <vc@akkartik.com>2020-12-26 13:22:28 -0800
committerKartik Agaram <vc@akkartik.com>2020-12-26 13:30:04 -0800
commitd8eacb3893a310f6f0ca5ef7ad9a7653fc7a8c67 (patch)
treee6d73bbc988e894e4f6b6b585dde7b9c08e2c819 /apps
parent2fcf7e24d14bad5c66071ba0c7c313e480987e50 (diff)
downloadmu-d8eacb3893a310f6f0ca5ef7ad9a7653fc7a8c67.tar.gz
7403 - baremetal/ for apps without a kernel
Diffstat (limited to 'apps')
-rw-r--r--apps/boot.bochsrc6
-rw-r--r--apps/boot.hex344
-rw-r--r--apps/bos/3-1.hex51
-rw-r--r--apps/bos/3-2.hex65
-rw-r--r--apps/bos/32bit.hex132
-rw-r--r--apps/bos/4.asm143
-rw-r--r--apps/bos/4.xxd87
-rw-r--r--apps/bos/README.md7
-rw-r--r--apps/bos/bochsrc3
-rw-r--r--apps/bos/print-mem-real-mode.hex67
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