Add: multiple process memory allocation
This commit is contained in:
parent
4339d5e349
commit
edb93e3967
|
@ -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 });
|
||||
|
||||
|
|
22
src/int.S
22
src/int.S
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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.");
|
||||
|
|
42
src/kernel.c
42
src/kernel.c
|
@ -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();
|
||||
|
|
154
src/paging.c
154
src/paging.c
|
@ -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;
|
||||
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)});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#include "userland.h"
|
||||
|
||||
struct userlands_data *userland_data = 0x3020000;
|
||||
|
||||
// void userland(void)
|
||||
// {
|
||||
// int res = 0;
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in New Issue