Compare commits

..

19 Commits

Author SHA1 Message Date
0d828c8067 wip: switch current_pcb and cr3 in switch_thread 2025-11-30 14:54:17 +01:00
274113a401 core: refactor fork function 2025-11-30 14:30:04 +01:00
896a0a04f9 fix: set content to the new thread_list node
fix: copy child to the current_pcb
2025-11-30 14:24:33 +01:00
5b25422f8d fix: memcpy not in the right order 2025-11-30 14:14:03 +01:00
afe83d5059 add: parentheses around param in PTE2VA 2025-11-30 15:10:51 +01:00
dbfa2febec fix: new_pt in deep_copy (still not working tho) 2025-11-30 13:45:12 +01:00
cde3702132 feature: fork() (to be tested) 2025-11-30 13:32:24 +01:00
6ff044c07a fix: get pd phys addr 2025-11-28 20:22:19 +01:00
700864cbf2 wip: allocate user process stack on the right PD 2025-11-28 19:16:54 +01:00
f9cb7a6a8a fix: use right var to prevent crash 2025-11-28 20:13:04 +01:00
24dce6e737 fix: setup recursive paging in process 2025-11-28 20:06:27 +01:00
d46fe337c1 fix: GET_PTE cast type 2025-11-28 19:25:16 +01:00
1992d7f79b fix: bzero page tables before use it, alloc return the right index 2025-11-28 19:24:40 +01:00
2308ef509c fix: GET_PTE uses the right value 2025-11-28 17:39:10 +01:00
3df6011d7a wip: user allocator 2025-11-28 17:36:10 +01:00
c6a5bf25c2 feature: reboot on space with kpanic 2025-11-28 16:35:40 +01:00
9c91830007 core: change multiboot pde 2025-11-28 16:22:55 +01:00
3c2c9b0a10 core: init_multiboot in main 2025-11-28 16:22:30 +01:00
674509a79e fix: init_mmap: use right addr 2025-11-28 16:22:03 +01:00
26 changed files with 280 additions and 200 deletions

View File

@ -75,10 +75,10 @@ int new_vzone(block_type_t type, size_t size);
int new_kzone(block_type_t type, size_t size);
/*----------------------------*/
void *vmalloc(size_t size);
void vfree(void *ptr);
void *umalloc(size_t size);
void ufree(void *ptr);
void *vrealloc(void *ptr, size_t size);
void show_valloc_mem(void);
void show_ualloc_mem(void);
size_t vsize(void *virt_addr);
void *kmalloc(size_t size);
void kfree(void *ptr);

View File

