Add: multiple process memory allocation

This commit is contained in:
brice.boisson 2023-09-21 17:50:46 +09:00
parent 4339d5e349
commit edb93e3967
10 changed files with 240 additions and 23 deletions

View File

@ -67,6 +67,9 @@ void init_idt(void)
.Type = 0x06, .D = 1, .DPL = 0, .P = 1 });
}
idt[14] = init_gate((struct interrupt_gate_param) { .Offset = (u32) _asm_page_fault, .SegSelect = 0x08,
.Type = 0x06, .D = 1, .DPL = 0, .P = 1 });
idt[32] = init_gate((struct interrupt_gate_param) { .Offset = (u32) _asm_irq_0, .SegSelect = 0x08,
.Type = 0x06, .D = 1, .DPL = 0, .P = 1 });

View File

@ -1,5 +1,5 @@
.extern isr_default_int, isr_clock_int, isr_kbd_int, syscall_handler
.global _asm_default_int, _asm_irq_0, _asm_irq_1, _asm_sycall_handler
.extern isr_default_int, isr_clock_int, isr_kbd_int, syscall_handler, isr_page_fault
.global _asm_default_int, _asm_irq_0, _asm_irq_1, _asm_sycall_handler, _asm_page_fault
_asm_default_int:
pushal
@ -19,6 +19,24 @@ _asm_default_int:
popal
iret
_asm_page_fault:
pushal
push %ds
push %es
push %fs
push %gs
push %ebx
mov $0x10,%bx
mov %bx,%ds
pop %ebx
call isr_page_fault
pop %gs
pop %fs
pop %es
pop %ds
popal
iret
_asm_irq_0:
pushal
push %ds

View File

@ -2,6 +2,7 @@
#define INT_H
void _asm_default_int(void);
void _asm_page_fault(void);
void _asm_irq_0(void);
void _asm_irq_1(void);
int _asm_sycall_handler(int eax, int ebx);

View File

