From f00c44ac895db5a61f1ab0976db23c65013a7f77 Mon Sep 17 00:00:00 2001 From: Kat Richey Date: Sat, 29 Oct 2022 10:02:58 -0500 Subject: [PATCH 01/11] New release year! --- include/kernel/cmos.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/kernel/cmos.h b/include/kernel/cmos.h index cecc2d0..731156a 100644 --- a/include/kernel/cmos.h +++ b/include/kernel/cmos.h @@ -2,7 +2,7 @@ #define _KERNEL_CMOS /* This is kinda important, and has to be changed each year. */ -#define RELEASE_YEAR 2020 +#define RELEASE_YEAR 2022 struct _rtc_val { unsigned char second; From 87f8040eb2f0361782b6eda4af15161ba6b4c4a0 Mon Sep 17 00:00:00 2001 From: Kat Richey Date: Sat, 29 Oct 2022 10:03:37 -0500 Subject: [PATCH 02/11] Added some packing stuff for GCC --- include/kernel/interrupt.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/include/kernel/interrupt.h b/include/kernel/interrupt.h index 781a599..caf6d9c 100644 --- a/include/kernel/interrupt.h +++ b/include/kernel/interrupt.h @@ -1,6 +1,15 @@ #ifndef _KERNEL_INTERRUPT #define _KERNEL_INTERRUPT +#ifdef __GNUC__ +struct IDT_entry { + unsigned short int offset_lowerbits; + unsigned short int selector; + unsigned char zero; + unsigned char type_attr; + unsigned short int offset_higherbits; +} __attribute__((packed)); +#else struct IDT_entry { unsigned short int offset_lowerbits; unsigned short int selector; @@ -8,7 +17,11 @@ struct IDT_entry { unsigned char type_attr; unsigned short int offset_higherbits; }; +#endif +#ifdef __GNUC__ +__attribute((aligned(0x10))) +#endif struct IDT_entry IDT[256]; void idt_init(void); From d7889d3a847d1d692febdce78a28bf7a984fd25a Mon Sep 17 00:00:00 2001 From: Kat Richey Date: Sat, 29 Oct 2022 10:03:56 -0500 Subject: [PATCH 03/11] Higher half, baby!!! --- arch/i386/boot.S | 79 +++++++++++++++++++++++++++++++++++++++++---- arch/i386/linker.ld | 28 +++++++++++----- 2 files changed, 93 insertions(+), 14 deletions(-) diff --git a/arch/i386/boot.S b/arch/i386/boot.S index c28621b..13d29fd 100755 --- a/arch/i386/boot.S +++ b/arch/i386/boot.S @@ -6,25 +6,93 @@ .set CHECKSUM, -(MAGIC + FLAGS) # checksum to prove we're multiboot # Declare header for multiboot - .section .multiboot + .section .multiboot.data, "aw" .align 4 .long MAGIC .long FLAGS .long CHECKSUM # Reserve stack for initial thread - .section .bss - .align 16 + .section .bootstrap_stack, "aw", @nobits stack_bottom: .skip 16384 # 16K stack_top: + # Preallocate pages for paging + .section .bss, "aw", @nobits + .align 4096 +boot_page_directory: + .skip 4096 +boot_page_table1: + .skip 4096 + # May need additional page for kernel > 3 MiB + # Kernel entry - .section .text + .section .multiboot.text, "a" .global _start .type _start, @function _start: - movl $stack_top, %esp + # Physical address of boot_page_table 1 + movl $(boot_page_table1 - 0xC0000000), %edi + # Map address 0 + movl $0, %esi + # Map first 1023 pages + movl $1023, %ecx + +1: + # Only map the kernel + cmpl $_kernel_start, %esi + jl 2f + cmpl $(_kernel_end - 0xC0000000), %esi + jge 3f + + # Map physical address as "present, writable" + # TODO: map .text and .rodata as non-writable + movl %esi, %edx + orl $0x003, %edx + movl %edx, (%edi) + +2: + # Size of page is 4KiB + addl $4096, %esi + # Size of entries in boot_page_table1 is 4 bytes + addl $4, %edi + # Loop to next if not done + loop 1b + +3: + # Map VGA memory to 0xC03FF000 as "present, writable" + movl $(0x000B8000 | 0x003), boot_page_table1 - 0xC0000000 + 1023 * 4 + + # Map page table to 0x0 and 0xC0000000 + movl $(boot_page_table1 - 0xC0000000 + 0x003), boot_page_directory - 0xC0000000 + 0 + movl $(boot_page_table1 - 0xC0000000 + 0x003), boot_page_directory - 0xC0000000 + 768 * 4 + + # Set cr3 to address of boot page directory + movl $(boot_page_directory - 0xC0000000), %ecx + movl %ecx, %cr3 + + # Enable paging and write-protect + movl %cr0, %ecx + orl $0x80010000, %ecx + movl %ecx, %cr0 + + # Jump to higher half + lea 4f, %ecx + jmp *%ecx + + .section .text + +4: + # Unmap identity mapping + movl $0, boot_page_directory + 0 + + # Reload cr3 to force TLB flush + movl %cr3, %ecx + movl %ecx, %cr3 + + # Set up stack + mov $stack_top, %esp # Call global constructors call _init @@ -36,4 +104,3 @@ _start: cli 1: hlt jmp 1b - .size _start, . - _start diff --git a/arch/i386/linker.ld b/arch/i386/linker.ld index d766d45..9a020c5 100755 --- a/arch/i386/linker.ld +++ b/arch/i386/linker.ld @@ -4,21 +4,33 @@ SECTIONS { . = 1M; - .text BLOCK (4K) : ALIGN (4K) { - *(.multiboot) - *(.text) + _kernel_start = .; + .multiboot.data : { + *(.multiboot.data) + } + + .multiboot.text : { + *(.multiboot.text) + } + + . += 0xC0000000; + + .text ALIGN (4K) : AT (ADDR (.text) - 0xC0000000) { + *(.text) } - .rodata BLOCK (4K) : ALIGN (4K) { + .rodata ALIGN (4K) : AT (ADDR (.rodata) - 0xC0000000) { *(.rodata) } - .data BLOCK (4K) : ALIGN (4K) { - *(.data) + .data ALIGN (4K) : AT (ADDR(.data) - 0xC0000000) { + *(.data) } - .bss BLOCK (4K) : ALIGN (4K) { - *(COMMON) + .bss ALIGN (4K) : AT (ADDR (.bss) - 0xC0000000) { + *(COMMON) *(.bss) + *(.bootstrap_stack) } + _kernel_end = .; } From 15db278319cb6eb88ab6fe662776e09cabb16ec3 Mon Sep 17 00:00:00 2001 From: Kat Richey Date: Sat, 29 Oct 2022 10:04:39 -0500 Subject: [PATCH 04/11] Some stuff for utsname and skeleton for syscalls --- arch/i386/syscall_uname.c | 13 +++++++++++++ include/kernel/syscall.h | 6 ++++++ 2 files changed, 19 insertions(+) create mode 100644 arch/i386/syscall_uname.c create mode 100644 include/kernel/syscall.h diff --git a/arch/i386/syscall_uname.c b/arch/i386/syscall_uname.c new file mode 100644 index 0000000..cdc3f00 --- /dev/null +++ b/arch/i386/syscall_uname.c @@ -0,0 +1,13 @@ +#include +#include + +#define PTR ((struct utsname *) v) + +int __syscall_uname(void * v) { + strcpy(PTR->sysname, "FENIX"); + strcpy(PTR->release, "PRE-ALPHA"); + strcpy(PTR->version, "20220726_1700"); + strcpy(PTR->machine, "i386"); + + return 0; +} \ No newline at end of file diff --git a/include/kernel/syscall.h b/include/kernel/syscall.h new file mode 100644 index 0000000..3df2ae1 --- /dev/null +++ b/include/kernel/syscall.h @@ -0,0 +1,6 @@ +#ifndef _KERNEL_SYSCALL +#define _KERNEL_SYSCALL + +int __syscall_uname(void *); + +#endif \ No newline at end of file From 863a63472f67c0e6b10e9be14dc260e77bc89f56 Mon Sep 17 00:00:00 2001 From: Kat Richey Date: Sat, 29 Oct 2022 10:05:05 -0500 Subject: [PATCH 05/11] Hey, look! uname! --- kernel/kernel.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/kernel/kernel.c b/kernel/kernel.c index 3895fa7..1aaafbc 100755 --- a/kernel/kernel.c +++ b/kernel/kernel.c @@ -1,7 +1,12 @@ #include #include +#include +#include void kern_main(void) { term_init(); - init(); + init(); + struct utsname u; + uname(&u); + printf("%s %s %s\n", u.sysname, u.release, u.machine); } From 494ed66266f036fbfb5acf5a61392a2fdccdb9af Mon Sep 17 00:00:00 2001 From: Kat Richey Date: Sat, 29 Oct 2022 10:05:24 -0500 Subject: [PATCH 06/11] Some attempts at PS/2 kbd stuff --- arch/i386/ps2_kbd.c | 15 +++++++++++++++ arch/i386/ps2_kbd.h | 10 ++++++++++ 2 files changed, 25 insertions(+) create mode 100644 arch/i386/ps2_kbd.c create mode 100644 arch/i386/ps2_kbd.h diff --git a/arch/i386/ps2_kbd.c b/arch/i386/ps2_kbd.c new file mode 100644 index 0000000..2aaf774 --- /dev/null +++ b/arch/i386/ps2_kbd.c @@ -0,0 +1,15 @@ +#include "ps2_kbd.h" +#include + +unsigned char get_ps2_inbyte() { + return inb(0x60); +} + +unsigned char* identify_device() { + unsigned char ret_val[2]; int j = 0; + outb(0xF2, 0x64); + for(unsigned char i; i != 0xFA; i = inb(0x60)) { + ret_val[j++] = i; + } + return ret_val; +} \ No newline at end of file diff --git a/arch/i386/ps2_kbd.h b/arch/i386/ps2_kbd.h new file mode 100644 index 0000000..45826c5 --- /dev/null +++ b/arch/i386/ps2_kbd.h @@ -0,0 +1,10 @@ +#ifndef _ARCH_I386_PS2_KBD_H +#define _ARCH_I386_PS2_KBD_H + +int scan_set; + +unsigned char get_ps2_inbyte(); + +unsigned char* identify_device(); + +#endif \ No newline at end of file From 7017065d74ae2a031ae730e7d2a5585430d7f67b Mon Sep 17 00:00:00 2001 From: Kat Richey Date: Sat, 29 Oct 2022 10:05:51 -0500 Subject: [PATCH 07/11] VGA_MEMORY higher half relocation --- arch/i386/tty.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/i386/tty.c b/arch/i386/tty.c index 8e017bb..a6e28fe 100755 --- a/arch/i386/tty.c +++ b/arch/i386/tty.c @@ -9,7 +9,7 @@ static const size_t VGA_WIDTH = 80; static const size_t VGA_HEIGHT = 24; -static uint16_t* const VGA_MEMORY = (uint16_t*) 0xB8000 ; +static uint16_t* const VGA_MEMORY = (uint16_t*) 0xC03FF000 ; static size_t term_row; static size_t term_col; From 4a283060cc68ece7ee727ec2f9cd3361f438a3c6 Mon Sep 17 00:00:00 2001 From: Kat Richey Date: Sat, 29 Oct 2022 10:06:13 -0500 Subject: [PATCH 08/11] Some changes for PS/2 attempts --- arch/i386/interrupt.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/i386/interrupt.c b/arch/i386/interrupt.c index 98ce0e0..3100731 100644 --- a/arch/i386/interrupt.c +++ b/arch/i386/interrupt.c @@ -1,5 +1,7 @@ #include #include +#include +#include "ps2_kbd.h" void idt_init(void) { extern int load_idt(); @@ -192,6 +194,7 @@ void irq0_handler(void) { /* Keyboard Interrupt */ void irq1_handler(void) { + printf("owo\n"); outb(0x20, 0x20); } From 02c887dcea3d39be76ccc65355038e28703f848f Mon Sep 17 00:00:00 2001 From: Kat Richey Date: Sat, 29 Oct 2022 10:06:27 -0500 Subject: [PATCH 09/11] Change pusha to pushal??? --- arch/i386/inter.s | 65 ++++++++++++++++++++++++----------------------- 1 file changed, 33 insertions(+), 32 deletions(-) diff --git a/arch/i386/inter.s b/arch/i386/inter.s index 155a262..597b3c3 100644 --- a/arch/i386/inter.s +++ b/arch/i386/inter.s @@ -69,99 +69,100 @@ .extern irq15_handler irq0: - pusha + pushal call irq0_handler - popa + popal iret irq1: - pusha + pushal + cld call irq1_handler - popa + popal iret irq2: - pusha + pushal call irq2_handler - popa + popal iret irq3: - pusha + pushal call irq3_handler - popa + popal iret irq4: - pusha + pushal call irq4_handler - popa + popal iret irq5: - pusha + pushal call irq5_handler - popa + popal iret irq6: - pusha + pushal call irq6_handler - popa + popal iret irq7: - pusha + pushal call irq7_handler - popa + popal iret irq8: - pusha + pushal call irq8_handler - popa + popal iret irq9: - pusha + pushal call irq9_handler - popa + popal iret irq10: - pusha + pushal call irq10_handler - popa + popal iret irq11: - pusha + pushal call irq11_handler - popa + popal iret irq12: - pusha + pushal call irq12_handler - popa + popal iret irq13: - pusha + pushal call irq13_handler - popa + popal iret irq14: - pusha + pushal call irq14_handler - popa + popal iret irq15: - pusha + pushal call irq15_handler - popa + popal iret load_idt: From 5b4e9dccd61f98f27382571f7a273e9ba9de8f8a Mon Sep 17 00:00:00 2001 From: Kat Richey Date: Sat, 29 Oct 2022 10:06:37 -0500 Subject: [PATCH 10/11] Add PS/2 attempt --- arch/i386/init.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 75 insertions(+), 1 deletion(-) diff --git a/arch/i386/init.c b/arch/i386/init.c index 7645b57..5e88ff3 100755 --- a/arch/i386/init.c +++ b/arch/i386/init.c @@ -3,6 +3,7 @@ #include #include #include "gdt.h" +#include "ps2_kbd.h" int tss[16][2]; @@ -42,11 +43,84 @@ void setup_gdt(void) { extern void enter_pmode(void); +int initialize_ps2_kbd() { + /* Should really make sure PS/2 controller exists here: */ + + /* Disable devices */ + outb(0xAD, 0x64); + outb(0xA7, 0xAD); + + /* Flush output buffer */ + get_ps2_inbyte(); + + /* Set config byte */ + outb(0x20, 0x64); + unsigned char config_byte = get_ps2_inbyte(); + int is_dual_ch = (config_byte & 020) != 0 ? 1 : 0; + config_byte &= 0274; + outb(0x60, 0x64); + outb(config_byte, 0x60); + + /* Quick self-test */ + outb(0xAA, 0x64); + unsigned char test_response = get_ps2_inbyte(); + if(test_response != 0x55) { + printf("error: PS/2 self-test failed\n"); + return 1; + } + outb(0x60, 0x64); + outb(config_byte, 0x60); + + /* Double check dual channel stuff */ + if(is_dual_ch) { + outb(0xA8, 0x64); + outb(0x20, 0x64); + unsigned char new_config_byte = get_ps2_inbyte(); + is_dual_ch = (new_config_byte & 020) == 0 ? 1 : 0; + if(is_dual_ch) { + outb(0xA7, 0x64); + } + } + + /* Interface tests */ + outb(0xAB, 0x64); + test_response = get_ps2_inbyte(); + int working_ports = test_response == 0x00 ? 01 : 00; + if(test_response != 0x00 && !is_dual_ch) { + printf("error: could not initialize PS/2 device\n"); + return 2; + } + if(is_dual_ch) { + outb(0xA9, 0x64); + test_response = get_ps2_inbyte(); + working_ports |= test_response == 0x00 ? 02 : 00; + if(test_response != 0x00 && working_ports != 01) { + printf("error: could not initialize PS/2 device\n"); + return 2; + } + } + + /* Enable devices */ + if(working_ports & 01) { + outb(0xAE, 0x64); + config_byte |= 01; + } + if(working_ports & 02) { + outb(0xA8, 0x64); + config_byte |= 02; + } + outb(0x60, 0x64); + outb(config_byte, 0x60); + + return 0; +} + int init(void) { printf("Setting up GDT...\n"); setup_gdt(); printf("Enabling interrupts...\n"); idt_init(); - printf("Fenix Dev Pre-release v0.0.3\n"); + printf("Initializing PS/2 controller...\n"); + initialize_ps2_kbd(); return 0; } From 723f064975de920d456a781c9bbf4181f31a8393 Mon Sep 17 00:00:00 2001 From: Kat Richey Date: Sat, 29 Oct 2022 10:07:02 -0500 Subject: [PATCH 11/11] Added uname and PS/2 to build list --- arch/i386/make.config | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/i386/make.config b/arch/i386/make.config index 558cf5d..b0913be 100755 --- a/arch/i386/make.config +++ b/arch/i386/make.config @@ -10,4 +10,6 @@ $(ARCHDIR)/cmos.o \ $(ARCHDIR)/gdt.o \ $(ARCHDIR)/gdt_load.o \ $(ARCHDIR)/interrupt.o \ -$(ARCHDIR)/inter.o \ No newline at end of file +$(ARCHDIR)/inter.o \ +$(ARCHDIR)/ps2_kbd.o \ +$(ARCHDIR)/syscall_uname.o \ No newline at end of file