Merge pull request #3 from BriceBoisson/brice-elf

Brice elf
This commit is contained in:
BOISSON Brice 2023-09-27 10:39:36 +09:00 committed by GitHub
commit 917988e871
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 449 additions and 94 deletions

View File

@ -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

View File

@ -4,3 +4,4 @@ ASFLAGS = -m32
GRUBDIR = iso
SOURCEDIR = src
TARGET = kernel
LIB=libk

20
libk/Makefile Normal file
View File

@ -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

27
libk/syscall.c Normal file
View File

@ -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);
}

7
libk/syscall.h Normal file
View File

@ -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 */

View File

@ -14,6 +14,8 @@ OBJS = \
userland.o \
launch_process.o \
paging.o \
elf.o \
myfile.o \
DEPS = $(OBJS:.o=.d)

41
src/elf.c Normal file
View File

@ -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;
}
}
}
}

51
src/elf.h Normal file
View File

@ -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

View File

@ -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 });

View File

@ -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 });

View File

@ -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

View File

@ -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);

View File

@ -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");

View File

@ -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();

View File

@ -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_ = .;
}
}

View File

@ -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));
}

View File

@ -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 */

View File

@ -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)});
}

View File

@ -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];

View File

@ -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);

View File

@ -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))

View File

@ -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 */

View File

@ -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);
}

View File

@ -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 */