aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksa Vučković <aleksav013@gmail.com>2022-06-29 01:52:48 +0200
committerAleksa Vučković <aleksav013@gmail.com>2022-06-29 16:44:25 +0200
commit1f57e99720c4bc5e3e27a88ff469cef43c202a43 (patch)
tree8161bd72d272009a520dd173eac3658a48a9f096
parent58240b0509d11b09ce2994b88308650e7cfb93bd (diff)
HigherHalf
-rw-r--r--Makefile6
-rw-r--r--src/as/boot.s119
-rw-r--r--src/as/paging.s20
-rw-r--r--src/c/kernel.c2
-rw-r--r--src/c/paging.c24
-rw-r--r--src/c/shell/game.c8
-rw-r--r--src/c/vga.c3
-rw-r--r--src/include/source/paging.h1
-rw-r--r--src/linker.ld70
9 files changed, 178 insertions, 75 deletions
diff --git a/Makefile b/Makefile
index a1b385d..67f0d8c 100644
--- a/Makefile
+++ b/Makefile
@@ -18,9 +18,9 @@ export CFLAGS=-std=gnu99 -O3 $(WARNINGS) -ffreestanding -fstack-protector-all
export MKDIR=mkdir -p
export RM=rm -rf
export CP=cp -r
-QEMU=qemu-system-x86_64
+QEMU=qemu-system-i386
QEMU_FLAGS=-enable-kvm
-QEMU_DEBUG=
+QEMU_DEBUG=-s
@@ -105,4 +105,4 @@ run: compile
$(QEMU) $(QEMU_FLAGS) -kernel $(BINARY) $(QEMU_DEBUG)
run-iso: iso
- $(QEMU) $(QEMU_FLAGS) -cdrom $(ISO)
+ $(QEMU) $(QEMU_FLAGS) -cdrom $(ISO) $(QEMU_DEBUG)
diff --git a/src/as/boot.s b/src/as/boot.s
index f65cc72..adb24b7 100644
--- a/src/as/boot.s
+++ b/src/as/boot.s
@@ -1,42 +1,125 @@
-.set ALIGN, 1<<0
-.set MEMINFO, 1<<1
-.set FLAGS, ALIGN | MEMINFO
-.set MAGIC, 0x1BADB002
-.set CHECKSUM, -(MAGIC + FLAGS)
+# Declare constants for the multiboot header.
+.set ALIGN, 1<<0 # align loaded modules on page boundaries
+.set MEMINFO, 1<<1 # provide memory map
+.set FLAGS, ALIGN | MEMINFO # this is the Multiboot 'flag' field
+.set MAGIC, 0x1BADB002 # 'magic number' lets bootloader find the header
+.set CHECKSUM, -(MAGIC + FLAGS) # checksum of above, to prove we are multiboot
-.section .multiboot
+# Declare a multiboot header that marks the program as a kernel.
+.section .multiboot.data, "aw"
.align 4
.long MAGIC
.long FLAGS
.long CHECKSUM
-.set CODE_SEGMENT, 0x08
-.set DATA_SEGMENT, 0x10
-
-.section .bss
-.align 16
+# Allocate the initial stack.
+.section .bootstrap_stack, "aw", @nobits
stack_bottom:
-.skip 16384
+.skip 16384 # 16 KiB
stack_top:
-.section .text
+# Preallocate pages used for paging. Don't hard-code addresses and assume they
+# are available, as the bootloader might have loaded its multiboot structures or
+# modules there. This lets the bootloader know it must avoid the addresses.
+.section .bss, "aw", @nobits
+ .align 4096
+boot_page_directory:
+ .skip 4096
+boot_page_table1:
+ .skip 4096
+boot_page_table2:
+ .skip 4096
+# Further page tables may be required if the kernel grows beyond 3 MiB.
+
+# The kernel entry point.
+.section .multiboot.text, "a"
.global _start
.type _start, @function
_start:
+ movl $(boot_page_table1 - 0xC0000000), %edi
+ movl $0, %esi
+
+1:
+ jl 2f
+ cmpl $0x00400000, %esi
+ jge 3f
+
+ movl %esi, %edx
+ orl $0x003, %edx
+ movl %edx, (%edi)
+
+2:
+ # Size of page is 4096 bytes.
+ addl $4096, %esi
+ # Size of entries in boot_page_table1 is 4 bytes.
+ addl $4, %edi
+ # Loop to the next entry if we haven't finished.
+ loop 1b
+
+3:
+ movl $(boot_page_table2 - 0xC0000000), %edi
+
+4:
+ jl 5f
+ cmpl $0x00800000, %esi
+ jge 6f
+
+ movl %esi, %edx
+ orl $0x003, %edx
+ movl %edx, (%edi)
+
+5:
+ # Size of page is 4096 bytes.
+ addl $4096, %esi
+ # Size of entries in boot_page_table1 is 4 bytes.
+ addl $4, %edi
+ # Loop to the next entry if we haven't finished.
+ loop 4b
+
+6:
+ movl $(boot_page_table1 - 0xC0000000 + 0x003), boot_page_directory - 0xC0000000 + 0 * 4
+ movl $(boot_page_table2 - 0xC0000000 + 0x003), boot_page_directory - 0xC0000000 + 1 * 4
+ movl $(boot_page_table1 - 0xC0000000 + 0x003), boot_page_directory - 0xC0000000 + 768 * 4
+ movl $(boot_page_table2 - 0xC0000000 + 0x003), boot_page_directory - 0xC0000000 + 769 * 4
+
+ # Set cr3 to the address of the boot_page_directory.
+ movl $(boot_page_directory - 0xC0000000), %ecx
+ movl %ecx, %cr3
+
+ # Enable paging and the write-protect bit.
+ movl %cr0, %ecx
+ orl $0x80010000, %ecx
+ movl %ecx, %cr0
+
+ # Jump to higher half with an absolute jump.
+ lea 7f, %ecx
+ jmp *%ecx
+
+.section .text
+
+7:
+ # At this point, paging is fully set up and enabled.
+
+ # Unmap the identity mapping as it is now unnecessary.
+ movl $0, boot_page_directory + 0
+ movl $0, boot_page_directory + 4
+
+ # Reload crc3 to force a TLB flush so the changes to take effect.
+ movl %cr3, %ecx
+ movl %ecx, %cr3
+
+ movl $stack_top, %esp
call init_gdt_table
- ljmp $CODE_SEGMENT, $code
+ ljmp $0x08, $code
code:
- movw $DATA_SEGMENT, %ax
+ movw $0x10, %ax
movw %ax, %ds
movw %ax, %es
movw %ax, %fs
movw %ax, %gs
movw %ax, %ss
- movl $stack_top, %esp
cli
call _init
call kernel_main
hlt
-
-.size _start, . - _start
diff --git a/src/as/paging.s b/src/as/paging.s
index e1cf42a..c3a9a0d 100644
--- a/src/as/paging.s
+++ b/src/as/paging.s
@@ -1,14 +1,16 @@
+.text
+
.global loadPageDirectory
loadPageDirectory:
push %ebp
- mov %esp, %ebp
- mov 8(%esp), %eax
- mov %eax, %cr3
+ movl %esp, %ebp
+ movl 8(%esp), %eax
+ subl $0xC0000000, %eax
+ movl %eax, %cr3
mov %ebp, %esp
pop %ebp
ret
-.text
.global enablePaging
enablePaging:
push %ebp
@@ -19,3 +21,13 @@ enablePaging:
mov %ebp, %esp
pop %ebp
ret
+
+.global flushPaging
+flushPaging:
+ push %ebp
+ mov %esp, %ebp
+ movl %cr3, %ecx
+ movl %ecx, %cr3
+ mov %ebp, %esp
+ pop %ebp
+ ret
diff --git a/src/c/kernel.c b/src/c/kernel.c
index a5dc31a..9692b32 100644
--- a/src/c/kernel.c
+++ b/src/c/kernel.c
@@ -14,7 +14,7 @@ void kernel_main(void)
init_timer(50);
init_keyboard();
kheapinit();
- kheapaddblock(0x00200000, 0x00100000, 16);
+ kheapaddblock(0xC0700000, 0x00100000, 16);
terminal_initialize();
prompt();
diff --git a/src/c/paging.c b/src/c/paging.c
index 4aba4af..0a4c01f 100644
--- a/src/c/paging.c
+++ b/src/c/paging.c
@@ -3,6 +3,7 @@
extern void loadPageDirectory(uint32_t*);
extern void enablePaging(void);
+extern void flushPaging(void);
uint32_t page_directory[1024] __attribute__((aligned(4096)));
@@ -23,11 +24,6 @@ uint32_t page_table[1024][1024] __attribute__((aligned(4096)));
void set_pt(size_t num,uint32_t address)
{
- // holds the physical address where we want to start mapping these pages
- // to.
- // in this case, we want to map these pages to the very beginning of
- // memory.
-
//we will fill all 1024 entries in the table, mapping 4 megabytes
for(size_t i=0;i<1024;i++)
{
@@ -37,14 +33,26 @@ void set_pt(size_t num,uint32_t address)
// attributes: supervisor level, read/write, present.
}
- page_directory[num] = ((uint32_t)page_table[num]) | 3;
+ page_directory[num] = ((uint32_t)page_table[num] - 0xC0000000) | 3;
// attributes: supervisor level, read/write, present
}
+void empty_pt(size_t num)
+{
+ for(size_t i=0;i<1024;i++)
+ {
+ page_table[num][i] = 0;
+ }
+
+ page_directory[num] = 0x00000002;
+}
+
void set_paging(void)
{
set_pd();
- for(size_t i=0;i<1024;i++) set_pt(i,0x00400000 * i); // all 4GB mapped
+ set_pt(768,0x00000000); // maps 0x00000000 to 0xC0000000
+ set_pt(769,0x00400000); // maps 0x00400000 to 0xC0400000
+ set_pt(832,0x000B8000); // maps 0x000B8000 to 0xD0000000
loadPageDirectory(page_directory);
- enablePaging();
+ flushPaging();
}
diff --git a/src/c/shell/game.c b/src/c/shell/game.c
index ce7793b..9e7323e 100644
--- a/src/c/shell/game.c
+++ b/src/c/shell/game.c
@@ -56,8 +56,8 @@ void game_keyboard_handler(uint16_t keycode)
void game_init(void)
{
- x=VGA_WIDTH/2;
- y=VGA_HEIGHT/2;
+ x=(uint16_t)VGA_WIDTH/2;
+ y=(uint16_t)VGA_HEIGHT/2;
game_time=0;
game_tick=0;
duzina=1;
@@ -80,7 +80,7 @@ void game_timer_handler()
{
case 1:
if(y>0) y--;
- else y=VGA_HEIGHT-1;
+ else y=(uint16_t)VGA_HEIGHT-1;
break;
case 2:
if(y<VGA_HEIGHT-1) y++;
@@ -88,7 +88,7 @@ void game_timer_handler()
break;
case 3:
if(x>0) x--;
- else x=VGA_WIDTH-1;
+ else x=(uint16_t)VGA_WIDTH-1;
break;
case 4:
if(x<VGA_WIDTH-1) x++;
diff --git a/src/c/vga.c b/src/c/vga.c
index 84eb538..4e20745 100644
--- a/src/c/vga.c
+++ b/src/c/vga.c
@@ -27,7 +27,8 @@ void terminal_initialize(void)
terminal_row=0;
terminal_column=0;
set_color(VGA_COLOR_LIGHT_GREY, VGA_COLOR_BLACK);
- terminal_buffer=(uint16_t*) 0xB8000;
+ //terminal_buffer=(uint16_t*) 0xC00B8000;
+ terminal_buffer=(uint16_t*) 0xD0000000;
for(size_t y=0;y<VGA_HEIGHT;y++)
{
for(size_t x=0;x<VGA_WIDTH;x++)
diff --git a/src/include/source/paging.h b/src/include/source/paging.h
index dc4e357..f236365 100644
--- a/src/include/source/paging.h
+++ b/src/include/source/paging.h
@@ -5,6 +5,7 @@
void set_pd(void);
void set_pt(size_t num, uint32_t address);
+void empty_pt(size_t num);
void set_paging(void);
#endif
diff --git a/src/linker.ld b/src/linker.ld
index d8e7f4b..54437ba 100644
--- a/src/linker.ld
+++ b/src/linker.ld
@@ -1,43 +1,41 @@
-/* The bootloader will look at this image and start execution at the symbol
- designated as the entry point. */
-ENTRY(_start)
+ENTRY (_start)
-/* Tell where the various sections of the object files will be put in the final
- kernel image. */
SECTIONS
{
- /* Begin putting sections at 1 MiB, a conventional place for kernels to be
- loaded at by the bootloader. */
- . = 1M;
+ . = 0x00100000;
+ /* The kernel will live at 3GB + 1MB in the virtual address space, */
+ /* which will be mapped to 1MB in the physical address space. */
+ /* Note that we page-align the sections. */
- /* First put the multiboot header, as it is required to be put very early
- early in the image or the bootloader won't recognize the file format.
- Next we'll put the .text section. */
- .text BLOCK(4K) : ALIGN(4K)
- {
- *(.multiboot)
- *(.text)
- }
+ _kernel_start = .;
+ .multiboot.data : {
+ *(.multiboot.data)
+ }
- /* Read-only data. */
- .rodata BLOCK(4K) : ALIGN(4K)
- {
- *(.rodata)
- }
+ .multiboot.text : {
+ *(.multiboot.text)
+ }
- /* Read-write data (initialized) */
- .data BLOCK(4K) : ALIGN(4K)
- {
- *(.data)
- }
-
- /* Read-write data (uninitialized) and stack */
- .bss BLOCK(4K) : ALIGN(4K)
- {
- *(COMMON)
- *(.bss)
- }
-
- /* The compiler may produce other sections, by default it will put them in
- a segment with the same name. Simply add stuff here as needed. */
+ . += 0xC0000000;
+ /* Add a symbol that indicates the start address of the kernel. */
+ .text ALIGN (4K) : AT (ADDR (.text) - 0xC0000000)
+ {
+ *(.text)
+ }
+ .rodata ALIGN (4K) : AT (ADDR (.rodata) - 0xC0000000)
+ {
+ *(.rodata)
+ }
+ .data ALIGN (4K) : AT (ADDR (.data) - 0xC0000000)
+ {
+ *(.data)
+ }
+ .bss ALIGN (4K) : AT (ADDR (.bss) - 0xC0000000)
+ {
+ *(COMMON)
+ *(.bss)
+ *(.bootstrap_stack)
+ }
+ /* Add a symbol that indicates the end address of the kernel. */
+ _kernel_end = .;
}