This repository has been archived by the owner on Jan 12, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #39 from lvntky/feature/memory
Feature/memory
- Loading branch information
Showing
14 changed files
with
308 additions
and
135 deletions.
There are no files selected for viewing
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,57 +1,83 @@ | ||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
; ; | ||
; Artillery OS GRUB BootLoader ; | ||
; ; | ||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
|
||
[BITS 32] | ||
extern kernel_main | ||
|
||
global start | ||
start: | ||
mov esp, _sys_stack ; This points the stack to our new stack area | ||
jmp stublet | ||
|
||
; This part MUST be 4byte aligned, so we solve that issue using 'ALIGN 4' | ||
ALIGN 4 | ||
mboot: | ||
; Multiboot macros to make a few lines later more readable | ||
MULTIBOOT_PAGE_ALIGN equ 1<<0 | ||
MULTIBOOT_MEMORY_INFO equ 1<<1 | ||
MULTIBOOT_AOUT_KLUDGE equ 1<<16 | ||
MULTIBOOT_HEADER_MAGIC equ 0x1BADB002 | ||
MULTIBOOT_HEADER_FLAGS equ MULTIBOOT_PAGE_ALIGN | MULTIBOOT_MEMORY_INFO | MULTIBOOT_AOUT_KLUDGE | ||
MULTIBOOT_CHECKSUM equ -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS) | ||
EXTERN code, bss, end | ||
|
||
; This is the GRUB Multiboot header. A boot signature | ||
dd MULTIBOOT_HEADER_MAGIC | ||
dd MULTIBOOT_HEADER_FLAGS | ||
dd MULTIBOOT_CHECKSUM | ||
; AOUT kludge - must be physical addresses. Make a note of these: | ||
; The linker script fills in the data for these ones! | ||
dd mboot | ||
dd code | ||
dd bss | ||
dd end | ||
dd start | ||
|
||
; This is an endless loop here. Make a note of this: Later on, we | ||
; will insert an 'extern _main', followed by 'call _main', right | ||
; before the 'jmp $'. | ||
stublet: | ||
call kernel_main | ||
jmp $ | ||
|
||
|
||
; Shortly we will add code for loading the GDT right here! | ||
|
||
|
||
; In just a few pages in this tutorial, we will add our Interrupt | ||
; Service Routines (ISRs) right here! | ||
|
||
|
||
|
||
; Here is the definition of our BSS section. Right now, we'll use | ||
; it just to store the stack. Remember that a stack actually grows | ||
; downwards, so we declare the size of the data before declaring | ||
; the identifier '_sys_stack' | ||
SECTION .bss | ||
resb 8192 ; This reserves 8KBytes of memory here | ||
_sys_stack: | ||
global loader ; the entry point for the linker | ||
|
||
extern kernel_main ; kmain is defined in kmain.c | ||
extern end_of_kernel | ||
|
||
; setting up the multiboot headers for GRUB | ||
MODULEALIGN equ 1<<0 ; align loaded modules on page | ||
; boundaries | ||
MEMINFO equ 1<<1 ; provide memory map | ||
FLAGS equ MODULEALIGN | MEMINFO ; the multiboot flag field | ||
MAGIC equ 0x1BADB002 ; magic number for bootloader to | ||
; find the header | ||
CHECKSUM equ -(MAGIC + FLAGS) ; checksum required | ||
|
||
; paging for the kernel | ||
KERNEL_VIRTUAL_BASE equ 0xC0000000 ; we start at 3GB | ||
KERNEL_PAGE_IDX equ (KERNEL_VIRTUAL_BASE >> 22) ; PDT index for 4MB PDE | ||
|
||
; the page directory used to boot the kernel into the higher half | ||
section .data | ||
align 4096 ; align on 4kB blocks | ||
boot_page_directory: | ||
dd 00000000000000000000000010001011b ; identity mapped first 4MB | ||
times (KERNEL_PAGE_IDX-1) dd 0 ; no pages here | ||
dd 00000000000000000000000010001011b ; map 0xC0000000 to the first 4MB | ||
times (1024-KERNEL_PAGE_IDX-1) dd 0 ; no more pages | ||
|
||
|
||
section .text | ||
align 4 | ||
dd MAGIC | ||
dd FLAGS | ||
dd CHECKSUM | ||
|
||
; the entry point, called by GRUB | ||
loader: | ||
mov ecx, (boot_page_directory-KERNEL_VIRTUAL_BASE) | ||
and ecx, 0xFFFFF000 ; we only care about the upper 20 bits | ||
or ecx, 0x08 ; PWT, enable page write through? | ||
mov cr3, ecx ; load pdt | ||
|
||
mov ecx, cr4 ; read current config from cr4 | ||
or ecx, 0x00000010 ; set bit enabling 4MB pages | ||
mov cr4, ecx ; enable it by writing to cr4 | ||
|
||
mov ecx, cr0 ; read current config from cr0 | ||
or ecx, 0x80000000 ; the highest bit controls paging | ||
mov cr0, ecx ; enable paging by writing config to cr0 | ||
|
||
lea ecx, [higher_half] ; store the address higher_half in ecx | ||
jmp ecx ; now we jump into 0xC0100000 | ||
|
||
; code executing from here on uses the page table, and is accessed through | ||
; the upper half, 0xC0100000 | ||
higher_half: | ||
mov DWORD [boot_page_directory], 0 ; erase identity mapping of kernel | ||
invlpg [0] ; and flush any tlb-references to it | ||
|
||
mov esp, stack+STACKSIZE ; sets up the stack pointer | ||
push end_of_kernel | ||
push eax ; eax contains the MAGIC number | ||
push ebx ; ebx contains the multiboot data | ||
; structure | ||
call kernel_main ; call the main function of the kernel | ||
|
||
hang: | ||
jmp hang ; loop forever | ||
|
||
; reserve initial stack space | ||
STACKSIZE equ 0x4000 ; 16kB | ||
|
||
section .bss | ||
align 4 | ||
stack: | ||
resb STACKSIZE ; reserve memory for stack on | ||
; doubleworded memory |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
#ifndef _COMMON_H_ | ||
#define _COMMON_H_ | ||
|
||
#define UNUSED_ARGUMENT(x) (void)x; | ||
#define KERNEL_BASE_ADDR 0xC0000000 | ||
|
||
#endif |
This file contains 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
This file contains 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
This file contains 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
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
global pdt_set | ||
|
||
section .text: | ||
|
||
pdt_set: | ||
mov eax, [esp+4] ; loads the address of the pdt into eax | ||
mov cr3, eax ; loads the PDT | ||
mov eax, cr0 ; read current config from cr0 | ||
or eax, 0x80000000 ; the highest bit controls paging | ||
mov cr0, eax ; enable paging by writing config to cr0 | ||
ret |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,54 +1,28 @@ | ||
#ifndef _PAGING_H_ | ||
#define _PAGING_H_ | ||
|
||
#define PAGING_ENTRY_SIZE 1024 | ||
#define KERNEL_BASE_VIRT 0xC0000000 | ||
|
||
#define PHYS_TO_VIRT(addr) ((addr) + KERNEL_BASE_VIRT) | ||
#define VIRT_TO_PHYS(addr) ((addr)-KERNEL_BASE_VIRT) | ||
|
||
#define PAGE_DIRECTORY_INDEX(x) (((x) >> 22) & 0x3FF) | ||
#define PAGE_TABLE_INDEX(x) (((x) >> 12) & 0x3FF) | ||
|
||
#include <stdint.h> | ||
#include <stdbool.h> | ||
#include "../../include/qemu_debug.h" | ||
#include "../../descriptor_tables/include/isr.h" | ||
#include "../../libc/include/string.h" | ||
|
||
typedef struct page_directory_entry { | ||
uint8_t config; | ||
uint8_t low_addr; /* only the highest 4 bits are used */ | ||
uint16_t high_addr; | ||
} __attribute__((packed)) page_directory_entry_t; | ||
|
||
typedef struct directory_entry { | ||
uint32_t present : 1; | ||
uint32_t rw : 1; | ||
uint32_t user : 1; | ||
uint32_t writethrough : 1; | ||
uint32_t disable_cache : 1; | ||
uint32_t accessed : 1; | ||
uint32_t zero : 1; | ||
uint32_t large_pages : 1; | ||
uint32_t unused : 1; | ||
uint32_t available : 3; | ||
uint32_t frame : 20; | ||
} __attribute__((packed)) directory_entry_t; | ||
typedef struct page_table_entry { | ||
uint8_t config; | ||
uint8_t middle; /* only the highest 4 bits and the lowest bit are used */ | ||
uint16_t high_addr; | ||
} __attribute__((packed)) page_table_entry_t; | ||
|
||
typedef struct page { | ||
uint32_t present : 1; | ||
uint32_t rw : 1; | ||
uint32_t user : 1; | ||
uint32_t writethrough : 1; | ||
uint32_t disable_cache : 1; | ||
uint32_t accessed : 1; | ||
uint32_t dirty : 1; | ||
uint32_t zero : 1; | ||
uint32_t global : 1; | ||
uint32_t available : 3; | ||
uint32_t frame : 20; | ||
} __attribute__((packed)) page_t; | ||
#define NUM_ENTRIES 1024 | ||
#define PDT_SIZE NUM_ENTRIES * sizeof(page_directory_entry_t) | ||
#define PT_SIZE NUM_ENTRIES * sizeof(page_table_entry_t) | ||
|
||
typedef struct page_table { | ||
page_t entries[PAGING_ENTRY_SIZE]; | ||
} page_table_t; | ||
#define VIRTUAL_TO_PDT_IDX(a) ((a >> 20) & 0x3FF) | ||
|
||
typedef struct page_directory { | ||
directory_entry_t entries[PAGING_ENTRY_SIZE]; | ||
} page_directory_t; | ||
void paging_init(uint32_t); | ||
|
||
#endif |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
# Memory | ||
|
||
## Memory Layout | ||
|
||
Each process in the Artillery OS runs in its own memory sandbox. This sandbox is the virtual address space, | ||
which in 32-bit mode is always a 4GB block of memory addresses. These virtual addresses are mapped to | ||
physical memory by page tables, which are maintained by the operating system kernel and consulted by the processor. | ||
Each process has its own set of page tables, but there is a catch. Once virtual addresses are enabled, | ||
they apply to all software running in the machine, including the kernel itself. Thus a portion of the virtual | ||
address space must be reserved to the kernel | ||
|
||
* Artillery OS User/Kernel Memory Split | ||
|
||
..................... -> 0xFFFFFFFF | ||
. Kernel Space . | ||
. (1GB) . | ||
..................... -> 0xC0000000 | ||
. . | ||
. . | ||
. . | ||
. User Space . | ||
. Mode . | ||
. (3GB) . | ||
. . | ||
. . | ||
..................... 0x00000000 |
Oops, something went wrong.