Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- %define Kernel_load_position_macro 0x1000
- [bits 16]
- [org 0x0600]
- ; This section moves the MBR from 0x7C00 to 0x0600
- __ENTRY: ; Old entry point
- cli ; Clear Interrupts
- xor ax, ax ; Zero out AX (set to 0)
- mov ds, ax ; Set Data Segment to 0 (AX)
- mov es, ax ; Set Extra Segment to 0 (AX)
- mov ss, ax ; Set Stack Segment to 0 (AX)
- mov sp, ax ; Set Stack Pointer to 0 (AX)
- __SET__LOWER__ENTRY:
- mov cx, 0x0100 ; 256 WORDs in MBR
- mov si, 0x7C00 ; Current MBR Address
- mov di, 0x0600 ; New MBR Address
- rep movsw ; Copy MBR
- jmp 0:__LOWER_ENTRY ; Jump to new Address
- __LOWER_ENTRY: ; New entry point
- sti
- mov al, 1 ; Load one sector
- call Load_sectors ; Call the loading routine
- jmp Enter_protected_mode ; Enter protected mode
- ; Calls interrupt 13 to load sectors into memory
- Load_sectors:
- pusha
- mov ah, 02h
- mov ch, 0x0
- mov cl, 0x02
- mov dh, 0x0
- mov dl, 0x0
- mov bx, Kernel_load_position_macro ; Loads to 0x1000
- int 13h
- jc Infinite_loop ; Jump to the infinite loop if interrupt set carry flag
- popa
- ret
- Infinite_loop:
- jmp $
- Enter_protected_mode:
- cli ; Disable interrupts
- lgdt [GDTR] ; Load GDT
- pusha
- mov eax, cr0 ;
- or al, 1 ; Those three instructions should enable protected mode
- mov cr0, eax ;
- popa
- jmp 0x08:Far_Jump_into_kernel ; What does 0x08 mean here?
- ; Switch to 32 bits
- [bits 32]
- Far_Jump_into_kernel:
- mov ax, 0x10
- mov ds, ax
- mov ss, ax
- mov fs, ax
- mov es, ax
- mov gs, ax
- jmp Kernel_load_position_macro ; Jump to the loaded sector
- ; This is the GDT
- GDT:
- GDT_NULL_DESC:
- dd 0 ; null descriptor
- dd 0
- GDT_CODE_DESC:
- dw 0xFFFF ; limit low
- dw 0 ; base low
- db 0 ; base middle
- db 10011010b ; access
- db 11001111b ; granularity
- db 0 ; base high
- GDT_DATA_DESC:
- dw 0xFFFF ; data descriptor
- dw 0 ; limit low
- db 0 ; base low
- db 10010010b ; access
- db 11001111b ; granularity
- db 0 ; base high
- GDTR:
- Limit dw 24 ; length of GDT
- Base dd GDT_NULL_DESC ; base of GDT
- times (446 - ($-$$)) db 0 ; Pad to Partition table
- ; This is the partition entry for kernel
- PT1: ; First Partition Entry ( KERNEL HERE )
- db 0x80 ; Bootable ( Active ) ( 8 bits )
- db 0x00 ; Starting Head ( Start at head 0 ) ( 8 bits )
- db 0b00000010 ; Starting Sector ( Start at Sector 2 ) ( 6 bits ) NOTE: 2 LSB are for the following cylinder field
- db 0b00000000 ; Starting Cylinder ( Start at Cylinder 0 ) ( 10 bits )
- db 0x21 ; System ID ( Filysystem ) ( 21, Reserved )
- db 0x00 ; Ending Head ( End at head 0 ) ( 8 bits )
- db 0b00000100 ; Ending Sector ( End at Sector 4 ) ( 6 bits ) NOTE: 2 LSB are for the following cylinder field
- db 0b00000000 ; Ending Cylinder ( End at Cylinder 0 ) ( 10 bits )
- db 0x00 ; | Relative sector ( 32 bits )
- db 0x00 ; |
- db 0x00 ; |
- db 0x01 ; |
- db 0x00 ; | Total sectors in partition ( 32 bits )
- db 0x00 ; |
- db 0x00 ; |
- db 0x02 ; |
- PT2: times 48 db 0
- dw 0xAA55 ; Magic Word
- ; Start of second sector here
- [bits 32]
- Kernel_Entry_Point:
- mov esi, Hello_World_message_label
- mov ah, 0x0F ; White on black
- call Print_Until_Null ; Print from ESI
- jmp $ ; Loop infinitely
- ; This prints a single character from AL at the offset of ECX
- Print_Single_Character:
- pushad
- mov ebx, 0xb8000
- add ebx, ecx
- mov [ebx], eax
- popad
- ret
- ; This subroutine uses LODSB and Print_Single_Character
- ; to print until a null (ascii 0) character is loaded
- Print_Until_Null:
- pushad
- .internal_loop:
- lodsb
- cmp al, 0
- je .internal_end
- call Print_Single_Character
- add ecx, 0x02 ; Move to the next position in video memory
- jmp .internal_loop
- .internal_end:
- popad
- ret
- Hello_World_message_label:
- db "Hello, World!", 0
- times (1024 - ($-$$)) db 0 ; Pad to end of 2nd sector
Advertisement
Add Comment
Please, Sign In to add comment