Compare commits
21 Commits
7819b4a02d
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 0d828c8067 | |||
| 274113a401 | |||
| 896a0a04f9 | |||
| 5b25422f8d | |||
| afe83d5059 | |||
| dbfa2febec | |||
| cde3702132 | |||
| 6ff044c07a | |||
| 700864cbf2 | |||
| f9cb7a6a8a | |||
| 24dce6e737 | |||
| d46fe337c1 | |||
| 1992d7f79b | |||
| 2308ef509c | |||
| 3df6011d7a | |||
| c6a5bf25c2 | |||
| 9c91830007 | |||
| 3c2c9b0a10 | |||
| 674509a79e | |||
| 99ee5b8cec | |||
| 5591120deb |
@ -75,10 +75,10 @@ int new_vzone(block_type_t type, size_t size);
|
|||||||
int new_kzone(block_type_t type, size_t size);
|
int new_kzone(block_type_t type, size_t size);
|
||||||
/*----------------------------*/
|
/*----------------------------*/
|
||||||
|
|
||||||
void *vmalloc(size_t size);
|
void *umalloc(size_t size);
|
||||||
void vfree(void *ptr);
|
void ufree(void *ptr);
|
||||||
void *vrealloc(void *ptr, size_t size);
|
void *vrealloc(void *ptr, size_t size);
|
||||||
void show_valloc_mem(void);
|
void show_ualloc_mem(void);
|
||||||
size_t vsize(void *virt_addr);
|
size_t vsize(void *virt_addr);
|
||||||
void *kmalloc(size_t size);
|
void *kmalloc(size_t size);
|
||||||
void kfree(void *ptr);
|
void kfree(void *ptr);
|
||||||
|
|||||||
@ -21,14 +21,21 @@
|
|||||||
#define KERNEL_END ((uint32_t)&_kernel_end - VIRT_OFFSET)
|
#define KERNEL_END ((uint32_t)&_kernel_end - VIRT_OFFSET)
|
||||||
#define KERNEL_PT_END 1020
|
#define KERNEL_PT_END 1020
|
||||||
#define KERNEL_PT_START 769
|
#define KERNEL_PT_START 769
|
||||||
|
#define USER_PT_START 1
|
||||||
|
#define USER_PT_END 768
|
||||||
|
|
||||||
#define PDE_VBE 1021
|
#define PDE_VBE 1021
|
||||||
#define PDE_FRAME_ZONES 1022
|
#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) \
|
#define PTE2VA(pd_index, pt_index) \
|
||||||
((uint32_t *)((((uint32_t)pd_index * 1024) + (uint32_t)pt_index) * \
|
((uint32_t *)(( \
|
||||||
4096))
|
((((uint32_t)pd_index) * 1024) + ((uint32_t)pt_index)) * 4096)))
|
||||||
|
|
||||||
static inline uint32_t *VA2PTE(uint32_t va)
|
static inline uint32_t *VA2PTE(uint32_t va)
|
||||||
{
|
{
|
||||||
uint32_t pde = va >> 22;
|
uint32_t pde = va >> 22;
|
||||||
@ -64,10 +71,11 @@ extern multiboot_memory_map_t *mmap_addr;
|
|||||||
extern multiboot_uint32_t mmap_length;
|
extern multiboot_uint32_t mmap_length;
|
||||||
extern struct frame_zone *head;
|
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);
|
void *alloc_frame(void);
|
||||||
int free_frame(void *frame_ptr);
|
int free_frame(void *frame_ptr);
|
||||||
void *kalloc_pages(size_t nb_pages);
|
void *kalloc_pages(size_t nb_pages);
|
||||||
void *valloc_pages(size_t size, void **phys_addr);
|
void *ualloc_pages(size_t nb_pages);
|
||||||
int kfree_pages(void *page_ptr, size_t size);
|
int kfree_pages(void *page_ptr, size_t nb_pages);
|
||||||
int vfree_pages(void *page_ptr, size_t size);
|
int ufree_pages(void *page_ptr, size_t nb_pages);
|
||||||
|
|||||||
@ -28,5 +28,5 @@ struct pcb {
|
|||||||
|
|
||||||
void switch_process(struct pcb *next_pcb);
|
void switch_process(struct pcb *next_pcb);
|
||||||
struct pcb *create_process(uid_t uid);
|
struct pcb *create_process(uid_t uid);
|
||||||
// int8_t create_kernel_process(void);
|
|
||||||
void remove_process(struct pcb *pcb);
|
void remove_process(struct pcb *pcb);
|
||||||
|
pid_t fork(void);
|
||||||
|
|||||||
@ -24,4 +24,4 @@ struct tcb {
|
|||||||
|
|
||||||
struct tcb *create_thread(struct pcb *process, void (*entry)(void));
|
struct tcb *create_thread(struct pcb *process, void (*entry)(void));
|
||||||
void delete_thread(struct tcb *thread);
|
void delete_thread(struct tcb *thread);
|
||||||
void switch_thread(uint32_t *esp);
|
void switch_thread(struct tcb *thread_to_switch);
|
||||||
|
|||||||
@ -93,6 +93,10 @@ _start:
|
|||||||
movl $(boot_page_table1 - 0xC0000000 + 0x003), boot_page_directory - 0xC0000000 + 0
|
movl $(boot_page_table1 - 0xC0000000 + 0x003), boot_page_directory - 0xC0000000 + 0
|
||||||
movl $(boot_page_table1 - 0xC0000000 + 0x003), boot_page_directory - 0xC0000000 + 768 * 4
|
movl $(boot_page_table1 - 0xC0000000 + 0x003), boot_page_directory - 0xC0000000 + 768 * 4
|
||||||
|
|
||||||
|
# Map the recusive paging
|
||||||
|
movl $(boot_page_directory - 0xC0000000 + 0x003), boot_page_directory - 0xC0000000 + 1023 * 4
|
||||||
|
|
||||||
|
|
||||||
# Set cr3 to the address of the boot_page_directory.
|
# Set cr3 to the address of the boot_page_directory.
|
||||||
movl $(boot_page_directory - 0xC0000000), %ecx
|
movl $(boot_page_directory - 0xC0000000), %ecx
|
||||||
movl %ecx, %cr3
|
movl %ecx, %cr3
|
||||||
|
|||||||
@ -40,7 +40,7 @@ static void clock_handler(struct registers *regs)
|
|||||||
{
|
{
|
||||||
scheduler_counter++;
|
scheduler_counter++;
|
||||||
sleep_counter--;
|
sleep_counter--;
|
||||||
if (scheduler_counter % 100 == 0)
|
if (scheduler_counter % 30 == 0)
|
||||||
scheduler((uint32_t *)regs);
|
scheduler((uint32_t *)regs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
12
src/kernel.c
12
src/kernel.c
@ -33,9 +33,11 @@
|
|||||||
|
|
||||||
static void uwu(void)
|
static void uwu(void)
|
||||||
{
|
{
|
||||||
|
pid_t pid = fork();
|
||||||
|
kprintf("pid: %d\n", pid);
|
||||||
while (1) {
|
while (1) {
|
||||||
// sleep(1000);
|
// 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();
|
cli();
|
||||||
init_gdt();
|
init_gdt();
|
||||||
init_idt();
|
init_idt();
|
||||||
init_memory(mbd, magic);
|
init_multiboot(mbd, magic);
|
||||||
|
init_memory();
|
||||||
load_drivers();
|
load_drivers();
|
||||||
terminal_initialize();
|
terminal_initialize();
|
||||||
create_process(1);
|
create_process(1);
|
||||||
create_thread(current_pcb, shell_init);
|
// create_thread(current_pcb, shell_init);
|
||||||
create_process(2);
|
create_thread(current_pcb, uwu);
|
||||||
create_thread(current_pcb->next, uwu);
|
|
||||||
toris();
|
toris();
|
||||||
while (true)
|
while (true)
|
||||||
;
|
;
|
||||||
|
|||||||
@ -27,10 +27,13 @@ __attribute__((noreturn)) void kpanic(const char *format, ...)
|
|||||||
kprintf("fault at address: %p\n", faulting_address);
|
kprintf("fault at address: %p\n", faulting_address);
|
||||||
// for (int i = 16; i < 32; i++)
|
// for (int i = 16; i < 32; i++)
|
||||||
// kprintf("%p\n", page_table1[i]);
|
// kprintf("%p\n", page_table1[i]);
|
||||||
// show_valloc_mem();
|
// show_ualloc_mem();
|
||||||
/* kprintf("\n\n"); */
|
/* kprintf("\n\n"); */
|
||||||
/* print_stack(); */
|
/* print_stack(); */
|
||||||
/* kprintf("\n\n"); */
|
/* kprintf("\n\n"); */
|
||||||
/* kprintf("PRESS SPACE TO REBOOT"); */
|
kprintf("PRESS SPACE TO REBOOT");
|
||||||
__asm__ __volatile__("jmp panic");
|
while (terminal_getkey().c != ' ')
|
||||||
|
;
|
||||||
|
reboot();
|
||||||
|
// __asm__ __volatile__("jmp panic");
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,6 +3,7 @@
|
|||||||
#include "kprintf.h"
|
#include "kprintf.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
Zone *kzones[3];
|
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)
|
int new_kzone(block_type_t type, uint32_t size)
|
||||||
{
|
{
|
||||||
// assert(current_task->pid);
|
// assert(current_task->pid);
|
||||||
void *heap = kalloc_pages(size);
|
void *heap = kalloc_pages(CEIL(size, PAGE_SIZE));
|
||||||
if (heap == NULL) {
|
if (heap == NULL) {
|
||||||
kprintf(KERN_ERR "error: alloc_frame failed\n");
|
kprintf(KERN_ERR "error: alloc_frame failed\n");
|
||||||
return (-1);
|
return (-1);
|
||||||
|
|||||||
@ -12,14 +12,15 @@
|
|||||||
static uint32_t *find_next_block(size_t nb_pages)
|
static uint32_t *find_next_block(size_t nb_pages)
|
||||||
{
|
{
|
||||||
uint32_t count = 0;
|
uint32_t count = 0;
|
||||||
for (uint32_t *pte = PTE2VA(1023, 0); pte < PTE2VA(1023, 1023); pte++) {
|
for (uint32_t *pte = PTE2VA(1023, KERNEL_PT_START);
|
||||||
if (!*pte) {
|
pte < PTE2VA(1023, KERNEL_PT_END); pte++) {
|
||||||
|
if (*pte) {
|
||||||
count = 0;
|
count = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
count++;
|
count++;
|
||||||
if (count == nb_pages)
|
if (count == nb_pages)
|
||||||
return pte - count;
|
return pte - (count - 1);
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -27,6 +28,8 @@ static uint32_t *find_next_block(size_t nb_pages)
|
|||||||
void *kalloc_pages(size_t nb_pages)
|
void *kalloc_pages(size_t nb_pages)
|
||||||
{
|
{
|
||||||
uint32_t *start = find_next_block(nb_pages);
|
uint32_t *start = find_next_block(nb_pages);
|
||||||
|
if (!start)
|
||||||
|
return NULL;
|
||||||
for (uint32_t i = 0; i < nb_pages; i++) {
|
for (uint32_t i = 0; i < nb_pages; i++) {
|
||||||
void *frame = alloc_frame();
|
void *frame = alloc_frame();
|
||||||
if (!frame) {
|
if (!frame) {
|
||||||
@ -35,7 +38,7 @@ void *kalloc_pages(size_t nb_pages)
|
|||||||
PAGE_MASK));
|
PAGE_MASK));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
assert(!((uint32_t)frame & PAGE_MASK));
|
assert((uint32_t)frame & PAGE_MASK);
|
||||||
start[i] = (uint32_t)frame | INIT_FLAGS;
|
start[i] = (uint32_t)frame | INIT_FLAGS;
|
||||||
}
|
}
|
||||||
uint32_t page_index = start - PTE2VA(1023, 0);
|
uint32_t page_index = start - PTE2VA(1023, 0);
|
||||||
|
|||||||
@ -23,17 +23,16 @@ static void lst_add_back(struct frame_zone **root, struct frame_zone *element)
|
|||||||
|
|
||||||
static void add_frame_node(multiboot_memory_map_t *mmmt)
|
static void add_frame_node(multiboot_memory_map_t *mmmt)
|
||||||
{
|
{
|
||||||
static uint32_t index;
|
static uint32_t index = 0;
|
||||||
uint32_t *pd = &boot_page_directory;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* # = kernel code
|
* # = kernel code
|
||||||
* - = blank
|
* - = blank
|
||||||
*/
|
*/
|
||||||
|
|
||||||
uint32_t start_addr = mmmt->addr;
|
uint64_t start_addr = mmmt->addr;
|
||||||
uint32_t end_addr = mmmt->addr + mmmt->len;
|
uint64_t end_addr = mmmt->addr + mmmt->len;
|
||||||
uint32_t len = mmmt->len;
|
uint64_t len = mmmt->len;
|
||||||
|
|
||||||
/** Kernel code cover all the block
|
/** Kernel code cover all the block
|
||||||
* this situation:
|
* this situation:
|
||||||
@ -60,62 +59,73 @@ static void add_frame_node(multiboot_memory_map_t *mmmt)
|
|||||||
}
|
}
|
||||||
end_addr = ROUND_CEIL(start_addr + len, PAGE_SIZE);
|
end_addr = ROUND_CEIL(start_addr + len, PAGE_SIZE);
|
||||||
|
|
||||||
pd[PDE_FRAME_ZONES] =
|
PD[PDE_FRAME_ZONES] =
|
||||||
((uint32_t)frame_zones_page_table - VIRT_OFFSET) | INIT_FLAGS;
|
((uint32_t)frame_zones_page_table - VIRT_OFFSET) | INIT_FLAGS;
|
||||||
frame_zones_page_table[index] =
|
|
||||||
((uint32_t)start_addr & PAGE_MASK) | 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)
|
||||||
|
*/
|
||||||
|
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 i = 0;
|
||||||
|
for (; i < page_needed; i++)
|
||||||
|
frame_zones_page_table[index + i] =
|
||||||
|
(((uint32_t)start_addr + i * PAGE_SIZE) & PAGE_MASK) |
|
||||||
|
INIT_FLAGS;
|
||||||
|
|
||||||
struct frame_zone *current =
|
struct frame_zone *current =
|
||||||
(struct frame_zone *)PTE2VA(PDE_FRAME_ZONES, index++);
|
(struct frame_zone *)PTE2VA(PDE_FRAME_ZONES, index);
|
||||||
|
|
||||||
current->frame_table = (uint8_t *)current + sizeof(struct frame_zone);
|
current->frame_table =
|
||||||
|
(uint8_t *)((uint32_t)current + sizeof(struct frame_zone));
|
||||||
|
|
||||||
/** 8 is cause we are using uint8_t
|
|
||||||
nb_frame = size / (PAGE_SIZE + 1 / 8)
|
|
||||||
cause we are using non decimal number
|
|
||||||
nb_frame = ((size * 8) / (PAGE_SIZE * 8 + 1))
|
|
||||||
*/
|
|
||||||
const uint32_t nb_frame = ((len * 8) / (PAGE_SIZE * 8 + 1));
|
|
||||||
current->first_free_frame = 0;
|
current->first_free_frame = 0;
|
||||||
current->next = NULL;
|
current->next = NULL;
|
||||||
current->remaining_frames = nb_frame;
|
current->remaining_frames = nb_frame;
|
||||||
current->total_frames = nb_frame;
|
current->total_frames = nb_frame;
|
||||||
|
current->addr = (void *)(uint32_t)start_addr + page_needed * PAGE_SIZE;
|
||||||
|
|
||||||
memset(current->frame_table, 0,
|
bzero(current->frame_table, frame_table_size);
|
||||||
nb_frame * sizeof(*current->frame_table));
|
|
||||||
|
|
||||||
uint32_t i = 1;
|
index += i;
|
||||||
for (; i < CEIL(nb_frame, PAGE_SIZE); i++)
|
|
||||||
frame_zones_page_table[index + i] =
|
|
||||||
((uint32_t)(start_addr + i * PAGE_SIZE) & PAGE_MASK) |
|
|
||||||
INIT_FLAGS;
|
|
||||||
current->addr = (void *)(start_addr + i * PAGE_SIZE);
|
|
||||||
index += i - 1;
|
|
||||||
lst_add_back(&head, current);
|
lst_add_back(&head, current);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void init_frame_zones(void)
|
static void init_frame_zones(void)
|
||||||
{
|
{
|
||||||
for (uint32_t i = 0; i < mmap_length; i++) {
|
for (uint32_t i = 0; i < mmap_length;
|
||||||
|
i += sizeof(multiboot_memory_map_t)) {
|
||||||
multiboot_memory_map_t *mmmt =
|
multiboot_memory_map_t *mmmt =
|
||||||
(multiboot_memory_map_t *)mmap_addr + i;
|
(multiboot_memory_map_t *)((uint32_t)mmap_addr + i);
|
||||||
if (mmmt->type == MULTIBOOT_MEMORY_AVAILABLE)
|
if (mmmt->type == MULTIBOOT_MEMORY_AVAILABLE)
|
||||||
add_frame_node(mmmt);
|
add_frame_node(mmmt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void init_memory(multiboot_info_t *mbd, uint32_t magic)
|
void init_memory()
|
||||||
{
|
{
|
||||||
init_multiboot(mbd, magic);
|
|
||||||
init_frame_zones();
|
init_frame_zones();
|
||||||
// initialize all the PTs
|
// initialize all the PTs
|
||||||
for (uint16_t i = KERNEL_PT_START; i < KERNEL_PT_END; i++) {
|
for (uint16_t i = KERNEL_PT_START; i < KERNEL_PT_END; i++) {
|
||||||
uint32_t frame = (uint32_t)alloc_frame();
|
uint32_t frame = (uint32_t)alloc_frame();
|
||||||
if (!frame)
|
if (!frame)
|
||||||
kpanic("Couldn't initialize kernel PTs\n");
|
kpanic("Couldn't initialize kernel PTs\n");
|
||||||
PD[i] = frame | RW;
|
PD[i] = frame | INIT_FLAGS;
|
||||||
|
bzero(PTE2VA(1023, i), PAGE_SIZE);
|
||||||
}
|
}
|
||||||
PD[1023] = ((uint32_t)&boot_page_directory - VIRT_OFFSET) | INIT_FLAGS;
|
|
||||||
// kalash kalash kalash sur la mélodie chez nous pas de félonie ça vient
|
// kalash kalash kalash sur la mélodie chez nous pas de félonie ça vient
|
||||||
// de Sevran les R
|
// de Sevran les R
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,6 +4,7 @@
|
|||||||
#include "kprintf.h"
|
#include "kprintf.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
Zone *vzones[3];
|
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)
|
int new_vzone(block_type_t type, uint32_t size)
|
||||||
{
|
{
|
||||||
// assert(current_task->pid);
|
// assert(current_task->pid);
|
||||||
void *heap = valloc_pages(size, NULL);
|
void *heap = ualloc_pages(CEIL(size, PAGE_SIZE));
|
||||||
if (heap == NULL) {
|
if (heap == NULL) {
|
||||||
kprintf(KERN_ERR "error: alloc_pages failed\n");
|
kprintf(KERN_ERR "error: alloc_pages failed\n");
|
||||||
return (-1);
|
return (-1);
|
||||||
@ -5,7 +5,7 @@
|
|||||||
// FULL_INFO is to display (or not) both used and unused blocks
|
// FULL_INFO is to display (or not) both used and unused blocks
|
||||||
#define FULL_INFO 1
|
#define FULL_INFO 1
|
||||||
|
|
||||||
void show_valloc_mem(void)
|
void show_ualloc_mem(void)
|
||||||
{
|
{
|
||||||
char *const zones_name[3] = {"TINY", "SMALL", "LARGE"};
|
char *const zones_name[3] = {"TINY", "SMALL", "LARGE"};
|
||||||
uint32_t total_size = 0;
|
uint32_t total_size = 0;
|
||||||
77
src/memory/user/page.c
Normal file
77
src/memory/user/page.c
Normal 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;
|
||||||
|
}
|
||||||
@ -47,7 +47,7 @@ static int unmap_zone(Zone *zone)
|
|||||||
if (right)
|
if (right)
|
||||||
right->prev = left;
|
right->prev = left;
|
||||||
unmap:
|
unmap:
|
||||||
err = vfree_pages((void *)zone, zone->size);
|
err = ufree_pages((void *)zone, zone->size);
|
||||||
if (err)
|
if (err)
|
||||||
kprintf(KERN_ERR "error: munmap failed\n");
|
kprintf(KERN_ERR "error: munmap failed\n");
|
||||||
return (err);
|
return (err);
|
||||||
@ -94,7 +94,7 @@ static int add_available(Block *available, Block *merged)
|
|||||||
* newly merged block
|
* newly merged block
|
||||||
* Finally, we add the block to the list of available blocks
|
* Finally, we add the block to the list of available blocks
|
||||||
*/
|
*/
|
||||||
void vfree(void *ptr)
|
void ufree(void *ptr)
|
||||||
{
|
{
|
||||||
if (ptr == NULL)
|
if (ptr == NULL)
|
||||||
return;
|
return;
|
||||||
@ -33,7 +33,7 @@ static Block *find_block(Zone *head, uint32_t size)
|
|||||||
* After the allocation, this will become
|
* After the allocation, this will become
|
||||||
* ... -> [5] -> [new] -> [6] -> ...
|
* ... -> [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:
|
* Let's say the metadata takes a size of 2:
|
||||||
* ... -> [metadata][data][remaining size] -> [6]
|
* ... -> [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)
|
* ptr: returns the aligned pointer of the block (after the metadata)
|
||||||
*/
|
*/
|
||||||
void *vmalloc(uint32_t size)
|
void *umalloc(uint32_t size)
|
||||||
{
|
{
|
||||||
void *ptr = NULL;
|
void *ptr = NULL;
|
||||||
|
|
||||||
if (size == 0) {
|
if (size == 0) {
|
||||||
kprintf(KERN_WARNING "vmalloc: can't vmalloc(0)\n");
|
kprintf(KERN_WARNING "umalloc: can't umalloc(0)\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2,9 +2,9 @@
|
|||||||
#include "string.h"
|
#include "string.h"
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
// Prototype for kfree and vmalloc
|
// Prototype for kfree and umalloc
|
||||||
void kfree(void *ptr);
|
void kfree(void *ptr);
|
||||||
void *vmalloc(uint32_t size);
|
void *umalloc(uint32_t size);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ptr: block to resize (undefined behavior if invalid)
|
* ptr: block to resize (undefined behavior if invalid)
|
||||||
@ -28,10 +28,10 @@ void *vrealloc(void *ptr, uint32_t size)
|
|||||||
block->sub_size = size;
|
block->sub_size = size;
|
||||||
return (ptr);
|
return (ptr);
|
||||||
}
|
}
|
||||||
new_ptr = vmalloc(size);
|
new_ptr = umalloc(size);
|
||||||
if (new_ptr == NULL)
|
if (new_ptr == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
memmove(new_ptr, ptr, block->size);
|
memmove(new_ptr, ptr, block->size);
|
||||||
vfree(ptr);
|
ufree(ptr);
|
||||||
return (new_ptr);
|
return (new_ptr);
|
||||||
}
|
}
|
||||||
@ -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;
|
|
||||||
}
|
|
||||||
@ -16,15 +16,15 @@ static void init_mmap(multiboot_info_t *mbd_virt, size_t *pt_index)
|
|||||||
{
|
{
|
||||||
// Index mbd->mmap_addr pointers
|
// Index mbd->mmap_addr pointers
|
||||||
uint32_t i = 0;
|
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] =
|
multiboot_page_table[i + *pt_index] =
|
||||||
((mbd_virt->mmap_addr + i * PAGE_SIZE) & PAGE_MASK) |
|
((mbd_virt->mmap_addr + i * PAGE_SIZE) & PAGE_MASK) |
|
||||||
INIT_FLAGS;
|
INIT_FLAGS;
|
||||||
mmap_addr =
|
mmap_addr =
|
||||||
(multiboot_memory_map_t *)(PTE2VA(PDE_MULTIBOOT, *pt_index) +
|
(multiboot_memory_map_t *)((uint32_t)PTE2VA(PDE_MULTIBOOT, *pt_index) +
|
||||||
(uint32_t)mbd_virt->mmap_addr %
|
(mbd_virt->mmap_addr %
|
||||||
PAGE_SIZE);
|
PAGE_SIZE));
|
||||||
mmap_length = mbd_virt->mmap_length / sizeof(multiboot_memory_map_t);
|
mmap_length = mbd_virt->mmap_length;
|
||||||
*pt_index += i;
|
*pt_index += i;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,8 +52,7 @@ void init_multiboot(multiboot_info_t *mbd, uint32_t magic)
|
|||||||
if (magic != MULTIBOOT_BOOTLOADER_MAGIC)
|
if (magic != MULTIBOOT_BOOTLOADER_MAGIC)
|
||||||
kpanic("invalid magic number! (git gud skill issue)");
|
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;
|
((uint32_t)multiboot_page_table - VIRT_OFFSET) | INIT_FLAGS;
|
||||||
size_t pt_index = CEIL(
|
size_t pt_index = CEIL(
|
||||||
(uint32_t)mbd % PAGE_SIZE + sizeof(multiboot_info_t), PAGE_SIZE);
|
(uint32_t)mbd % PAGE_SIZE + sizeof(multiboot_info_t), PAGE_SIZE);
|
||||||
|
|||||||
@ -4,19 +4,85 @@
|
|||||||
#include "string.h"
|
#include "string.h"
|
||||||
#include "thread.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));
|
for (size_t i = USER_PT_END / 2; PD[i]; i++) {
|
||||||
if (!new_tcb)
|
uint32_t *pt = PTE2VA(1023, i);
|
||||||
return NULL;
|
for (size_t j = 0; j < 1024; j++)
|
||||||
new_tcb->tid = thread->tid;
|
if (pt[j])
|
||||||
new_tcb->esp0 = kalloc_pages(STACK_SIZE);
|
ufree_pages(PTE2VA(i, j), 1);
|
||||||
if (!new_tcb->esp0) {
|
ufree_pages(pt, 1);
|
||||||
delete_thread(new_tcb);
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
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)
|
pid_t fork(void)
|
||||||
@ -24,15 +90,18 @@ pid_t fork(void)
|
|||||||
struct pcb *new_pcb = create_process(current_pcb->uid);
|
struct pcb *new_pcb = create_process(current_pcb->uid);
|
||||||
if (!new_pcb)
|
if (!new_pcb)
|
||||||
return -1;
|
return -1;
|
||||||
struct list *new_node = vmalloc(sizeof(struct list));
|
struct list *new_node = kmalloc(sizeof(struct list));
|
||||||
if (!new_node) {
|
if (!new_node) {
|
||||||
remove_process(new_pcb);
|
remove_process(new_pcb);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
new_pcb->daddy = current_pcb;
|
new_pcb->daddy = current_pcb;
|
||||||
lst_add_back(&new_pcb->children, new_node);
|
lst_add_back(¤t_pcb->children, new_node);
|
||||||
// loop on threads clone
|
|
||||||
thread_clone(current_pcb->thread_list->content);
|
|
||||||
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
#include "thread.h"
|
#include "thread.h"
|
||||||
|
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
struct pcb *create_process(uid_t uid)
|
struct pcb *create_process(uid_t uid)
|
||||||
{
|
{
|
||||||
@ -22,8 +23,10 @@ struct pcb *create_process(uid_t uid)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
new_pcb->cr3 =
|
new_pcb->cr3 =
|
||||||
(void *)((uint32_t)VA2PTE((uint32_t)new_pcb->heap) & PAGE_MASK);
|
(void *)((uint32_t)*VA2PTE((uint32_t)new_pcb->heap) & PAGE_MASK);
|
||||||
memcpy(new_pcb->heap, PD, 4096);
|
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->daddy = NULL;
|
||||||
new_pcb->children = NULL;
|
new_pcb->children = NULL;
|
||||||
|
|||||||
@ -20,7 +20,8 @@ static struct list *get_thread_to_switch(void)
|
|||||||
it_t = current_tcb == NULL ? NULL : current_tcb->next;
|
it_t = current_tcb == NULL ? NULL : current_tcb->next;
|
||||||
while (it_p) {
|
while (it_p) {
|
||||||
while (it_t != NULL) {
|
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;
|
return it_t;
|
||||||
it_t = it_t->next;
|
it_t = it_t->next;
|
||||||
}
|
}
|
||||||
@ -38,8 +39,6 @@ void scheduler(uint32_t *esp)
|
|||||||
struct tcb *thread_to_switch = (struct tcb *)list_node->content;
|
struct tcb *thread_to_switch = (struct tcb *)list_node->content;
|
||||||
if (current_tcb)
|
if (current_tcb)
|
||||||
CURRENT_TCB->esp = esp;
|
CURRENT_TCB->esp = esp;
|
||||||
if (thread_to_switch->process != current_pcb)
|
|
||||||
switch_process(thread_to_switch->process);
|
|
||||||
current_tcb = list_node;
|
current_tcb = list_node;
|
||||||
switch_thread(thread_to_switch->esp);
|
switch_thread(thread_to_switch);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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
|
|
||||||
@ -7,8 +7,20 @@
|
|||||||
switch_thread:
|
switch_thread:
|
||||||
|
|
||||||
mov eax, [esp + 4]
|
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
|
pop eax
|
||||||
mov ds, eax
|
mov ds, eax
|
||||||
|
|
||||||
|
|||||||
@ -7,6 +7,7 @@
|
|||||||
#include "process.h"
|
#include "process.h"
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
#include "thread.h"
|
#include "thread.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
struct tcb *create_thread(struct pcb *process, void (*entry)(void))
|
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;
|
return NULL;
|
||||||
new_tcb->tid = process->tid++;
|
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) {
|
if (!new_tcb->esp0) {
|
||||||
vfree(new_tcb);
|
ufree(new_tcb);
|
||||||
return NULL;
|
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 *stack = (uint32_t *)((uint8_t *)new_tcb->esp0 + STACK_SIZE);
|
||||||
uint32_t *esp = stack;
|
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));
|
struct list *new_node = kmalloc(sizeof(struct list));
|
||||||
if (!new_node) {
|
if (!new_node) {
|
||||||
kfree_pages(new_tcb->esp0, STACK_SIZE);
|
kfree_pages(new_tcb->esp0, STACK_SIZE);
|
||||||
vfree(new_tcb);
|
ufree(new_tcb);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
new_node->content = new_tcb;
|
new_node->content = new_tcb;
|
||||||
|
|||||||
@ -5,5 +5,5 @@
|
|||||||
void heap_cmd(char *arg)
|
void heap_cmd(char *arg)
|
||||||
{
|
{
|
||||||
(void)arg;
|
(void)arg;
|
||||||
show_valloc_mem();
|
show_ualloc_mem();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user