Creating scheduler, debug paging

This commit is contained in:
Loic Guegan 2021-05-01 11:37:52 +02:00
parent fb69c7b058
commit 4f08ba2b1d
16 changed files with 227 additions and 88 deletions

View file

@ -1,5 +1,5 @@
EXEC := boucane
CC := g++ -mcmodel=large -nostdlib -nostdinc -no-pie -fno-builtin -fno-stack-protector -I ./ -I include
CC := g++ -Wno-write-strings -Wno-int-to-pointer-cast -mcmodel=large -nostdlib -nostdinc -no-pie -fno-builtin -fno-stack-protector -I ./ -I include
LD_SCRIPT := linker.ld
# Note that BOOT_OBJ do not match boot.S

View file

@ -4,9 +4,9 @@
#include "libs/stdio.hpp"
u32* mb2_find_tag(u32 *mb2_info_addr, char type){
PAGE_MAP(mb2_info_addr);
PAGE_VIRT_MAP(mb2_info_addr,PAGING_OPT_DEFAULTS);
u32 size=(u32)VIRT(mb2_info_addr)[0]; // Todo: check for size
PAGE_RMAP(mb2_info_addr, size);
PAGE_VIRT_RMAP(mb2_info_addr, PAGING_OPT_DEFAULTS,size);
char *location=((char*)VIRT(mb2_info_addr))+8; // Goto first tag
char *start=(char*)VIRT(mb2_info_addr);

View file

@ -1,4 +1,5 @@
#include "boucane.hpp"
#include "core/apic.hpp"
#include "core/paging.hpp"
#include "drivers/memtext.hpp"
#include "core/idt.hpp"
@ -9,6 +10,7 @@
#include "libs/stdio.hpp"
#include "libs/string.hpp"
#include "drivers/bmp.hpp"
#include "core/scheduler.hpp"
u64 kvar_kernel_vma;
u64 kvar_stack_pma;
@ -25,26 +27,35 @@ void (*printk)(char *str,...)=printf;
extern u64 gdt64_tss;
void configure_tss(){
u64 tss_addr=(u64)&kvar_tss;
u32 desc1=(tss_addr&0xFFFF)<<16|(sizeof(TSS)&0xFFFF);
tss_addr>>=16;
u32 desc2=(tss_addr&0xFF)|((tss_addr>>8)<<24);
tss_addr>>=16;
u32 desc3=tss_addr;
// Get TSS physical address
u64 tss_addr=(u64)PHY(&kvar_tss);
u32 limit=sizeof(TSS);
// Options
u32 options=0b1001; // 64-bits TSS type
options|=(0b1000<<4); // Present
u32 desc1=(tss_addr&0xFFFF)<<16|(limit&0xFFFF);
u32 desc2=(tss_addr&0xFF);
desc2|=0b1001<<8; // Type
desc2|=0b111<<13; // Permission & present
u32 desc3=((limit>>8)&0xFFFF)|(limit>>24);
// Configure GDT
u32 *gdt_entry=(u32*)&gdt64_tss;
gdt_entry[0]=desc1;
gdt_entry[1]=desc2|(options<<8);
gdt_entry[1]=desc2;
gdt_entry[2]=desc3;
gdt_entry[3]=0;
// Configure segment
kvar_tss.rsp0=(u64)VIRT(kvar_stack_pma);
asm(
"mov $0x28, %ax \n\t"
"ltr %ax"
);
}
void task1(){
u64 a=0xEEEEEE;
DUMP(a);
while(1);
}
extern "C" void boucane(u64 mb_info){
@ -60,11 +71,12 @@ extern "C" void boucane(u64 mb_info){
asm volatile ("movq $res_binary_res_logo_bmp_end, %0":"=m"(kvar_logo_bmp_end));
// Init data structures
configure_tss();
asm volatile ("call load_gdt");
configure_tss();
paging_enable();
memtext_init();
idt_enable_interrupt();
apic_enable();
// Looking for framebuffer
FRAMEBUFFER fb_info;
@ -101,7 +113,7 @@ extern "C" void boucane(u64 mb_info){
printk("RAM:%dMB\n", mem);
}
printk("%x",&kvar_tss);
DUMP(&gdt64_tss);
//create_task((void*)task1, 50);
//scheduler_start();
while(1);
}

View file

@ -5,49 +5,56 @@
#include "asm.hpp"
#include "libs/stdio.hpp"
char enable=0;
#define APIC_LAPIC_ADDR 0xFEE00000
#define APIC_IOAPIC_ADDR 0xFEC00000
#define APIC_LAPIC_REG_SPURIOUS 0xF0
#define APIC_LAPIC_TIMER_LVT 0x320
#define APIC_LAPIC_TIMER_IC 0x380
#define APIC_LAPIC_TIMER_DVD 0x3E0
#define APIC_PRIOR 0x80
#define APIC_DFR 0xE0
#define APIC_EOI 0xB0
u8 lapic_space[4096] __attribute__((aligned(4096)));
u8 ioapic_space[4096] __attribute__((aligned(4096)));
void apic_enable(){
// Allocate APIC registers TODODODODOOD!!!!!
// paging_allocate_addr(kpml4, APIC_LAPIC_ADDR, APIC_LAPIC_ADDR,
//PAGING_OPT_RW|PAGING_OPT_P|PAGING_OPT_PCD);
//paging_allocate_addr(kpml4, APIC_IOAPIC_ADDR, APIC_IOAPIC_ADDR,
//PAGING_OPT_RW|PAGING_OPT_P|PAGING_OPT_PCD);
// Memory Allocation
PAGE_MAP(lapic_space,APIC_LAPIC_ADDR, PAGING_OPT_DEFAULTS);
PAGE_MAP(lapic_space,APIC_LAPIC_ADDR,PAGING_OPT_DEFAULTS);
// Configure APIC register location
u32 h=APIC_LAPIC_ADDR>>32;
u32 l=(APIC_LAPIC_ADDR&0xFFFFFFFF);
l|=0x800; // Enable apic
WRITE_MSR(0x1B,h,l);
// Configure APIC register location and enable it via MSR
u64 lapic_addr=(u64)APIC_LAPIC_ADDR;
u32 high=lapic_addr>>32;
u32 low=((u64)APIC_LAPIC_ADDR&0xFFFFFFFF);
low|=0x800; // Enable apic
WRITE_MSR(0x1B,high,low);
// Enable apic 2
u8 *c_base=(u8*)APIC_LAPIC_ADDR;
c_base+=APIC_LAPIC_REG_SPURIOUS;
u32* base=(u32*)c_base;
*base=0x100|(*base);
// Configure LAPIC device using mmap
apic_write(APIC_LAPIC_REG_SPURIOUS, 0x100&apic_read(APIC_LAPIC_REG_SPURIOUS));
apic_write(APIC_DFR, 0xFFFFFFFF);
apic_write(APIC_PRIOR, 0);
apic_write(APIC_LAPIC_TIMER_DVD, 1);
apic_write(APIC_LAPIC_TIMER_LVT, (1<<17)|61);
apic_write(APIC_LAPIC_TIMER_IC, 100000);
u8 *c_base2=(u8*)APIC_IOAPIC_ADDR;
u32* base2=(u32*)c_base2;
*base2=0x12;
base2=(u32*)(c_base2+0x10);
*base2=(0x0<<12)|0x3C;
enable=1;
// Configure I/O APIC
u32 *ioapic_reg=(u32*)ioapic_space;
*ioapic_reg=0x12; // Select the 0x12 IRQ
ioapic_reg=(u32*)(((u64)ioapic_space)+0x10); // Now use the IOREGWIN to write
*ioapic_reg=(0x0<<12)|60; // Enable IRQ 1 (0x12) and assign it to the vector 0x3C (index 60 in the IDT)
}
void apic_write(u32 reg, u32 value){
u32 *lapic_reg=(u32*)(lapic_space+reg);
*lapic_reg=value;
}
u32 apic_read(u32 reg){
u32 *lapic_reg=(u32*)(lapic_space+reg);
return *lapic_reg;
}
extern "C" void ack(){
if(enable){
u8 data;
do {
inb(0x64,data);
}
while((data&0x01) == 0);
inb(0x60,data);
u8 *c_base=(u8*)(APIC_LAPIC_ADDR|0xB0);
u32* base=(u32*)c_base;
*base=*base|0;
}
apic_write(APIC_EOI, 0);
}

View file

@ -3,4 +3,7 @@
#include "boucane.hpp"
void apic_enable();
void apic_enable();
void apic_write(u32 reg, u32 value);
u32 apic_read(u32 reg);

View file

@ -6,7 +6,7 @@
u32 idt[IDT_MAX_ENTRIES][4] __attribute__((aligned(4096)));;
IDT_REGISTER IDTR;
extern u64 INT_DEFAULT,INT_0,INT_14,INT_KBD;
extern u64 INT_DEFAULT,INT_0,INT_14,INT_KBD,INT_CLK;
void idt_enable_interrupt(void){
IDTR.base=((u64)idt);
@ -32,6 +32,10 @@ void idt_enable_interrupt(void){
d.offset=(u64)&INT_KBD;
idt_write_descriptor(d, i);
}
else if(i==61){ // Clock
d.offset=(u64)&INT_CLK;
idt_write_descriptor(d, i);
}
else {
d.offset=(u64)&INT_DEFAULT;
idt_write_descriptor(d, i);

View file

@ -32,7 +32,14 @@ INT_14:
.globl INT_KBD
INT_KBD:
call_printk $MSG_INT_KBD
#call_printk $MSG_INT_KBD
call ack
iretq
.globl INT_CLK
.extern clock
INT_CLK:
call clock
call ack
iretq

View file

@ -7,6 +7,7 @@
char paging_status[PAGING_MAX_PAGE / 8];
u64 kpages[MAX_TABLES][512] __attribute__((aligned(4096)));
int kpages_next=1; // First page is for the pml4
u64* kpml4;
u64* paging_allocate_table(){
u64 addr=(u64)kpages[kpages_next];
@ -18,6 +19,12 @@ u64* paging_allocate_table(){
}
return allocated;
}
u64* paging_allocate_utable(){
u64 *table=PAGE_ALLOCATE();
for(u32 i=0;i<512;i++)
table[i]=0;
return table;
}
void paging_enable() {
// Init status
@ -38,17 +45,17 @@ void paging_enable() {
// Setting up new kernel address space
for(u64 i=0;i<=0x10000000;i+=4096){
// Higher half mapping
PAGE_MAP(i);
PAGE_VIRT_MAP(i,PAGING_OPT_DEFAULTS);
// Allow access to RAM:
paging_allocate_addr(kpages[0], i, i, PAGING_OPT_P|PAGING_OPT_RW, 1);
paging_allocate_addr(kpages[0], i, i, PAGING_OPT_DEFAULTS, 1);
}
// 4096 bytes stack
PAGE_MAP_PHY(-4096, kvar_stack_pma);
PAGE_MAP(kvar_kernel_vma-4096, kvar_stack_pma,PAGING_OPT_DEFAULTS);
// Load new pml4
u64 kpage_phy=((u64)kpages[0]-kvar_kernel_vma);
lpml4(kpage_phy);
kpml4=(u64*)((u64)kpages[0]-kvar_kernel_vma);
lpml4(kpml4);
}
u64* paging_allocate_contiguous(int npages){
@ -146,7 +153,7 @@ void paging_allocate_addr(u64* pml4_table, u64 virt, u64 phy, u16 options, char
// Solve pdp
if(pml4_table[pml4] == 0){
pml4_table[pml4]=(u64)(useKernelTables ? paging_allocate_table() : PAGE_ALLOCATE());
pml4_table[pml4]=(u64)(useKernelTables ? paging_allocate_table() : paging_allocate_utable());
pml4_table[pml4]|=options;
paging_allocate_addr(pml4_table,virt,phy,options,useKernelTables);
return;
@ -156,7 +163,7 @@ void paging_allocate_addr(u64* pml4_table, u64 virt, u64 phy, u16 options, char
u64* pdp_table=(u64*)(PAGE(pml4_table[pml4]));
pdp_table=useKernelTables ? VIRT(pdp_table) : pdp_table;
if(pdp_table[pdp] == 0){
pdp_table[pdp]=(u64)(useKernelTables ? paging_allocate_table() : PAGE_ALLOCATE());
pdp_table[pdp]=(u64)(useKernelTables ? paging_allocate_table() : paging_allocate_utable());
pdp_table[pdp]|=options;
paging_allocate_addr(pml4_table,virt,phy,options,useKernelTables);
return;
@ -166,7 +173,7 @@ void paging_allocate_addr(u64* pml4_table, u64 virt, u64 phy, u16 options, char
u64* pd_table=(u64*)(PAGE(pdp_table[pdp]));
pd_table=useKernelTables ? VIRT(pd_table) : pd_table;
if(pd_table[pd] == 0){
pd_table[pd]=(u64)(useKernelTables ? paging_allocate_table() : PAGE_ALLOCATE());
pd_table[pd]=(u64)(useKernelTables ? paging_allocate_table() : paging_allocate_utable());
pd_table[pd]|=options;
paging_allocate_addr(pml4_table,virt,phy,options,useKernelTables);
return;
@ -175,19 +182,17 @@ void paging_allocate_addr(u64* pml4_table, u64 virt, u64 phy, u16 options, char
// Solve address
u64* pt_table=(u64*)(PAGE(pd_table[pd]));
pt_table=useKernelTables ? VIRT(pt_table) : pt_table;
if(pt_table[pt] == 0){
pt_table[pt]=PAGE(phy);
pt_table[pt]|=options;
return;
}
pt_table[pt]=PAGE(phy);
pt_table[pt]|=options;
return;
}
u64* paging_create_task(int npages){
u64 *pml4=PAGE_ALLOCATE();
u64 *pml4=paging_allocate_utable();
for(int i=0;i<npages;i++)
paging_allocate_addr(pml4, 0, (u64)PAGE_ALLOCATE(), PAGING_OPT_P|PAGING_OPT_RW, 0);
for(int i=0;i<npages;i++){
paging_allocate_addr(pml4, i*4096, (u64)PAGE_ALLOCATE(), PAGING_OPT_P|PAGING_OPT_RW|PAGING_OPT_US, 0);
}
// Enable kernel access
u16 pml4_entry=kvar_kernel_vma>>39&0x1FF;

View file

@ -16,31 +16,31 @@
/// @brief Options
#define PAGING_OPT_P 1
#define PAGING_OPT_RW (1<<1)
#define PAGING_OPT_US 4
#define PAGING_OPT_PCD (1<<3)
#define PAGING_OPT_DEFAULTS (PAGING_OPT_P|PAGING_OPT_RW)
/// @brief Get page address that contain addr
#define PAGE(addr) (addr&(~(0xFFF)))
#define VIRT(addr) ((u64*)(((u64)addr)+kvar_kernel_vma))
#define PHY(addr) ((u64*)(((u64)addr)-kvar_kernel_vma))
/// @brief Mapping facilities
#define PAGE_ID_MAP(addr) paging_allocate_addr(kpages[0],(u64)(addr),(u64)(addr),PAGING_OPT_P|PAGING_OPT_RW,1)
#define PAGE_ID_RMAP(addr, n) { \
/// @brief Mapping facilities
#define PAGE_MAP(virt,phy,opt) paging_allocate_addr(kpages[0],(u64)(virt),(u64)(phy),(opt),1)
#define PAGE_RMAP(virt,phy,opt,n) { \
for(u64 i=0;i<(n);i+=4096){ \
paging_allocate_addr(kpages[0],((u64)(addr))+i,((u64)(addr))+i,PAGING_OPT_P|PAGING_OPT_RW,1); \
paging_allocate_addr(kpages[0],((u64)(virt))+i,((u64)(phy))+i,(opt),1); \
}}
#define PAGE_MAP(addr) paging_allocate_addr(kpages[0],(u64)((addr)+kvar_kernel_vma),(u64)(addr),PAGING_OPT_P|PAGING_OPT_RW,1)
#define PAGE_RMAP(addr, n) { \
#define PAGE_VIRT_MAP(phy,opt) paging_allocate_addr(kpages[0],(u64)(phy)+kvar_kernel_vma,(u64)(phy),(opt),1)
#define PAGE_VIRT_RMAP(phy,opt,n) { \
for(u64 i=0;i<(n);i+=4096){ \
paging_allocate_addr(kpages[0],(((u64)(addr))+kvar_kernel_vma)+i,((u64)(addr))+i,PAGING_OPT_P|PAGING_OPT_RW,1); \
}}
#define PAGE_MAP_PHY(addr,phy) paging_allocate_addr(kpages[0],(u64)((addr)+kvar_kernel_vma),(u64)(phy),PAGING_OPT_P|PAGING_OPT_RW,1)
#define PAGE_RMAP_PHY(addr,phy, n) { \
for(u64 i=0;i<(n);i+=4096){ \
paging_allocate_addr(kpages[0],(((u64)(addr))+kvar_kernel_vma)+i,((u64)(phy))+i,PAGING_OPT_P|PAGING_OPT_RW,1); \
paging_allocate_addr(kpages[0],(((u64)(phy))+kvar_kernel_vma)+i,((u64)(phy))+i,(opt),1); \
}}
/// @brief All PAE table structures are allocated here
extern u64 kpages[MAX_TABLES][512];
extern u64 *kpml4;
/// CF boucane.hpp
extern u64 kvar_kernel_vma,kvar_stack_pma,kvar_userspace_pma;
@ -57,6 +57,8 @@ void paging_enable();
*/
u64* paging_allocate_contiguous(int npages);
u64* paging_allocate_utable();
/**
* Deallocate a page located at addr
*/

40
src/core/scheduler.cc Normal file
View file

@ -0,0 +1,40 @@
#include "scheduler.hpp"
TASK tasks[MAX_TASK];
u32 ntasks=0;
char show_ticks=0;
extern "C" void clock(){
if(show_ticks)
print(".");
}
void schedule(){
}
void create_task(void* task, u32 size){
if(ntasks>=MAX_TASK){
printk("Could not create more tasks.");
return;
}
TASK *t=&tasks[ntasks];
t->id=ntasks;
t->pid=ntasks;
t->size=size;
t->pml4=paging_create_task(size/4096+1);
// Load task using
lpml4(t->pml4);
memcpy(task, TASK_VMA, size);
lpml4(kpml4);
ntasks++;
}
void scheduler_start(){
TASK *t=&tasks[0];
lpml4(t->pml4);
asm("jmp switch");
}

31
src/core/scheduler.hpp Normal file
View file

@ -0,0 +1,31 @@
#pragma once
#include "boucane.hpp"
#define MAX_TASK 5
#define TASK_VMA 0x0
typedef struct {
u32 rax, rbx, rcx, rdx;
u32 cs, rip;
u32 ss, rsp, rbp;
u32 rsi, rdi;
u32 ds, es, fs, gs;
u32 eflags;
u32 ss0, rsp0;
} __attribute__((packed)) REGS;
typedef struct {
u32 id;
u32 pid;
u64* pml4;
u32 size;
REGS registers;
} __attribute__((packed)) TASK;
extern char show_ticks;
extern "C" void clock();
void schedule();
void create_task(void*task, u32 size);
void scheduler_start();

27
src/core/scheduler_asm.S Normal file
View file

@ -0,0 +1,27 @@
.globl switch
switch:
mov $0x23, %ax
mov %ax, %ds
mov %ax, %es
mov %ax, %fs
mov %ax, %gs
push $0x23 #
push $0x80
pushf
pop %rax
#orl $0x200, %%eax
mov $0xffffbfff, %rbx
and %rbx, %rax
push %rax
push $0x1B
push $0x0
iretq

View file

@ -32,7 +32,7 @@ char acpi_init(void* rsdp_p){
}
char acpi_load_rsdt(){
PAGE_ID_MAP(rsdp.rsdt_addr); // Ensure page is accessible
PAGE_MAP(rsdp.rsdt_addr,rsdp.rsdt_addr,PAGING_OPT_DEFAULTS); // Ensure page is accessible
memcpy((void*)rsdp.rsdt_addr, &rsdt, sizeof(rsdt));
rsdt.first_entry_addr_ptr=rsdp.rsdt_addr+36;
if(rsdt.header.signature !=ACPI_RSDT_SIGNATURE){
@ -54,7 +54,7 @@ char acpi_load_madt(){
u32 *addr=(u32*)(rsdt.first_entry_addr_ptr+i*4);
// Load header
ACPI_TABLE_HEADER header;
PAGE_ID_MAP(*addr);
PAGE_MAP(*addr,*addr,PAGING_OPT_DEFAULTS);
memcpy((void*)*addr, &header, sizeof(header));
// Check if it is MADT
if(header.signature==ACPI_MADT_SIGNATURE){

View file

@ -11,11 +11,11 @@ void framebuffer_init(FB_CFG config){
// indeed fb_cfg.location could be to big and
// thus leading to cross u64 size limit while summing it with
// kvar_kernel_vma in paging.cc/hpp
u64 start=0xFFFFFFFFFFFFFFFF - fb_cfg.pitch*fb_cfg.height;
u64 start=0xFFFFFFFFFFFFFFFF - (fb_cfg.pitch*fb_cfg.height);
// Ensure we start writing at the begining of the page since
// start is not necessarly 4096 bytes aligned
start=PAGE(start);
PAGE_RMAP_PHY(start-kvar_kernel_vma,fb_cfg.location, fb_cfg.pitch*fb_cfg.height);
PAGE_RMAP(start,fb_cfg.location, PAGING_OPT_DEFAULTS,fb_cfg.pitch*fb_cfg.height);
fb_cfg.location=start;
}

View file

@ -8,7 +8,7 @@ char memtext_buffer[MEMTEXT_BUFFER_SIZE];
u64 memtext_x=0;
void memtext_init(){
PAGE_RMAP(MEMTEXT_ADDR_LOCATION,8);
PAGE_VIRT_MAP(MEMTEXT_ADDR_LOCATION,PAGING_OPT_DEFAULTS);
u64* p_addr=(u64*)VIRT(MEMTEXT_ADDR_LOCATION);
*p_addr=(u64)memtext_buffer;

View file

@ -1,6 +1,7 @@
#include "vgatext.hpp"
#include "boucane.hpp"
#include "core/paging.hpp"
#define MAX_COL 80
#define MAX_LINE 25
@ -14,7 +15,7 @@ VIDEO_STATE VS={
};
void vgatext_init(){
PAGE_RMAP(0xB8000,4096*2);
PAGE_VIRT_RMAP(0xB8000,PAGING_OPT_DEFAULTS,2);
VS.mem=(u8*)VIRT(0xB8000);
}