Compare commits

..

1 Commits

Author SHA1 Message Date
brice.boisson 3a3795d524 Add: basic scheduler 2023-10-01 00:40:00 +09:00
23 changed files with 104 additions and 106 deletions

View File

@ -11,8 +11,8 @@ install:
bin: bin:
$(MAKE) -C $(LIB) $(MAKE) -C $(LIB)
gcc -c ./app/$(APP).c -Ilibk -Llibk -lk -m32 gcc -c test.c -Ilibk -Llibk -lk -m32
ld -m elf_i386 -Ttext=0x6000000 --entry=main ./$(APP).o -L./libk/ -lk ld -m elf_i386 -Ttext=0x6000000 --entry=main test.o -L./libk/ -lk
objcopy --input binary --output elf32-i386 --binary-architecture i386 --rename-section .data=.rodata,CONTENTS,ALLOC,LOAD,READONLY,DATA a.out myfile.o objcopy --input binary --output elf32-i386 --binary-architecture i386 --rename-section .data=.rodata,CONTENTS,ALLOC,LOAD,READONLY,DATA a.out myfile.o
cp myfile.o $(SOURCEDIR)/myfile.o cp myfile.o $(SOURCEDIR)/myfile.o

View File

@ -5,4 +5,3 @@ GRUBDIR = iso
SOURCEDIR = src SOURCEDIR = src
TARGET = kernel TARGET = kernel
LIB=libk LIB=libk
APP=hello_world

View File

@ -1,10 +0,0 @@
#include <syscall.h>
static char s[] = "Hello from userland!\n";
int main(void)
{
write(1, s, 21);
while (1);
return 0;
}

View File

@ -16,7 +16,6 @@ OBJS = \
paging.o \ paging.o \
elf.o \ elf.o \
myfile.o \ myfile.o \
tools.o \
DEPS = $(OBJS:.o=.d) DEPS = $(OBJS:.o=.d)

View File

@ -19,7 +19,7 @@ int print_variadic(char *msg, va_list args)
write_serial(va_arg(args, char *)); write_serial(va_arg(args, char *));
break; break;
case 'b': case 'b':
write_serial_bin((int) va_arg(args, char *), false); write_serial_bin(va_arg(args, char *), false);
break; break;
case 'c': case 'c':
write_serial_char(va_arg(args, int)); write_serial_char(va_arg(args, int));
@ -36,14 +36,12 @@ int print_variadic(char *msg, va_list args)
msg++; msg++;
} }
} }
return 0;
} }
int debug_info(const char *fnt, char *msg, ...) int debug_info(char *fnt, char *msg, ...)
{ {
write_serial("\033[0;34m[INFO]\033[0m "); write_serial("\033[0;34m[INFO]\033[0m ");
write_serial((char *) fnt); write_serial(fnt);
write_serial("\t: "); write_serial("\t: ");
va_list args; va_list args;
@ -56,10 +54,10 @@ int debug_info(const char *fnt, char *msg, ...)
return 0; return 0;
} }
int debug_warn(const char *fnt, char *msg, ...) int debug_warn(char *fnt, char *msg, ...)
{ {
write_serial("\033[0;33m[WARNING]\033[0m "); write_serial("\033[0;33m[WARNING]\033[0m ");
write_serial((char *) fnt); write_serial(fnt);
write_serial("\t: "); write_serial("\t: ");
va_list args; va_list args;
@ -72,10 +70,10 @@ int debug_warn(const char *fnt, char *msg, ...)
return 0; return 0;
} }
int debug_err(const char *fnt, char *msg, ...) int debug_err(char *fnt, char *msg, ...)
{ {
write_serial("\033[0;31m[ERROR]\033[0m "); write_serial("\033[0;31m[ERROR]\033[0m ");
write_serial((char *) fnt); write_serial(fnt);
write_serial("\t: "); write_serial("\t: ");
va_list args; va_list args;

View File

@ -15,8 +15,8 @@
#define DEBUG_ERR(...) #define DEBUG_ERR(...)
#endif #endif
int debug_info(const char *fnt, char *msg, ...); int debug_info(char *fnt, char *msg, ...);
int debug_warn(const char *fnt, char *msg, ...); int debug_warn(char *fnt, char *msg, ...);
int debug_err(const char *fnt, char *msg, ...); int debug_err(char *fnt, char *msg, ...);
#endif /* DEBUG_H */ #endif /* DEBUG_H */

View File

@ -4,7 +4,6 @@
#include "serial.h" #include "serial.h"
#include "debug.h" #include "debug.h"
#include "paging.h" #include "paging.h"
#include "tools.h"
int load_elf(char *elf_data_start, int uid) int load_elf(char *elf_data_start, int uid)
{ {
@ -30,15 +29,13 @@ int load_elf(char *elf_data_start, int uid)
allocate_new_page(uid, mem << 12); allocate_new_page(uid, mem << 12);
} }
memcpy((void *) elf_header_table->p_vaddr, elf_data_start + elf_header_table->p_offset, elf_header_table->p_filesz); memcpy(elf_header_table->p_vaddr, elf_data_start + elf_header_table->p_offset, elf_header_table->p_filesz);
if (elf_header_table->p_filesz < elf_header_table->p_memsz) if (elf_header_table->p_filesz < elf_header_table->p_memsz)
{ {
for (u32 i = elf_header_table->p_filesz; i < elf_header_table->p_memsz; i++) for (int i = elf_header_table->p_filesz; i < elf_header_table->p_memsz; i++)
elf_header_table->p_vaddr[elf_data_start + elf_header_table->p_offset + i] = 0; elf_header_table->p_vaddr[elf_data_start + elf_header_table->p_offset + i] = 0;
} }
} }
} }
return 0;
} }

