Last active
November 25, 2021 12:18
-
-
Save matyklug18/cd71a3e0175c92646f3fbceee2953711 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
; the bios places the first sector (512 bytes) at 0x7c00 | |
; thus, thats the location of this code | |
[org 0x7c00] | |
; set the video mode to | |
; 80x25 16 color text (CGA,EGA,MCGA,VGA) | |
; (https://stanislavs.org/helppc/int_10-0.html) | |
; used for clearing the screen | |
mov ah, 0x00 | |
mov al, 0x03 | |
int 0x10 | |
; set the base of the stack (bp) to an arbitrary value | |
mov bp, 0x9000 | |
; set the stack pointer (sp) to the base pointer (bp) | |
mov sp, bp | |
; switch to protected mode (32 bits) | |
call switch_to_pm | |
; in case something weird goes wrong, loop infinitely | |
jmp $ | |
; start of the global descriptor table (gdt) | |
; https://wiki.osdev.org/Global_Descriptor_Table | |
gdt_start: | |
; needed 8 bytes of zeroes, as the first segment | |
dq 0x0000_0000_0000_0000 | |
gdt_code: | |
; segment length, 1st to 16th | |
dw 0xffff | |
; base, 1st to 24th bit | |
dw 0x0000 | |
db 0x00 | |
; Access Byte | |
; | |
; Present: true | |
; Ring Level: kernel | |
; Type: code/data | |
; | |
; Executable: true | |
; Allow Lower Rings: disabled | |
; Readable: true | |
; Access: 0 | |
db 10011010b | |
; flags (4 bit) + | |
; segment length, 17th to 20th | |
; | |
; Granuality: page (4kib) | |
; Size: protected mode (32 bit) | |
db 11001111b | |
; base, 25th to 32nd | |
db 0x00 | |
gdt_data: | |
; segment length, 1st to 16th | |
dw 0xffff | |
; base, 1st to 24th bit | |
dw 0x0000 | |
db 0x00 | |
; Access Byte | |
; https://wiki.osdev.org/Global_Descriptor_Table | |
; | |
; Present: true | |
; Ring Level: kernel | |
; Type: code/data | |
; | |
; Executable: false | |
; Direction: upwards | |
; Readable: true | |
; Access: 0 | |
db 10010010b | |
; flags (4 bit) + | |
; segment length, 17th to 20th | |
; | |
; Granuality: page (4kib) | |
; Size: protected mode (32 bit) | |
db 11001111b | |
; base, 25th to 32nd | |
db 0x00 | |
gdt_end: | |
; start of the gdt descriptor | |
gdt_descriptor: | |
; size, 16 bit, exclusive (one less than true size) | |
dw gdt_end - gdt_start - 1 | |
dd gdt_start ; address of the table (32 bit) | |
; constants containing the offsets | |
CODE_SEG equ gdt_code - gdt_start | |
DATA_SEG equ gdt_data - gdt_start | |
; the "function" that switches to protected mode | |
switch_to_pm: | |
; disable interrupts | |
cli | |
; load the gdt descriptor | |
lgdt [gdt_descriptor] | |
; set 32-bit mode bit in cr0 | |
; https://wiki.osdev.org/CPU_Registers_x86#CR0 | |
mov eax, cr0 | |
or eax, 0x1 | |
mov cr0, eax | |
; far jump to the init_pm function in the code segment | |
; TODO more info | |
jmp CODE_SEG:init_pm | |
; switch the assembler to 32 bits | |
[bits 32] | |
init_pm: | |
; TODO more info | |
mov ax, DATA_SEG | |
mov ds, ax | |
mov ss, ax | |
mov es, ax | |
mov fs, ax | |
mov gs, ax | |
; set the stack at a bigger arbitrary value | |
mov ebp, 0x90000 | |
mov esp, ebp | |
; call the actual code | |
call BEGIN_PM | |
BEGIN_PM: | |
; insert the c code | |
incbin './main-c.bin' | |
; infinite loop | |
jmp $ | |
; padding | |
; 512 - magic number = 510 | |
; $ = current address | |
; $$ = beginning of file address | |
times 510-($-$$) db 0 | |
; magic number | |
dw 0xaa55 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
int main() { | |
char* video_memory = (char*) 0xb8000; | |
*video_memory = 'X'; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment