From 6b6eaf395ef5ec78aebf551f4ec43b646fe490d2 Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Wed, 23 Dec 2020 23:17:53 -0800 Subject: 7397 Some manual tweaks to boot.hex.html --- html/apps/boot.hex.html | 722 +++++++++++++++++++++++++----------------------- 1 file changed, 376 insertions(+), 346 deletions(-) diff --git a/html/apps/boot.hex.html b/html/apps/boot.hex.html index 31aeeb67..328073da 100644 --- a/html/apps/boot.hex.html +++ b/html/apps/boot.hex.html @@ -6,7 +6,7 @@ - + - - -https://github.com/akkartik/mu/blob/master/apps/boot.hex -
-# 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 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 is considered safe not to assume
-  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
+
+
+
+https://github.com/akkartik/mu/blob/master/apps/boot.hex
+
+  1 # Bootable image that:
+  2 #   - loads more sectors past the first boot sector (using BIOS primitives)
+  3 #   - switches to 32-bit mode (giving up access to BIOS primitives)
+  4 #   - sets up a handler for keyboard events
+  5 #   - as an example program, prints alphabets to the top-left position on screen (by writing to memory-mapped VGA memory) as they're typed
+  6 #
+  7 # If the initial load fails, it prints 'D' to the top-left of the screen and
+  8 # halts.
+  9 #
+ 10 # To convert to a disk image, first prepare a realistically sized disk image:
+ 11 #   dd if=/dev/zero of=disk.img count=20160  # 512-byte sectors, so 10MB
+ 12 # Now fill in sectors:
+ 13 #   ./bootstrap run apps/hex < apps/boot.hex > boot.bin
+ 14 #   dd if=boot.bin of=disk.img conv=notrunc
+ 15 # To run:
+ 16 #   qemu-system-i386 disk.img
+ 17 # Or:
+ 18 #   bochs -f apps/boot.bochsrc  # boot.bochsrc loads disk.img
+ 19 #
+ 20 # Since we start out in 16-bit mode, we need instructions SubX doesn't
+ 21 # support.
+ 22 # This file contains just hex bytes and comments. Zero error-checking. Make
+ 23 # liberal use of:
+ 24 #   - comments documenting expected offsets
+ 25 #   - size checks on the emitted file (currently: 512 bytes)
+ 26 #   - xxd to eyeball that offsets contain expected bytes
+ 27 
+ 28 ## 16-bit entry point
+ 29 
+ 30 # Upon reset, the IBM PC
+ 31 #   loads the first sector (512 bytes)
+ 32 #   from some bootable image (see the boot sector marker at the end of this file)
+ 33 #   to the address range [0x7c00, 0x7e00)
+ 34 
+ 35 # offset 00 (address 0x7c00):
+ 36   # disable interrupts for this initialization
+ 37   fa  # cli
+ 38 
+ 39   # initialize segment registers
+ 40   # this isn't always needed, but is considered safe not to assume
+ 41   b8 00 00  # ax <- 0
+ 42   8e d8  # ds <- ax
+ 43   8e d0  # ss <- ax
+ 44   8e c0  # es <- ax
+ 45   8e e0  # fs <- ax
+ 46   8e e8  # gs <- ax
+ 47 
+ 48   # We don't read or write the stack before we get to 32-bit mode. No function
+ 49   # calls, so we don't need to initialize the stack.
+ 50 
+ 51 # 0e:
+ 52   # load more sectors from disk
+ 53   b4 02  # ah <- 2  # read sectors from disk
+ 54   # dl comes conveniently initialized at boot time with the index of the device being booted
+ 55   b5 00  # ch <- 0  # cylinder 0
+ 56   b6 00  # dh <- 0  # track 0
+ 57   b1 02  # cl <- 2  # second sector, 1-based
+ 58   b0 01  # al <- 1  # number of sectors to read
+ 59   # address to write sectors to = es:bx = 0x7e00, contiguous with boot segment
+ 60   bb 00 00  # bx <- 0
+ 61   8e c3  # es <- bx
+ 62   bb 00 7e  # bx <- 0x7e00
+ 63   cd 13  # int 13h, BIOS disk service
+ 64   0f 82 76 00  # jump-if-carry disk-error
+ 65 
+ 66 # 26:
+ 67   # undo the A20 hack: https://en.wikipedia.org/wiki/A20_line
+ 68   # this is from https://github.com/mit-pdos/xv6-public/blob/master/bootasm.S
+ 69   # seta20.1:
+ 70   e4 64  # al <- port 0x64
+ 71   a8 02  # set zf if bit 1 (second-least significant) is not set
+ 72   75 fa  # if zf not set, goto seta20.1 (-6)
+ 73 
+ 74   b0 d1  # al <- 0xd1
+ 75   e6 64  # port 0x64 <- al
+ 76 
+ 77 # 30:
+ 78   # seta20.2:
+ 79   e4 64  # al <- port 0x64
+ 80   a8 02  # set zf if bit 1 (second-least significant) is not set
+ 81   75 fa  # if zf not set, goto seta20.2 (-6)
+ 82 
+ 83   b0 df  # al <- 0xdf
+ 84   e6 64  # port 0x64 <- al
+ 85 
+ 86 # 3a:
+ 87   # switch to 32-bit mode
+ 88   0f 01 16  # lgdt 00/mod/indirect 010/subop 110/rm/use-disp16
+ 89     80 7c  # *gdt_descriptor
+ 90 # 3f:
+ 91   0f 20 c0  # eax <- cr0
+ 92   66 83 c8 01  # eax <- or 0x1
+ 93   0f 22 c0  # cr0 <- eax
+ 94   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)
+ 95 
+ 96 # padding
+ 97 # 4e:
+ 98                                           00 00
+ 99 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+100 
+101 ## GDT: 3 records of 8 bytes each
+102 
+103 # 60:
+104 # gdt_start:
+105 # gdt_null:  mandatory null descriptor
+106   00 00 00 00 00 00 00 00
+107 # gdt_code:  (offset 8 from gdt_start)
+108   ff ff  # limit[0:16]
+109   00 00 00  # base[0:24]
+110   9a  # 1/present 00/privilege 1/descriptor type = 1001b
+111       # 1/code 0/conforming 1/readable 0/accessed = 1010b
+112   cf  # 1/granularity 1/32-bit 0/64-bit-segment 0/AVL = 1100b
+113       # limit[16:20] = 1111b
+114   00  # base[24:32]
+115 # gdt_data:  (offset 16 from gdt_start)
+116   ff ff  # limit[0:16]
+117   00 00 00  # base[0:24]
+118   92  # 1/present 00/privilege 1/descriptor type = 1001b
+119       # 0/data 0/conforming 1/readable 0/accessed = 0010b
+120   cf  # same as gdt_code
+121   00  # base[24:32]
+122 # gdt_end:
+123 
+124 # padding
+125 # 78:
+126                         00 00 00 00 00 00 00 00
+127 
+128 # 80:
+129 # gdt_descriptor:
+130   17 00  # final index of gdt = gdt_end - gdt_start - 1
+131   60 7c 00 00  # start = gdt_start
+132 
+133 # padding
+134 # 85:
+135                   00 00 00 00 00 00 00 00 00 00
+136 
+137 # 90:
+138 # disk_error:
+139   # print 'D' to top-left of screen to indicate disk error
+140   # *0xb8000 <- 0x0f44
+141   # bx <- 0xb800
+142   bb 00 b8
+143   # ds <- bx
+144   8e db  # 11b/mod 011b/reg/ds 011b/rm/bx
+145   # al <- 'D'
+146   b0 44
+147   # ah <- 0x0f  # white on black
+148   b4 0f
+149   # bx <- 0
+150   bb 00 00
+151   # *ds:bx <- ax
+152   89 07  # 00b/mod/indirect 000b/reg/ax 111b/rm/bx
+153 
+154 e9 fb ff  # loop forever
+155 
+156 # padding
+157 # a1:
+158    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+159 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+160 
+161 ## 32-bit code from this point (still some instructions not in SubX)
+162 
+163 # c0:
+164 # initialize_32bit_mode:
+165   66 b8 10 00  # ax <- offset 16 from gdt_start
+166   8e d8  # ds <- ax
+167   8e d0  # ss <- ax
+168   8e c0  # es <- ax
+169   8e e0  # fs <- ax
+170   8e e8  # gs <- ax
+171 
+172   # load interrupt handlers
+173   0f 01 1d  # lidt 00/mod/indirect 011/subop 101/rm32/use-disp32
+174     00 7f 00 00  # *idt_descriptor
+175 
+176   # enable keyboard IRQ
+177   b0 fd  # al <- 0xfd  # enable just IRQ1
+178   e6 21  # port 0x21 <- al
+179 
+180   # initialization is done; enable interrupts
+181   fb
+182   e9 21 00 00 00  # jump to 0x7d00
+183 
+184 # padding
+185 # df:
+186                                              00
+187 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+188 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+189 
+190 ## 'application' SubX code: print one character to top-left of screen
+191 
+192 # offset 100 (address 0x7d00):
+193 # Entry:
+194   # eax <- *0x7ff4  # random address in second segment containing 'H'
+195   8b  # copy rm32 to r32
+196     05  # 00/mod/indirect 000/r32/eax 101/rm32/use-disp32
+197     # disp32
+198     f4 7f 00 00
+199   # *0xb8000 <- eax
+200   89  # copy r32 to rm32
+201     05  # 00/mod/indirect 000/r32/eax 101/rm32/use-disp32
+202     # disp32
+203     00 80 0b 00
+204 
+205 e9 fb ff ff ff  # loop forever
+206 
+207 # padding
+208 # 111:
+209    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+210 
+211 # 120:
+212 # null interrupt handler:
+213   cf  # iret
+214 
+215 # padding
+216 # 121:
+217    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+218 
+219 # 130:
+220 # keyboard interrupt handler:
+221   # prologue
+222   fa  # disable interrupts
+223   60  # push all registers to stack
+224   # acknowledge interrupt
+225   b0 20  # al <- 0x20
+226   e6 20  # port 0x20 <- al
+227   # 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)
+228 #?   e4 64  # al <- port 0x64
+229 #?   a8 01  # set zf if bit 0 (least significant) is not set
+230 #?   74 11  # if bit 0 is not set, skip to epilogue
+231   # read keycode into eax
+232   31 c0  # eax <- xor eax;  11/direct 000/r32/eax 000/rm32/eax
+233   e4 60  # al <- port 0x60
+234   # map key '1' to ascii; if eax == 2, eax = 0x31
+235   3d 02 00 00 00  # compare eax with 0x02
+236   75 0b  # if not equal, goto epilogue
+237   b8 31 0f 00 00  # eax <- 0x0f31
+238   # print eax to top-left of screen (*0xb8000)
+239   89  # copy r32 to rm32
+240     05  # 00/mod/indirect 000/r32/eax 101/rm32/use-disp32
+241     # disp32
+242     00 80 0b 00
+243   # epilogue
+244   61  # pop all registers
+245   fb  # enable interrupts
+246   cf  # iret
+247 
+248 # padding
+249 # 14f
+250                                              00
+251 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+252 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+253 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+254 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+255 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+256 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+257 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+258 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+259 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+260 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+261 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+262 
+263 # final 2 bytes of boot sector
+264 55 aa
+265 
+266 ## sector 2
+267 # not loaded on boot; loaded by load_disk
+268 
+269 # offset 200 (address 0x7e00): interrupt descriptor table
+270 # 32 entries * 8 bytes each = 256 bytes (0x100)
+271 # idt_start:
+272 
+273 00 00 00 00 00 00 00 00
+274 00 00 00 00 00 00 00 00
+275 00 00 00 00 00 00 00 00
+276 00 00 00 00 00 00 00 00
+277 00 00 00 00 00 00 00 00
+278 00 00 00 00 00 00 00 00
+279 00 00 00 00 00 00 00 00
+280 00 00 00 00 00 00 00 00
+281 
+282 # entry 8: clock?
+283   20 7d  # target[0:16] = null interrupt handler
+284   08 00  # segment selector (gdt_code)
+285   00  # unused
+286   8e  # 1/p 00/dpl 0 1110/type/32-bit-interrupt-gate
+287   00 00  # target[16:32]
+288 
+289 # entry 9: keyboard?
+290   30 7d  # target[0:16] = keyboard interrupt handler
+291   08 00  # segment selector (gdt_code)
+292   00  # unused
+293   8e  # 1/p 00/dpl 0 1110/type/32-bit-interrupt-gate
+294   00 00  # target[16:32]
+295 
+296 00 00 00 00 00 00 00 00
+297 00 00 00 00 00 00 00 00
+298 00 00 00 00 00 00 00 00
+299 00 00 00 00 00 00 00 00
+300 00 00 00 00 00 00 00 00
+301 00 00 00 00 00 00 00 00
+302 00 00 00 00 00 00 00 00
+303 00 00 00 00 00 00 00 00
+304 00 00 00 00 00 00 00 00
+305 00 00 00 00 00 00 00 00
+306 00 00 00 00 00 00 00 00
+307 00 00 00 00 00 00 00 00
+308 00 00 00 00 00 00 00 00
+309 00 00 00 00 00 00 00 00
+310 00 00 00 00 00 00 00 00
+311 00 00 00 00 00 00 00 00
+312 00 00 00 00 00 00 00 00
+313 00 00 00 00 00 00 00 00
+314 00 00 00 00 00 00 00 00
+315 00 00 00 00 00 00 00 00
+316 00 00 00 00 00 00 00 00
+317 00 00 00 00 00 00 00 00
+318 # idt_end:
+319 
+320 # offset 300 (address 0x7f00):
+321 # idt_descriptor:
+322   ff 00  # idt_end - idt_start - 1
+323   00 7e 00 00  # start = idt_start
+324 
+325 # padding
+326                   00 00 00 00 00 00 00 00 00 00
+327 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+328 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+329 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+330 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+331 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+332 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+333 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+334 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+335 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+336 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+337 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+338 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+339 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+340 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+341 00 00 00 00 48 0f 00 00 00 00 00 00 00 00 00 00  # spot the 'H' with attributes
+342 # offset 400 (address 0x8000)
+343 
+344 # vim:ft=conf
 
-- cgit 1.4.1-2-gfad0