Compare commits
12 Commits
brice-pagi
...
main
Author | SHA1 | Date |
---|---|---|
brice.boisson | 5492a13018 | |
brice.boisson | 37dbb99f50 | |
BOISSON Brice | 917988e871 | |
brice.boisson | 633decc0af | |
brice.boisson | 62837e9c44 | |
brice.boisson | edb93e3967 | |
brice.boisson | 4339d5e349 | |
brice.boisson | df52b4aca2 | |
brice.boisson | 76dd8867e0 | |
BOISSON Brice | 883afe0753 | |
BOISSON Brice | 37a2be9c6c | |
BOISSON Brice | 8e9de58df5 |
10
Makefile
10
Makefile
|
@ -1,6 +1,6 @@
|
||||||
include Makefile.common
|
include Makefile.common
|
||||||
|
|
||||||
all: k.iso
|
all: bin k.iso
|
||||||
|
|
||||||
k.iso: install
|
k.iso: install
|
||||||
./tools/create_iso.sh
|
./tools/create_iso.sh
|
||||||
|
@ -9,8 +9,16 @@ install:
|
||||||
mkdir -p $(GRUBDIR)
|
mkdir -p $(GRUBDIR)
|
||||||
$(MAKE) -C $(SOURCEDIR) $@
|
$(MAKE) -C $(SOURCEDIR) $@
|
||||||
|
|
||||||
|
bin:
|
||||||
|
$(MAKE) -C $(LIB)
|
||||||
|
gcc -c ./app/$(APP).c -Ilibk -Llibk -lk -m32
|
||||||
|
ld -m elf_i386 -Ttext=0x6000000 --entry=main ./$(APP).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:
|
clean:
|
||||||
$(MAKE) -C $(SOURCEDIR) $@
|
$(MAKE) -C $(SOURCEDIR) $@
|
||||||
|
$(MAKE) -C $(LIB) $@
|
||||||
$(RM) kernel.iso
|
$(RM) kernel.iso
|
||||||
$(RM) -r iso
|
$(RM) -r iso
|
||||||
|
|
||||||
|
|
|
@ -4,3 +4,5 @@ ASFLAGS = -m32
|
||||||
GRUBDIR = iso
|
GRUBDIR = iso
|
||||||
SOURCEDIR = src
|
SOURCEDIR = src
|
||||||
TARGET = kernel
|
TARGET = kernel
|
||||||
|
LIB=libk
|
||||||
|
APP=hello_world
|
||||||
|
|
|
@ -6,7 +6,9 @@ This kernel is written as a educative project. The goal is to have a kernel able
|
||||||
- [X] Manage IRQ (enable PIC)
|
- [X] Manage IRQ (enable PIC)
|
||||||
- [X] Running and Userland (TSS)
|
- [X] Running and Userland (TSS)
|
||||||
- [X] Let the userland call the kernel (syscall)
|
- [X] Let the userland call the kernel (syscall)
|
||||||
|
- [ ] Use paging
|
||||||
- [ ] Running multiple userland (ordonnanceur)
|
- [ ] Running multiple userland (ordonnanceur)
|
||||||
|
- [ ] Using ext2 File System
|
||||||
- [ ] Running elf binary
|
- [ ] Running elf binary
|
||||||
- [ ] Having a small libc and needed syscall to run the shell
|
- [ ] Having a small libc and needed syscall to run the shell
|
||||||
- [ ] (Bonus) Having a basic visual interface (VGA ?)
|
- [ ] (Bonus) Having a basic visual interface (VGA ?)
|
||||||
|
@ -19,4 +21,4 @@ https://github.com/Galli24/kernel-k-project
|
||||||
- The ressources on the website OSDev:
|
- The ressources on the website OSDev:
|
||||||
https://wiki.osdev.org/Main_Page
|
https://wiki.osdev.org/Main_Page
|
||||||
- The in Intel® 64 and IA-32 Architectures, Software Developer’s Manual, Volume 3A: System Programming Guide, Part 1:
|
- The in Intel® 64 and IA-32 Architectures, Software Developer’s Manual, Volume 3A: System Programming Guide, Part 1:
|
||||||
https://www.intel.com/content/www/us/en/developer/articles/technical/intel-sdm.html
|
https://www.intel.com/content/www/us/en/developer/articles/technical/intel-sdm.html
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
#include <syscall.h>
|
||||||
|
|
||||||
|
static char s[] = "Hello from userland!\n";
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
write(1, s, 21);
|
||||||
|
while (1);
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -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,9 @@ OBJS = \
|
||||||
userland.o \
|
userland.o \
|
||||||
launch_process.o \
|
launch_process.o \
|
||||||
paging.o \
|
paging.o \
|
||||||
|
elf.o \
|
||||||
|
myfile.o \
|
||||||
|
tools.o \
|
||||||
|
|
||||||
DEPS = $(OBJS:.o=.d)
|
DEPS = $(OBJS:.o=.d)
|
||||||
|
|
||||||
|
|
16
src/debug.c
16
src/debug.c
|
@ -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(va_arg(args, char *), false);
|
write_serial_bin((int) 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,12 +36,14 @@ int print_variadic(char *msg, va_list args)
|
||||||
msg++;
|
msg++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int debug_info(char *fnt, char *msg, ...)
|
int debug_info(const char *fnt, char *msg, ...)
|
||||||
{
|
{
|
||||||
write_serial("\033[0;34m[INFO]\033[0m ");
|
write_serial("\033[0;34m[INFO]\033[0m ");
|
||||||
write_serial(fnt);
|
write_serial((char *) fnt);
|
||||||
write_serial("\t: ");
|
write_serial("\t: ");
|
||||||
|
|
||||||
va_list args;
|
va_list args;
|
||||||
|
@ -54,10 +56,10 @@ int debug_info(char *fnt, char *msg, ...)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int debug_warn(char *fnt, char *msg, ...)
|
int debug_warn(const char *fnt, char *msg, ...)
|
||||||
{
|
{
|
||||||
write_serial("\033[0;33m[WARNING]\033[0m ");
|
write_serial("\033[0;33m[WARNING]\033[0m ");
|
||||||
write_serial(fnt);
|
write_serial((char *) fnt);
|
||||||
write_serial("\t: ");
|
write_serial("\t: ");
|
||||||
|
|
||||||
va_list args;
|
va_list args;
|
||||||
|
@ -70,10 +72,10 @@ int debug_warn(char *fnt, char *msg, ...)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int debug_err(char *fnt, char *msg, ...)
|
int debug_err(const char *fnt, char *msg, ...)
|
||||||
{
|
{
|
||||||
write_serial("\033[0;31m[ERROR]\033[0m ");
|
write_serial("\033[0;31m[ERROR]\033[0m ");
|
||||||
write_serial(fnt);
|
write_serial((char *) fnt);
|
||||||
write_serial("\t: ");
|
write_serial("\t: ");
|
||||||
|
|
||||||
va_list args;
|
va_list args;
|
||||||
|
|
|
@ -15,8 +15,8 @@
|
||||||
#define DEBUG_ERR(...)
|
#define DEBUG_ERR(...)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int debug_info(char *fnt, char *msg, ...);
|
int debug_info(const char *fnt, char *msg, ...);
|
||||||
int debug_warn(char *fnt, char *msg, ...);
|
int debug_warn(const char *fnt, char *msg, ...);
|
||||||
int debug_err(char *fnt, char *msg, ...);
|
int debug_err(const char *fnt, char *msg, ...);
|
||||||
|
|
||||||
#endif /* DEBUG_H */
|
#endif /* DEBUG_H */
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
#include "elf.h"
|
||||||
|
|
||||||
|
#include <types.h>
|
||||||
|
#include "serial.h"
|
||||||
|
#include "debug.h"
|
||||||
|
#include "paging.h"
|
||||||
|
#include "tools.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((void *) 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 (u32 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 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 */
|
20
src/gdt.c
20
src/gdt.c
|
@ -8,17 +8,6 @@
|
||||||
#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 {
|
||||||
|
@ -64,13 +53,12 @@ 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", sizeof(gdt) - 1);
|
DEBUG_INFO("GDT LIMIT: %d", gdt_size - 1);
|
||||||
kgdtr.limit = sizeof(gdt) - 1;
|
kgdtr.limit = sizeof(gdt) - 1;
|
||||||
kgdtr.base = (u32) gdt;
|
kgdtr.base = (u32) gdt;
|
||||||
|
|
||||||
memcpy((char*) 0x30000, &userland, 1000);
|
|
||||||
|
|
||||||
gdt[0] = init_descriptor((struct segment_desc_param) { .Limit_1 = 0,
|
gdt[0] = init_descriptor((struct segment_desc_param) { .Limit_1 = 0,
|
||||||
.Base = 0, .Type = 0, .S = 0, .DPL = 0, .P = 0,
|
.Base = 0, .Type = 0, .S = 0, .DPL = 0, .P = 0,
|
||||||
.Limit_2 = 0, .AVL = 0, .L = 0, .D_B = 0, .G = 0 });
|
.Limit_2 = 0, .AVL = 0, .L = 0, .D_B = 0, .G = 0 });
|
||||||
|
@ -102,10 +90,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 = &user_land_tss, .Type = 0x09, .S = 0, .DPL = 3, .P = 1,
|
.Base = (u32) &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 (int i = 0; i < sizeof(gdt) / 8; i++)
|
for (size_t i = 0; i < gdt_size; i++)
|
||||||
{
|
{
|
||||||
char *ptr = (char *) &gdt[i];
|
char *ptr = (char *) &gdt[i];
|
||||||
DEBUG_INFO("--------------------");
|
DEBUG_INFO("--------------------");
|
||||||
|
|
|
@ -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 */
|
13
src/idt.c
13
src/idt.c
|
@ -46,8 +46,9 @@ 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 |= param.DPL << 1;
|
descriptor.Flags = 0;
|
||||||
descriptor.Flags |= param.P << 3;
|
descriptor.Flags |= param.DPL << 1;
|
||||||
|
descriptor.Flags |= param.P << 3;
|
||||||
|
|
||||||
return descriptor;
|
return descriptor;
|
||||||
}
|
}
|
||||||
|
@ -56,17 +57,21 @@ 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", sizeof(idt) - 1);
|
DEBUG_INFO("IDT LIMIT: %d", idt_size - 1);
|
||||||
kidtr.limit = sizeof(idt) - 1;
|
kidtr.limit = sizeof(idt) - 1;
|
||||||
kidtr.base = (u32) idt;
|
kidtr.base = (u32) idt;
|
||||||
|
|
||||||
for (int i = 0; i < sizeof(idt); i++)
|
for (size_t i = 0; i < idt_size; 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 });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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,
|
idt[32] = init_gate((struct interrupt_gate_param) { .Offset = (u32) _asm_irq_0, .SegSelect = 0x08,
|
||||||
.Type = 0x06, .D = 1, .DPL = 0, .P = 1 });
|
.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
|
.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
|
.global _asm_default_int, _asm_irq_0, _asm_irq_1, _asm_sycall_handler, _asm_page_fault
|
||||||
|
|
||||||
_asm_default_int:
|
_asm_default_int:
|
||||||
pushal
|
pushal
|
||||||
|
@ -19,6 +19,24 @@ _asm_default_int:
|
||||||
popal
|
popal
|
||||||
iret
|
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:
|
_asm_irq_0:
|
||||||
pushal
|
pushal
|
||||||
push %ds
|
push %ds
|
||||||
|
@ -64,16 +82,24 @@ _asm_sycall_handler:
|
||||||
push %ds
|
push %ds
|
||||||
push %es
|
push %es
|
||||||
push %fs
|
push %fs
|
||||||
push %gs
|
push %gs
|
||||||
push %ebx
|
push %ebx
|
||||||
mov $0x10,%bx
|
mov $0x10,%bx
|
||||||
mov %bx,%ds
|
mov %bx,%ds
|
||||||
pop %ebx
|
pop %ebx
|
||||||
|
push %esi
|
||||||
|
push %edi
|
||||||
|
push %edx
|
||||||
|
push %ecx
|
||||||
push %ebx
|
push %ebx
|
||||||
push %eax
|
push %eax
|
||||||
call syscall_handler
|
call syscall_handler
|
||||||
pop %ebx
|
pop %ebx
|
||||||
pop %ebx
|
pop %ebx
|
||||||
|
pop %ecx
|
||||||
|
pop %edx
|
||||||
|
pop %edi
|
||||||
|
pop %esi
|
||||||
pop %gs
|
pop %gs
|
||||||
pop %fs
|
pop %fs
|
||||||
pop %es
|
pop %es
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#define INT_H
|
#define INT_H
|
||||||
|
|
||||||
void _asm_default_int(void);
|
void _asm_default_int(void);
|
||||||
|
void _asm_page_fault(void);
|
||||||
void _asm_irq_0(void);
|
void _asm_irq_0(void);
|
||||||
void _asm_irq_1(void);
|
void _asm_irq_1(void);
|
||||||
int _asm_sycall_handler(int eax, int ebx);
|
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)
|
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)
|
void isr_clock_int(void)
|
||||||
|
@ -23,16 +28,17 @@ void isr_kbd_int(void)
|
||||||
DEBUG_INFO("Keyboard input: %d", x);
|
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)
|
switch (eax)
|
||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
char t = *((char *) ebx);
|
int fd = (int) ebx;
|
||||||
DEBUG_INFO("Syscall write : %d", (int) t);
|
char *buf = (char *) ecx;
|
||||||
return write(1, (u32) ebx);
|
int size = (int) edx;
|
||||||
|
return write(fd, buf, size);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
DEBUG_INFO("Syscall keyboard");
|
DEBUG_INFO("Syscall keyboard");
|
||||||
|
|
16
src/kernel.c
16
src/kernel.c
|
@ -7,12 +7,21 @@
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "tss.h"
|
#include "tss.h"
|
||||||
#include "launch_process.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)
|
void main(void)
|
||||||
{
|
{
|
||||||
DEBUG_INFO("Entering Main Function");
|
DEBUG_INFO("Entering Main Function");
|
||||||
|
|
||||||
launch_process(0x28, 0x30000, 0x20, 0x18, 0x20);
|
char *data_start = (char *) &_binary_a_out_start;
|
||||||
|
|
||||||
|
create_process(0, data_start);
|
||||||
|
switch_to_process(0);
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
|
@ -23,7 +32,6 @@ void main(void)
|
||||||
|
|
||||||
void kernel_main(void)
|
void kernel_main(void)
|
||||||
{
|
{
|
||||||
|
|
||||||
init_serial();
|
init_serial();
|
||||||
|
|
||||||
DEBUG_INFO("Starting kernel");
|
DEBUG_INFO("Starting kernel");
|
||||||
|
@ -31,7 +39,7 @@ void kernel_main(void)
|
||||||
init_gdt();
|
init_gdt();
|
||||||
init_idt();
|
init_idt();
|
||||||
pic_init();
|
pic_init();
|
||||||
make_page();
|
create_kernel_page();
|
||||||
asm volatile ("sti");
|
asm volatile ("sti");
|
||||||
|
|
||||||
main();
|
main();
|
||||||
|
|
|
@ -3,21 +3,20 @@ OUTPUT_FORMAT("elf32-i386")
|
||||||
|
|
||||||
SECTIONS
|
SECTIONS
|
||||||
{
|
{
|
||||||
.text : ALIGN(CONSTANT(MAXPAGESIZE)) {
|
.text : ALIGN(CONSTANT(MAXPAGESIZE)) {
|
||||||
_TEXT_START_ = .;
|
_TEXT_START_ = .;
|
||||||
*(.multiboot) *(.text)
|
*(.multiboot) *(.text)
|
||||||
_TEXT_END_ = .;
|
_TEXT_END_ = .;
|
||||||
}
|
}
|
||||||
|
|
||||||
.data : ALIGN(CONSTANT(MAXPAGESIZE)) {
|
.data : ALIGN(CONSTANT(MAXPAGESIZE)) {
|
||||||
_DATA_START_ = .;
|
_DATA_START_ = .;
|
||||||
*(.data)
|
*(.data)
|
||||||
_DATA_END_ = .;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
.bss : ALIGN(CONSTANT(MAXPAGESIZE)) {
|
.bss : ALIGN(CONSTANT(MAXPAGESIZE)) {
|
||||||
_BSS_START_ = .;
|
_BSS_START_ = .;
|
||||||
*(.bss)
|
*(.bss)
|
||||||
_BSS_END_ = .;
|
_BSS_END_ = .;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
#include "tss.h"
|
#include "tss.h"
|
||||||
#include "debug.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 userland_stack, int userland_code, u16 userland_data)
|
||||||
{
|
{
|
||||||
// Setting DPL and GDT bits
|
// Setting DPL and GDT bits
|
||||||
userland_stack += 3;
|
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");
|
DEBUG_INFO("LAUCHING USER LAND PROCESS");
|
||||||
|
|
||||||
asm volatile (" \n \
|
asm volatile (" \n \
|
||||||
movw %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 \
|
||||||
cli \n \
|
movw $0x23, %%ax \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 %%ax, %%ds \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.ss0),
|
||||||
"=m" (user_land_tss.esp0),
|
"=m" (user_land_tss.esp0));
|
||||||
"=m" (userland_stack),
|
|
||||||
"=m" (memory_start),
|
|
||||||
"=m" (userland_code),
|
|
||||||
"=m" (user_land_tss.esp0),
|
|
||||||
"=m" (userland_data));
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#ifndef LAUNCH_PROCESS_H
|
#ifndef LAUNCH_PROCESS_H
|
||||||
#define 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 userland_stack, int userland_code, u16 userland_data);
|
||||||
|
|
||||||
#endif /* !LAUNCH_PROCESS_H */
|
#endif /* !LAUNCH_PROCESS_H */
|
140
src/paging.c
140
src/paging.c
|
@ -2,9 +2,43 @@
|
||||||
|
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "serial.h"
|
#include "serial.h"
|
||||||
|
#include "userland.h"
|
||||||
|
|
||||||
struct page_directory_entry *page_dir = 0x2000; //__attribute__((aligned(4096)));
|
struct page_directory_entry *page_dir; // = 0x3000000; //__attribute__((aligned(4096)));
|
||||||
struct page_table_entry *page_table = 0x3000; //__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 {
|
struct page_directory_param {
|
||||||
u8 P;
|
u8 P;
|
||||||
|
@ -73,21 +107,27 @@ struct page_table_entry create_page_table_entry(struct page_table_param param)
|
||||||
return page_table;
|
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) {
|
for (int j = 0; j < 1024; j++)
|
||||||
.P = 1, .R_W = 1, .U = 1, .PWT = 0, .PCD = 0,
|
{
|
||||||
.A = 0, .D = 0, .PAT = 0, .G = 0,
|
page_table[i * 1024 + j] = create_page_table_entry((struct page_table_param) {
|
||||||
.address = 1 * i});
|
.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 = (u32) &page_table[i * 1024]});
|
||||||
}
|
}
|
||||||
|
|
||||||
page_dir[0] = create_page_directory_entry((struct page_directory_param) {
|
for (int i = NB_KERNEL_PAGE_DIR; i < 1024; i++)
|
||||||
.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++)
|
|
||||||
{
|
{
|
||||||
page_dir[i] = create_page_directory_entry((struct page_directory_param) {
|
page_dir[i] = create_page_directory_entry((struct page_directory_param) {
|
||||||
.P = 0, .R_W = 0, .U = 0, .PWT = 0, .PCD = 0,
|
.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 Page Directory Array: %d", page_dir);
|
||||||
DEBUG_INFO("address of the first Page Table array: %d", page_table);
|
DEBUG_INFO("address of the first Page Table array: %d", page_table);
|
||||||
|
|
||||||
|
// load page directory and enable paging (cr0 bit 31)
|
||||||
asm volatile (" \
|
asm volatile (" \
|
||||||
mov %0, %%eax \n \
|
mov %0, %%eax \n \
|
||||||
mov %%eax, %%cr3 \n \
|
mov %%eax, %%cr3 \n \
|
||||||
|
@ -141,3 +182,76 @@ int make_page(void)
|
||||||
|
|
||||||
return 0;
|
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 = (u32) &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 = (u32) 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});
|
||||||
|
}
|
||||||
|
|
||||||
|
return 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 = (struct page_table_entry *) (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)});
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -16,7 +16,9 @@ struct page_table_entry {
|
||||||
u32 address : 20;
|
u32 address : 20;
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
int make_page(void);
|
int create_kernel_page(void);
|
||||||
|
int create_new_userland_page(int uid);
|
||||||
|
int allocate_new_page(int uid, int address);
|
||||||
|
|
||||||
// extern struct page_directory_entry page_dir[1024];
|
// extern struct page_directory_entry page_dir[1024];
|
||||||
// extern struct page_table_entry page_table[1024];
|
// extern struct page_table_entry page_table[1024];
|
||||||
|
|
12
src/serial.c
12
src/serial.c
|
@ -20,10 +20,20 @@ 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)
|
||||||
{
|
{
|
||||||
|
if (nb < 0)
|
||||||
|
{
|
||||||
|
while ((inb(PORT + 5) & 0x20) == 0);
|
||||||
|
outb(PORT, '-');
|
||||||
|
write_serial_nb(-nb, ln);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (nb < 10)
|
if (nb < 10)
|
||||||
{
|
{
|
||||||
while ((inb(PORT + 5) & 0x20) == 0);
|
while ((inb(PORT + 5) & 0x20) == 0);
|
||||||
|
@ -78,7 +88,7 @@ int write_serial_char(char c)
|
||||||
|
|
||||||
int write_serial(char * s)
|
int write_serial(char * s)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < strlen(s); i++)
|
for (int 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]);
|
||||||
|
|
|
@ -6,9 +6,9 @@
|
||||||
* Syscall handler for write, currently only serial write is supported.
|
* Syscall handler for write, currently only serial write is supported.
|
||||||
* Use the fd 1, to make a serial write.
|
* 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;
|
return -1;
|
||||||
|
|
||||||
if (write_serial(buf))
|
if (write_serial(buf))
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef SYSCALL_H
|
#ifndef SYSCALL_H
|
||||||
#define SYSCALL_H
|
#define SYSCALL_H
|
||||||
|
|
||||||
int write(int fd, void *buf);
|
int write(int fd, void *buf, int size);
|
||||||
int keyboard(void);
|
int keyboard(void);
|
||||||
|
|
||||||
#endif /* !SYSCALL_H */
|
#endif /* !SYSCALL_H */
|
|
@ -0,0 +1,14 @@
|
||||||
|
#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;
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
#ifndef TOOLS_H
|
||||||
|
#define TOOLS_H
|
||||||
|
|
||||||
|
#include <types.h>
|
||||||
|
|
||||||
|
void *memcpy(void *dest, const void *src, size_t n);
|
||||||
|
|
||||||
|
#endif /* !TOOLS_H */
|
|
@ -1,26 +1,48 @@
|
||||||
#include "userland.h"
|
#include "userland.h"
|
||||||
|
|
||||||
void userland(void)
|
#include "debug.h"
|
||||||
|
#include "paging.h"
|
||||||
|
#include "elf.h"
|
||||||
|
#include "launch_process.h"
|
||||||
|
|
||||||
|
struct userlands_data *userland_data = (struct userlands_data *) 0x3020000;
|
||||||
|
|
||||||
|
int create_process(int uid, char *data_start)
|
||||||
{
|
{
|
||||||
int res = 0;
|
create_new_userland_page(uid);
|
||||||
// asm ("mov $1, %0" : "=r" (res));
|
|
||||||
// asm volatile ("movl $2, %eax; int $0x30");
|
DEBUG_INFO("CREATE PROCESS");
|
||||||
// asm("movl %%eax,%0" : "=r"(res));
|
void *process_page_dir_adress = userland_data->userland_data[uid].page_directories;
|
||||||
// asm volatile ("int $0x30");
|
|
||||||
char *str = (void *) 0x30100;
|
// load cr3
|
||||||
str[0] = 'H';
|
asm volatile (" \
|
||||||
str[1] = 'e';
|
mov %0, %%eax \n \
|
||||||
str[2] = 'l';
|
mov %%eax, %%cr3" : "+r" (process_page_dir_adress));
|
||||||
str[3] = 'l';
|
|
||||||
str[4] = 'o';
|
// Allocate stack
|
||||||
str[5] = '\0';
|
allocate_new_page(uid, 0x7FFFF000);
|
||||||
asm volatile ("mov $1, %%eax; movl $0x30100, %%ebx; int $0x30; movl %%eax, %1" : "=m" (str), "=r" (res));
|
allocate_new_page(uid, 0x7FFFE000);
|
||||||
// asm volatile ("mov $1, %%eax; movl %0, %%ebx; int $0x30" : "=m" (str));
|
allocate_new_page(uid, 0x7FFFD000);
|
||||||
// asm ("mov $1, %eax; int $0x30");
|
|
||||||
// asm ("movl %0, %eax; int $0x30" : "=m" (res));
|
// TODO : create data seg by process
|
||||||
// asm ("movl %eax, %eax; int $0x30");
|
// load elf
|
||||||
// asm ("movl $28, %eax; movl $5, %ebx; int $0x30");
|
load_elf(data_start, uid);
|
||||||
// asm ("movl $43, %eax; movl $7, %ebx; int $0x30");
|
|
||||||
while (1);
|
return 0;
|
||||||
return; /* never go there */
|
}
|
||||||
}
|
|
||||||
|
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, 0x20, 0x18, 0x20);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,26 @@
|
||||||
#ifndef USERLAND_H
|
#ifndef USERLAND_H
|
||||||
#define 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 */
|
#endif /* !USERLAND_H */
|
||||||
|
|
Loading…
Reference in New Issue