MBR (Master Boot Record)
Segment Registers
Example MBR
```asm-intel-x86-generic
ORG 0x7c00 ;; ORG is really the offset of: Address * 16 + offset
BITS 16 ;; real-mode is constrained to 16-bit code
CODE_SEG equ gdt_code - gdt_start ;; Code segment (.text)
DATA_SEG equ gdt_data - gdt_start ;; Data Segment (.data)
_start:
jmp short start
nop
times 33 db 0 ;; 33 bytes after short jump for BIOS Parameter Block
;; https://wiki.osdev.org/FAT#Boot_Record
;; If BIOS fills in parameter block values, it won't
;; corrupt our code
start:
jmp 0:present ;; forces code segment to 0x7c0 (0x7c0 * 16) = 0x7c00
;; this give our code the best chance of booting on any system
;; cs replaced with 0x7C0
;; USB/HD that are partitioned will have a boolader in the first sector
;; each partition will have a volumbe boot record
init_segments:
cli ;; clear interrupt flags, meaning ignore maskable interrupts
mov ax, 0x00
mov ds, ax
mov es, ax
mov ss, ax
mov sp, 0x7c00
sti ;; enable interrupts
ret
present:
call init_segments ;; mask interrupts for safe operation
.protected: ;; Entering protected mode
cli ;; Mask interrupts
lgdt[gdt_descripter] ;; Load GDT register with start address of Global descriptor table
mov eax, cr0 ;; cr0 is control register 0
or eax, 0x1 ;; set PE (protection Enable) bit in CR0
mov cr0, eax
;; Perform a far jump to selector 08h (offset into GDT, pointing at 32-bit PM code segment descriptor)
;; to load the CS with proper PM32 descriptor. Recall that in protected mode, segment registers become
;; selectors
jmp CODE_SEG:load32 ;; Switch to by replaceing CODE_SET with GDT[Entry[1]], then jump to load32.
;; GDT Section
gdt_start: ;; Global Descriptor Table
;; offset 0 ;; GDT Null Descriptor
gdt_null:
dd 0x0
dd 0x0
;; offset 0x8 ;; Entry 1
gdt_code: ;; CS points here
dw 0xffff ;; Limit GDT[15:0]
dw 0 ;; Base GDT[15:0]
db 0 ;; Base GDT[16:23]
db 0x9a ;; Access Byte GDT[7:0]
db 11001111b ;; High 4 bit flags and low 4 bit flags Limit[19:16] and flags[3:0]
db 0 ;; Base [31:24]
;; offset 0x10 ;; Entry 2
gdt_data: ;; DS, SS, FS, GS, ES
dw 0xffff ;; Limit GDT[15:0]
dw 0 ;; Base GDT[15:0]
db 0 ;; Base GDT[16:23]
db 0x92 ;; Access Byte GDT[7:0]
db 11001111b ;; High 4 bit flags and low 4 bit flags Limit[19:16] and flags[3:0]
db 0 ;; Base [31:24]
;; end gdt
gdt_end: ;; Marks the end of GDT descriptor
;; gdt descripter ;; Computing size gives us the entire GDT
gdt_descripter:
dw gdt_end - gdt_start-1 ;; size of descriptor
dd gdt_start
;; 32-Bt code ;; Start 32-bit Mode, and switch from selector memory to paging
[BITS 32] ;; Start 32-bit mode
load32:
mov ax, DATA_SEG
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
mov ebp, 0x00200000
mov esp, ebp
jmp $
times 510-($ - $$) db 0 ;; pad zeros to get 510 bytes
dw 0xAA55 ;; 511th and 512th byte boot signature dw = 2 bytes
```ORG Form
Code & Data Segment
FAT Partitioning
Masking Interrupts
Global Descriptor Table
Boot Signature
Last updated
Was this helpful?