mbr.S 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  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. # build a temporary stack
  9. xor %esp, %esp
  10. mov $0x0e00, %sp
  11. mov $128, %cx # 512 bytes
  12. mov $0x7c00, %si
  13. mov $0x0e00, %di
  14. rep movsl
  15. lgdt .Learly_gdt_descriptor
  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 .Lax
  30. mov %cx, %ax
  31. mov %dx, %bx
  32. .Lax:
  33. sub $1024, %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. .Le820_read_mem_map:
  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 .Le820_read_mem_map
  63. .Lsave_mem_fin:
  64. cli
  65. lidt .Lnull_idt_descriptor
  66. mov %cr0, %eax
  67. or $1, %eax
  68. mov %eax, %cr0
  69. ljmp $0x08, $start_32bit
  70. .Lhalt:
  71. hlt
  72. jmp .Lhalt
  73. .align 16
  74. .Learly_gdt:
  75. .8byte 0x0 # null selector
  76. .8byte 0x00cf9a000000ffff # code selector
  77. .8byte 0x00cf92000000ffff # data selector
  78. .8byte 0x000f9a000000ffff # 16 bit code selector
  79. .8byte 0x000f92000000ffff # 16 bit data selector
  80. # null IDT descriptor
  81. # so that exceptions will cause the system to reset
  82. .align 4
  83. .Lnull_idt_descriptor:
  84. .word 0 # size
  85. .long 0 # base
  86. .align 4
  87. .Learly_gdt_descriptor:
  88. .word 0x27 # 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 0x00001000 # read to 0000:1000
  94. .8byte 1 # read from LBA 1