@ -21,14 +21,21 @@
#define KERNEL_END ((uint32_t)&_kernel_end - VIRT_OFFSET)
#define KERNEL_PT_END 1020
#define KERNEL_PT_START 769
#define USER_PT_START 1
#define USER_PT_END 768
#define PDE_VBE 1021
#define PDE_FRAME_ZONES 1022
#define PDE_MULTIBOOT 1023
#define PDE_MULTIBOOT 1020
#define GET_PTE(pd_index, pt_index) \
((uint32_t *)(VIRT_PT_BASE + ((uint32_t)pd_index) * 4096 + \
((uint32_t)pt_index) * 4))
#define PTE2VA(pd_index, pt_index) \
((uint32_t *)((((uint32_t)pd_index * 1024) + (uint32_t)pt_index) * \
4096))
((uint32_t *)(( \
((((uint32_t)pd_index) * 1024) + ((uint32_t)pt_index)) * 4096)))
static inline uint32_t *VA2PTE(uint32_t va)
{
uint32_t pde = va >> 22;
@ -64,10 +71,11 @@ extern multiboot_memory_map_t *mmap_addr;
extern multiboot_uint32_t mmap_length;
extern struct frame_zone *head;
void init_memory(multiboot_info_t *mbd, uint32_t magic);
void init_multiboot(multiboot_info_t *mbd, uint32_t magic);
void init_memory(void);
void *alloc_frame(void);
int free_frame(void *frame_ptr);
void *kalloc_pages(size_t nb_pages);
void *valloc_pages(size_t size, void **phys_addr);
int kfree_pages(void *page_ptr, size_t size);
int vfree_pages(void *page_ptr, size_t size);
void *ualloc_pages(size_t nb_pages);
int kfree_pages(void *page_ptr, size_t nb_pages);
int ufree_pages(void *page_ptr, size_t nb_pages);

View File

@ -28,5 +28,5 @@ struct pcb {
void switch_process(struct pcb *next_pcb);
struct pcb *create_process(uid_t uid);
// int8_t create_kernel_process(void);
void remove_process(struct pcb *pcb);
pid_t fork(void);

View File

@ -24,4 +24,4 @@ struct tcb {
struct tcb *create_thread(struct pcb *process, void (*entry)(void));
void delete_thread(struct tcb *thread);
void switch_thread(uint32_t *esp);
void switch_thread(struct tcb *thread_to_switch);

View File

@ -40,7 +40,7 @@ static void clock_handler(struct registers *regs)
{
scheduler_counter++;
sleep_counter--;
if (scheduler_counter % 100 == 0)
if (scheduler_counter % 30 == 0)
scheduler((uint32_t *)regs);
}

View File

@ -33,9 +33,11 @@
static void uwu(void)
{
pid_t pid = fork();
kprintf("pid: %d\n", pid);
while (1) {
// sleep(1000);
kprintf("uwu\n");
// kprintf("%d\n", current_pcb->pid);
}
}
@ -50,13 +52,13 @@ void kernel_main(multiboot_info_t *mbd, uint32_t magic)
cli();
init_gdt();
init_idt();
init_memory(mbd, magic);
init_multiboot(mbd, magic);
init_memory();
load_drivers();
terminal_initialize();
create_process(1);
create_thread(current_pcb, shell_init);
create_process(2);
create_thread(current_pcb->next, uwu);
// create_thread(current_pcb, shell_init);
create_thread(current_pcb, uwu);
toris();
while (true)
;

View File

@ -27,10 +27,13 @@ __attribute__((noreturn)) void kpanic(const char *format, ...)
kprintf("fault at address: %p\n", faulting_address);
// for (int i = 16; i < 32; i++)
// kprintf("%p\n", page_table1[i]);
// show_valloc_mem();
// show_ualloc_mem();
/* kprintf("\n\n"); */
/* print_stack(); */
/* kprintf("\n\n"); */
/* kprintf("PRESS SPACE TO REBOOT"); */
__asm__ __volatile__("jmp panic");
kprintf("PRESS SPACE TO REBOOT");
while (terminal_getkey().c != ' ')
;
reboot();
// __asm__ __volatile__("jmp panic");
}

View File

@ -3,6 +3,7 @@
#include "kprintf.h"
#include "memory.h"
#include "string.h"
#include "utils.h"
Zone *kzones[3];
@ -49,7 +50,7 @@ static void new_block(Zone *zone, uint32_t zone_size)
int new_kzone(block_type_t type, uint32_t size)
{
// assert(current_task->pid);
void *heap = kalloc_pages(size);
void *heap = kalloc_pages(CEIL(size, PAGE_SIZE));
if (heap == NULL) {
kprintf(KERN_ERR "error: alloc_frame failed\n");
return (-1);

View File

@ -12,14 +12,15 @@
static uint32_t *find_next_block(size_t nb_pages)
{
uint32_t count = 0;
for (uint32_t *pte = PTE2VA(1023, 0); pte < PTE2VA(1023, 1023); pte++) {
if (!*pte) {
for (uint32_t *pte = PTE2VA(1023, KERNEL_PT_START);
pte < PTE2VA(1023, KERNEL_PT_END); pte++) {
if (*pte) {
count = 0;
continue;
}
count++;
if (count == nb_pages)
return pte - count;
return pte - (count - 1);
}
return NULL;
}
@ -27,6 +28,8 @@ static uint32_t *find_next_block(size_t nb_pages)
void *kalloc_pages(size_t nb_pages)
{
uint32_t *start = find_next_block(nb_pages);
if (!start)
return NULL;
for (uint32_t i = 0; i < nb_pages; i++) {
void *frame = alloc_frame();
if (!frame) {
@ -35,7 +38,7 @@ void *kalloc_pages(size_t nb_pages)
PAGE_MASK));
return NULL;
}
assert(!((uint32_t)frame & PAGE_MASK));
assert((uint32_t)frame & PAGE_MASK);
start[i] = (uint32_t)frame | INIT_FLAGS;
}
uint32_t page_index = start - PTE2VA(1023, 0);

View File

@ -21,7 +21,6 @@ static void lst_add_back(struct frame_zone **root, struct frame_zone *element)
it->next = element;
}
static void add_frame_node(multiboot_memory_map_t *mmmt)
{
static uint32_t index = 0;
@ -64,33 +63,40 @@ static void add_frame_node(multiboot_memory_map_t *mmmt)
((uint32_t)frame_zones_page_table - VIRT_OFFSET) | INIT_FLAGS;
/** We need to determine how many frames are available
to save how many frame the blocks contain etc we need some meta data
1 struct frame_zone and a frame_table, the size of the frame_table is 1 bit per frame
the frame_table is a uint8_t so 8 bit, so its size must be CEIL(max_frames, 8)
But we don't have max_frames.
We can determine max_frame = (block_len - sizeof(struct frame_zone)) / (PAGE_SIZE + 1 / 8) (1 / 8 because size is in byte but we only need one bit)
Because we don't use float we can't have 1 / 8
So we will multiplicate every members of this equation by 8 to have only complet number
So... max_frame = (block_len - sizeof(struct frame_zone)) * 8 / (PAGE_SIZE * 8 + 1)
to save how many frame the blocks contain etc we need some meta
data 1 struct frame_zone and a frame_table, the size of the
frame_table is 1 bit per frame the frame_table is a uint8_t so 8 bit,
so its size must be CEIL(max_frames, 8) But we don't have max_frames.
We can determine max_frame = (block_len - sizeof(struct
frame_zone)) / (PAGE_SIZE + 1 / 8) (1 / 8 because size is in byte but
we only need one bit) Because we don't use float we can't have 1 / 8
So we will multiplicate every members of this equation by 8 to
have only complet number So... max_frame = (block_len - sizeof(struct
frame_zone)) * 8 / (PAGE_SIZE * 8 + 1)
*/
const uint32_t nb_frame = (len - sizeof(struct frame_zone)) * 8 / (PAGE_SIZE * 8 + 1);
const uint32_t nb_frame =
(len - sizeof(struct frame_zone)) * 8 / (PAGE_SIZE * 8 + 1);
const uint32_t frame_table_size = CEIL(nb_frame, (sizeof(uint8_t) * 8));
uint32_t page_needed = CEIL(frame_table_size + sizeof(struct frame_zone), PAGE_SIZE);
uint32_t page_needed =
CEIL(frame_table_size + sizeof(struct frame_zone), PAGE_SIZE);
uint32_t i = 0;
for (; i < page_needed; i++)
frame_zones_page_table[index + i] = (((uint32_t)start_addr + i * PAGE_SIZE) & PAGE_MASK) | INIT_FLAGS;
frame_zones_page_table[index + i] =
(((uint32_t)start_addr + i * PAGE_SIZE) & PAGE_MASK) |
INIT_FLAGS;
struct frame_zone *current =
(struct frame_zone *)PTE2VA(PDE_FRAME_ZONES, index);
current->frame_table = (uint8_t*) ((uint32_t) current + sizeof(struct frame_zone));
current->frame_table =
(uint8_t *)((uint32_t)current + sizeof(struct frame_zone));
current->first_free_frame = 0;
current->next = NULL;
current->remaining_frames = nb_frame;
current->total_frames = nb_frame;
current->addr = (void*)(uint32_t)start_addr + page_needed * PAGE_SIZE;
current->addr = (void *)(uint32_t)start_addr + page_needed * PAGE_SIZE;
bzero(current->frame_table, frame_table_size);
@ -98,15 +104,12 @@ static void add_frame_node(multiboot_memory_map_t *mmmt)
lst_add_back(&head, current);
}
static void init_frame_zones(void)
{
for(uint32_t i = 0; i < mmap_length;
i += sizeof(multiboot_memory_map_t))
{
multiboot_memory_map_t* mmmt =
(multiboot_memory_map_t*) ((uint32_t)mmap_addr + i);
for (uint32_t i = 0; i < mmap_length;
i += sizeof(multiboot_memory_map_t)) {
multiboot_memory_map_t *mmmt =
(multiboot_memory_map_t *)((uint32_t)mmap_addr + i);
if (mmmt->type == MULTIBOOT_MEMORY_AVAILABLE)
add_frame_node(mmmt);
}
@ -120,7 +123,8 @@ void init_memory()
uint32_t frame = (uint32_t)alloc_frame();
if (!frame)
kpanic("Couldn't initialize kernel PTs\n");
PD[i] = frame | RW;
PD[i] = frame | INIT_FLAGS;
bzero(PTE2VA(1023, i), PAGE_SIZE);
}
// kalash kalash kalash sur la mélodie chez nous pas de félonie ça vient
// de Sevran les R

View File

@ -4,6 +4,7 @@
#include "kprintf.h"
#include "memory.h"
#include "string.h"
#include "utils.h"
Zone *vzones[3];
@ -50,7 +51,7 @@ static void new_block(Zone *zone, uint32_t zone_size)
int new_vzone(block_type_t type, uint32_t size)
{
// assert(current_task->pid);
void *heap = valloc_pages(size, NULL);
void *heap = ualloc_pages(CEIL(size, PAGE_SIZE));
if (heap == NULL) {
kprintf(KERN_ERR "error: alloc_pages failed\n");
return (-1);

View File

@ -5,7 +5,7 @@
// FULL_INFO is to display (or not) both used and unused blocks
#define FULL_INFO 1
void show_valloc_mem(void)
void show_ualloc_mem(void)
{
char *const zones_name[3] = {"TINY", "SMALL", "LARGE"};
uint32_t total_size = 0;

77
src/memory/user/page.c Normal file
View File

@ -0,0 +1,77 @@
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include "assert.h"
#include "kprintf.h"
#include "memory.h"
#include "process.h"
#include "string.h"
#include "utils.h"
static int8_t alloc_pagetable(uint16_t pd_index)
{
uint32_t *pt = alloc_frame();
if (!pt)
return -1;
PD[pd_index] = (uint32_t)pt | INIT_FLAGS;
bzero(PTE2VA(1023, pd_index), PAGE_SIZE);
return 0;
}
static uint32_t *find_next_block(size_t nb_pages)
{
size_t count = 0;
for (size_t i = USER_PT_START; i < USER_PT_END; i++) {
if (!PD[i])
if (alloc_pagetable(i) < 0)
return NULL;
for (size_t j = 0; j < 1024; j++) {
if (*GET_PTE(i, j)) {
count = 0;
continue;
}
count++;
if (count == nb_pages) {
return GET_PTE(i, j) - (count - 1);
}
}
}
return NULL;
}
void *ualloc_pages(size_t nb_pages)
{
uint32_t *start = find_next_block(nb_pages);
if (!start)
return NULL;
for (uint32_t i = 0; i < nb_pages; i++) {
void *frame = alloc_frame();
if (!frame) {
for (uint32_t j = 0; j < i; j++)
free_frame((void *)(((uint32_t)(start + j)) &
PAGE_MASK));
return NULL;
}
assert((uint32_t)frame & PAGE_MASK);
start[i] = (uint32_t)frame | INIT_FLAGS;
}
uint32_t page_index = start - PTE2VA(1023, 0);
return PTE2VA(page_index / 1024, page_index % 1024);
}
int ufree_pages(void *page_ptr, size_t nb_pages)
{
const uint32_t page_addr = (uint32_t)page_ptr;
if (page_addr % PAGE_SIZE) {
kprintf(KERN_WARNING "Invalid address\n");
return -1;
}
for (uint32_t *pte = VA2PTE(page_addr);
pte < VA2PTE(page_addr) + nb_pages; pte++) {
free_frame((void *)(*pte & PAGE_MASK));
*pte = 0;
}
return 0;
}

View File

@ -47,7 +47,7 @@ static int unmap_zone(Zone *zone)
if (right)
right->prev = left;
unmap:
err = vfree_pages((void *)zone, zone->size);
err = ufree_pages((void *)zone, zone->size);
if (err)
kprintf(KERN_ERR "error: munmap failed\n");
return (err);
@ -94,7 +94,7 @@ static int add_available(Block *available, Block *merged)
* newly merged block
* Finally, we add the block to the list of available blocks
*/
void vfree(void *ptr)
void ufree(void *ptr)
{
if (ptr == NULL)
return;

View File

@ -33,7 +33,7 @@ static Block *find_block(Zone *head, uint32_t size)
* After the allocation, this will become
* ... -> [5] -> [new] -> [6] -> ...
*
* For an example of [5].size = 32 and requiring a vmalloc of 10
* For an example of [5].size = 32 and requiring a umalloc of 10
* Let's say the metadata takes a size of 2:
* ... -> [metadata][data][remaining size] -> [6]
* ^ ^ ^
@ -126,12 +126,12 @@ static void save_block(Zone *head, Block *block, Zone *zone)
*
* ptr: returns the aligned pointer of the block (after the metadata)
*/
void *vmalloc(uint32_t size)
void *umalloc(uint32_t size)
{
void *ptr = NULL;
if (size == 0) {
kprintf(KERN_WARNING "vmalloc: can't vmalloc(0)\n");
kprintf(KERN_WARNING "umalloc: can't umalloc(0)\n");
return NULL;
}

View File

@ -2,9 +2,9 @@
#include "string.h"
#include <stdint.h>
// Prototype for kfree and vmalloc
// Prototype for kfree and umalloc
void kfree(void *ptr);
void *vmalloc(uint32_t size);
void *umalloc(uint32_t size);
/*
* ptr: block to resize (undefined behavior if invalid)
@ -28,10 +28,10 @@ void *vrealloc(void *ptr, uint32_t size)
block->sub_size = size;
return (ptr);
}
new_ptr = vmalloc(size);
new_ptr = umalloc(size);
if (new_ptr == NULL)
return NULL;
memmove(new_ptr, ptr, block->size);
vfree(ptr);
ufree(ptr);
return (new_ptr);
}

View File

@ -1,90 +0,0 @@
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include "assert.h"
#include "kprintf.h"
#include "memory.h"
#include "process.h"
#include "string.h"
#include "utils.h"
static int16_t find_next_block(size_t nb_pages, uint16_t *pd_index_ptr,
uint32_t **page_table_ptr)
{
for (*pd_index_ptr = 2; *pd_index_ptr < 768; (*pd_index_ptr)++) {
// if (current_pd[(*pd_index_ptr)] == 0x02) {
// if (add_page_table(*pd_index_ptr, 1) < 0)
// return -2;
// }
*page_table_ptr = (uint32_t *)PTE2VA(1, *pd_index_ptr);
for (uint16_t i = 0; i + nb_pages - 1 < 1024; i++) {
uint16_t j;
for (j = 0; (*page_table_ptr)[i + j] >> 12 == i + j &&
j < nb_pages;
j++)
;
if (j == nb_pages)
return i;
i += j;
}
}
return -1;
}
void *valloc_pages(size_t size, void **phys_addr)
{
const uint32_t nb_pages = CEIL(size, PAGE_SIZE);
uint16_t pd_index;
uint32_t *page_table;
const int16_t index = find_next_block(nb_pages, &pd_index, &page_table);
if (index < 0) {
kprintf(KERN_CRIT "%d: Not enough pages (max: %d)\n", index,
1024);
return NULL;
}
for (size_t i = index; i - (size_t)index < nb_pages; i++) {
void *frame = alloc_frame();
if (!frame) {
for (size_t j = index; j < i; j++)
free_frame((void *)(page_table[j] & PAGE_MASK));
return NULL;
}
if (phys_addr)
*phys_addr = frame;
page_table[i] = ((uint32_t)frame & PAGE_MASK) | INIT_FLAGS;
}
return (void *)PTE2VA(pd_index, index);
}
int vfree_pages(void *page_ptr, size_t size)
{
const uint32_t page_addr = (uint32_t)page_ptr;
const uint32_t nb_pages = CEIL(size, PAGE_SIZE);
const uint32_t page_index = page_addr / PAGE_SIZE;
const uint32_t pd_index = page_index / 1024;
const uint32_t pt_index = page_index % 1024;
if ((uint32_t)pd_index > 0x300) {
kprintf(KERN_WARNING "Address out of range\n");
return -1;
} else if (page_addr % PAGE_SIZE) {
kprintf(KERN_WARNING "Invalid address\n");
return -1;
} else if (pt_index + nb_pages > 1024) {
kprintf(KERN_WARNING "Invalid number of frames\n");
return -1;
}
uint32_t *page_table = (uint32_t *)PTE2VA(1, pd_index);
for (uint16_t i = pt_index; i < pt_index + nb_pages; i++) {
if (page_table[i] >> 12 == i) {
kprintf(KERN_WARNING "Page already freed\n");
return -2;
}
free_frame((void *)(page_table[i] & PAGE_MASK));
page_table[i] = i << 12;
}
return 0;
}

View File

@ -16,15 +16,15 @@ static void init_mmap(multiboot_info_t *mbd_virt, size_t *pt_index)
{
// Index mbd->mmap_addr pointers
uint32_t i = 0;
for (; i < mbd_virt->mmap_length; i++)
for (; i < CEIL(mbd_virt->mmap_length, PAGE_SIZE); i++)
multiboot_page_table[i + *pt_index] =
((mbd_virt->mmap_addr + i * PAGE_SIZE) & PAGE_MASK) |
INIT_FLAGS;
mmap_addr =
(multiboot_memory_map_t *)(PTE2VA(PDE_MULTIBOOT, *pt_index) +
(uint32_t)mbd_virt->mmap_addr %
PAGE_SIZE);
mmap_length = mbd_virt->mmap_length / sizeof(multiboot_memory_map_t);
(multiboot_memory_map_t *)((uint32_t)PTE2VA(PDE_MULTIBOOT, *pt_index) +
(mbd_virt->mmap_addr %
PAGE_SIZE));
mmap_length = mbd_virt->mmap_length;
*pt_index += i;
}
@ -52,8 +52,7 @@ void init_multiboot(multiboot_info_t *mbd, uint32_t magic)
if (magic != MULTIBOOT_BOOTLOADER_MAGIC)
kpanic("invalid magic number! (git gud skill issue)");
uint32_t *pd = &boot_page_directory;
pd[PDE_MULTIBOOT] =
PD[PDE_MULTIBOOT] =
((uint32_t)multiboot_page_table - VIRT_OFFSET) | INIT_FLAGS;
size_t pt_index = CEIL(
(uint32_t)mbd % PAGE_SIZE + sizeof(multiboot_info_t), PAGE_SIZE);

View File

@ -4,19 +4,85 @@
#include "string.h"
#include "thread.h"
static struct tcb *thread_clone(struct tcb *thread)
static void free_pts(void)
{
struct tcb *new_tcb = vmalloc(sizeof(struct tcb));
if (!new_tcb)
return NULL;
new_tcb->tid = thread->tid;
new_tcb->esp0 = kalloc_pages(STACK_SIZE);
if (!new_tcb->esp0) {
delete_thread(new_tcb);
return NULL;
for (size_t i = USER_PT_END / 2; PD[i]; i++) {
uint32_t *pt = PTE2VA(1023, i);
for (size_t j = 0; j < 1024; j++)
if (pt[j])
ufree_pages(PTE2VA(i, j), 1);
ufree_pages(pt, 1);
}
memcpy(new_tcb->esp0, thread->esp0, STACK_SIZE);
return new_tcb;
}
static int copy_pt(uint32_t *pt_src, uint32_t *pt_dest, size_t pd_index)
{
for (size_t i = 0; i < 1024; i++) {
if (pt_src[i]) {
pt_dest[i] = (uint32_t)alloc_frame() | INIT_FLAGS;
if (pt_dest[i] == INIT_FLAGS) {
for (size_t j = 0; j < i; j++)
free_frame(
(void *)(pt_dest[j] & PAGE_MASK));
return -1;
}
void *src_page = PTE2VA(pd_index, i);
void *dest_page = PTE2VA(pd_index + USER_PT_END / 2, i);
memcpy(dest_page, src_page, PAGE_SIZE);
}
}
return 0;
}
static int copy_thread_list(struct pcb *new_pcb)
{
struct list *e;
struct list *prev = NULL;
for (struct list *it = current_pcb->thread_list; it; it = it->next) {
e = kmalloc(sizeof(struct list));
if (!e)
return -1;
if (prev)
prev->next = e;
else
new_pcb->thread_list = e;
struct tcb *new_content = kmalloc(sizeof(struct tcb));
if (!new_content) {
kfree(e);
return -1;
}
memcpy(new_content, it->content, sizeof(struct tcb));
new_content->process = new_pcb;
e->next = NULL;
e->content = new_content;
prev = e;
}
return 0;
}
static int deep_copy(struct pcb *new_pcb)
{
if (PD[USER_PT_END / 2])
return -2;
size_t i;
for (i = USER_PT_START; PD[i]; i++) {
void *new_pt = alloc_frame();
if (!new_pt) {
free_pts();
return -1;
}
PD[i + USER_PT_END / 2] = (uint32_t)new_pt | INIT_FLAGS;
if (copy_pt(PTE2VA(1023, i), PTE2VA(1023, i + USER_PT_END / 2),
i) < 0) {
free_pts();
return -1;
}
new_pcb->heap[i] = (uint32_t)new_pt | INIT_FLAGS;
}
bzero(PD + USER_PT_END / 2, i * sizeof(uint32_t));
if (copy_thread_list(new_pcb) < 0)
return -1;
return 0;
}
pid_t fork(void)
@ -24,15 +90,18 @@ pid_t fork(void)
struct pcb *new_pcb = create_process(current_pcb->uid);
if (!new_pcb)
return -1;
struct list *new_node = vmalloc(sizeof(struct list));
struct list *new_node = kmalloc(sizeof(struct list));
if (!new_node) {
remove_process(new_pcb);
return -1;
}
new_pcb->daddy = current_pcb;
lst_add_back(&new_pcb->children, new_node);
// loop on threads clone
thread_clone(current_pcb->thread_list->content);
lst_add_back(&current_pcb->children, new_node);
return new_pcb->pid;
if (deep_copy(new_pcb) < 0) {
remove_process(new_pcb);
return -1;
}
return current_pcb == new_pcb ? 0 : new_pcb->pid;
}

View File

@ -5,6 +5,7 @@
#include "thread.h"
#include "string.h"
#include <stdint.h>
struct pcb *create_process(uid_t uid)
{
@ -22,8 +23,10 @@ struct pcb *create_process(uid_t uid)
return NULL;
}
new_pcb->cr3 =
(void *)((uint32_t)VA2PTE((uint32_t)new_pcb->heap) & PAGE_MASK);
memcpy(new_pcb->heap, PD, 4096);
(void *)((uint32_t)*VA2PTE((uint32_t)new_pcb->heap) & PAGE_MASK);
memcpy(new_pcb->heap, PD,
4096); // TODO optimize to copy only used bytes
new_pcb->heap[1023] = (uint32_t)new_pcb->cr3 | INIT_FLAGS;
new_pcb->daddy = NULL;
new_pcb->children = NULL;

View File

@ -20,7 +20,8 @@ static struct list *get_thread_to_switch(void)
it_t = current_tcb == NULL ? NULL : current_tcb->next;
while (it_p) {
while (it_t != NULL) {
if (it_t != NULL && CURRENT_TCB->state != WAITING)
if (it_t != NULL &&
((struct tcb *)it_t->content)->state != WAITING)
return it_t;
it_t = it_t->next;
}
@ -38,8 +39,6 @@ void scheduler(uint32_t *esp)
struct tcb *thread_to_switch = (struct tcb *)list_node->content;
if (current_tcb)
CURRENT_TCB->esp = esp;
if (thread_to_switch->process != current_pcb)
switch_process(thread_to_switch->process);
current_tcb = list_node;
switch_thread(thread_to_switch->esp);
switch_thread(thread_to_switch);
}

View File

@ -1,16 +0,0 @@
.intel_syntax noprefix
.extern current_pcb
.section .text
.global switch_process
switch_process:
// change current_pcb global
mov eax, [esp + 4]
mov [current_pcb], eax
// reload cr3 with the new heap
mov edx, [eax + 0]
mov cr3, edx
ret

View File

@ -7,8 +7,20 @@
switch_thread:
mov eax, [esp + 4]
mov esp, eax
mov esp, [eax]
mov edx, [eax + 16]
cmp [current_pcb], edx
je LABEL1
// change current_pcb
mov [current_pcb], edx
// reload cr3 with the new heap
mov edx, [edx]
mov cr3, edx
LABEL1:
pop eax
mov ds, eax

View File

@ -7,6 +7,7 @@
#include "process.h"
#include "string.h"
#include "thread.h"
#include "utils.h"
struct tcb *create_thread(struct pcb *process, void (*entry)(void))
{
@ -15,11 +16,15 @@ struct tcb *create_thread(struct pcb *process, void (*entry)(void))
return NULL;
new_tcb->tid = process->tid++;
new_tcb->esp0 = valloc_pages(STACK_SIZE, NULL);
memcpy(PD, process->heap,
(USER_PT_END - USER_PT_START) * sizeof(uint32_t));
new_tcb->esp0 = ualloc_pages(CEIL(STACK_SIZE, PAGE_SIZE));
if (!new_tcb->esp0) {
vfree(new_tcb);
ufree(new_tcb);
return NULL;
}
memcpy(process->heap, PD,
(USER_PT_END - USER_PT_START) * sizeof(uint32_t));
uint32_t *stack = (uint32_t *)((uint8_t *)new_tcb->esp0 + STACK_SIZE);
uint32_t *esp = stack;
@ -49,7 +54,7 @@ struct tcb *create_thread(struct pcb *process, void (*entry)(void))
struct list *new_node = kmalloc(sizeof(struct list));
if (!new_node) {
kfree_pages(new_tcb->esp0, STACK_SIZE);
vfree(new_tcb);
ufree(new_tcb);
return NULL;
}
new_node->content = new_tcb;

View File

@ -5,5 +5,5 @@
void heap_cmd(char *arg)
{
(void)arg;
show_valloc_mem();
show_ualloc_mem();
}