mbr.S 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. .section .mbr
  2. .code16
  3. move_mbr:
  4. xor %ax, %ax
  5. mov %ax, %ds
  6. mov %ax, %es
  7. mov %ax, %ss
  8. # move the MBR to 0xe00
  9. mov $128, %cx # 512 bytes
  10. mov $0x7c00, %si
  11. mov $0x0e00, %di
  12. rep movsl
  13. ljmp $0x00, $2f
  14. 2:
  15. # read the kernel stage1
  16. mov $.Lread_data_packet, %si
  17. mov $0x42, %ah
  18. mov $0x80, %dl
  19. int $0x13
  20. jc .Lhalt
  21. # get memory size info and storage it
  22. mov $0xe801, %ax
  23. int $0x15
  24. jc .Lhalt
  25. cmp $0x86, %ah # unsupported function
  26. je .Lhalt
  27. cmp $0x80, %ah # invalid command
  28. je .Lhalt
  29. jcxz 2f
  30. mov %cx, %ax
  31. mov %dx, %bx
  32. 2:
  33. mov $E820_MEM_MAP_DATA, %esp
  34. movzw %ax, %eax
  35. mov %eax, 8(%esp) # 1k blocks
  36. movzw %bx, %ebx
  37. mov %ebx, 12(%esp) # 64k blocks
  38. # save the destination address to es:di
  39. mov %sp, %di
  40. add $16, %di # buffer is 1024 - 16 bytes
  41. # set default entry size
  42. movl $20, 4(%esp)
  43. # clear %ebx, len
  44. xor %ebx, %ebx
  45. mov %ebx, (%esp)
  46. 2:
  47. # set the magic number to edx
  48. mov $0x534D4150, %edx
  49. # set function number to eax
  50. mov $0xe820, %eax
  51. # set default entry size
  52. mov $24, %ecx
  53. int $0x15
  54. incl (%esp)
  55. add $24, %edi
  56. jc .Lsave_mem_fin
  57. cmp $0, %ebx
  58. jz .Lsave_mem_fin
  59. cmp $24, %ecx
  60. cmovnz 4(%esp), %ecx
  61. mov %ecx, 4(%esp)
  62. jmp 2b
  63. .Lsave_mem_fin:
  64. mov $0x3ff, %ax
  65. mov $BIOS_IDT_DESCRIPTOR, %di
  66. mov %ax, (%di)
  67. xor %eax, %eax
  68. mov %eax, 2(%di)
  69. lgdt .Learly_gdt_descriptor
  70. cli
  71. # IDT descriptor is 6 0's. borrow the null gdt entry
  72. lidt .Learly_gdt
  73. # enable protection mode
  74. mov %cr0, %eax
  75. or $1, %eax
  76. mov %eax, %cr0
  77. ljmp $0x08, $start_32bit
  78. .Lhalt:
  79. hlt
  80. jmp .
  81. .align 16
  82. .Learly_gdt:
  83. .8byte 0x0 # null selector
  84. .8byte 0x00cf9a000000ffff # 32bit code selector
  85. .8byte 0x00cf92000000ffff # 32bit data selector
  86. .align 4
  87. .Learly_gdt_descriptor:
  88. .word 0x17 # size
  89. .long .Learly_gdt # address
  90. .align 16
  91. .Lread_data_packet:
  92. .long 0x00080010 # .stage1 takes up 4K, or 8 sectors
  93. .long 0x00007000 # read to 0000:7000
  94. .8byte 1 # read from LBA 1