View File

@ -48,4 +48,4 @@ enum elf_segment_type {
int load_elf(char *elf_data_start, int uid); int load_elf(char *elf_data_start, int uid);
#endif /* !ELF_H */ #endif ELF_H

View File

@ -8,6 +8,19 @@
#include "tss.h" #include "tss.h"
#include "userland.h" #include "userland.h"
void *memcpy(void *dest, const void *src, size_t n)
{
const char *s = src;
char *d = dest;
for (size_t i = 0; i < n; i++)
{
*d++ = *s++;
}
return dest;
}
struct tss user_land_tss; struct tss user_land_tss;
struct segment_desc_param { struct segment_desc_param {
@ -53,9 +66,8 @@ void init_gdt(void)
{ {
DEBUG_INFO("Initializing GDT"); DEBUG_INFO("Initializing GDT");
u16 gdt_size = sizeof(gdt) / sizeof(struct segdesc);
DEBUG_INFO("GDT BASE ADDRESS: %d", (u32) &kgdtr); DEBUG_INFO("GDT BASE ADDRESS: %d", (u32) &kgdtr);
DEBUG_INFO("GDT LIMIT: %d", gdt_size - 1); DEBUG_INFO("GDT LIMIT: %d", sizeof(gdt) - 1);
kgdtr.limit = sizeof(gdt) - 1; kgdtr.limit = sizeof(gdt) - 1;
kgdtr.base = (u32) gdt; kgdtr.base = (u32) gdt;
@ -90,10 +102,10 @@ void init_gdt(void)
DEBUG_INFO("TSS BASE ADDRESS: %d", (u32) &user_land_tss); DEBUG_INFO("TSS BASE ADDRESS: %d", (u32) &user_land_tss);
gdt[5] = init_descriptor((struct segment_desc_param) { .Limit_1 = sizeof(user_land_tss), gdt[5] = init_descriptor((struct segment_desc_param) { .Limit_1 = sizeof(user_land_tss),
.Base = (u32) &user_land_tss, .Type = 0x09, .S = 0, .DPL = 3, .P = 1, .Base = &user_land_tss, .Type = 0x09, .S = 0, .DPL = 3, .P = 1,
.Limit_2 = 0x00, .AVL = 0, .L = 0, .D_B = 0, .G = 0 }); .Limit_2 = 0x00, .AVL = 0, .L = 0, .D_B = 0, .G = 0 });
for (size_t i = 0; i < gdt_size; i++) for (int i = 0; i < sizeof(gdt) / 8; i++)
{ {
char *ptr = (char *) &gdt[i]; char *ptr = (char *) &gdt[i];
DEBUG_INFO("--------------------"); DEBUG_INFO("--------------------");

View File

@ -27,4 +27,4 @@ struct segdesc {
void init_gdt(void); void init_gdt(void);
void temp_run_process(void); void temp_run_process(void);
#endif /* !GDT_H */ #endif /* !GDT_H */

View File

@ -46,9 +46,8 @@ struct idt_segdesc init_gate(struct interrupt_gate_param param)
descriptor.Type = param.Type | (param.D << 3); descriptor.Type = param.Type | (param.D << 3);
descriptor.Flags = 0; descriptor.Flags |= param.DPL << 1;
descriptor.Flags |= param.DPL << 1; descriptor.Flags |= param.P << 3;
descriptor.Flags |= param.P << 3;
return descriptor; return descriptor;
} }
@ -57,13 +56,12 @@ void init_idt(void)
{ {
DEBUG_INFO("Initializing IDT"); DEBUG_INFO("Initializing IDT");
u16 idt_size = sizeof(idt) / sizeof(struct idt_segdesc);
DEBUG_INFO("IDT BASE ADDRESS: %d", (u32) &kidtr); DEBUG_INFO("IDT BASE ADDRESS: %d", (u32) &kidtr);
DEBUG_INFO("IDT LIMIT: %d", idt_size - 1); DEBUG_INFO("IDT LIMIT: %d", sizeof(idt) - 1);
kidtr.limit = sizeof(idt) - 1; kidtr.limit = sizeof(idt) - 1;
kidtr.base = (u32) idt; kidtr.base = (u32) idt;
for (size_t i = 0; i < idt_size; i++) for (int i = 0; i < sizeof(idt); i++)
{ {
idt[i] = init_gate((struct interrupt_gate_param) { .Offset = (u32) _asm_default_int, .SegSelect = 0x08, idt[i] = init_gate((struct interrupt_gate_param) { .Offset = (u32) _asm_default_int, .SegSelect = 0x08,
.Type = 0x06, .D = 1, .DPL = 0, .P = 1 }); .Type = 0x06, .D = 1, .DPL = 0, .P = 1 });

View File

@ -4,6 +4,7 @@
#include "pic_controler.h" #include "pic_controler.h"
#include "debug.h" #include "debug.h"
#include "syscall.h" #include "syscall.h"
#include "userland.h"
void isr_default_int(void) void isr_default_int(void)
{ {
@ -17,7 +18,15 @@ void isr_page_fault(void)
void isr_clock_int(void) void isr_clock_int(void)
{ {
DEBUG_INFO("Enterring clock interrupt handler."); DEBUG_INFO("Clock interrupt handler.");
for (int i = (userland_data->curent_process + 1) % 128; i != userland_data->curent_process; i = (i + 1) % 128)
{
if (userland_data->active_process[i / 32] & (1 << (i % 32)))
{
switch_to_process(i);
return;
}
}
} }
void isr_kbd_int(void) void isr_kbd_int(void)

View File

@ -18,10 +18,16 @@ void main(void)
{ {
DEBUG_INFO("Entering Main Function"); DEBUG_INFO("Entering Main Function");
char *data_start = (char *) &_binary_a_out_start; char *data_start = &_binary_a_out_start;
char *data_end = _binary_a_out_end;
size_t data_size = (size_t)_binary_a_out_size;
u16 tss = 0x28;
create_process(0, data_start); create_process(0, data_start);
switch_to_process(0); create_process(1, data_start);
userland_data->active_process[0] |= 1 << (1 % 32);
switch_to_ring_3(0);
for (;;) for (;;)
{ {

View File

@ -2,32 +2,33 @@
#include "tss.h" #include "tss.h"
#include "debug.h" #include "debug.h"
#include "userland.h"
void launch_process(u16 tss, int userland_stack, int userland_code, u16 userland_data) void launch_process(u16 tss, int memory_start, int userland_stack, int userland_code, u16 userland_data_seg)
{ {
// Setting DPL and GDT bits // Setting DPL and GDT bits
userland_stack += 3; userland_stack += 3;
userland_code += 3; userland_code += 3;
userland_data += 3; userland_data_seg += 3;
DEBUG_INFO("LAUCHING USER LAND PROCESS"); DEBUG_INFO("LAUCHING USER LAND PROCESS");
asm volatile (" \n \ asm volatile (" \n \
mov %0, %%ax \n \ mov %0, %%ax \n \
ltr %%ax \n \ ltr %%ax \n \
movw %%ss, %1 \n \ movw %%ss, %1 \n \
movl %%esp, %2 \n \ movl %%esp, %2 \n \
movw $0x23, %%ax \n \ movw $0x23, %%ax \n \
movw %%ax, %%ds \n \ movw %%ax, %%ds \n \
movw %%ax, %%es \n \ movw %%ax, %%es \n \
movw %%ax, %%fs \n \ movw %%ax, %%fs \n \
movw %%ax, %%gs \n \ movw %%ax, %%gs \n \
mov %%esp, %%eax \n \ mov %%esp, %%eax \n \
push $0x23 \n \ push $0x23 \n \
push $0x7FFFEFFF \n \ push $0x7FFFEFFF \n \
pushfl \n \ pushfl \n \
push $0x1B \n \ push $0x1B \n \
push $0x6000000 \n \ push $0x6000000 \n \
iret" : "+r" (tss), iret" : "+r" (tss),
"=m" (user_land_tss.ss0), "=m" (user_land_tss.ss0),
"=m" (user_land_tss.esp0)); "=m" (user_land_tss.esp0));

View File

@ -3,6 +3,6 @@
#include <types.h> #include <types.h>
void launch_process(u16 tss, int userland_stack, int userland_code, u16 userland_data); void launch_process(u16 tss, int memory_start, int userland_stack, int userland_code, u16 userland_data);
#endif /* !LAUNCH_PROCESS_H */ #endif /* !LAUNCH_PROCESS_H */

View File

@ -124,7 +124,7 @@ int create_kernel_page(void)
DEBUG_INFO("PAGE_TABLE %d", &page_table[i * 1024]); DEBUG_INFO("PAGE_TABLE %d", &page_table[i * 1024]);
page_dir[i] = create_page_directory_entry((struct page_directory_param) { page_dir[i] = create_page_directory_entry((struct page_directory_param) {
.P = 1, .R_W = 1, .U = 0, .PWT = 0, .PCD = 0, .P = 1, .R_W = 1, .U = 0, .PWT = 0, .PCD = 0,
.A = 0, .PS = 0, .address = (u32) &page_table[i * 1024]}); .A = 0, .PS = 0, .address = &page_table[i * 1024]});
} }
for (int i = NB_KERNEL_PAGE_DIR; i < 1024; i++) for (int i = NB_KERNEL_PAGE_DIR; i < 1024; i++)
@ -193,7 +193,7 @@ int create_new_userland_page(int uid)
DEBUG_INFO("PAGE_TABLE %d", &kernel_page_table[i * 1024]); DEBUG_INFO("PAGE_TABLE %d", &kernel_page_table[i * 1024]);
userland_page_dir[i] = create_page_directory_entry((struct page_directory_param) { userland_page_dir[i] = create_page_directory_entry((struct page_directory_param) {
.P = 1, .R_W = 1, .U = 0, .PWT = 0, .PCD = 0, .P = 1, .R_W = 1, .U = 0, .PWT = 0, .PCD = 0,
.A = 0, .PS = 0, .address = (u32) &kernel_page_table[i * 1024]}); .A = 0, .PS = 0, .address = &kernel_page_table[i * 1024]});
} }
for (int i = 0; i < 1024; i++) for (int i = 0; i < 1024; i++)
@ -208,7 +208,7 @@ int create_new_userland_page(int uid)
userland_page_dir[NB_KERNEL_PAGE_DIR] = create_page_directory_entry((struct page_directory_param) { userland_page_dir[NB_KERNEL_PAGE_DIR] = create_page_directory_entry((struct page_directory_param) {
.P = 1, .R_W = 1, .U = 0, .PWT = 0, .PCD = 0, .P = 1, .R_W = 1, .U = 0, .PWT = 0, .PCD = 0,
.A = 0, .PS = 0, .address = (u32) userland_data->userland_data[uid].page_table}); .A = 0, .PS = 0, .address = userland_data->userland_data[uid].page_table});
for (int i = NB_KERNEL_PAGE_DIR + 1; i < 1024; i++) for (int i = NB_KERNEL_PAGE_DIR + 1; i < 1024; i++)
{ {
@ -216,8 +216,6 @@ int create_new_userland_page(int uid)
.P = 0, .R_W = 0, .U = 0, .PWT = 0, .PCD = 0, .P = 0, .R_W = 0, .U = 0, .PWT = 0, .PCD = 0,
.A = 0, .PS = 0, .address = 0}); .A = 0, .PS = 0, .address = 0});
} }
return 0;
} }
int allocate_new_page(int uid, int address) int allocate_new_page(int uid, int address)
@ -233,7 +231,7 @@ int allocate_new_page(int uid, int address)
// CPU does't use page table when decoding page table, so it need the physical address // CPU does't use page table when decoding page table, so it need the physical address
int new_page_table_real = (int) userland_data->userland_data[uid].page_table[dir_address].address; int new_page_table_real = (int) userland_data->userland_data[uid].page_table[dir_address].address;
DEBUG_INFO("PAGE TABLE REAL ADDRESS %d", new_page_table_real << 12); DEBUG_INFO("PAGE TABLE REAL ADDRESS %d", new_page_table_real << 12);
struct page_table_entry *new_page_table = (struct page_table_entry *) (USERLAND_BASE_ADDRESS + dir_address * 1024 * 4 + table_address * 4); struct page_table_entry *new_page_table = USERLAND_BASE_ADDRESS + dir_address * 1024 * 4 + table_address * 4;
if (userland_page_dir[dir_address].address != 0 && new_page_table->address != 0) if (userland_page_dir[dir_address].address != 0 && new_page_table->address != 0)
clear_page(new_page_table->address); clear_page(new_page_table->address);
@ -252,6 +250,4 @@ int allocate_new_page(int uid, int address)
.P = 1, .R_W = 1, .U = 1, .PWT = 0, .PCD = 0, .P = 1, .R_W = 1, .U = 1, .PWT = 0, .PCD = 0,
.A = 0, .D = 0, .PAT = 0, .G = 0, .A = 0, .D = 0, .PAT = 0, .G = 0,
.address = (avl_address >> 12)}); .address = (avl_address >> 12)});
return 0;
} }

View File

@ -17,7 +17,6 @@ struct page_table_entry {
} __attribute__((packed)); } __attribute__((packed));
int create_kernel_page(void); int create_kernel_page(void);
int create_new_userland_page(int uid);
int allocate_new_page(int uid, int address); int allocate_new_page(int uid, int address);
// extern struct page_directory_entry page_dir[1024]; // extern struct page_directory_entry page_dir[1024];

