Compare commits

..

2 Commits

Author SHA1 Message Date
brice.boisson 5492a13018 Fix: warning 2023-10-11 10:13:35 +09:00
brice.boisson 37dbb99f50 Add: userland hello world code 2023-10-11 09:38:29 +09:00
23 changed files with 106 additions and 104 deletions

View File

@ -11,8 +11,8 @@ install:
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
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

View File

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

10
app/hello_world.c Normal file
View File

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

View File

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

View File

@ -19,7 +19,7 @@ int print_variadic(char *msg, va_list args)
write_serial(va_arg(args, char *));
break;
case 'b':
write_serial_bin(va_arg(args, char *), false);
write_serial_bin((int) va_arg(args, char *), false);
break;
case 'c':
write_serial_char(va_arg(args, int));
@ -36,12 +36,14 @@ int print_variadic(char *msg, va_list args)
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(fnt);
write_serial((char *) fnt);
write_serial("\t: ");
va_list args;
@ -54,10 +56,10 @@ int debug_info(char *fnt, char *msg, ...)
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(fnt);
write_serial((char *) fnt);
write_serial("\t: ");
va_list args;
@ -70,10 +72,10 @@ int debug_warn(char *fnt, char *msg, ...)
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(fnt);
write_serial((char *) fnt);
write_serial("\t: ");
va_list args;

View File

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

View File

@ -4,6 +4,7 @@
#include "serial.h"
#include "debug.h"
#include "paging.h"
#include "tools.h"
int load_elf(char *elf_data_start, int uid)
{
@ -29,13 +30,15 @@ int load_elf(char *elf_data_start, int uid)
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);
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 (int i = elf_header_table->p_filesz; i < elf_header_table->p_memsz; i++)
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;
}

View File

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

View File

@ -8,19 +8,6 @@
#include "tss.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 segment_desc_param {
@ -66,8 +53,9 @@ void init_gdt(void)
{
DEBUG_INFO("Initializing GDT");
u16 gdt_size = sizeof(gdt) / sizeof(struct segdesc);
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.base = (u32) gdt;
@ -102,10 +90,10 @@ void init_gdt(void)
DEBUG_INFO("TSS BASE ADDRESS: %d", (u32) &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 });
for (int i = 0; i < sizeof(gdt) / 8; i++)
for (size_t i = 0; i < gdt_size; i++)
{
char *ptr = (char *) &gdt[i];
DEBUG_INFO("--------------------");

View File

@ -46,6 +46,7 @@ struct idt_segdesc init_gate(struct interrupt_gate_param param)
descriptor.Type = param.Type | (param.D << 3);
descriptor.Flags = 0;
descriptor.Flags |= param.DPL << 1;
descriptor.Flags |= param.P << 3;
@ -56,12 +57,13 @@ void init_idt(void)
{
DEBUG_INFO("Initializing IDT");
u16 idt_size = sizeof(idt) / sizeof(struct idt_segdesc);
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.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,
.Type = 0x06, .D = 1, .DPL = 0, .P = 1 });

View File

@ -4,7 +4,6 @@
#include "pic_controler.h"
#include "debug.h"
#include "syscall.h"
#include "userland.h"
void isr_default_int(void)
{
@ -18,15 +17,7 @@ void isr_page_fault(void)
void isr_clock_int(void)
{
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;
}
}
DEBUG_INFO("Enterring clock interrupt handler.");
}
void isr_kbd_int(void)

View File

@ -18,16 +18,10 @@ void main(void)
{
DEBUG_INFO("Entering Main Function");
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;
char *data_start = (char *) &_binary_a_out_start;
create_process(0, data_start);
create_process(1, data_start);
userland_data->active_process[0] |= 1 << (1 % 32);
switch_to_ring_3(0);
switch_to_process(0);
for (;;)
{

View File

@ -2,14 +2,13 @@
#include "tss.h"
#include "debug.h"
#include "userland.h"
void launch_process(u16 tss, int memory_start, int userland_stack, int userland_code, u16 userland_data_seg)
void launch_process(u16 tss, int userland_stack, int userland_code, u16 userland_data)
{
// Setting DPL and GDT bits
userland_stack += 3;
userland_code += 3;
userland_data_seg += 3;
userland_data += 3;
DEBUG_INFO("LAUCHING USER LAND PROCESS");

View File

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

View File

@ -124,7 +124,7 @@ int create_kernel_page(void)
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]});
.A = 0, .PS = 0, .address = (u32) &page_table[i * 1024]});
}
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]);
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]});
.A = 0, .PS = 0, .address = (u32) &kernel_page_table[i * 1024]});
}
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) {
.P = 1, .R_W = 1, .U = 0, .PWT = 0, .PCD = 0,
.A = 0, .PS = 0, .address = userland_data->userland_data[uid].page_table});
.A = 0, .PS = 0, .address = (u32) userland_data->userland_data[uid].page_table});
for (int i = NB_KERNEL_PAGE_DIR + 1; i < 1024; i++)
{
@ -216,6 +216,8 @@ int create_new_userland_page(int uid)
.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)
@ -231,7 +233,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
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;
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);
@ -250,4 +252,6 @@ int allocate_new_page(int uid, int address)
.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;
}

View File

@ -17,6 +17,7 @@ struct page_table_entry {
} __attribute__((packed));
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];

View File

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

View File

@ -20,6 +20,8 @@ int init_serial()
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 + 4, 0x0B); // IRQs enabled, RTS/DSR set
return 0;
}
int write_serial_nb(int nb, int ln)
@ -86,7 +88,7 @@ int write_serial_char(char c)
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);
outb(PORT, s[i]);

14
src/tools.c Normal file
View File

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

8
src/tools.h Normal file
View File

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

View File

@ -2,9 +2,10 @@
#include "debug.h"
#include "paging.h"
#include "elf.h"
#include "launch_process.h"
struct userlands_data *userland_data = 0x3020000;
struct userlands_data *userland_data = (struct userlands_data *) 0x3020000;
int create_process(int uid, char *data_start)
{
@ -30,21 +31,6 @@ int create_process(int uid, char *data_start)
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)
{
DEBUG_INFO("SWITCHING TO PROCESS");
@ -55,8 +41,8 @@ int switch_to_process(int uid)
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);
// TODO : once data by process has been implemented, load the right one
launch_process(0x28, 0x20, 0x18, 0x20);
return 0;
}

View File

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