commit
917988e871
10
Makefile
10
Makefile
|
@ -1,6 +1,6 @@
|
|||
include Makefile.common
|
||||
|
||||
all: k.iso
|
||||
all: bin k.iso
|
||||
|
||||
k.iso: install
|
||||
./tools/create_iso.sh
|
||||
|
@ -9,8 +9,16 @@ install:
|
|||
mkdir -p $(GRUBDIR)
|
||||
$(MAKE) -C $(SOURCEDIR) $@
|
||||
|
||||
bin:
|
||||
$(MAKE) -C $(LIB)
|
||||
gcc -c test.c -Ilibk -Llibk -lk -m32
|
||||
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
|
||||
cp myfile.o $(SOURCEDIR)/myfile.o
|
||||
|
||||
clean:
|
||||
$(MAKE) -C $(SOURCEDIR) $@
|
||||
$(MAKE) -C $(LIB) $@
|
||||
$(RM) kernel.iso
|
||||
$(RM) -r iso
|
||||
|
||||
|
|
|
@ -4,3 +4,4 @@ ASFLAGS = -m32
|
|||
GRUBDIR = iso
|
||||
SOURCEDIR = src
|
||||
TARGET = kernel
|
||||
LIB=libk
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
include ../Makefile.common
|
||||
|
||||
|
||||
OBJS = \
|
||||
syscall.o \
|
||||
|
||||
DEPS = $(OBJS:.o=.d)
|
||||
|
||||
CPPFLAGS += -MMD -Iinclude
|
||||
CFLAGS += $(K_EXTRA_CFLAGS) -g -nostdlib
|
||||
LDFLAGS += -Wl,-Tkernel.lds
|
||||
LDLIBS =
|
||||
|
||||
all: $(TARGET)
|
||||
ar -rcs $(LIB).a *.o
|
||||
|
||||
$(TARGET): $(OBJS)
|
||||
|
||||
clean:
|
||||
$(RM) $(OBJS) $(DEPS) $(TARGET) $(LIB).a
|
|
@ -0,0 +1,27 @@
|
|||
#include "syscall.h"
|
||||
|
||||
int __syscall(int num, void *a0, void *a1, void *a2, void *a3, void *a4)
|
||||
{
|
||||
int ret;
|
||||
asm volatile(" \n \
|
||||
mov %1, %%eax; \n \
|
||||
mov %2, %%ebx; \n \
|
||||
mov %3, %%ecx; \n \
|
||||
mov %4, %%edx; \n \
|
||||
mov %5, %%edi; \n \
|
||||
mov %6, %%esi; \n \
|
||||
int $48; \n \
|
||||
mov %%eax, %0" : "=m" (ret),
|
||||
"+m" (num),
|
||||
"+m" (a0),
|
||||
"+m" (a1),
|
||||
"+m" (a2),
|
||||
"+m" (a3),
|
||||
"+m" (a4));
|
||||
return ret;
|
||||
}
|
||||
|
||||
int write(int fd, char *buf, int count)
|
||||
{
|
||||
return __syscall(1, (void *) fd, (void *) buf, (void *) count, (void *) 0, (void *) 0);
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
#ifndef SYSCALL_H
|
||||
#define SYSCALL_H
|
||||
|
||||
int __syscall(int num, void *a0, void *a1, void *a2, void *a3, void *a4);
|
||||
int write(int fd, char *buf, int count);
|
||||
|
||||
#endif /* !SYSCALL_H */
|
|
@ -14,6 +14,8 @@ OBJS = \
|
|||
userland.o \
|
||||
launch_process.o \
|
||||
paging.o \
|
||||
elf.o \
|
||||
myfile.o \
|
||||
|
||||
DEPS = $(OBJS:.o=.d)
|
||||
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
#include "elf.h"
|
||||
|
||||
#include <types.h>
|
||||
#include "serial.h"
|
||||
#include "debug.h"
|
||||
#include "paging.h"
|
||||
|
||||
int load_elf(char *elf_data_start, int uid)
|
||||
{
|
||||
DEBUG_INFO("LOAD ELF: ", elf_data_start);
|
||||
|
||||
struct elf_header *elf_header = (struct elf_header *) elf_data_start;
|
||||
|
||||
DEBUG_INFO("ELF ENTRY POINT: %d", elf_header->entry_point);
|
||||
DEBUG_INFO("PROGRAM HEADER ENTRY POINT: %d", elf_header->program_header_table_offset);
|
||||
DEBUG_INFO("NUMBER PROGRAM HEADER ENTRY: %d", elf_header->number_of_program_header_table_entries);
|
||||
|
||||
for (int i = 0; i < elf_header->number_of_program_header_table_entries; i++)
|
||||
{
|
||||
struct elf_header_table *elf_header_table = (struct elf_header_table *) (elf_data_start + elf_header->program_header_table_offset + sizeof(struct elf_header_table) * i);
|
||||
u32 segment_type = elf_header_table->segment_type;
|
||||
|
||||
DEBUG_INFO("ELF type : %d", segment_type == LOAD);
|
||||
if (segment_type == LOAD && elf_header_table->p_vaddr >= 0x6000000)
|
||||
{
|
||||
for (u32 mem = (elf_header_table->p_vaddr >> 12); mem < ((elf_header_table->p_vaddr + elf_header_table->p_filesz) >> 12) + 1; mem += 1)
|
||||
{
|
||||
DEBUG_INFO("ELF ALLOCATE %d: ", mem << 12);
|
||||
allocate_new_page(uid, mem << 12);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
#ifndef ELF_H
|
||||
#define ELF_H
|
||||
|
||||
#include <types.h>
|
||||
|
||||
struct elf_header
|
||||
{
|
||||
u32 magic_number;
|
||||
u8 bus_size;
|
||||
u8 endianess;
|
||||
u8 elf_header_version;
|
||||
u8 os_abi;
|
||||
u32 unused[2];
|
||||
u16 type;
|
||||
u16 isa;
|
||||
u32 elf_version;
|
||||
u32 entry_point;
|
||||
u32 program_header_table_offset;
|
||||
u32 section_header_table_offset;
|
||||
u32 flags;
|
||||
u16 header_size;
|
||||
u16 program_header_table_entry_size;
|
||||
u16 number_of_program_header_table_entries;
|
||||
u16 size_of_program_header_table_entries;
|
||||
u16 number_of_section_header_table_entries;
|
||||
u16 index_section_header_table_with_section_names;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct elf_header_table
|
||||
{
|
||||
u32 segment_type;
|
||||
u32 p_offset;
|
||||
u32 p_vaddr;
|
||||
u32 undefined;
|
||||
u32 p_filesz;
|
||||
u32 p_memsz;
|
||||
u32 flags;
|
||||
u32 alignment;
|
||||
} __attribute__((packed));
|
||||
|
||||
enum elf_segment_type {
|
||||
NULL = 0,
|
||||
LOAD = 1,
|
||||
DYNAMIC = 2,
|
||||
INTERP = 3,
|
||||
NOTE = 4
|
||||
};
|
||||
|
||||
int load_elf(char *elf_data_start, int uid);
|
||||
|
||||
#endif ELF_H
|
|
@ -14,7 +14,9 @@ void *memcpy(void *dest, const void *src, size_t n)
|
|||
char *d = dest;
|
||||
|
||||
for (size_t i = 0; i < n; i++)
|
||||
{
|
||||
*d++ = *s++;
|
||||
}
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
@ -69,8 +71,6 @@ void init_gdt(void)
|
|||
kgdtr.limit = sizeof(gdt) - 1;
|
||||
kgdtr.base = (u32) gdt;
|
||||
|
||||
memcpy((char*) 0x30000, &userland, 1000);
|
||||
|
||||
gdt[0] = init_descriptor((struct segment_desc_param) { .Limit_1 = 0,
|
||||
.Base = 0, .Type = 0, .S = 0, .DPL = 0, .P = 0,
|
||||
.Limit_2 = 0, .AVL = 0, .L = 0, .D_B = 0, .G = 0 });
|
||||
|
|
|
@ -67,6 +67,9 @@ void init_idt(void)
|
|||
.Type = 0x06, .D = 1, .DPL = 0, .P = 1 });
|
||||
}
|
||||
|
||||
idt[14] = init_gate((struct interrupt_gate_param) { .Offset = (u32) _asm_page_fault, .SegSelect = 0x08,
|
||||
.Type = 0x06, .D = 1, .DPL = 0, .P = 1 });
|
||||
|
||||
idt[32] = init_gate((struct interrupt_gate_param) { .Offset = (u32) _asm_irq_0, .SegSelect = 0x08,
|
||||
.Type = 0x06, .D = 1, .DPL = 0, .P = 1 });
|
||||
|
||||
|
|
32
src/int.S
32
src/int.S
|
@ -1,5 +1,5 @@
|
|||
.extern isr_default_int, isr_clock_int, isr_kbd_int, syscall_handler
|
||||
.global _asm_default_int, _asm_irq_0, _asm_irq_1, _asm_sycall_handler
|
||||
.extern isr_default_int, isr_clock_int, isr_kbd_int, syscall_handler, isr_page_fault
|
||||
.global _asm_default_int, _asm_irq_0, _asm_irq_1, _asm_sycall_handler, _asm_page_fault
|
||||
|
||||
_asm_default_int:
|
||||
pushal
|
||||
|
@ -19,6 +19,24 @@ _asm_default_int:
|
|||
popal
|
||||
iret
|
||||
|
||||
_asm_page_fault:
|
||||
pushal
|
||||
push %ds
|
||||
push %es
|
||||
push %fs
|
||||
push %gs
|
||||
push %ebx
|
||||
mov $0x10,%bx
|
||||
mov %bx,%ds
|
||||
pop %ebx
|
||||
call isr_page_fault
|
||||
pop %gs
|
||||
pop %fs
|
||||
pop %es
|
||||
pop %ds
|
||||
popal
|
||||
iret
|
||||
|
||||
_asm_irq_0:
|
||||
pushal
|
||||
push %ds
|
||||
|
@ -64,16 +82,24 @@ _asm_sycall_handler:
|
|||
push %ds
|
||||
push %es
|
||||
push %fs
|
||||
push %gs
|
||||
push %gs
|
||||
push %ebx
|
||||
mov $0x10,%bx
|
||||
mov %bx,%ds
|
||||
pop %ebx
|
||||
push %esi
|
||||
push %edi
|
||||
push %edx
|
||||
push %ecx
|
||||
push %ebx
|
||||
push %eax
|
||||
call syscall_handler
|
||||
pop %ebx
|
||||
pop %ebx
|
||||
pop %ecx
|
||||
pop %edx
|
||||
pop %edi
|
||||
pop %esi
|
||||
pop %gs
|
||||
pop %fs
|
||||
pop %es
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#define INT_H
|
||||
|
||||
void _asm_default_int(void);
|
||||
void _asm_page_fault(void);
|
||||
void _asm_irq_0(void);
|
||||
void _asm_irq_1(void);
|
||||
int _asm_sycall_handler(int eax, int ebx);
|
||||
|
|
18
src/isr.c
18
src/isr.c
|
@ -7,7 +7,12 @@
|
|||
|
||||
void isr_default_int(void)
|
||||
{
|
||||
DEBUG_INFO("An INT has been raised, entering default interrupt handler.");
|
||||
// DEBUG_INFO("An INT has been raised, entering default interrupt handler.");
|
||||
}
|
||||
|
||||
void isr_page_fault(void)
|
||||
{
|
||||
DEBUG_INFO("A page fault exception occured");
|
||||
}
|
||||
|
||||
void isr_clock_int(void)
|
||||
|
@ -23,16 +28,17 @@ void isr_kbd_int(void)
|
|||
DEBUG_INFO("Keyboard input: %d", x);
|
||||
}
|
||||
|
||||
void syscall_handler(int eax, int ebx)
|
||||
int syscall_handler(int eax, void *ebx, void *ecx, void *edx, void *edi, void *esi)
|
||||
{
|
||||
DEBUG_INFO("Syscall %d has been called from the userland with parameter %d", eax, ebx);
|
||||
DEBUG_INFO("Syscall %d has been called from the userland with parameters: %d, %d, %d, %d, %d", eax, ebx, ecx, edx, edi, esi);
|
||||
|
||||
switch (eax)
|
||||
{
|
||||
case 1:
|
||||
char t = *((char *) ebx);
|
||||
DEBUG_INFO("Syscall write : %d", (int) t);
|
||||
return write(1, (u32) ebx);
|
||||
int fd = (int) ebx;
|
||||
char *buf = (char *) ecx;
|
||||
int size = (int) edx;
|
||||
return write(fd, buf, size);
|
||||
break;
|
||||
case 2:
|
||||
DEBUG_INFO("Syscall keyboard");
|
||||
|
|
18
src/kernel.c
18
src/kernel.c
|
@ -7,12 +7,23 @@
|
|||
#include "debug.h"
|
||||
#include "tss.h"
|
||||
#include "launch_process.h"
|
||||
#include "elf.h"
|
||||
#include "userland.h"
|
||||
|
||||
extern char _binary_a_out_start[];
|
||||
extern char _binary_a_out_end[];
|
||||
extern char _binary_a_out_size[];
|
||||
|
||||
void main(void)
|
||||
{
|
||||
DEBUG_INFO("Entering Main Function");
|
||||
DEBUG_INFO("Entering Main Function");
|
||||
|
||||
launch_process(0x28, 0x30000, 0x20, 0x18, 0x20);
|
||||
char *data_start = &_binary_a_out_start;
|
||||
char *data_end = _binary_a_out_end;
|
||||
size_t data_size = (size_t)_binary_a_out_size;
|
||||
|
||||
create_process(0, data_start);
|
||||
switch_to_process(0);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
|
@ -23,7 +34,6 @@ void main(void)
|
|||
|
||||
void kernel_main(void)
|
||||
{
|
||||
|
||||
init_serial();
|
||||
|
||||
DEBUG_INFO("Starting kernel");
|
||||
|
@ -31,7 +41,7 @@ void kernel_main(void)
|
|||
init_gdt();
|
||||
init_idt();
|
||||
pic_init();
|
||||
make_page();
|
||||
create_kernel_page();
|
||||
asm volatile ("sti");
|
||||
|
||||
main();
|
||||
|
|
|
@ -3,21 +3,20 @@ OUTPUT_FORMAT("elf32-i386")
|
|||
|
||||
SECTIONS
|
||||
{
|
||||
.text : ALIGN(CONSTANT(MAXPAGESIZE)) {
|
||||
_TEXT_START_ = .;
|
||||
*(.multiboot) *(.text)
|
||||
_TEXT_END_ = .;
|
||||
}
|
||||
.text : ALIGN(CONSTANT(MAXPAGESIZE)) {
|
||||
_TEXT_START_ = .;
|
||||
*(.multiboot) *(.text)
|
||||
_TEXT_END_ = .;
|
||||
}
|
||||
|
||||
.data : ALIGN(CONSTANT(MAXPAGESIZE)) {
|
||||
_DATA_START_ = .;
|
||||
*(.data)
|
||||
_DATA_END_ = .;
|
||||
}
|
||||
.data : ALIGN(CONSTANT(MAXPAGESIZE)) {
|
||||
_DATA_START_ = .;
|
||||
*(.data)
|
||||
}
|
||||
|
||||
.bss : ALIGN(CONSTANT(MAXPAGESIZE)) {
|
||||
_BSS_START_ = .;
|
||||
*(.bss)
|
||||
_BSS_END_ = .;
|
||||
}
|
||||
.bss : ALIGN(CONSTANT(MAXPAGESIZE)) {
|
||||
_BSS_START_ = .;
|
||||
*(.bss)
|
||||
_BSS_END_ = .;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
#include "tss.h"
|
||||
#include "debug.h"
|
||||
|
||||
void launch_process(int tss, int memory_start, int userland_stack, int userland_code, int userland_data)
|
||||
void launch_process(u16 tss, int memory_start, int userland_stack, int userland_code, u16 userland_data)
|
||||
{
|
||||
// Setting DPL and GDT bits
|
||||
userland_stack += 3;
|
||||
|
@ -13,29 +13,22 @@ void launch_process(int tss, int memory_start, int userland_stack, int userland_
|
|||
DEBUG_INFO("LAUCHING USER LAND PROCESS");
|
||||
|
||||
asm volatile (" \n \
|
||||
movw %0, %%ax \n \
|
||||
mov %0, %%ax \n \
|
||||
ltr %%ax \n \
|
||||
movw %%ss, %1 \n \
|
||||
movl %%esp, %2 \n \
|
||||
cli \n \
|
||||
push %3 \n \
|
||||
push %4 \n \
|
||||
pushfl \n \
|
||||
popl %%eax \n \
|
||||
orl $0x200, %%eax \n \
|
||||
and $0xffffbfff, %%eax \n \
|
||||
push %%eax \n \
|
||||
push %5 \n \
|
||||
push $0x30000 \n \
|
||||
movl $0x20000, %6 \n \
|
||||
movw %7, %%ax \n \
|
||||
movw $0x23, %%ax \n \
|
||||
movw %%ax, %%ds \n \
|
||||
iret" : "=m" (tss),
|
||||
movw %%ax, %%es \n \
|
||||
movw %%ax, %%fs \n \
|
||||
movw %%ax, %%gs \n \
|
||||
mov %%esp, %%eax \n \
|
||||
push $0x23 \n \
|
||||
push $0x7FFFEFFF \n \
|
||||
pushfl \n \
|
||||
push $0x1B \n \
|
||||
push $0x6000000 \n \
|
||||
iret" : "+r" (tss),
|
||||
"=m" (user_land_tss.ss0),
|
||||
"=m" (user_land_tss.esp0),
|
||||
"=m" (userland_stack),
|
||||
"=m" (memory_start),
|
||||
"=m" (userland_code),
|
||||
"=m" (user_land_tss.esp0),
|
||||
"=m" (userland_data));
|
||||
"=m" (user_land_tss.esp0));
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#ifndef LAUNCH_PROCESS_H
|
||||
#define LAUNCH_PROCESS_H
|
||||
|
||||
void launch_process(int tss, int memory_start, int userland_stack, int userland_code, int userland_data);
|
||||
#include <types.h>
|
||||
|
||||
void launch_process(u16 tss, int memory_start, int userland_stack, int userland_code, u16 userland_data);
|
||||
|
||||
#endif /* !LAUNCH_PROCESS_H */
|
136
src/paging.c
136
src/paging.c
|
@ -2,9 +2,43 @@
|
|||
|
||||
#include "debug.h"
|
||||
#include "serial.h"
|
||||
#include "userland.h"
|
||||
|
||||
struct page_directory_entry *page_dir = 0x2000; //__attribute__((aligned(4096)));
|
||||
struct page_table_entry *page_table = 0x3000; //__attribute__((aligned(4096)));
|
||||
struct page_directory_entry *page_dir; // = 0x3000000; //__attribute__((aligned(4096)));
|
||||
struct page_table_entry *page_table; // = 0x3010000; //__attribute__((aligned(4096)));
|
||||
u8 page_avl[131072] = {0};
|
||||
int page_avl_index = (USERLAND_BASE_ADDRESS >> 12) / 8;
|
||||
int userland_page_dir_index = 0;
|
||||
|
||||
#define KERNEL_PAGE_DIR 0x3000000
|
||||
#define KERNEL_PAGE_TABLE 0x3010000
|
||||
#define NB_KERNEL_PAGE_DIR 20
|
||||
|
||||
int find_page_avl(void)
|
||||
{
|
||||
for (int i = page_avl_index; i < 131071; i++) {
|
||||
for (int j = 0; j < 8; j++) {
|
||||
if ((page_avl[i] & (1 << j)) == 0) {
|
||||
page_avl_index = i;
|
||||
return (i * 8 + j) << 12;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO : Add memory deallocation policies
|
||||
return -1;
|
||||
}
|
||||
|
||||
void set_page(int address)
|
||||
{
|
||||
page_avl[(address >> 12) / 8] |= (1 << ((address >> 12) % 8));
|
||||
}
|
||||
|
||||
void clear_page(int address)
|
||||
{
|
||||
page_avl[(address >> 12) / 8] |= (1 << ((address >> 12) % 8));
|
||||
page_avl[(address >> 12) / 8] ^= (1 << ((address >> 12) % 8));
|
||||
}
|
||||
|
||||
struct page_directory_param {
|
||||
u8 P;
|
||||
|
@ -73,21 +107,27 @@ struct page_table_entry create_page_table_entry(struct page_table_param param)
|
|||
return page_table;
|
||||
}
|
||||
|
||||
int make_page(void)
|
||||
int create_kernel_page(void)
|
||||
{
|
||||
for (int i = 0; i < 1024; i++)
|
||||
page_dir = (struct page_directory_entry *) KERNEL_PAGE_DIR;
|
||||
page_table = (struct page_table_entry *) KERNEL_PAGE_TABLE;
|
||||
|
||||
for (int i = 0; i < NB_KERNEL_PAGE_DIR; i++)
|
||||
{
|
||||
page_table[i] = create_page_table_entry((struct page_table_param) {
|
||||
.P = 1, .R_W = 1, .U = 1, .PWT = 0, .PCD = 0,
|
||||
.A = 0, .D = 0, .PAT = 0, .G = 0,
|
||||
.address = 1 * i});
|
||||
for (int j = 0; j < 1024; j++)
|
||||
{
|
||||
page_table[i * 1024 + j] = create_page_table_entry((struct page_table_param) {
|
||||
.P = 1, .R_W = 1, .U = 0, .PWT = 0, .PCD = 0,
|
||||
.A = 0, .D = 0, .PAT = 0, .G = 0,
|
||||
.address = j + i * 1024});
|
||||
}
|
||||
DEBUG_INFO("PAGE_TABLE %d", &page_table[i * 1024]);
|
||||
page_dir[i] = create_page_directory_entry((struct page_directory_param) {
|
||||
.P = 1, .R_W = 1, .U = 0, .PWT = 0, .PCD = 0,
|
||||
.A = 0, .PS = 0, .address = &page_table[i * 1024]});
|
||||
}
|
||||
|
||||
page_dir[0] = create_page_directory_entry((struct page_directory_param) {
|
||||
.P = 1, .R_W = 1, .U = 1, .PWT = 0, .PCD = 0,
|
||||
.A = 0, .PS = 0, .address = page_table});
|
||||
|
||||
for (int i = 1; i < 1024; i++)
|
||||
for (int i = NB_KERNEL_PAGE_DIR; i < 1024; i++)
|
||||
{
|
||||
page_dir[i] = create_page_directory_entry((struct page_directory_param) {
|
||||
.P = 0, .R_W = 0, .U = 0, .PWT = 0, .PCD = 0,
|
||||
|
@ -132,6 +172,7 @@ int make_page(void)
|
|||
DEBUG_INFO("address of Page Directory Array: %d", page_dir);
|
||||
DEBUG_INFO("address of the first Page Table array: %d", page_table);
|
||||
|
||||
// load page directory and enable paging (cr0 bit 31)
|
||||
asm volatile (" \
|
||||
mov %0, %%eax \n \
|
||||
mov %%eax, %%cr3 \n \
|
||||
|
@ -141,3 +182,72 @@ int make_page(void)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int create_new_userland_page(int uid)
|
||||
{
|
||||
struct page_directory_entry *userland_page_dir = userland_data->userland_data[uid].page_directories;
|
||||
struct page_table_entry *kernel_page_table = (struct page_table_entry *) KERNEL_PAGE_TABLE;
|
||||
|
||||
for (int i = 0; i < NB_KERNEL_PAGE_DIR; i++)
|
||||
{
|
||||
DEBUG_INFO("PAGE_TABLE %d", &kernel_page_table[i * 1024]);
|
||||
userland_page_dir[i] = create_page_directory_entry((struct page_directory_param) {
|
||||
.P = 1, .R_W = 1, .U = 0, .PWT = 0, .PCD = 0,
|
||||
.A = 0, .PS = 0, .address = &kernel_page_table[i * 1024]});
|
||||
}
|
||||
|
||||
for (int i = 0; i < 1024; i++)
|
||||
{
|
||||
int avl_address = find_page_avl();
|
||||
set_page(avl_address);
|
||||
userland_data->userland_data[uid].page_table[i] = create_page_table_entry((struct page_table_param) {
|
||||
.P = 1, .R_W = 1, .U = 0, .PWT = 0, .PCD = 0,
|
||||
.A = 0, .D = 0, .PAT = 0, .G = 0,
|
||||
.address = (avl_address >> 12)});
|
||||
}
|
||||
|
||||
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,
|
||||
.A = 0, .PS = 0, .address = userland_data->userland_data[uid].page_table});
|
||||
|
||||
for (int i = NB_KERNEL_PAGE_DIR + 1; i < 1024; i++)
|
||||
{
|
||||
userland_page_dir[i] = create_page_directory_entry((struct page_directory_param) {
|
||||
.P = 0, .R_W = 0, .U = 0, .PWT = 0, .PCD = 0,
|
||||
.A = 0, .PS = 0, .address = 0});
|
||||
}
|
||||
}
|
||||
|
||||
int allocate_new_page(int uid, int address)
|
||||
{
|
||||
struct page_directory_entry *userland_page_dir = userland_data->userland_data[uid].page_directories;
|
||||
|
||||
int dir_address = address >> 22;
|
||||
int table_address = (address >> 12) ^ ((address >> 22) << 10);
|
||||
|
||||
DEBUG_INFO("dir_address %d", dir_address);
|
||||
DEBUG_INFO("table_address %d", table_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;
|
||||
DEBUG_INFO("PAGE TABLE REAL ADDRESS %d", new_page_table_real << 12);
|
||||
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)
|
||||
clear_page(new_page_table->address);
|
||||
|
||||
if (userland_page_dir[dir_address].address == 0)
|
||||
{
|
||||
DEBUG_INFO("NEW DIR ENTRY");
|
||||
userland_page_dir[dir_address] = create_page_directory_entry((struct page_directory_param) {
|
||||
.P = 1, .R_W = 1, .U = 1, .PWT = 0, .PCD = 0,
|
||||
.A = 0, .PS = 0, .address = new_page_table_real << 12});
|
||||
}
|
||||
|
||||
int avl_address = find_page_avl();
|
||||
set_page(avl_address);
|
||||
*new_page_table = create_page_table_entry((struct page_table_param) {
|
||||
.P = 1, .R_W = 1, .U = 1, .PWT = 0, .PCD = 0,
|
||||
.A = 0, .D = 0, .PAT = 0, .G = 0,
|
||||
.address = (avl_address >> 12)});
|
||||
}
|
||||
|
|
|
@ -16,7 +16,8 @@ struct page_table_entry {
|
|||
u32 address : 20;
|
||||
} __attribute__((packed));
|
||||
|
||||
int make_page(void);
|
||||
int create_kernel_page(void);
|
||||
int allocate_new_page(int uid, int address);
|
||||
|
||||
// extern struct page_directory_entry page_dir[1024];
|
||||
// extern struct page_table_entry page_table[1024];
|
||||
|
|
|
@ -24,6 +24,14 @@ int init_serial()
|
|||
|
||||
int write_serial_nb(int nb, int ln)
|
||||
{
|
||||
if (nb < 0)
|
||||
{
|
||||
while ((inb(PORT + 5) & 0x20) == 0);
|
||||
outb(PORT, '-');
|
||||
write_serial_nb(-nb, ln);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (nb < 10)
|
||||
{
|
||||
while ((inb(PORT + 5) & 0x20) == 0);
|
||||
|
|
|
@ -6,9 +6,9 @@
|
|||
* Syscall handler for write, currently only serial write is supported.
|
||||
* Use the fd 1, to make a serial write.
|
||||
*/
|
||||
int write(int fd, void *buf)
|
||||
int write(int fd, void *buf, int size)
|
||||
{
|
||||
if (fd != 1)
|
||||
if (fd != 1 || size < 0)
|
||||
return -1;
|
||||
|
||||
if (write_serial(buf))
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef SYSCALL_H
|
||||
#define SYSCALL_H
|
||||
|
||||
int write(int fd, void *buf);
|
||||
int write(int fd, void *buf, int size);
|
||||
int keyboard(void);
|
||||
|
||||
#endif /* !SYSCALL_H */
|
|
@ -1,26 +1,45 @@
|
|||
#include "userland.h"
|
||||
|
||||
void userland(void)
|
||||
#include "debug.h"
|
||||
#include "paging.h"
|
||||
#include "launch_process.h"
|
||||
|
||||
struct userlands_data *userland_data = 0x3020000;
|
||||
|
||||
int create_process(int uid, char *data_start)
|
||||
{
|
||||
int res = 0;
|
||||
// asm ("mov $1, %0" : "=r" (res));
|
||||
// asm volatile ("movl $2, %eax; int $0x30");
|
||||
// asm("movl %%eax,%0" : "=r"(res));
|
||||
// asm volatile ("int $0x30");
|
||||
char *str = (void *) 0x30100;
|
||||
str[0] = 'H';
|
||||
str[1] = 'e';
|
||||
str[2] = 'l';
|
||||
str[3] = 'l';
|
||||
str[4] = 'o';
|
||||
str[5] = '\0';
|
||||
asm volatile ("mov $1, %%eax; movl $0x30100, %%ebx; int $0x30; movl %%eax, %1" : "=m" (str), "=r" (res));
|
||||
// asm volatile ("mov $1, %%eax; movl %0, %%ebx; int $0x30" : "=m" (str));
|
||||
// asm ("mov $1, %eax; int $0x30");
|
||||
// asm ("movl %0, %eax; int $0x30" : "=m" (res));
|
||||
// asm ("movl %eax, %eax; int $0x30");
|
||||
// asm ("movl $28, %eax; movl $5, %ebx; int $0x30");
|
||||
// asm ("movl $43, %eax; movl $7, %ebx; int $0x30");
|
||||
while (1);
|
||||
return; /* never go there */
|
||||
}
|
||||
create_new_userland_page(uid);
|
||||
|
||||
DEBUG_INFO("CREATE PROCESS");
|
||||
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));
|
||||
|
||||
// Allocate stack
|
||||
allocate_new_page(uid, 0x7FFFF000);
|
||||
allocate_new_page(uid, 0x7FFFE000);
|
||||
allocate_new_page(uid, 0x7FFFD000);
|
||||
|
||||
// TODO : create data seg by process
|
||||
// load elf
|
||||
load_elf(data_start, uid);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int switch_to_process(int uid)
|
||||
{
|
||||
DEBUG_INFO("SWITCHING TO PROCESS");
|
||||
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));
|
||||
|
||||
// TODO : once data by process has been implemented, load the right one
|
||||
launch_process(0x28, 0x6000000, 0x20, 0x18, 0x20);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,26 @@
|
|||
#ifndef USERLAND_H
|
||||
#define USERLAND_H
|
||||
|
||||
void userland(void);
|
||||
#include <types.h>
|
||||
#include "paging.h"
|
||||
|
||||
#define USERLAND_BASE_ADDRESS 0x5000000
|
||||
|
||||
struct userland_data
|
||||
{
|
||||
struct page_directory_entry page_directories[1024];
|
||||
struct page_table_entry page_table[1024];
|
||||
};
|
||||
|
||||
|
||||
struct userlands_data {
|
||||
struct userland_data userland_data[128];
|
||||
u32 page_dir[4];
|
||||
};
|
||||
|
||||
extern struct userlands_data *userland_data;
|
||||
|
||||
int create_process(int uid, char *data_start);
|
||||
int switch_to_process(int uid);
|
||||
|
||||
#endif /* !USERLAND_H */
|
||||
|
|
Loading…
Reference in New Issue