View File

@ -101,6 +101,8 @@ void pic_init(void)
IRQ_set_mask(i); IRQ_set_mask(i);
} }
DEBUG_INFO("Unmasking IRQ 0 - Clock");
IRQ_clear_mask(0);
DEBUG_INFO("Unmasking IRQ 1 - Keyboard"); DEBUG_INFO("Unmasking IRQ 1 - Keyboard");
IRQ_clear_mask(1); IRQ_clear_mask(1);

View File

@ -20,8 +20,6 @@ int init_serial()
outb(PORT + 3, 0x03); // 8 bits, no parity, one stop bit outb(PORT + 3, 0x03); // 8 bits, no parity, one stop bit
outb(PORT + 2, 0xC7); // Enable FIFO, clear them, with 14-byte threshold outb(PORT + 2, 0xC7); // Enable FIFO, clear them, with 14-byte threshold
outb(PORT + 4, 0x0B); // IRQs enabled, RTS/DSR set outb(PORT + 4, 0x0B); // IRQs enabled, RTS/DSR set
return 0;
} }
int write_serial_nb(int nb, int ln) int write_serial_nb(int nb, int ln)
@ -88,7 +86,7 @@ int write_serial_char(char c)
int write_serial(char * s) int write_serial(char * s)
{ {
for (int i = 0; i < strlen(s); i++) for (size_t i = 0; i < strlen(s); i++)
{ {
while ((inb(PORT + 5) & 0x20) == 0); while ((inb(PORT + 5) & 0x20) == 0);
outb(PORT, s[i]); outb(PORT, s[i]);

View File

@ -1,14 +0,0 @@
#include "tools.h"
void *memcpy(void *dest, const void *src, size_t n)
{
const char *s = src;
char *d = dest;
for (size_t i = 0; i < n; i++)
{
*d++ = *s++;
}
return dest;
}

View File

@ -1,8 +0,0 @@
#ifndef TOOLS_H
#define TOOLS_H
#include <types.h>
void *memcpy(void *dest, const void *src, size_t n);
#endif /* !TOOLS_H */

View File

@ -2,10 +2,9 @@
#include "debug.h" #include "debug.h"
#include "paging.h" #include "paging.h"
#include "elf.h"
#include "launch_process.h" #include "launch_process.h"
struct userlands_data *userland_data = (struct userlands_data *) 0x3020000; struct userlands_data *userland_data = 0x3020000;
int create_process(int uid, char *data_start) int create_process(int uid, char *data_start)
{ {
@ -31,6 +30,21 @@ int create_process(int uid, char *data_start)
return 0; return 0;
} }
int switch_to_ring_3(int uid){
DEBUG_INFO("SWITCHING TO RING 3");
void *process_page_dir_adress = userland_data->userland_data[uid].page_directories;
// load cr3
asm volatile (" \
mov %0, %%eax \n \
mov %%eax, %%cr3" : "+r" (process_page_dir_adress));
userland_data->curent_process = uid;
userland_data->active_process[uid / 32] |= 1 << (uid % 32);
launch_process(0x28, 0x6000000, 0x20, 0x18, 0x20);
}
int switch_to_process(int uid) int switch_to_process(int uid)
{ {
DEBUG_INFO("SWITCHING TO PROCESS"); DEBUG_INFO("SWITCHING TO PROCESS");
@ -41,8 +55,8 @@ int switch_to_process(int uid)
mov %0, %%eax \n \ mov %0, %%eax \n \
mov %%eax, %%cr3" : "+r" (process_page_dir_adress)); mov %%eax, %%cr3" : "+r" (process_page_dir_adress));
// TODO : once data by process has been implemented, load the right one userland_data->curent_process = uid;
launch_process(0x28, 0x20, 0x18, 0x20); userland_data->active_process[uid / 32] |= 1 << (uid % 32);
return 0; return 0;
} }

View File

@ -10,17 +10,19 @@ struct userland_data
{ {
struct page_directory_entry page_directories[1024]; struct page_directory_entry page_directories[1024];
struct page_table_entry page_table[1024]; struct page_table_entry page_table[1024];
}; } __attribute__((packed));
struct userlands_data { struct userlands_data {
struct userland_data userland_data[128]; struct userland_data userland_data[128];
u32 page_dir[4]; int curent_process;
}; u32 active_process[4];
} __attribute__((packed));
extern struct userlands_data *userland_data; extern struct userlands_data *userland_data;
int create_process(int uid, char *data_start); int create_process(int uid, char *data_start);
int switch_to_ring_3(int uid);
int switch_to_process(int uid); int switch_to_process(int uid);
#endif /* !USERLAND_H */ #endif /* !USERLAND_H */