Created
May 6, 2020 18:39
-
-
Save brunoperezm/0ec3b1f6e494809422ba872c580bd574 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
#include "common.h" | |
BEGIN | |
CLEAR | |
/* Must come before they are used. */ | |
.equ CODE_SEG, 8 | |
.equ DATA_SEG, gdt_data - gdt_start | |
/* Tell the processor where our Global Descriptor Table is in memory. */ | |
lgdt gdt_descriptor | |
/* Set PE (Protection Enable) bit in CR0 (Control Register 0), | |
* effectively entering protected mode. | |
*/ | |
mov %cr0, %eax | |
orl $0x1, %eax | |
mov %eax, %cr0 | |
ljmp $CODE_SEG, $protected_mode | |
/* Our GDT contains: | |
* | |
* * a null entry to fill the unusable entry 0: | |
* http://stackoverflow.com/questions/33198282/why-have-the-first-segment-descriptor-of-the-global-descriptor-table-contain-onl | |
* * a code and data. Both are necessary, because: | |
* + | |
* -- | |
* ** it is impossible to write to the code segment | |
* ** it is impossible execute the data segment | |
* -- | |
* + | |
* Both start at 0 and span the entire memory, | |
* allowing us to access anything without problems. | |
* | |
* A real OS might have 2 extra segments: user data and code. | |
* | |
* This is the case for the Linux kernel. | |
* | |
* This is better than modifying the privilege bit of the GDT | |
* as we'd have to reload it several times, losing cache. | |
*/ | |
gdt_start: | |
gdt_null: | |
.long 0x0 | |
.long 0x0 | |
gdt_code: | |
.word 0x5000 /* Limite */ | |
.word 0x0000 /* Desde donde arranca */ | |
.byte 0x0 | |
.byte 0b10011010 | |
.byte 0b11001111 | |
.byte 0x0 | |
gdt_data: | |
.word 0x1000 /* Limite */ | |
.word 0x8000 /* Desde donde arranca */ | |
.byte 0x0 | |
.byte 0b10010000 /* Termina siendo read only */ | |
.byte 0b11001111 | |
.byte 0x0 | |
gdt_end: | |
gdt_descriptor: | |
.word gdt_end - gdt_start | |
.long gdt_start | |
vga_current_line: | |
.long 0 | |
.code32 | |
protected_mode: | |
/* Setup the other segments. | |
* Those movs are mandatory because they update the descriptor cache: | |
* http://wiki.osdev.org/Descriptor_Cache | |
*/ | |
mov $DATA_SEG, %ax | |
mov %ax, %ds | |
mov %ax, %es | |
mov %ax, %fs | |
mov %ax, %gs | |
mov %ax, %ss | |
/* TODO detect the last memory address available properly. | |
* It depends on how much RAM we have. | |
*/ | |
mov $0X7000, %ebp | |
mov %ebp, %esp | |
VGA_PRINT_STRING $message | |
jmp . | |
.data | |
message: | |
.asciz "hello world" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment