about summary refs log tree commit diff stats
path: root/baremetal
diff options
context:
space:
mode:
authorKartik Agaram <vc@akkartik.com>2021-01-24 21:24:35 -0800
committerKartik Agaram <vc@akkartik.com>2021-01-24 21:24:35 -0800
commit45592062439a89450c6350fbcc0d1da78d3453bd (patch)
treee262057f0aa03fb22564670d90cf31441308e763 /baremetal
parentec75fe7f28dfc1cd23f69311a35f44d92318e5b7 (diff)
downloadmu-45592062439a89450c6350fbcc0d1da78d3453bd.tar.gz
7561
Another attempt at reorganizing how I read disks. Everything continues
to work in Qemu, but Bochs still doesn't love me.
Diffstat (limited to 'baremetal')
-rw-r--r--baremetal/boot.hex46
1 files changed, 35 insertions, 11 deletions
diff --git a/baremetal/boot.hex b/baremetal/boot.hex
index 5eda9153..9f7a390e 100644
--- a/baremetal/boot.hex
+++ b/baremetal/boot.hex
@@ -53,12 +53,20 @@
 #   offset 1000 (address 8c00): bitmap font (2KB)
 #   offset 1800 (address 9400): entrypoint for applications (don't forget to adjust survey_baremetal if this changes)
 
+# Other details of the current memory map:
+#   code: first two default-sized disk tracks into [0x7c00, 0x17800)
+#   heap: [0x01000000, 0x02000000)
+#     see baremetal/120allocate.subx
+#   stack grows down from 0x00070000
+#     see baremetal/mu-init.subx
+
 ## 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)
+#     call this disk read #0
 #   - starts executing code at address 0x7c00
 
 # offset 00 (address 0x7c00):
@@ -78,7 +86,7 @@
   # calls, so we don't need to initialize the stack.
 
 # 0e:
-  # load 62 sectors from disk into addresses [0x7e00, 0xfa00)
+  # disk read #1: load remaining 62 sectors from first track of disk into addresses [0x7e00, 0xfa00)
   b4 02  # ah <- 2  # read sectors from disk
 # 10:
   # dl comes conveniently initialized at boot time with the index of the device being booted
@@ -94,12 +102,14 @@
   cd 13  # int 13h, BIOS disk service
   0f 82 8a 00  # jump-if-carry disk_error [label]
 # 26:
-  # load second track from disk into addresses [0xfa00, 0x17800)
+  # disk read #2: 3 sectors from (0, 1, 0) to [0xfa00, 0x10000)
+  # It looks like some BIOSs can't handle sector reads that cross segment
+  # alignment boundaries.
   b4 02  # ah <- 2  # read sectors from disk
   b5 00  # ch <- 0  # cylinder 0
   b6 01  # dh <- 1  # track 1
   b1 01  # cl <- 1  # first sector, 1-based
-  b0 3f  # al <- 63  # number of sectors to read
+  b0 03  # al <- 3  # number of sectors to read
 # 30:
   # "Addressing of Buffer should guarantee that the complete buffer is inside
   # the given segment, i.e. ( BX + size_of_buffer ) <= 10000h."
@@ -113,8 +123,23 @@
   # reset es
   bb 00 00  # bx <- 0
   8e c3  # es <- bx
-
 # 43:
+  # disk read #3: remaining 60 sectors from (0, 1, 3) to [0x10000, 0x17800)
+  b4 02  # ah <- 2  # read sectors from disk
+  b5 00  # ch <- 0  # cylinder 0
+  b6 01  # dh <- 1  # track 1
+  b1 04  # cl <- 4  # sector 3, 1-based
+  b0 3c  # al <- 60  # number of sectors to read
+  bb 00 10  # bx <- 0x1000
+  8e c3  # es <- bx
+  bb 00 00  # bx <- 0
+  cd 13  # int 13h, BIOS disk service
+  0f 82 72 00  # jump-if-carry disk_error [label]
+  # reset es
+  bb 00 00  # bx <- 0
+  8e c3  # es <- bx
+
+# 60:
   # 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:
@@ -125,7 +150,7 @@
   b0 d1  # al <- 0xd1
   e6 64  # port 0x64 <- al
 
-# 4d:
+# 6a:
   # seta20.2:
   e4 64  # al <- port 0x64
   a8 02  # set zf if bit 1 (second-least significant) is not set
@@ -134,7 +159,7 @@
   b0 df  # al <- 0xdf
   e6 64  # port 0x64 <- al
 
-# 57:
+# 74:
   # adjust video mode
   b4 4f  # ah <- 4f (VBE)
   b0 02  # al <- 02 (set video mode)
@@ -143,7 +168,7 @@
             # fallback mode: 0x0101 (640x480x256)
   cd 10  # int 10h, Vesa BIOS extensions
 
-# 60:
+# 8d:
   # load information for the (hopefully) current video mode
   # mostly just for the address to the linear frame buffer
   b4 4f  # ah <- 4f (VBE)
@@ -152,7 +177,7 @@
   bf 00 7f  # di <- 0x7f00 (video mode info) [label]
   cd 10
 
-# 6c:
+# 99:
   # switch to 32-bit mode
   0f 01 16  # lgdt 00/mod/indirect 010/subop 110/rm/use-disp16
     f8 7c  # *gdt_descriptor [label]
@@ -162,9 +187,8 @@
   ea 00 7d 08 00  # far jump to initialize_32bit_mode after setting cs to the record at offset 8 in the gdt (gdt_code) [label]
 
 # padding
-# 80:
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+# ad:
+                                       00 00 00
 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00