Portability work
This commit is contained in:
parent
76eedfb921
commit
eef40edb3f
7
Makefile
7
Makefile
@ -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
|
||||||
|
@ -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
13
kernel/cpu/arch_consts.h
Normal 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
|
@ -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
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
13
kernel/cpu/i386/arch_consts.h
Normal file
13
kernel/cpu/i386/arch_consts.h
Normal 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
|
@ -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
5
kernel/cpu/i386/halt.asm
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
global halt
|
||||||
|
halt:
|
||||||
|
cli
|
||||||
|
halt_label: hlt
|
||||||
|
jmp halt_label
|
@ -1,5 +0,0 @@
|
|||||||
void halt() {
|
|
||||||
asm volatile("cli;\
|
|
||||||
hltlabel: hlt;\
|
|
||||||
jmp hltlabel");
|
|
||||||
}
|
|
@ -14,10 +14,11 @@ isr_common_stub:
|
|||||||
mov fs, ax
|
mov fs, ax
|
||||||
mov gs, ax
|
mov gs, ax
|
||||||
|
|
||||||
push esp
|
|
||||||
|
|
||||||
; 2. Call C handler
|
; 2. Call C handler
|
||||||
|
push esp
|
||||||
|
|
||||||
call isr_handler
|
call isr_handler
|
||||||
|
|
||||||
; 3. Restore state
|
; 3. Restore state
|
||||||
pop eax
|
pop eax
|
||||||
pop eax
|
pop eax
|
||||||
@ -41,11 +42,11 @@ irq_common_stub:
|
|||||||
mov fs, ax
|
mov fs, ax
|
||||||
mov gs, ax
|
mov gs, ax
|
||||||
|
|
||||||
push esp
|
push esp
|
||||||
|
|
||||||
call irq_handler ; Different than the ISR code
|
call irq_handler ; Different than the ISR code
|
||||||
|
|
||||||
pop ebx
|
pop ebx
|
||||||
|
|
||||||
pop ebx ; Different than the ISR code
|
pop ebx ; Different than the ISR code
|
||||||
mov ds, bx
|
mov ds, bx
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
@ -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
|
|
@ -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
|
||||||
|
@ -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
19
kernel/cpu/isr.h
Normal 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
|
@ -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
|
@ -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
|
|
@ -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
|
7
kernel/cpu/x86_64/arch_consts.h
Normal file
7
kernel/cpu/x86_64/arch_consts.h
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#ifndef ARCH_CONSTS_H
|
||||||
|
#define ARCH_CONSTS_H
|
||||||
|
|
||||||
|
#define PAGE_SZ 496
|
||||||
|
#define FRAME_SZ PAGE_SZ
|
||||||
|
|
||||||
|
#endif
|
@ -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();
|
|
||||||
}
|
|
||||||
|
@ -21,9 +21,10 @@ isr_common_stub:
|
|||||||
push r13
|
push r13
|
||||||
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
|
||||||
pop r14
|
pop r14
|
||||||
pop r13
|
pop r13
|
||||||
@ -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
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -1,10 +0,0 @@
|
|||||||
#ifndef PAGING_H
|
|
||||||
#define PAGING_H
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#define NUM_KERN_DIRS 4
|
|
||||||
|
|
||||||
void paging_init();
|
|
||||||
|
|
||||||
#endif
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
@ -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
|
|
@ -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));
|
|
||||||
}
|
|
@ -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;
|
||||||
|
@ -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;
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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);
|
@ -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
|
@ -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,
|
||||||
|
Loading…
Reference in New Issue
Block a user