@ -10,6 +10,11 @@ void isr_default_int(void)
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)
{
DEBUG_INFO("Enterring clock interrupt handler.");

View File

@ -8,6 +8,7 @@
#include "tss.h"
#include "launch_process.h"
#include "elf.h"
#include "userland.h"
extern char _binary_a_out_start[];
extern char _binary_a_out_end[];
@ -21,9 +22,44 @@ void main(void)
char *data_end = _binary_a_out_end;
size_t data_size = (size_t)_binary_a_out_size;
load_elf(data_start);
launch_process(0x28, 0x30000, 0x20, 0x18, 0x20);
create_new_userland_page(0);
DEBUG_INFO("PAGE DIR: %d", userland_data->userland_data[0].page_directories);
struct page_table_entry *ttt = userland_data->userland_data[0].page_directories[20].address << 12;
DEBUG_INFO("PAGE DIR: %d", ttt->address);
asm volatile (" \
mov $0x3020000, %eax \n \
mov %eax, %cr3");
// DEBUG_INFO("BIN %b", 0x13000000);
allocate_new_page(0, 0x32400000);
// asm volatile (" \
// xor $0x80000000, %eax \n \
// mov %eax, %cr0");
// u32 *data2 = 50466816;
// DEBUG_INFO("BIN %b", *data2);
// u32 *data = 83886080;
// DEBUG_INFO("BIN %b", *data);
// struct page_directory_entry *var = 0x3020000;
// DEBUG_INFO("address %d", var[76].address);
// u32 *var = 0x13000000;
u32 *var = 0x32403400;
*var = 10;
DEBUG_INFO("%d", *var);
// asm volatile (" \
// mov %0, %%eax \n \
// mov %%eax, %%cr3" : "=m" (userland_data->userland_data[0].page_directories));
// load_elf(data_start);
// launch_process(0x28, 0x30000, 0x20, 0x18, 0x20);
for (;;)
{
@ -41,7 +77,7 @@ void kernel_main(void)
init_gdt();
init_idt();
pic_init();
make_page();
create_kernel_page();
asm volatile ("sti");
main();

View File

@ -2,11 +2,17 @@
#include "debug.h"
#include "serial.h"
#include "userland.h"
struct page_directory_entry *page_dir; // = 0x3000000; //__attribute__((aligned(4096)));
struct page_table_entry *page_table; // = 0x3010000; //__attribute__((aligned(4096)));
u8 page_avl[131072] = { 0 };
int page_avl_index = 0x300000 / 8;
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)
{
@ -14,7 +20,7 @@ int find_page_avl(void)
for (int j = 0; j < 8; j++) {
if ((page_avl[i] & (1 << j)) == 0) {
page_avl_index = i;
return i * 8 + j;
return (i * 8 + j) << 12;
}
}
}
@ -25,7 +31,13 @@ int find_page_avl(void)
void set_page(int address)
{
page_avl[address / 8] |= (1 << (address % 8));
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 {
@ -95,24 +107,27 @@ struct page_table_entry create_page_table_entry(struct page_table_param param)
return page_table;
}
int make_page(void)
int create_kernel_page(void)
{
page_dir = (struct page_directory_entry *) 0x3000000;
page_table = (struct page_table_entry *) 0x3010000;
page_dir = (struct page_directory_entry *) KERNEL_PAGE_DIR;
page_table = (struct page_table_entry *) KERNEL_PAGE_TABLE;
for (int i = 0; i < 1024; i++)
for (int i = 0; i < NB_KERNEL_PAGE_DIR; i++)
{
page_table[i] = create_page_table_entry((struct page_table_param) {
.P = 1, .R_W = 1, .U = 1, .PWT = 0, .PCD = 0,
for (int j = 0; j < 1024; j++)
{
page_table[i * 1024 + j] = create_page_table_entry((struct page_table_param) {
.P = 1, .R_W = 1, .U = 0, .PWT = 0, .PCD = 0,
.A = 0, .D = 0, .PAT = 0, .G = 0,
.address = 1 * i});
.address = j + i * 1024});
}
DEBUG_INFO("PAGE_TABLE %d", &page_table[i * 1024]);
page_dir[i] = create_page_directory_entry((struct page_directory_param) {
.P = 1, .R_W = 1, .U = 0, .PWT = 0, .PCD = 0,
.A = 0, .PS = 0, .address = &page_table[i * 1024]});
}
page_dir[0] = create_page_directory_entry((struct page_directory_param) {
.P = 1, .R_W = 1, .U = 1, .PWT = 0, .PCD = 0,
.A = 0, .PS = 0, .address = page_table});
for (int i = 1; i < 1024; i++)
for (int i = NB_KERNEL_PAGE_DIR; i < 1024; i++)
{
page_dir[i] = create_page_directory_entry((struct page_directory_param) {
.P = 0, .R_W = 0, .U = 0, .PWT = 0, .PCD = 0,
@ -167,3 +182,112 @@ int make_page(void)
return 0;
}
int create_new_userland_page(int uid)
{
struct page_directory_entry *userland_page_dir = userland_data->userland_data[uid].page_directories;
struct page_table_entry *kernel_page_table = (struct page_table_entry *) KERNEL_PAGE_TABLE;
for (int i = 0; i < NB_KERNEL_PAGE_DIR; i++)
{
DEBUG_INFO("PAGE_TABLE %d", &kernel_page_table[i * 1024]);
userland_page_dir[i] = create_page_directory_entry((struct page_directory_param) {
.P = 1, .R_W = 1, .U = 0, .PWT = 0, .PCD = 0,
.A = 0, .PS = 0, .address = &kernel_page_table[i * 1024]});
}
for (int i = 0; i < 1024; i++)
{
int avl_address = find_page_avl();
set_page(avl_address);
userland_data->userland_data[uid].page_table[i] = create_page_table_entry((struct page_table_param) {
.P = 1, .R_W = 1, .U = 0, .PWT = 0, .PCD = 0,
.A = 0, .D = 0, .PAT = 0, .G = 0,
.address = (avl_address >> 12)});
}
userland_page_dir[NB_KERNEL_PAGE_DIR] = create_page_directory_entry((struct page_directory_param) {
.P = 1, .R_W = 1, .U = 0, .PWT = 0, .PCD = 0,
.A = 0, .PS = 0, .address = userland_data->userland_data[uid].page_table});
for (int i = NB_KERNEL_PAGE_DIR + 1; i < 1024; i++)
{
userland_page_dir[i] = create_page_directory_entry((struct page_directory_param) {
.P = 0, .R_W = 0, .U = 0, .PWT = 0, .PCD = 0,
.A = 0, .PS = 0, .address = 0});
}
}
// int find_empty_page(struct page_directory_entry *page_dir)
// {
// for (int i = 20; i < 1024; i++)
// {
// if (page_dir[i].address == 0)
// {
// int page_table_entry = 0;
// if (i != 20)
// {
// if ((page_table_entry = find_empty_page_table(page_dir[i - 1].address)) != -1)
// return (i - 1, )
// }
// }
// }
// return -1;
// }
// int find_empty_page_table(struct page_table_entry *page_table)
// {
// for (int i = 0; i < 1024; i++)
// {
// if (page_table[i].address == 0)
// {
// return i;
// }
// }
// return -1;
// }
// int find_last_page_dir_entry(struct page_directory_entry *page_dir)
// {
// for (int i = NB_KERNEL_PAGE_DIR; i < 1024; i++)
// {
// if (page_dir[i].address == 0)
// return i - 1;
// }
// return -1;
// }
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;
struct page_table_entry *new_page_table = USERLAND_BASE_ADDRESS + dir_address * 1024 * 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)
{
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});
}
for (struct page_table_entry *i = new_page_table; i < new_page_table + 1024; i++)
{
int avl_address = find_page_avl();
set_page(avl_address);
*i = create_page_table_entry((struct page_table_param) {
.P = 1, .R_W = 1, .U = 1, .PWT = 0, .PCD = 0,
.A = 0, .D = 0, .PAT = 0, .G = 0,
.address = (avl_address >> 12)});
}
}

View File

@ -16,7 +16,8 @@ struct page_table_entry {
u32 address : 20;
} __attribute__((packed));
int make_page(void);
int create_kernel_page(void);
int allocate_new_page(int uid, int address);
// extern struct page_directory_entry page_dir[1024];
// extern struct page_table_entry page_table[1024];

View File

@ -24,6 +24,14 @@ int init_serial()
int write_serial_nb(int nb, int ln)
{
if (nb < 0)
{
while ((inb(PORT + 5) & 0x20) == 0);
outb(PORT, '-');
write_serial_nb(-nb, ln);
return 0;
}
if (nb < 10)
{
while ((inb(PORT + 5) & 0x20) == 0);

View File

@ -1,5 +1,7 @@
#include "userland.h"
struct userlands_data *userland_data = 0x3020000;
// void userland(void)
// {
// int res = 0;

View File

@ -1,6 +1,25 @@
#ifndef USERLAND_H
#define USERLAND_H
#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;
void userland(void);
#endif /* !USERLAND_H */