summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--kernel/Makefile5
-rw-r--r--kernel/include/ext2.h1
-rw-r--r--kernel/include/font.h4
-rw-r--r--kernel/include/gdt.h40
-rw-r--r--kernel/include/keymap.h8
-rw-r--r--kernel/include/tss.h42
-rw-r--r--kernel/include/userspace.h7
-rw-r--r--kernel/src/boot/boot.S9
-rw-r--r--kernel/src/boot/boot64.S3
-rw-r--r--kernel/src/cpu/gdt.c53
-rw-r--r--kernel/src/cpu/irq.c5
-rw-r--r--kernel/src/cpu/irq_stub.S4
-rw-r--r--kernel/src/cpu/tss.c15
-rw-r--r--kernel/src/fs/ext2.c6
-rw-r--r--kernel/src/main.c18
-rw-r--r--kernel/src/mem/paging.c7
-rw-r--r--kernel/src/sys/syscall.S0
-rw-r--r--kernel/src/sys/userspace.c9
-rw-r--r--kernel/src/sys/userspace_asm.S20
19 files changed, 223 insertions, 33 deletions
diff --git a/kernel/Makefile b/kernel/Makefile
index 9516567..54a2838 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -5,11 +5,13 @@ OBJS = \
src/boot/boot.o \
src/boot/header.o \
src/boot/multiboot2.o \
+ src/cpu/gdt.o \
src/cpu/idt.o \
src/cpu/io.o \
src/cpu/irq.o \
src/cpu/irq_stub.o \
src/cpu/pic.o \
+ src/cpu/tss.o \
src/devices/disc.o \
src/devices/keyboard.o \
src/devices/timer.o \
@@ -25,6 +27,9 @@ OBJS = \
src/misc/debug.o \
src/misc/graphics.o \
src/misc/stdbuff.o \
+ src/sys/syscall.o \
+ src/sys/userspace_asm.o \
+ src/sys/userspace.o \
all: kernel.bin
diff --git a/kernel/include/ext2.h b/kernel/include/ext2.h
index 1760fef..1acdb18 100644
--- a/kernel/include/ext2.h
+++ b/kernel/include/ext2.h
@@ -130,6 +130,7 @@ extern ext2_superblock_t* ext2_superblock;
#define INODES_PER_BLOCK (BLOCK_SIZE / INODE_SIZE)
+void ext2_init(void);
void read_block(uint32_t block_num, void* block_ptr);
void read_superblock(ext2_superblock_t* ext2_superblock);
void read_bg_desc(uint32_t bg_desc, ext2_bg_desc_t* ext2_bg_desc);
diff --git a/kernel/include/font.h b/kernel/include/font.h
index f405a90..debaba9 100644
--- a/kernel/include/font.h
+++ b/kernel/include/font.h
@@ -19,7 +19,7 @@ typedef struct {
/* font i used: /usr/share/kbd/consolefonts/lat9-16.psf.gz */
/* xxd -i font.psf */
-unsigned char font[] = {
+const unsigned char font[] = {
0x72, 0xb5, 0x4a, 0x86, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xc3,
@@ -365,6 +365,6 @@ unsigned char font[] = {
0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c,
0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00
};
-unsigned int font_len = 4128;
+const uint32_t font_len = 4128;
#endif
diff --git a/kernel/include/gdt.h b/kernel/include/gdt.h
new file mode 100644
index 0000000..4c84fe9
--- /dev/null
+++ b/kernel/include/gdt.h
@@ -0,0 +1,40 @@
+#ifndef GDT_H
+#define GDT_H
+
+#include <types.h>
+
+struct gdt_seg_entry {
+ uint16_t limit;
+ uint16_t offset1;
+ uint8_t offset2;
+ uint8_t access;
+ uint8_t limitflags;
+ uint8_t offset3;
+} __attribute__((packed));
+typedef struct gdt_seg_entry gdt_seg_entry;
+
+struct gdt_tss_entry {
+ uint16_t limit;
+ uint16_t offset1;
+ uint8_t offset2;
+ uint8_t access;
+ uint8_t limitflags;
+ uint8_t offset3;
+ uint32_t offset4;
+ uint32_t reserved;
+} __attribute__((packed));
+typedef struct gdt_tss_entry gdt_tss_entry;
+
+struct gdt_p {
+ uint16_t size;
+ uint64_t offset;
+} __attribute__((packed));
+typedef struct gdt_p gdt_p;
+
+void add_gdt_entry(uint32_t num, uint32_t offset, uint32_t limit, uint8_t access, uint8_t flags);
+void add_gdt_tss(uint32_t num, uint64_t offset, uint32_t limit, uint8_t access, uint8_t flags);
+void reload_gdt(void);
+void load_gdt(gdt_p* pointer);
+void init_gdt(void);
+
+#endif
diff --git a/kernel/include/keymap.h b/kernel/include/keymap.h
index c9b8697..62d6a96 100644
--- a/kernel/include/keymap.h
+++ b/kernel/include/keymap.h
@@ -89,7 +89,7 @@
#define KEY_F11 0x57
#define KEY_F12 0x58
-char keymap[] = {
+const char keymap[] = {
' ',
' ',
'1',
@@ -220,9 +220,9 @@ char keymap[] = {
' ',
};
-uint16_t keymap_len = 128;
+const uint16_t keymap_len = 128;
-char shift_keymap[] = {
+const char shift_keymap[] = {
' ',
' ',
'!',
@@ -353,6 +353,6 @@ char shift_keymap[] = {
' ',
};
-uint16_t shift_keymap_len = 128;
+const uint16_t shift_keymap_len = 128;
#endif
diff --git a/kernel/include/tss.h b/kernel/include/tss.h
new file mode 100644
index 0000000..f1af6d6
--- /dev/null
+++ b/kernel/include/tss.h
@@ -0,0 +1,42 @@
+#ifndef TSS_H
+#define TSS_H
+
+#include <types.h>
+
+struct tss_type {
+ uint32_t reserved1;
+ uint32_t rsp0_low;
+ uint32_t rsp0_high;
+ uint32_t rsp1_low;
+ uint32_t rsp1_high;
+ uint32_t rsp2_low;
+ uint32_t rsp2_high;
+ uint32_t reserved2;
+ uint32_t reserved3;
+ uint32_t ist1_low;
+ uint32_t ist1_high;
+ uint32_t ist2_low;
+ uint32_t ist2_high;
+ uint32_t ist3_low;
+ uint32_t ist3_high;
+ uint32_t ist4_low;
+ uint32_t ist4_high;
+ uint32_t ist5_low;
+ uint32_t ist5_high;
+ uint32_t ist6_low;
+ uint32_t ist6_high;
+ uint32_t ist7_low;
+ uint32_t ist7_high;
+ uint32_t reserved4;
+ uint32_t reserved5;
+ uint16_t reserved6;
+ uint16_t iopb;
+} __attribute__((packed, aligned(4096)));
+typedef struct tss_type tss_type;
+
+extern tss_type tss;
+
+void load_tss(void);
+void init_tss(void);
+
+#endif
diff --git a/kernel/include/userspace.h b/kernel/include/userspace.h
new file mode 100644
index 0000000..e03695d
--- /dev/null
+++ b/kernel/include/userspace.h
@@ -0,0 +1,7 @@
+#ifndef USERSPACE_H
+#define USERSPACE_H
+
+void begin_userspace(void);
+void jump_userspace(void);
+
+#endif
diff --git a/kernel/src/boot/boot.S b/kernel/src/boot/boot.S
index 81584ce..e0c5326 100644
--- a/kernel/src/boot/boot.S
+++ b/kernel/src/boot/boot.S
@@ -1,10 +1,10 @@
.code32
-.global _start
.extern begin_long_mode
.set KERNEL_VMA, 0xc0000000
.section .boot.text, "a"
+.global _start
_start:
cli
mov $stack_top - KERNEL_VMA, %esp
@@ -136,7 +136,7 @@ no_long_mode:
.section .text
4:
- lgdt gdt_pointer
+ lgdt gdtp
ljmp $0x08, $begin_long_mode
@@ -189,9 +189,6 @@ gdt_data = . - gdt
.byte PRESENT | NOT_SYS | RW
.byte GRAN_4K | SZ_32 | 0xF
.byte 0
-gdt_tss = . - gdt
- .long 0x00000068
- .long 0x00CF8900
-gdt_pointer:
+gdtp:
.word . - gdt - 1
.quad gdt
diff --git a/kernel/src/boot/boot64.S b/kernel/src/boot/boot64.S
index 50ee7cd..68eae38 100644
--- a/kernel/src/boot/boot64.S
+++ b/kernel/src/boot/boot64.S
@@ -1,8 +1,7 @@
-.global begin_long_mode
-
.section .text
.code64
+.global begin_long_mode
begin_long_mode:
// reload segment registers
mov $0x10, %eax
diff --git a/kernel/src/cpu/gdt.c b/kernel/src/cpu/gdt.c
new file mode 100644
index 0000000..b4f1ec0
--- /dev/null
+++ b/kernel/src/cpu/gdt.c
@@ -0,0 +1,53 @@
+#include <gdt.h>
+#include <tss.h>
+
+gdt_seg_entry gdt[7];
+gdt_p gdt_pointer;
+
+void add_gdt_entry(uint32_t num, uint32_t offset, uint32_t limit, uint8_t access, uint8_t flags)
+{
+ gdt[num].offset1 = offset & 0xffff;
+ gdt[num].offset2 = (offset >> 16) & 0xff;
+ gdt[num].offset3 = (uint8_t)(offset >> 24) & 0xff;
+ gdt[num].limit = limit & 0xffff;
+ gdt[num].limitflags = (limit >> 16) & 0xf;
+ gdt[num].access = access;
+ gdt[num].limitflags = flags << 4;
+}
+
+void add_gdt_tss(uint32_t num, uint64_t offset, uint32_t limit, uint8_t access, uint8_t flags)
+{
+ add_gdt_entry(num, offset & 0xffffffff, limit, access, flags);
+}
+
+void reload_gdt()
+{
+ __asm__ volatile (
+ "mov $0x10, %ax;"
+ "mov %ax, %ds;"
+ "mov %ax, %es;"
+ "mov %ax, %ss;"
+ );
+}
+
+void load_gdt(gdt_p* pointer)
+{
+ __asm__ volatile ("lgdt (%0);" : : "r"(pointer) : );
+ reload_gdt();
+}
+
+void init_gdt()
+{
+ gdt_pointer.offset = (uint64_t)&gdt;
+ gdt_pointer.size = sizeof(gdt) - 1;
+
+ add_gdt_entry(0, 0, 0, 0, 0);
+ add_gdt_entry(1, 0, 0xfffff, 0x9a, 0xa);
+ add_gdt_entry(2, 0, 0xfffff, 0x92, 0xc);
+ add_gdt_entry(3, 0, 0xfffff, 0xfa, 0xa);
+ add_gdt_entry(4, 0, 0xfffff, 0xf2, 0xc);
+ add_gdt_tss(5, (uint64_t)&tss, sizeof(tss_type), 0x89, 0);
+
+ load_gdt(&gdt_pointer);
+ init_tss();
+}
diff --git a/kernel/src/cpu/irq.c b/kernel/src/cpu/irq.c
index 096860a..a19a7f1 100644
--- a/kernel/src/cpu/irq.c
+++ b/kernel/src/cpu/irq.c
@@ -8,7 +8,7 @@
#include <paging.h>
#include <libk/stdio.h>
-const char* exception_name[] = {
+const char* const exception_name[] = {
"Divide-by-zero Error",
"Debug",
"Non-maskable Interrupt",
@@ -120,8 +120,9 @@ void isr13_handler(uint64_t error)
void isr14_handler(uint64_t error)
{
- page_fault(error);
printf("%s\n", exception_name[14]);
+ printf("error: %d\n", error);
+ page_fault(error);
}
void isr15_handler(void)
diff --git a/kernel/src/cpu/irq_stub.S b/kernel/src/cpu/irq_stub.S
index 4db722e..9b2b2d8 100644
--- a/kernel/src/cpu/irq_stub.S
+++ b/kernel/src/cpu/irq_stub.S
@@ -38,11 +38,9 @@ isr\number:
.macro isr_error number
.global isr\number
isr\number:
- add $8, %rsp
+ pop %rdi
pushall
cld
- # setting error to 0
- mov $0, %rdi
call isr\number\()_handler
popall
iretq
diff --git a/kernel/src/cpu/tss.c b/kernel/src/cpu/tss.c
new file mode 100644
index 0000000..c7f9dc2
--- /dev/null
+++ b/kernel/src/cpu/tss.c
@@ -0,0 +1,15 @@
+#include <tss.h>
+
+tss_type tss;
+
+void load_tss()
+{
+ __asm__ volatile ("mov $0x28, %ax; ltr %ax;");
+}
+
+void init_tss()
+{
+ tss.iopb = sizeof(tss_type);
+
+ load_tss();
+}
diff --git a/kernel/src/fs/ext2.c b/kernel/src/fs/ext2.c
index 11f26fc..5395dd0 100644
--- a/kernel/src/fs/ext2.c
+++ b/kernel/src/fs/ext2.c
@@ -24,6 +24,12 @@ void read_superblock(ext2_superblock_t* superblock)
memcpy(superblock, block, sizeof(ext2_superblock_t));
}
+void ext2_init()
+{
+ ext2_superblock = (ext2_superblock_t*)kalloc(sizeof(ext2_superblock_t));
+ read_superblock(ext2_superblock);
+}
+
void read_bg_desc(uint32_t bg_desc, ext2_bg_desc_t* ext2_bg_desc)
{
uint32_t starting_block_num = BLOCK_SIZE == 1024 ? 2 : 1;
diff --git a/kernel/src/main.c b/kernel/src/main.c
index c575a0e..45d2eeb 100644
--- a/kernel/src/main.c
+++ b/kernel/src/main.c
@@ -11,27 +11,23 @@
#include <disc.h>
#include <ext2.h>
#include <timer.h>
+#include <gdt.h>
+#include <userspace.h>
+#include <tss.h>
int kernel_main(mb2_tag_header* multiboot_bootinfo, uint32_t multiboot_magic);
int kernel_main(mb2_tag_header* multiboot_bootinfo, uint32_t multiboot_magic)
{
+ init_gdt();
init_paging();
init_idt();
init_timer(TICKS_PER_SECOND);
init_heap();
read_mb2(multiboot_bootinfo, multiboot_magic);
-
- // init disc
disc_init();
-
- // read superblock
- ext2_superblock = (ext2_superblock_t*)kalloc(sizeof(ext2_superblock_t));
- read_superblock(ext2_superblock);
-
- ls(path_to_inode("/"));
-
- // free superblock
- kfree(ext2_superblock);
+ ext2_init();
+// ls(path_to_inode("/"));
+// jump_userspace();
for(;;) {
__asm__ volatile ("hlt;");
diff --git a/kernel/src/mem/paging.c b/kernel/src/mem/paging.c
index 531c300..630fb6d 100644
--- a/kernel/src/mem/paging.c
+++ b/kernel/src/mem/paging.c
@@ -51,9 +51,10 @@ void init_paging(void)
page_table_lvl3[2] = (uint64_t)page_table_lvl2_2 + FLAG_PRESENT + FLAG_WRITABLE - KERNEL_VMA;
page_table_lvl3[3] = (uint64_t)page_table_lvl2_3 + FLAG_PRESENT + FLAG_WRITABLE - KERNEL_VMA;
- // higher half map first 4mb
- map_addr(KERNEL_VMA, 0x00000000, FLAG_PRESENT + FLAG_WRITABLE + FLAG_HUGE);
- map_addr(KERNEL_VMA + PAGE_SIZE, 0x00000000 + PAGE_SIZE, FLAG_PRESENT + FLAG_WRITABLE + FLAG_HUGE);
+ // higher half map first 6mb
+ for (size_t i = 0; i < 3; i++) {
+ map_addr(KERNEL_VMA + PAGE_SIZE * i, 0x00000000 + PAGE_SIZE * i, FLAG_PRESENT + FLAG_WRITABLE + FLAG_HUGE);
+ }
load_pt_lvl4(page_table_lvl4);
}
diff --git a/kernel/src/sys/syscall.S b/kernel/src/sys/syscall.S
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/kernel/src/sys/syscall.S
diff --git a/kernel/src/sys/userspace.c b/kernel/src/sys/userspace.c
new file mode 100644
index 0000000..4add4d5
--- /dev/null
+++ b/kernel/src/sys/userspace.c
@@ -0,0 +1,9 @@
+#include <types.h>
+#include <userspace.h>
+
+void begin_userspace()
+{
+ while(true) {
+
+ }
+}
diff --git a/kernel/src/sys/userspace_asm.S b/kernel/src/sys/userspace_asm.S
new file mode 100644
index 0000000..5838051
--- /dev/null
+++ b/kernel/src/sys/userspace_asm.S
@@ -0,0 +1,20 @@
+.text
+
+.extern begin_userspace
+
+.global jump_userspace
+jump_userspace:
+ mov $0x23, %ax
+ mov %ax, %ds
+ mov %ax, %es
+ mov %ax, %fs
+ mov %ax, %gs
+
+ mov %esp, %eax
+ push $0x23
+ push %rax
+ pushf
+ push $0x1b
+ sub $8, %rsp
+ movabs $begin_userspace, %rsp
+ iretq