From c3f2c7fbfcf41688fade2fcaa81ee2047e4312f5 Mon Sep 17 00:00:00 2001 From: Eric-Paul Ickhorn Date: Sun, 16 Jun 2024 23:03:30 +0200 Subject: [PATCH] Intermediate commit to add GDT In this commit, it was tried to set a linear GDT. It didn't work; but in the future, it will. --- i386/loader/src-asm/memory/gdt.asm | 206 +++++++++++++++++++++++++++++ 1 file changed, 206 insertions(+) create mode 100755 i386/loader/src-asm/memory/gdt.asm diff --git a/i386/loader/src-asm/memory/gdt.asm b/i386/loader/src-asm/memory/gdt.asm new file mode 100755 index 0000000..3607746 --- /dev/null +++ b/i386/loader/src-asm/memory/gdt.asm @@ -0,0 +1,206 @@ + +GDT_MEMORY_AREA equ 0x20000 +GDT_ENTRIES_CAPACITY equ 8 +GDT_ENTRY_SIZE equ 8 + +db "gdt_set_segment" +; [Furthest from EBP] +; 3. Bool (Lowest Address) Task State Segment (1) or Code/Data (0) +; Bool (Second-Lowest) Executable (1) or Not (0) +; Bool (Second-Highest) Stack (1) or Heap (0) Page +; Bool (Highest Address) Readable AND Writeable (1) or only what's necessary (0) +; 2. U32 Number of pages +; 1. Ptr32 Base address +; 0. U32 Index of Segment (0 is not allowed) +; [Nearest to EBP] +gdt_set_segment: +.prolog: + push dword esi + sub esp, 64 + mov esi, esp + + mov [esi + (64 - 4)], eax + mov [esi + (64 - 8)], ebx + mov [esi + (64 - 12)], ecx + mov [esi + (64 - 16)], edx + mov [esi + (64 - 20)], edi + +.get_work_address: + mov eax, [ebp - 4] + mov edx, GDT_ENTRY_SIZE + mul edx + mov [esi], eax + +.prepare_flags_and_access_byte: + ; Access Privilege + ; [Highest] + ; 7. Present Bit (Is in RAM: 1, is swapped out: 0) + ; 5+6. Descriptor Privilege Level (Kernel: 00, User; 11) + ; 4. Descriptor Type (0: System Segment, 1: Code or Data Segment) + ; 3. Is Executable? (Yes: 1, No: 0) + ; 2. Grows Up (Heap) / Grows Down (Stack: 0, Heap, 1) + ; 1. Secondary Access Bit (whether Read or Write is possible + ; even when it isn't strictly necessary for the segment type) + ; 0. Dirty Bit (Was Accessed: 1, Still Clean: 0) + ; [Lowest] + + xor al, al + cmp [ebp - 16], byte 0 + je .after_task_segment_bit_setter + or al, (1 << 4) +.after_task_segment_bit_setter: + + cmp [ebp - 15], byte 0 + je .after_executable_bit_setter + or al, (1 << 3) +.after_executable_bit_setter: + + cmp [ebp - 13], byte 0 + je .after_direction_bit_setter + or al, (1 << 2) +.after_direction_bit_setter: + + cmp [ebp - 12], byte 0 + je .after_read_write_bit_setter + or al, (1 << 1) +.after_read_write_bit_setter: + + ; Flags + ; [Highest] + ; 3. Address and Size Granularity (Bytes: 0, Pages: 1) + ; 2. 16-Bit or 32-Bit selector (0: 16-Bit, 1: 32-Bit) + ; 1. Long Mode / 64-Bit ( + ; 0. Reserved, should be 0 + ; [Lowest] + mov ah, (0b00001100 << 4) + + ; OR the uppermost 4 bits of the Limit into the + ; appropriate position in the byte of the flags. + mov ecx, [ebp - 12] + shr ecx, 16 + and ecx, 0b00001111 + or al, cl + + ; Store the Access Byte and the Flags into the entry. + mov ebx, [esi] + mov [ebx + 5], al ; Access Byte + mov [ebx + 6], ah ; Flags + Limit + + mov eax, [ebp - 8] + mov [ebx + 2], ax + shr eax, 16 + mov [ebx + 3], al + mov [ebx + 7], ah + + mov ax, [ebp - 12] + mov [ebx], ax + +.epilog: + mov ebx, [esi + (64 - 8)] + mov ecx, [esi + (64 - 12)] + mov edx, [esi + (64 - 16)] + mov edi, [esi + (64 - 20)] + + add esp, 64 + pop dword esi + ret + +db "load_flat_gdt" +; [Furthest from EBP] +; 0. 4B Return address +; [Nearest to EBP] +load_flat_gdt: +.prolog: + push dword esi + sub esp, 64 + mov esi, esp + + mov [esi + (64 - 8)], ebx + mov [esi + (64 - 12)], ecx + mov [esi + (64 - 16)], edx + mov [esi + (64 - 20)], edi + mov eax, [ebp - 4] + mov [esi + 20], eax + +.create_gdt: + push ebp + mov ebp, esp + push dword (GDT_MEMORY_AREA) + push dword (GDT_ENTRIES_CAPACITY * GDT_ENTRY_SIZE) + push dword 0 + call mem_set + mov esp, ebp + pop ebp + + ; Code Segment + push ebp + mov ebp, esp + push dword 1 + push dword 0xa00 + push dword 0xfffff + push byte 1 + push byte 0 + push byte 1 + push byte 0 + call gdt_set_segment + mov esp, ebp + pop ebp + + ; Stack Segment + push ebp + mov ebp, esp + push dword 2 + push dword 0 + push dword 0xfffff + push byte 1 + push byte 1 + push byte 0 + push byte 0 + call gdt_set_segment + mov esp, ebp + pop ebp + + ; Data Segment + push ebp + mov ebp, esp + push dword 3 + push dword 0 + push dword 0xfffff + push byte 1 + push byte 0 + push byte 1 + push byte 0 + call gdt_set_segment + mov esp, ebp + pop ebp + + ; Write the GDT Descriptor + cli + mov [esi + 10], dword GDT_MEMORY_AREA + mov [esi + 8], word 31 + mov eax, esi + add ebx, 8 + lgdt [ebx] + sti + + mov ax, (3 << 4) + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + mov ax, (2 << 4) + mov ss, ax + + mov eax, cr0 + or eax, 1 + mov cr0, eax + + jmp dword (1 << 4):.epilog +.epilog: + mov ebx, [esi + (64 - 8)] + mov ecx, [esi + (64 - 12)] + mov edx, [esi + (64 - 16)] + mov edi, [esi + (64 - 20)] + + mov esi, [esi + 20] + jmp esi