Portability work

This commit is contained in:
pjht 2020-07-22 19:26:55 -05:00
parent 76eedfb921
commit eef40edb3f
40 changed files with 230 additions and 499 deletions

View File

@ -70,7 +70,12 @@ libc: sysroot/usr/lib/libc.a
sysroot/usr/lib/libc.a: $(LIBC_OBJ) sysroot/usr/lib/libc.a: $(LIBC_OBJ)
@$(AR) rcs $@ $^ @$(AR) rcs $@ $^
%.o: %.c kernel/cpu/arch_consts.h: kernel/cpu/$(PLAT)/arch_consts.h
cp kernel/cpu/$(PLAT)/arch_consts.h kernel/cpu/arch_consts.h
kernel/cpu/isr.h: kernel/cpu/$(PLAT)/isr.h
cp kernel/cpu/$(PLAT)/isr.h kernel/cpu/isr.h
%.o: %.c kernel/cpu/arch_consts.h kernel/cpu/isr.h
@$(CC) $(CFLAGS) -c $< -o $@ @$(CC) $(CFLAGS) -c $< -o $@
%.o: %.asm %.o: %.asm

View File

@ -130,8 +130,9 @@ char load_proc(uint32_t datapos,char* initrd) {
// return 1; // return 1;
// } // }
void thread_func() { void* thread_func(void* arg) {
for (;;) yield(); for (;;) yield();
return NULL;
} }
int main() { int main() {

13
kernel/cpu/arch_consts.h Normal file
View File

@ -0,0 +1,13 @@
#ifndef ARCH_CONSTS_H
#define ARCH_CONSTS_H
#define PAGE_SZ 4096
#define FRAME_SZ PAGE_SZ
#define KMALLOC_START 0xFE800000
#define KMALLOC_SZ 16384
#define KSTACKS_START 0xC8000000
#define NUM_FRAMES 1024*1024
#define FRAME_NO_OFFSET 12
#define NUM_KERN_FRAMES 4096
#endif

View File

@ -1,8 +1,6 @@
#ifndef CPU_INIT_H #ifndef CPU_INIT_H
#define CPU_INIT_H #define CPU_INIT_H
#include <grub/multiboot2.h> void cpu_init();
void cpu_init(struct multiboot_boot_header_tag* tags);
#endif #endif

View File

@ -1,21 +1,20 @@
#include "paging.h" #include "../paging.h"
#include "arch_consts.h"
void address_spaces_copy_data(void* cr3, void* data,uint32_t size,void* virt_addr) { void address_spaces_copy_data(void* cr3, void* data,uint32_t size,void* virt_addr) {
uint32_t old_cr3; void* old_cr3=get_cr3();
asm volatile("movl %%cr3, %%eax; movl %%eax, %0;":"=m"(old_cr3)::"%eax");
void* phys_addr=virt_to_phys(data); void* phys_addr=virt_to_phys(data);
load_smap((uint32_t)cr3); load_smap(cr3);
map_pages(virt_addr,phys_addr,(size/4096)+1,1,1); map_pages(virt_addr,phys_addr,(size/PAGE_SZ)+1,1,1);
load_smap(old_cr3); load_smap(old_cr3);
} }
void* address_spaces_put_data(void* cr3, void* data,uint32_t size) { void* address_spaces_put_data(void* cr3, void* data,uint32_t size) {
uint32_t old_cr3; void* old_cr3=get_cr3();
asm volatile("movl %%cr3, %%eax; movl %%eax, %0;":"=m"(old_cr3)::"%eax");
void* phys_addr=virt_to_phys(data); void* phys_addr=virt_to_phys(data);
load_smap((uint32_t)cr3); load_smap(cr3);
void* virt_addr=find_free_pages((size/4096)+1); void* virt_addr=find_free_pages((size/PAGE_SZ)+1);
map_pages(virt_addr,phys_addr,(size/4096)+1,1,1); map_pages(virt_addr,phys_addr,(size/PAGE_SZ)+1,1,1);
load_smap(old_cr3); load_smap(old_cr3);
return virt_addr; return virt_addr;
} }

View File

@ -0,0 +1,13 @@
#ifndef ARCH_CONSTS_H
#define ARCH_CONSTS_H
#define PAGE_SZ 4096
#define FRAME_SZ PAGE_SZ
#define KMALLOC_START 0xFE800000
#define KMALLOC_SZ 16384
#define KSTACKS_START 0xC8000000
#define NUM_FRAMES 1024*1024
#define FRAME_NO_OFFSET 12
#define NUM_KERN_FRAMES 4096
#endif

View File

@ -1,16 +1,5 @@
#include "gdt.h" #include "gdt.h"
#include "paging.h"
#include "isr.h"
#include "pmem.h"
#include "serial.h"
#include "../tasking.h"
void cpu_init(struct multiboot_boot_header_tag* tags) { void cpu_init() {
gdt_init(); gdt_init();
isr_install();
asm volatile("sti");
serial_init();
pmem_init(tags);
paging_init();
tasking_init();
} }

5
kernel/cpu/i386/halt.asm Normal file
View File

@ -0,0 +1,5 @@
global halt
halt:
cli
halt_label: hlt
jmp halt_label

View File

@ -1,5 +0,0 @@
void halt() {
asm volatile("cli;\
hltlabel: hlt;\
jmp hltlabel");
}

View File

@ -14,10 +14,11 @@ isr_common_stub:
mov fs, ax mov fs, ax
mov gs, ax mov gs, ax
; 2. Call C handler
push esp push esp
; 2. Call C handler
call isr_handler call isr_handler
; 3. Restore state ; 3. Restore state
pop eax pop eax
pop eax pop eax

View File

@ -1,21 +1,21 @@
#include "isr.h" #include "../isr.h"
#include "idt.h" #include "idt.h"
#include "gdt.h" #include "gdt.h"
#include <cpu/ports.h> #include <cpu/ports.h>
#include "paging.h" #include "../paging.h"
#include "../halt.h" #include "../halt.h"
#include "../../vga_err.h" #include "../../vga_err.h"
#include "../../kernel.h" #include "../../kernel.h"
#include "../tasking.h" #include "../../tasking.h"
#include "interrupt.h" #include "interrupt.h"
#include "address_spaces.h" #include "../address_spaces.h"
#include <string.h> #include <string.h>
#include <stdint.h> #include <stdint.h>
#include "serial.h" #include "../serial.h"
#include <sys/types.h> #include <sys/types.h>
#include <sys/syscalls.h> #include <sys/syscalls.h>
void irq_handler(registers_t* r); void irq_handler(registers_t* r);
static isr_t interrupt_handlers[256]; static isr_t irq_handlers[16];
/* Can't do this with a loop because we need the address /* Can't do this with a loop because we need the address
* of the function names */ * of the function names */
@ -84,6 +84,8 @@ void isr_install() {
idt_set_gate(47,(uint32_t)irq15); idt_set_gate(47,(uint32_t)irq15);
load_idt(); load_idt();
asm volatile("sti");
} }
@ -267,7 +269,10 @@ void isr_handler(registers_t* r) {
void isr_register_handler(uint8_t n,isr_t handler) { void isr_register_handler(uint8_t n,isr_t handler) {
interrupt_handlers[n] = handler; if (n>16) {
return;
}
irq_handlers[n] = handler;
} }
void irq_handler(registers_t* r) { void irq_handler(registers_t* r) {
@ -276,8 +281,8 @@ void irq_handler(registers_t* r) {
if (r->int_no >= 40) port_byte_out(0xA0,0x20); /* slave */ if (r->int_no >= 40) port_byte_out(0xA0,0x20); /* slave */
port_byte_out(0x20,0x20); /* master */ port_byte_out(0x20,0x20); /* master */
/* Handle the interrupt in a more modular way */ /* Handle the interrupt in a more modular way */
if (interrupt_handlers[r->int_no] != 0) { if (irq_handlers[r->int_no-32] != NULL) {
isr_t handler = interrupt_handlers[r->int_no]; isr_t handler = irq_handlers[r->int_no];
handler(r); handler(r);
} }
} }

View File

@ -3,58 +3,6 @@
#include <stdint.h> #include <stdint.h>
/* ISRs reserved for CPU exceptions */
extern void isr0();
extern void isr1();
extern void isr2();
extern void isr3();
extern void isr4();
extern void isr5();
extern void isr6();
extern void isr7();
extern void isr8();
extern void isr9();
extern void isr10();
extern void isr11();
extern void isr12();
extern void isr13();
extern void isr14();
extern void isr15();
extern void isr16();
extern void isr17();
extern void isr18();
extern void isr19();
extern void isr20();
extern void isr21();
extern void isr22();
extern void isr23();
extern void isr24();
extern void isr25();
extern void isr26();
extern void isr27();
extern void isr28();
extern void isr29();
extern void isr30();
extern void isr31();
extern void isr80();
/* IRQ definitions */
extern void irq0();
extern void irq1();
extern void irq2();
extern void irq3();
extern void irq4();
extern void irq5();
extern void irq6();
extern void irq7();
extern void irq8();
extern void irq9();
extern void irq10();
extern void irq11();
extern void irq12();
extern void irq13();
extern void irq14();
extern void irq15();
/* Struct which aggregates many registers */ /* Struct which aggregates many registers */
typedef struct { typedef struct {
uint32_t ds; /* Data segment selector */ uint32_t ds; /* Data segment selector */
@ -63,29 +11,9 @@ typedef struct {
uint32_t eip,cs,eflags,useresp,ss; /* Pushed by the processor automatically */ uint32_t eip,cs,eflags,useresp,ss; /* Pushed by the processor automatically */
} registers_t; } registers_t;
#define IRQ0 32
#define IRQ1 33
#define IRQ2 34
#define IRQ3 35
#define IRQ4 36
#define IRQ5 37
#define IRQ6 38
#define IRQ7 39
#define IRQ8 40
#define IRQ9 41
#define IRQ10 42
#define IRQ11 43
#define IRQ12 44
#define IRQ13 45
#define IRQ14 46
#define IRQ15 47
typedef void (*isr_t)(registers_t*); typedef void (*isr_t)(registers_t*);
void isr_install(); void isr_install();
void isr_handler(registers_t* r);
void irq_handler(registers_t* r);
void isr_register_handler(uint8_t n,isr_t handler); void isr_register_handler(uint8_t n,isr_t handler);
#endif #endif

View File

@ -1,14 +1,15 @@
#include <stdint.h> #include <stdint.h>
#include <stdlib.h> #include <stdlib.h>
#include "paging_helpers.h" #include "paging_helpers.h"
#include "paging.h" #include "../paging.h"
#include "pmem.h" #include "../../pmem.h"
#include "../..//vga_err.h" #include "../../vga_err.h"
#include <klog.h> #include <klog.h>
#include "../halt.h" #include "../halt.h"
#include "arch_consts.h"
static uint32_t page_directory[1024] __attribute__((aligned(4096))); static uint32_t page_directory[1024] __attribute__((aligned(4096)));
static uint32_t kern_page_tables[NUM_KERN_DIRS*1024] __attribute__((aligned(4096))); static uint32_t kern_page_tables[NUM_KERN_FRAMES] __attribute__((aligned(4096)));
static uint32_t kstack_page_tables[218*1024] __attribute__((aligned(4096))); static uint32_t kstack_page_tables[218*1024] __attribute__((aligned(4096)));
static uint32_t kmalloc_page_tables[4*1024] __attribute__((aligned(4096))); static uint32_t kmalloc_page_tables[4*1024] __attribute__((aligned(4096)));
static uint32_t smap_page_tables[2048] __attribute__((aligned(4096))); static uint32_t smap_page_tables[2048] __attribute__((aligned(4096)));
@ -178,13 +179,13 @@ void* paging_new_address_space() {
return dir; return dir;
} }
void load_address_space(uint32_t cr3) { void load_address_space(void* cr3) {
load_smap(cr3); load_smap(cr3);
load_page_directory((uint32_t*)cr3); load_page_directory((uint32_t*)cr3);
} }
void load_smap(uint32_t cr3) { void load_smap(void* cr3) {
smap_page_tables[0]=cr3|0x3; smap_page_tables[0]=(uint32_t)cr3|0x3;
invl_page(&smap[0]); invl_page(&smap[0]);
for (uint32_t i=1;i<2048;i++) { for (uint32_t i=1;i<2048;i++) {
invl_page(&smap[i*1024]); invl_page(&smap[i*1024]);
@ -222,7 +223,7 @@ char make_protector(int page) {
return 1; return 1;
} }
char is_in_protector(uint32_t* addr) { char is_in_protector(void* addr) {
int page=((uint32_t)addr)>>12; int page=((uint32_t)addr)>>12;
if (is_page_present(page)) return 0; if (is_page_present(page)) return 0;
int table=page>>10; int table=page>>10;
@ -233,7 +234,7 @@ char is_in_protector(uint32_t* addr) {
} }
void paging_init() { void paging_init() {
for (uint32_t i=0;i<NUM_KERN_DIRS*1024;i++) { for (uint32_t i=0;i<NUM_KERN_FRAMES;i++) {
kern_page_tables[i]=(i<<12)|0x3; kern_page_tables[i]=(i<<12)|0x3;
} }
for (uint32_t i=0;i<218*1024;i++) { for (uint32_t i=0;i<218*1024;i++) {
@ -246,7 +247,7 @@ void paging_init() {
for (uint32_t i=1;i<2048;i++) { for (uint32_t i=1;i<2048;i++) {
smap_page_tables[i]=0; smap_page_tables[i]=0;
} }
for (uint32_t i=0;i<NUM_KERN_DIRS;i++) { for (uint32_t i=0;i<NUM_KERN_FRAMES/1024;i++) {
uint32_t entry_virt=(uint32_t)&(kern_page_tables[i*1024]); uint32_t entry_virt=(uint32_t)&(kern_page_tables[i*1024]);
page_directory[i+768]=(entry_virt-0xC0000000)|0x3; page_directory[i+768]=(entry_virt-0xC0000000)|0x3;
} }
@ -269,3 +270,9 @@ void paging_init() {
} }
load_page_directory((uint32_t*)((uint32_t)page_directory-0xC0000000)); load_page_directory((uint32_t*)((uint32_t)page_directory-0xC0000000));
} }
void* get_cr3() {
void* cr3;
asm volatile("movl %%cr3, %%eax; movl %%eax, %0;":"=m"(cr3)::"%eax");
return cr3;
}

View File

@ -1,12 +0,0 @@
#ifndef PORTS_H
#define PORTS_H
#include <stdint.h>
uint8_t port_byte_in(uint16_t port);
void port_byte_out(uint16_t port,uint8_t data);
uint16_t port_word_in(uint16_t port);
void port_word_out(uint16_t port,uint16_t data);
uint32_t port_long_in(uint16_t port);
void port_long_out(uint16_t port,uint32_t data);
#endif

View File

@ -1,9 +1,8 @@
#include "ports.h" #include <cpu/ports.h>
#include "../../cpu/i386/isr.h" #include "../isr.h"
#include "serial.h" #include "../serial.h"
#include <stdio.h> #include <stdarg.h>
#include <string.h> #include <string.h>
#include <devbuf.h>
#include <stdint.h> #include <stdint.h>
#define SERIAL_LINE_ENABLE_DLAB 0x80 #define SERIAL_LINE_ENABLE_DLAB 0x80

View File

@ -66,3 +66,10 @@ task_init:
push 0x1B push 0x1B
push ebx push ebx
iret iret
global wait_for_unblocked_thread_asm
wait_for_unblocked_thread_asm:
sti ;As interrupts are stopped in tasking code, re-enable them
hlt ;Wait for an interrupt handler to run and return.
cli ;Clear interrupts, as tasking code must not be run with interrupts on.

19
kernel/cpu/isr.h Normal file
View File

@ -0,0 +1,19 @@
#ifndef ISR_H
#define ISR_H
#include <stdint.h>
/* Struct which aggregates many registers */
typedef struct {
uint32_t ds; /* Data segment selector */
uint32_t edi,esi,ebp,esp,ebx,edx,ecx,eax; /* Pushed by pusha. */
uint32_t int_no,err_code; /* Interrupt number and error code (if applicable) */
uint32_t eip,cs,eflags,useresp,ss; /* Pushed by the processor automatically */
} registers_t;
typedef void (*isr_t)(registers_t*);
void isr_install();
void isr_register_handler(uint8_t n,isr_t handler);
#endif

View File

@ -2,9 +2,7 @@
#define PAGING_H #define PAGING_H
#include <stdint.h> #include <stdint.h>
#include "paging_helpers.h" #include "arch_consts.h"
#define NUM_KERN_DIRS 4
void map_pages(void* virt_addr_ptr,void* phys_addr_ptr,int num_pages,char usr,char wr); void map_pages(void* virt_addr_ptr,void* phys_addr_ptr,int num_pages,char usr,char wr);
int new_kstack(); int new_kstack();
@ -13,12 +11,13 @@ void* alloc_pages(int num_pages);
void alloc_pages_virt(int num_pages,void* addr); void alloc_pages_virt(int num_pages,void* addr);
void paging_init(); void paging_init();
void* paging_new_address_space(); void* paging_new_address_space();
void load_address_space(uint32_t cr3); void load_address_space(void* cr3);
void* virt_to_phys(void* virt_addr); void* virt_to_phys(void* virt_addr);
void* find_free_pages(int num_pages); void* find_free_pages(int num_pages);
void* find_free_pages_wstart(int num_pages,int start_page); void* find_free_pages_wstart(int num_pages,int start_page);
void load_smap(uint32_t cr3); void load_smap(void* cr3);
char make_protector(int page); char make_protector(int page);
char is_in_protector(uint32_t* addr); char is_in_protector(void* addr);
void* get_cr3();
#endif #endif

View File

@ -1,23 +0,0 @@
#ifndef CPU_TASKING_H
#define CPU_TASKING_H
#include "i386/tasking.h"
#include "i386/isr.h"
#include <sys/types.h>
#include "../rpc.h"
extern Thread* currentThread;
void tasking_createTask(void* eip,void* cr3,char kmode,char param1_exists,uint32_t param1_arg,char param2_exists,uint32_t param2_arg,char isThread);
void tasking_init();
char tasking_isPrivleged();
pid_t tasking_getPID();
int* tasking_get_errno_address();
uint32_t tasking_new_thread(void* start,pid_t pid,char param_exists,uint32_t param_arg);
void tasking_exit(uint8_t code);
void tasking_block(ThreadState newstate);
void tasking_unblock(pid_t pid,uint32_t tid);
void tasking_yield();
#endif

View File

@ -5,5 +5,6 @@
void switch_to_thread_asm(Thread* thread); void switch_to_thread_asm(Thread* thread);
void task_init(); void task_init();
void wait_for_unblocked_thread_asm();
#endif #endif

View File

@ -0,0 +1,7 @@
#ifndef ARCH_CONSTS_H
#define ARCH_CONSTS_H
#define PAGE_SZ 496
#define FRAME_SZ PAGE_SZ
#endif

View File

@ -1,13 +1,2 @@
#include "paging.h"
#include "isr.h"
#include <grub/multiboot2.h>
#include "pmem.h"
// #include "../tasking.h"
void cpu_init(struct multiboot_boot_header_tag* mbd) { void cpu_init() {}
isr_install();
asm volatile("sti");
pmem_init(mbd);
paging_init();
// tasking_init();
}

View File

@ -22,6 +22,7 @@ isr_common_stub:
push r14 push r14
push r15 push r15
; 2. Call C handler ; 2. Call C handler
mov rdi,rsp
call isr_handler call isr_handler
; 3. Restore state ; 3. Restore state
pop r15 pop r15
@ -65,6 +66,7 @@ irq_common_stub:
push r14 push r14
push r15 push r15
; 2. Call C handler ; 2. Call C handler
mov rdi,rsp
call irq_handler call irq_handler
; 3. Restore state ; 3. Restore state
pop r15 pop r15

View File

@ -1,4 +1,4 @@
#include "isr.h" #include "../isr.h"
#include "idt.h" #include "idt.h"
#include <cpu/ports.h> #include <cpu/ports.h>
// #include "paging.h" // #include "paging.h"
@ -8,8 +8,7 @@
#include "interrupt.h" #include "interrupt.h"
#include <string.h> #include <string.h>
#include <stdint.h> #include <stdint.h>
void irq_handler(registers_t r); static isr_t irq_handlers[16];
static isr_t interrupt_handlers[256];
/* Can't do this with a loop because we need the address /* Can't do this with a loop because we need the address
* of the function names */ * of the function names */
@ -78,6 +77,8 @@ void isr_install() {
idt_set_gate(47,(uint64_t)irq15); idt_set_gate(47,(uint64_t)irq15);
load_idt(); load_idt();
asm volatile("sti");
} }
@ -120,26 +121,26 @@ static char *exception_messages[] = {
"Reserved" "Reserved"
}; };
void isr_handler(registers_t r) { void isr_handler(registers_t* r) {
switch (r.int_no) { switch (r->int_no) {
case 14: { case 14: {
uint64_t addr; uint64_t addr;
asm("movq %%cr2,%0": "=r"(addr)); asm("movq %%cr2,%0": "=r"(addr));
if (r.err_code==0) { if (r->err_code==0) {
vga_write_string("Kernel process tried to read a non-present page entry at address "); vga_write_string("Kernel process tried to read a non-present page entry at address ");
} else if (r.err_code==1) { } else if (r->err_code==1) {
vga_write_string("Kernel process tried to read a page and caused a protection fault at address "); vga_write_string("Kernel process tried to read a page and caused a protection fault at address ");
} else if (r.err_code==2) { } else if (r->err_code==2) {
vga_write_string("Kernel process tried to write to a non-present page entry at address "); vga_write_string("Kernel process tried to write to a non-present page entry at address ");
} else if (r.err_code==3) { } else if (r->err_code==3) {
vga_write_string("Kernel process tried to write a page and caused a protection fault at address "); vga_write_string("Kernel process tried to write a page and caused a protection fault at address ");
} else if (r.err_code==4) { } else if (r->err_code==4) {
vga_write_string("User process tried to read a non-present page entry at address "); vga_write_string("User process tried to read a non-present page entry at address ");
} else if (r.err_code==5) { } else if (r->err_code==5) {
vga_write_string("User process tried to read a page and caused a protection fault at address "); vga_write_string("User process tried to read a page and caused a protection fault at address ");
} else if (r.err_code==6) { } else if (r->err_code==6) {
vga_write_string("User process tried to write to a non-present page entry at address "); vga_write_string("User process tried to write to a non-present page entry at address ");
} else if (r.err_code==7) { } else if (r->err_code==7) {
vga_write_string("User process tried to write a page and caused a protection fault at address "); vga_write_string("User process tried to write a page and caused a protection fault at address ");
} }
char str[11]; char str[11];
@ -147,7 +148,7 @@ void isr_handler(registers_t r) {
hex_to_ascii(addr,str); hex_to_ascii(addr,str);
vga_write_string(str); vga_write_string(str);
vga_write_string("\n"); vga_write_string("\n");
// if ((r.err_code&1)==0) { // if ((r->err_code&1)==0) {
// // int dir_entry=(addr&0xFFC00000)>>22; // // int dir_entry=(addr&0xFFC00000)>>22;
// // int table_entry=(addr&0x3FF000)>12; // // int table_entry=(addr&0x3FF000)>12;
// // if (dir_entry_present(dir_entry)) { // // if (dir_entry_present(dir_entry)) {
@ -167,36 +168,38 @@ void isr_handler(registers_t r) {
halt(); halt();
break; break;
case 80: case 80:
// if (r.eax==1) { // if (r->eax==1) {
// tss_stack_reset(); // tss_stack_reset();
// tasking_yield(); // tasking_yield();
// } else if (r.eax==2) { // } else if (r->eax==2) {
// tasking_createTask((void*)r.ebx); // tasking_createTask((void*)r->ebx);
// } else if (r.eax==3) { // } else if (r->eax==3) {
// r.ebx=(uint64_t)alloc_pages(r.ebx); // r->ebx=(uint64_t)alloc_pages(r->ebx);
// } else if (r.eax==4) { // } else if (r->eax==4) {
// alloc_pages_virt(r.ebx,(void*)r.ecx); // alloc_pages_virt(r->ebx,(void*)r->ecx);
// } else if (r.eax==5) { // } else if (r->eax==5) {
// r.ebx=(uint64_t)tasking_get_errno_address(); // r->ebx=(uint64_t)tasking_get_errno_address();
// } // }
break; break;
} }
} }
} }
void isr_register_handler(uint8_t n,isr_t handler) { void isr_register_handler(uint8_t n,isr_t handler) {
interrupt_handlers[n] = handler; if (n>16) {
return;
}
irq_handlers[n] = handler;
} }
void irq_handler(registers_t r) { void irq_handler(registers_t* r) {
/* After every interrupt we need to send an EOI to the PICs /* After every interrupt we need to send an EOI to the PICs
* or they will not send another interrupt again */ * or they will not send another interrupt again */
if (r.int_no >= 40) port_byte_out(0xA0,0x20); /* slave */ if (r->int_no >= 40) port_byte_out(0xA0,0x20); /* slave */
port_byte_out(0x20,0x20); /* master */ port_byte_out(0x20,0x20); /* master */
/* Handle the interrupt in a more modular way */ /* Handle the interrupt in a more modular way */
if (interrupt_handlers[r.int_no] != 0) { if (irq_handlers[r->int_no-32] != NULL) {
isr_t handler = interrupt_handlers[r.int_no]; isr_t handler = irq_handlers[r->int_no];
handler(r); handler(r);
} }
} }

View File

@ -3,58 +3,6 @@
#include <stdint.h> #include <stdint.h>
/* ISRs reserved for CPU exceptions */
extern void isr0();
extern void isr1();
extern void isr2();
extern void isr3();
extern void isr4();
extern void isr5();
extern void isr6();
extern void isr7();
extern void isr8();
extern void isr9();
extern void isr10();
extern void isr11();
extern void isr12();
extern void isr13();
extern void isr14();
extern void isr15();
extern void isr16();
extern void isr17();
extern void isr18();
extern void isr19();
extern void isr20();
extern void isr21();
extern void isr22();
extern void isr23();
extern void isr24();
extern void isr25();
extern void isr26();
extern void isr27();
extern void isr28();
extern void isr29();
extern void isr30();
extern void isr31();
extern void isr80();
/* IRQ definitions */
extern void irq0();
extern void irq1();
extern void irq2();
extern void irq3();
extern void irq4();
extern void irq5();
extern void irq6();
extern void irq7();
extern void irq8();
extern void irq9();
extern void irq10();
extern void irq11();
extern void irq12();
extern void irq13();
extern void irq14();
extern void irq15();
/* Struct which aggregates many registers */ /* Struct which aggregates many registers */
typedef struct { typedef struct {
uint64_t r15,r14,r13,r12,r11,r10,r9,r8,rdi,rsi,rbp,rsp,rbx,rdx,rcx,rax; /* Pushed by our code. */ uint64_t r15,r14,r13,r12,r11,r10,r9,r8,rdi,rsi,rbp,rsp,rbx,rdx,rcx,rax; /* Pushed by our code. */
@ -62,29 +10,9 @@ typedef struct {
uint64_t rip,cs,rflags,userrsp,ss; /* Pushed by the processor automatically */ uint64_t rip,cs,rflags,userrsp,ss; /* Pushed by the processor automatically */
} registers_t; } registers_t;
#define IRQ0 32 typedef void (*isr_t)(registers_t*);
#define IRQ1 33
#define IRQ2 34
#define IRQ3 35
#define IRQ4 36
#define IRQ5 37
#define IRQ6 38
#define IRQ7 39
#define IRQ8 40
#define IRQ9 41
#define IRQ10 42
#define IRQ11 43
#define IRQ12 44
#define IRQ13 45
#define IRQ14 46
#define IRQ15 47
typedef void (*isr_t)(registers_t);
void isr_install(); void isr_install();
void isr_handler(registers_t r);
void irq_handler(registers_t r);
void isr_register_handler(uint8_t n,isr_t handler); void isr_register_handler(uint8_t n,isr_t handler);
#endif #endif

View File

@ -1,10 +0,0 @@
#ifndef PAGING_H
#define PAGING_H
#include <stdint.h>
#define NUM_KERN_DIRS 4
void paging_init();
#endif

View File

@ -1,123 +0,0 @@
#include <grub/multiboot2.h>
#include "../halt.h"
#include <stdint.h>
#include <stdlib.h>
#include <klog.h>
static char bmap[131072];
static char get_bmap_bit(int index) {
int byte=index/8;
int bit=index%8;
char entry=bmap[byte];
return (entry&(1<<bit))>0;
}
static void set_bmap_bit(int index) {
int byte=index/8;
int bit=index%8;
bmap[byte]=bmap[byte]|(1<<bit);
}
static void clear_bmap_bit(int index) {
int byte=index/8;
int bit=index%8;
bmap[byte]=bmap[byte]&(~(1<<bit));
}
void pmem_init(struct multiboot_boot_header_tag* tags) {
for (int i=0;i<131072;i++) {
bmap[i]=0xFF;
}
char found_mmap=0;
struct multiboot_tag* tag=(struct multiboot_tag*)(tags+1);
while (tag->type!=0) {
switch (tag->type) {
case MULTIBOOT_TAG_TYPE_MMAP: {
found_mmap=1;
struct multiboot_mmap_entry* orig_ptr=(struct multiboot_mmap_entry*)(((char*)tag)+16);
for (struct multiboot_mmap_entry* ptr=orig_ptr;(char*)ptr<((char*)orig_ptr)+tag->size;ptr++) {
if (ptr->type!=MULTIBOOT_MEMORY_AVAILABLE) continue;
uint32_t size=ptr->len;
uint32_t start=ptr->addr;
if (start<0x100000) continue;
uint32_t end=start+ptr->len-1;
if (start&0xFFF) {
start+=0x1000;
}
start=start>>12;
end=end>>12;
for (uint32_t i=start;i<end;i++) {
clear_bmap_bit(i);
}
}
char str[256];
break;
}
}
tag=(struct multiboot_tag*)((char*)tag+((tag->size+7)&0xFFFFFFF8));
}
if (!found_mmap) {
vga_write_string("[PANIC] No memory map supplied by bootloader!");
halt();
}
for (uint32_t i=0;i<2048;i++) {
set_bmap_bit(i);
}
}
void* pmem_alloc(int num_pages) {
uint32_t bmap_index;
uint32_t remaining_blks;
for(uint32_t i=0;i<131072;i++) {
if (bmap[i]!=0xFF) {
char got_0=0;
remaining_blks=num_pages;
uint32_t old_j;
for (uint32_t j=i*8;;j++) {
char bit=get_bmap_bit(j);
if (got_0) {
if (bit) {
if (remaining_blks==0) {
bmap_index=old_j;
break;
} else {
i+=j/8;
i--;
break;
}
} else {
remaining_blks--;
}
} else {
if (!bit) {
got_0=1;
old_j=j;
remaining_blks--;
}
}
if (remaining_blks==0) {
bmap_index=old_j;
break;
}
}
}
if (remaining_blks==0) {
break;
}
}
if (remaining_blks!=0) {
return NULL;
}
for (int i=0;i<num_pages;i++) {
set_bmap_bit(bmap_index+i);
}
void* addr=(void*)(bmap_index<<12);
return addr;
}
void pmem_free(int start_page,int num_pages) {
for (int i=start_page;i<num_pages;i++) {
set_bmap_bit(i);
}
}

View File

@ -1,10 +0,0 @@
#ifndef PMEM_H
#define PMEM_H
#include <grub/multiboot2.h>
void pmem_init(struct multiboot_boot_header_tag* tags);
void* pmem_alloc(int num_pages);
void pmem_free(int start_page,int num_pages);
#endif

View File

@ -1,31 +0,0 @@
#include <stdint.h>
uint8_t port_byte_in(uint16_t port) {
uint8_t result;
asm("in %%dx, %%al":"=a"(result):"d"(port));
return result;
}
void port_byte_out(uint16_t port,uint8_t data) {
asm("out %%al, %%dx":: "a"(data),"d"(port));
}
uint16_t port_word_in(uint16_t port) {
uint16_t result;
asm("in %%dx, %%ax":"=a"(result):"d"(port));
return result;
}
void port_word_out(uint16_t port,uint16_t data) {
asm("out %%ax, %%dx":: "a" (data), "d" (port));
}
uint32_t port_long_in(uint16_t port) {
uint32_t result;
asm("inl %%dx, %%eax":"=a"(result):"d"(port));
return result;
}
void port_long_out(uint16_t port,uint32_t data) {
asm("outl %%eax, %%dx":: "a" (data), "d" (port));
}

View File

@ -1,6 +1,7 @@
#include <grub/text_fb_info.h> #include <grub/text_fb_info.h>
#include <stdlib.h> #include <stdlib.h>
#include <tasking.h> #include <tasking.h>
#include "tasking.h"
#include <string.h> #include <string.h>
#include <memory.h> #include <memory.h>
#include <grub/multiboot2.h> #include <grub/multiboot2.h>
@ -8,6 +9,10 @@
#include "cpu/cpu_init.h" #include "cpu/cpu_init.h"
#include "vga_err.h" #include "vga_err.h"
#include <elf.h> #include <elf.h>
#include "cpu/serial.h"
#include "pmem.h"
#include "cpu/paging.h"
#include "cpu/isr.h"
typedef struct { typedef struct {
char filename[100]; char filename[100];
@ -52,7 +57,12 @@ uint32_t getsize(const char *in) {
void kmain(struct multiboot_boot_header_tag* hdr) { void kmain(struct multiboot_boot_header_tag* hdr) {
tags=hdr; tags=hdr;
cpu_init(tags); cpu_init();
isr_install();
serial_init();
pmem_init(tags);
paging_init();
tasking_init();
vga_init((char*)0xC00B8000); vga_init((char*)0xC00B8000);
read_initrd(tags); read_initrd(tags);
int pos=0; int pos=0;

View File

@ -2,9 +2,12 @@
#include <stdlib.h> #include <stdlib.h>
#include <math.h> #include <math.h>
#include <stdint.h> #include <stdint.h>
#include "cpu/arch_consts.h"
static char bitmap[2097152]; #define KMALLOC_BMAP_SZ (((KMALLOC_SZ*1024)/4)/8)
static void* data=(void*)0xFE800000;
static char bitmap[KMALLOC_BMAP_SZ];
static void* data=(void*)KMALLOC_START;
static char get_bmap_bit(uint32_t index) { static char get_bmap_bit(uint32_t index) {
@ -31,7 +34,7 @@ void* kmalloc(uint32_t size) {
num_4b_grps+=2; num_4b_grps+=2;
uint32_t bmap_index; uint32_t bmap_index;
uint32_t remaining_blks; uint32_t remaining_blks;
for(uint32_t i=0;i<2097152;i++) { for(uint32_t i=0;i<KMALLOC_BMAP_SZ;i++) {
char got_0=0; char got_0=0;
remaining_blks=num_4b_grps; remaining_blks=num_4b_grps;
uint32_t old_j; uint32_t old_j;

View File

@ -1,11 +1,14 @@
#include <grub/multiboot2.h> #include <grub/multiboot2.h>
#include "../halt.h" #include "cpu/halt.h"
#include "../..//vga_err.h" #include "vga_err.h"
#include <stdint.h> #include <stdint.h>
#include <stdlib.h> #include <stdlib.h>
#include <klog.h> #include <klog.h>
#include "cpu/arch_consts.h"
static char bmap[131072]; #define BMAP_LEN (NUM_FRAMES/8)
static char bmap[BMAP_LEN];
static char get_bmap_bit(int index) { static char get_bmap_bit(int index) {
int byte=index/8; int byte=index/8;
@ -27,7 +30,7 @@ static void clear_bmap_bit(int index) {
} }
void pmem_init(struct multiboot_boot_header_tag* tags) { void pmem_init(struct multiboot_boot_header_tag* tags) {
for (int i=0;i<131072;i++) { for (int i=0;i<BMAP_LEN;i++) {
bmap[i]=0xFF; bmap[i]=0xFF;
} }
char found_mmap=0; char found_mmap=0;
@ -42,11 +45,11 @@ void pmem_init(struct multiboot_boot_header_tag* tags) {
uint32_t start=ptr->addr; uint32_t start=ptr->addr;
if (start<0x100000) continue; if (start<0x100000) continue;
uint32_t end=start+ptr->len-1; uint32_t end=start+ptr->len-1;
if (start&0xFFF) { if (start&(FRAME_SZ-1)) {
start+=0x1000; start+=FRAME_SZ;
} }
start=start>>12; start=start>>FRAME_NO_OFFSET;
end=end>>12; end=end>>FRAME_NO_OFFSET;
for (uint32_t i=start;i<end;i++) { for (uint32_t i=start;i<end;i++) {
clear_bmap_bit(i); clear_bmap_bit(i);
} }
@ -60,7 +63,7 @@ void pmem_init(struct multiboot_boot_header_tag* tags) {
vga_write_string("[PANIC] No memory map supplied by bootloader!"); vga_write_string("[PANIC] No memory map supplied by bootloader!");
halt(); halt();
} }
for (uint32_t i=0;i<2048;i++) { for (uint32_t i=0;i<NUM_KERN_FRAMES;i++) {
set_bmap_bit(i); set_bmap_bit(i);
} }
} }

View File

@ -1,11 +1,10 @@
#include "tasking.h" #include "tasking.h"
#include "../tasking.h"
#include <sys/types.h> #include <sys/types.h>
#include "kmalloc.h" #include "kmalloc.h"
#include "serial.h" #include "cpu/serial.h"
#include "../halt.h" #include "cpu/halt.h"
#include "paging.h" #include "cpu/paging.h"
#include "tasking_helpers.h" #include "cpu/tasking_helpers.h"
#define MAX_PROCS 32768 #define MAX_PROCS 32768
#define HAS_UNBLOCKED_THREADS(proc) (proc->numThreads!=proc->numThreadsBlocked) #define HAS_UNBLOCKED_THREADS(proc) (proc->numThreads!=proc->numThreadsBlocked)
#define NUM_UNBLOCKED_THREADS(proc) (proc->numThreads-proc->numThreadsBlocked) #define NUM_UNBLOCKED_THREADS(proc) (proc->numThreads-proc->numThreadsBlocked)
@ -18,7 +17,7 @@ char proc_schedule_bmap[MAX_PROCS/8];
Thread* currentThread; Thread* currentThread;
static Thread* readyToRunHead=NULL; static Thread* readyToRunHead=NULL;
static Thread* readyToRunTail=NULL; static Thread* readyToRunTail=NULL;
static uint32_t* kstacks=(uint32_t*)0xC8000000; static uint32_t* kstacks=(uint32_t*)KSTACKS_START;
static char is_proc_scheduled(uint32_t index) { static char is_proc_scheduled(uint32_t index) {
uint32_t byte=index/8; uint32_t byte=index/8;
@ -90,10 +89,9 @@ void tasking_createTask(void* eip,void* cr3,char kmode,char param1_exists,uint32
thread->errno=0; thread->errno=0;
thread->tid=proc->next_tid; thread->tid=proc->next_tid;
proc->next_tid++; proc->next_tid++;
void* old_cr3; void* old_cr3=get_cr3();
asm volatile("movl %%cr3, %%eax; movl %%eax, %0;":"=m"(old_cr3)::"%eax");
uint32_t kstack_num=new_kstack(); uint32_t kstack_num=new_kstack();
load_address_space((uint32_t)thread->cr3); load_address_space(thread->cr3);
if (kmode) { if (kmode) {
uint32_t top_idx=(1024*(kstack_num+1)); uint32_t top_idx=(1024*(kstack_num+1));
thread->kernel_esp=((uint32_t)(&kstacks[top_idx-5])); thread->kernel_esp=((uint32_t)(&kstacks[top_idx-5]));
@ -113,7 +111,7 @@ void tasking_createTask(void* eip,void* cr3,char kmode,char param1_exists,uint32
kstacks[top_idx-2]=(uint32_t)user_stack; kstacks[top_idx-2]=(uint32_t)user_stack;
kstacks[top_idx-1]=(uint32_t)eip; kstacks[top_idx-1]=(uint32_t)eip;
} }
load_address_space((uint32_t)old_cr3); load_address_space(old_cr3);
thread->prevReadyToRun=NULL; thread->prevReadyToRun=NULL;
thread->nextReadyToRun=NULL; thread->nextReadyToRun=NULL;
if (isThread) { if (isThread) {
@ -150,9 +148,7 @@ void tasking_createTask(void* eip,void* cr3,char kmode,char param1_exists,uint32
} }
void tasking_init() { void tasking_init() {
void* cr3; tasking_createTask(NULL,get_cr3(),1,0,0,0,0,0);
asm volatile("movl %%cr3, %%eax; movl %%eax, %0;":"=m"(cr3)::"%eax");
tasking_createTask(NULL,cr3,1,0,0,0,0,0);
} }
char tasking_isPrivleged() { char tasking_isPrivleged() {
@ -227,7 +223,7 @@ void switch_to_thread(Thread* thread) {
mark_proc_scheduled(currentThread->process->pid); mark_proc_scheduled(currentThread->process->pid);
} }
serial_printf("Switching to PID %d TID %d.\n",thread->process->pid,thread->tid); serial_printf("Switching to PID %d TID %d.\n",thread->process->pid,thread->tid);
load_smap((uint32_t)thread->cr3); load_smap(thread->cr3);
switch_to_thread_asm(thread); switch_to_thread_asm(thread);
} }
@ -250,11 +246,7 @@ void tasking_yield() {
} else { } else {
serial_printf("All threads in all processes blocked, waiting for an IRQ which unblocks a thread\n"); serial_printf("All threads in all processes blocked, waiting for an IRQ which unblocks a thread\n");
// All threads in all processes blocked, so wait for an IRQ whose handler unblocks a thread. // All threads in all processes blocked, so wait for an IRQ whose handler unblocks a thread.
do { do { wait_for_unblocked_thread_asm(); } while (readyToRunHead==NULL);
asm volatile("sti"); //As interrupts are stopped, re-enable them.
asm volatile("hlt"); //Wait for an interrupt handler to run and return.
asm volatile("cli"); //Clear interrupts, as tasking code must not be interrupted.
} while (readyToRunHead==NULL);
} }
serial_printf("Attempting to switch to PID %d TID %d\n",readyToRunHead->process->pid,readyToRunHead->tid); serial_printf("Attempting to switch to PID %d TID %d\n",readyToRunHead->process->pid,readyToRunHead->tid);
switch_to_thread(readyToRunHead); switch_to_thread(readyToRunHead);

View File

@ -1,15 +1,20 @@
#ifndef INT_TASKING_H #ifndef KERN_TASKING_H
#define INT_TASKING_H #define KERN_TASKING_H
#include <sys/types.h>
#include <stdint.h> #include <stdint.h>
#ifndef TASKING_H #ifndef TASKING_H
typedef enum ThreadState { typedef enum ThreadState {
THREAD_RUNNING, THREAD_RUNNING,
THREAD_READY, THREAD_READY,
THREAD_EXITED, THREAD_EXITED,
THREAD_BLOCKED THREAD_BLOCKED
} ThreadState; } ThreadState;
#endif #endif
struct Thread; struct Thread;
@ -37,4 +42,18 @@ typedef struct Thread {
Process* process; Process* process;
} Thread; } Thread;
extern Thread* currentThread;
void tasking_createTask(void* eip,void* cr3,char kmode,char param1_exists,uint32_t param1_arg,char param2_exists,uint32_t param2_arg,char isThread);
void tasking_init();
char tasking_isPrivleged();
pid_t tasking_getPID();
int* tasking_get_errno_address();
uint32_t tasking_new_thread(void* start,pid_t pid,char param_exists,uint32_t param_arg);
void tasking_exit(uint8_t code);
void tasking_block(ThreadState newstate);
void tasking_unblock(pid_t pid,uint32_t tid);
void tasking_yield();
#endif #endif

View File

@ -4,7 +4,7 @@
#include <stdint.h> #include <stdint.h>
#include <sys/types.h> #include <sys/types.h>
#ifndef INT_TASKING_H #ifndef KERN_TASKING_H
typedef enum ThreadState { typedef enum ThreadState {
THREAD_RUNNING, THREAD_RUNNING,
THREAD_READY, THREAD_READY,