about summary refs log tree commit diff stats
path: root/arc/.traces/convert-quotes-defer
blob: e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 (plain) (blame)

='n183' href='#n183'>183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Mu - apps/boot.hex</title>
<meta name="Generator" content="Vim/8.1">
<meta name="plugin-version" content="vim8.1_v1">
<meta name="syntax" content="conf">
<meta name="settings" content="use_css,pre_wrap,no_foldcolumn,expand_tabs,prevent_copy=">
<meta name="colorscheme" content="minimal-light">
<style type="text/css">
<!--
pre { white-space: pre-wrap; font-family: monospace; color: #000000; background-color: #c6c6c6; }
body { font-family: monospace; color: #000000; background-color: #c6c6c6; }
* { font-size: 1em; }
.Todo { color: #000000; background-color: #ffff00; padding-bottom: 1px; }
.Comment { color: #005faf; }
-->
</style>
</head>
<body>
<a href='https://github.com/akkartik/mu/blob/master/apps/boot.hex'>https://github.com/akkartik/mu/blob/master/apps/boot.hex</a>
<pre id='vimCodeElement'>
<span class="Comment"># Bootable image that:</span>
<span class="Comment">#   - loads more sectors past the first boot sector (using BIOS primitives)</span>
<span class="Comment">#   - switches to 32-bit mode (giving up access to BIOS primitives)</span>
<span class="Comment">#   - sets up a handler for keyboard events</span>
<span class="Comment">#   - as an example program, prints alphabets to the top-left position on screen (by writing to memory-mapped VGA memory) as they're typed</span>
<span class="Comment">#</span>
<span class="Comment"># If the initial load fails, it prints 'D' to the top-left of the screen and</span>
<span class="Comment"># halts.</span>
<span class="Comment">#</span>
<span class="Comment"># To convert to a disk image, first prepare a realistically sized disk image:</span>
<span class="Comment">#   dd if=/dev/zero of=disk.img count=20160  # 512-byte sectors, so 10MB</span>
<span class="Comment"># Now fill in sectors:</span>
<span class="Comment">#   ./bootstrap run apps/hex &lt; apps/boot.hex &gt; boot.bin</span>
<span class="Comment">#   dd if=boot.bin of=disk.img conv=notrunc</span>
<span class="Comment"># To run:</span>
<span class="Comment">#   qemu-system-i386 disk.img</span>
<span class="Comment"># Or:</span>
<span class="Comment">#   bochs -f apps/boot.bochsrc  # boot.bochsrc loads disk.img</span>
<span class="Comment">#</span>
<span class="Comment"># Since we start out in 16-bit mode, we need instructions SubX doesn't</span>
<span class="Comment"># support.</span>
<span class="Comment"># This file contains just hex bytes and comments. Zero error-checking. Make</span>
<span class="Comment"># liberal use of:</span>
<span class="Comment">#   - comments documenting expected offsets</span>
<span class="Comment">#   - size checks on the emitted file (currently: 512 bytes)</span>
<span class="Comment">#   - xxd to eyeball that offsets contain expected bytes</span>

<span class="Comment">## 16-bit entry point</span>

<span class="Comment"># Upon reset, the IBM PC</span>
<span class="Comment">#   loads the first sector (512 bytes)</span>
<span class="Comment">#   from some bootable image (see the boot sector marker at the end of this file)</span>
<span class="Comment">#   to the address range [0x7c00, 0x7e00)</span>

<span class="Comment"># offset 00 (address 0x7c00):</span>
  <span class="Comment"># disable interrupts for this initialization</span>
  fa  <span class="Comment"># cli</span>

  <span class="Comment"># initialize segment registers</span>
  <span class="Comment"># this isn't always needed, but is considered safe not to assume</span>
  b8 00 00  <span class="Comment"># ax &lt;- 0</span>
  8e d8  <span class="Comment"># ds &lt;- ax</span>
  8e d0  <span class="Comment"># ss &lt;- ax</span>
  8e c0  <span class="Comment"># es &lt;- ax</span>
  8e e0  <span class="Comment"># fs &lt;- ax</span>
  8e e8  <span class="Comment"># gs &lt;- ax</span>

  <span class="Comment"># We don't read or write the stack before we get to 32-bit mode. No function</span>
  <span class="Comment"># calls, so we don't need to initialize the stack.</span>

<span class="Comment"># 0e:</span>
  <span class="Comment"># load more sectors from disk</span>
  b4 02  <span class="Comment"># ah &lt;- 2  # read sectors from disk</span>
  <span class="Comment"># dl comes conveniently initialized at boot time with the index of the device being booted</span>
  b5 00  <span class="Comment"># ch &lt;- 0  # cylinder 0</span>
  b6 00  <span class="Comment"># dh &lt;- 0  # track 0</span>
  b1 02  <span class="Comment"># cl &lt;- 2  # second sector, 1-based</span>
  b0 01  <span class="Comment"># al &lt;- 1  # number of sectors to read</span>
  <span class="Comment"># address to write sectors to = es:bx = 0x7e00, contiguous with boot segment</span>
  bb 00 00  <span class="Comment"># bx &lt;- 0</span>
  8e c3  <span class="Comment"># es &lt;- bx</span>
  bb 00 7e  <span class="Comment"># bx &lt;- 0x7e00</span>
  cd 13  <span class="Comment"># int 13h, BIOS disk service</span>
  0f 82 76 00  <span class="Comment"># jump-if-carry disk-error</span>

<span class="Comment"># 26:</span>
  <span class="Comment"># undo the A20 hack: <a href="https://en.wikipedia.org/wiki/A20_line">https://en.wikipedia.org/wiki/A20_line</a></span>
  <span class="Comment"># this is from <a href="https://github.com/mit-pdos/xv6-public/blob/master/bootasm.S">https://github.com/mit-pdos/xv6-public/blob/master/bootasm.S</a></span>
  <span class="Comment"># seta20.1:</span>
  e4 64  <span class="Comment"># al &lt;- port 0x64</span>
  a8 02  <span class="Comment"># set zf if bit 1 (second-least significant) is not set</span>
  75 fa  <span class="Comment"># if zf not set, goto seta20.1 (-6)</span>

  b0 d1  <span class="Comment"># al &lt;- 0xd1</span>
  e6 64  <span class="Comment"># port 0x64 &lt;- al</span>

<span class="Comment"># 30:</span>
  <span class="Comment"># seta20.2:</span>
  e4 64  <span class="Comment"># al &lt;- port 0x64</span>
  a8 02  <span class="Comment"># set zf if bit 1 (second-least significant) is not set</span>
  75 fa  <span class="Comment"># if zf not set, goto seta20.2 (-6)</span>

  b0 df  <span class="Comment"># al &lt;- 0xdf</span>
  e6 64  <span class="Comment"># port 0x64 &lt;- al</span>

<span class="Comment"># 3a:</span>
  <span class="Comment"># switch to 32-bit mode</span>
  0f 01 16  <span class="Comment"># lgdt 00/mod/indirect 010/subop 110/rm/use-disp16</span>
    80 7c  <span class="Comment"># *gdt_descriptor</span>
<span class="Comment"># 3f:</span>
  0f 20 c0  <span class="Comment"># eax &lt;- cr0</span>
  66 83 c8 01  <span class="Comment"># eax &lt;- or 0x1</span>
  0f 22 c0  <span class="Comment"># cr0 &lt;- eax</span>
  ea c0 7c 08 00  <span class="Comment"># far jump to initialize_32bit_mode after setting cs to the record at offset 8 in the gdt (gdt_code)</span>

<span class="Comment"># padding</span>
<span class="Comment"># 4e:</span>
                                          00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

<span class="Comment">## GDT: 3 records of 8 bytes each</span>

<span class="Comment"># 60:</span>
<span class="Comment"># gdt_start:</span>
<span class="Comment"># gdt_null:  mandatory null descriptor</span>
  00 00 00 00 00 00 00 00
<span class="Comment"># gdt_code:  (offset 8 from gdt_start)</span>
  ff ff  <span class="Comment"># limit[0:16]</span>
  00 00 00  <span class="Comment"># base[0:24]</span>
  9a  <span class="Comment"># 1/present 00/privilege 1/descriptor type = 1001b</span>
      <span class="Comment"># 1/code 0/conforming 1/readable 0/accessed = 1010b</span>
  cf  <span class="Comment"># 1/granularity 1/32-bit 0/64-bit-segment 0/AVL = 1100b</span>
      <span class="Comment"># limit[16:20] = 1111b</span>
  00  <span class="Comment"># base[24:32]</span>
<span class="Comment"># gdt_data:  (offset 16 from gdt_start)</span>
  ff ff  <span class="Comment"># limit[0:16]</span>
  00 00 00  <span class="Comment"># base[0:24]</span>
  92  <span class="Comment"># 1/present 00/privilege 1/descriptor type = 1001b</span>
      <span class="Comment"># 0/data 0/conforming 1/readable 0/accessed = 0010b</span>
  cf  <span class="Comment"># same as gdt_code</span>
  00  <span class="Comment"># base[24:32]</span>
<span class="Comment"># gdt_end:</span>

<span class="Comment"># padding</span>
<span class="Comment"># 78:</span>
                        00 00 00 00 00 00 00 00

<span class="Comment"># 80:</span>
<span class="Comment"># gdt_descriptor:</span>
  17 00  <span class="Comment"># final index of gdt = gdt_end - gdt_start - 1</span>
  60 7c 00 00  <span class="Comment"># start = gdt_start</span>

<span class="Comment"># padding</span>
<span class="Comment"># 85:</span>
                  00 00 00 00 00 00 00 00 00 00

<span class="Comment"># 90:</span>
<span class="Comment"># disk_error:</span>
  <span class="Comment"># print 'D' to top-left of screen to indicate disk error</span>
  <span class="Comment"># *0xb8000 &lt;- 0x0f44</span>
  <span class="Comment"># bx &lt;- 0xb800</span>
  bb 00 b8
  <span class="Comment"># ds &lt;- bx</span>
  8e db  <span class="Comment"># 11b/mod 011b/reg/ds 011b/rm/bx</span>
  <span class="Comment"># al &lt;- 'D'</span>
  b0 44
  <span class="Comment"># ah &lt;- 0x0f  # white on black</span>
  b4 0f
  <span class="Comment"># bx &lt;- 0</span>
  bb 00 00
  <span class="Comment"># *ds:bx &lt;- ax</span>
  89 07  <span class="Comment"># 00b/mod/indirect 000b/reg/ax 111b/rm/bx</span>

e9 fb ff  <span class="Comment"># loop forever</span>

<span class="Comment"># padding</span>
<span class="Comment"># a1:</span>
   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

<span class="Comment">## 32-bit code from this point (still some instructions not in SubX)</span>

<span class="Comment"># c0:</span>
<span class="Comment"># initialize_32bit_mode:</span>
  66 b8 10 00  <span class="Comment"># ax &lt;- offset 16 from gdt_start</span>
  8e d8  <span class="Comment"># ds &lt;- ax</span>
  8e d0  <span class="Comment"># ss &lt;- ax</span>
  8e c0  <span class="Comment"># es &lt;- ax</span>
  8e e0  <span class="Comment"># fs &lt;- ax</span>
  8e e8  <span class="Comment"># gs &lt;- ax</span>

  <span class="Comment"># load interrupt handlers</span>
  0f 01 1d  <span class="Comment"># lidt 00/mod/indirect 011/subop 101/rm32/use-disp32</span>
    00 7f 00 00  <span class="Comment"># *idt_descriptor</span>

  <span class="Comment"># enable keyboard IRQ</span>
  b0 fd  <span class="Comment"># al &lt;- 0xfd  # enable just IRQ1</span>
  e6 21  <span class="Comment"># port 0x21 &lt;- al</span>

  <span class="Comment"># initialization is done; enable interrupts</span>
  fb
  e9 21 00 00 00  <span class="Comment"># jump to 0x7d00</span>

<span class="Comment"># padding</span>
<span class="Comment"># df:</span>
                                             00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

<span class="Comment">## 'application' SubX code: print one character to top-left of screen</span>

<span class="Comment"># offset 100 (address 0x7d00):</span>
<span class="Comment"># Entry:</span>
  <span class="Comment"># eax &lt;- *0x7ff4  # random address in second segment containing 'H'</span>
  8b  <span class="Comment"># copy rm32 to r32</span>
    05  <span class="Comment"># 00/mod/indirect 000/r32/eax 101/rm32/use-disp32</span>
    <span class="Comment"># disp32</span>
    f4 7f 00 00
  <span class="Comment"># *0xb8000 &lt;- eax</span>
  89  <span class="Comment"># copy r32 to rm32</span>
    05  <span class="Comment"># 00/mod/indirect 000/r32/eax 101/rm32/use-disp32</span>
    <span class="Comment"># disp32</span>
    00 80 0b 00

e9 fb ff ff ff  <span class="Comment"># loop forever</span>

<span class="Comment"># padding</span>
<span class="Comment"># 111:</span>
   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

<span class="Comment"># 120:</span>
<span class="Comment"># null interrupt handler:</span>
  cf  <span class="Comment"># iret</span>

<span class="Comment"># padding</span>
<span class="Comment"># 121:</span>
   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

<span class="Comment"># 130:</span>
<span class="Comment"># keyboard interrupt handler:</span>
  <span class="Comment"># prologue</span>
  fa  <span class="Comment"># disable interrupts</span>
  60  <span class="Comment"># push all registers to stack</span>
  <span class="Comment"># acknowledge interrupt</span>
  b0 20  <span class="Comment"># al &lt;- 0x20</span>
  e6 20  <span class="Comment"># port 0x20 &lt;- al</span>
  <span class="Comment"># read keyboard status (</span><span class="Todo">TODO</span><span class="Comment">: why bit 0? Doesn't line up with <a href="https://web.archive.org/web/20040604041507/http://panda.cs.ndsu.nodak.edu/~achapwes/PICmicro/keyboard/atkeyboard.html)">https://web.archive.org/web/20040604041507/http://panda.cs.ndsu.nodak.edu/~achapwes/PICmicro/keyboard/atkeyboard.html)</a></span>
<span class="Comment">#?   e4 64  # al &lt;- port 0x64</span>
<span class="Comment">#?   a8 01  # set zf if bit 0 (least significant) is not set</span>
<span class="Comment">#?   74 11  # if bit 0 is not set, skip to epilogue</span>
  <span class="Comment"># read keycode into eax</span>
  31 c0  <span class="Comment"># eax &lt;- xor eax;  11/direct 000/r32/eax 000/rm32/eax</span>
  e4 60  <span class="Comment"># al &lt;- port 0x60</span>
  <span class="Comment"># map key '1' to ascii; if eax == 2, eax = 0x31</span>
  3d 02 00 00 00  <span class="Comment"># compare eax with 0x02</span>
  75 0b  <span class="Comment"># if not equal, goto epilogue</span>
  b8 31 0f 00 00  <span class="Comment"># eax &lt;- 0x0f31</span>
  <span class="Comment"># print eax to top-left of screen (*0xb8000)</span>
  89  <span class="Comment"># copy r32 to rm32</span>
    05  <span class="Comment"># 00/mod/indirect 000/r32/eax 101/rm32/use-disp32</span>
    <span class="Comment"># disp32</span>
    00 80 0b 00
  <span class="Comment"># epilogue</span>
  61  <span class="Comment"># pop all registers</span>
  fb  <span class="Comment"># enable interrupts</span>
  cf  <span class="Comment"># iret</span>

<span class="Comment"># padding</span>
<span class="Comment"># 14f</span>
                                             00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00

<span class="Comment"># final 2 bytes of boot sector</span>
55 aa

<span class="Comment">## sector 2</span>
<span class="Comment"># not loaded on boot; loaded by load_disk</span>

<span class="Comment"># offset 200 (address 0x7e00): interrupt descriptor table</span>
<span class="Comment"># 32 entries * 8 bytes each = 256 bytes (0x100)</span>
<span class="Comment"># idt_start:</span>

00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00

<span class="Comment"># entry 8: clock?</span>
  20 7d  <span class="Comment"># target[0:16] = null interrupt handler</span>
  08 00  <span class="Comment"># segment selector (gdt_code)</span>
  00  <span class="Comment"># unused</span>
  8e  <span class="Comment"># 1/p 00/dpl 0 1110/type/32-bit-interrupt-gate</span>
  00 00  <span class="Comment"># target[16:32]</span>

<span class="Comment"># entry 9: keyboard?</span>
  30 7d  <span class="Comment"># target[0:16] = keyboard interrupt handler</span>
  08 00  <span class="Comment"># segment selector (gdt_code)</span>
  00  <span class="Comment"># unused</span>
  8e  <span class="Comment"># 1/p 00/dpl 0 1110/type/32-bit-interrupt-gate</span>
  00 00  <span class="Comment"># target[16:32]</span>

00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
<span class="Comment"># idt_end:</span>

<span class="Comment"># offset 300 (address 0x7f00):</span>
<span class="Comment"># idt_descriptor:</span>
  ff 00  <span class="Comment"># idt_end - idt_start - 1</span>
  00 7e 00 00  <span class="Comment"># start = idt_start</span>

<span class="Comment"># padding</span>
                  00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 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  <span class="Comment"># spot the 'H' with attributes</span>
<span class="Comment"># offset 400 (address 0x8000)</span>

<span class="Comment"># vim&#0058;ft=conf</span>
</pre>
</body>
</html>
<!-- vim: set foldmethod=manual : -->