about summary refs log blame commit diff stats
path: root/apps/bos/32bit.hex
blob: e8b1f21a08096e6065492d829e48b736795e4c59 (plain) (tree)



















                                                                 
                                                                      
                                                          
                            


                              
                                                                                                                      


         
                                               



                                               


                                 
     



















                                                             




                                               

                                                       
                                  

         



                                               
                                               


                                                                    
     






                                               
                                  

         
     
                                               
                                               


                                                                     
     










                                                            
 
                              
 
                      
                                               
      



















                                               
# 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