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 });
|
.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,
|
idt[32] = init_gate((struct interrupt_gate_param) { .Offset = (u32) _asm_irq_0, .SegSelect = 0x08,
|
||||||
.Type = 0x06, .D = 1, .DPL = 0, .P = 1 });
|
.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
|
.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
|
.global _asm_default_int, _asm_irq_0, _asm_irq_1, _asm_sycall_handler, _asm_page_fault
|
||||||
|
|
||||||
_asm_default_int:
|
_asm_default_int:
|
||||||
pushal
|
pushal
|
||||||
|
@ -19,6 +19,24 @@ _asm_default_int:
|
||||||
popal
|
popal
|
||||||
iret
|
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:
|
_asm_irq_0:
|
||||||
pushal
|
pushal
|
||||||
push %ds
|
push %ds
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#define INT_H
|
#define INT_H
|
||||||
|
|
||||||
void _asm_default_int(void);
|
void _asm_default_int(void);
|
||||||
|
void _asm_page_fault(void);
|
||||||
void _asm_irq_0(void);
|
void _asm_irq_0(void);
|
||||||
void _asm_irq_1(void);
|
void _asm_irq_1(void);
|
||||||
int _asm_sycall_handler(int eax, int ebx);
|
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.");
|
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)
|
void isr_clock_int(void)
|
||||||
{
|
{
|
||||||
DEBUG_INFO("Enterring clock interrupt handler.");
|
DEBUG_INFO("Enterring clock interrupt handler.");
|
||||||
|
|
42
src/kernel.c
42
src/kernel.c
|
@ -8,6 +8,7 @@
|
||||||
#include "tss.h"
|
#include "tss.h"
|
||||||
#include "launch_process.h"
|
#include "launch_process.h"
|
||||||
#include "elf.h"
|
#include "elf.h"
|
||||||
|
#include "userland.h"
|
||||||
|
|
||||||
extern char _binary_a_out_start[];
|
extern char _binary_a_out_start[];
|
||||||
extern char _binary_a_out_end[];
|
extern char _binary_a_out_end[];
|
||||||
|
@ -21,9 +22,44 @@ void main(void)
|
||||||
char *data_end = _binary_a_out_end;
|
char *data_end = _binary_a_out_end;
|
||||||
size_t data_size = (size_t)_binary_a_out_size;
|
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 (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
|
@ -41,7 +77,7 @@ void kernel_main(void)
|
||||||
init_gdt();
|
init_gdt();
|
||||||
init_idt();
|
init_idt();
|
||||||
pic_init();
|
pic_init();
|
||||||
make_page();
|
create_kernel_page();
|
||||||
asm volatile ("sti");
|
asm volatile ("sti");
|
||||||
|
|
||||||
main();
|
main();
|
||||||
|
|
154
src/paging.c
154
src/paging.c
|
@ -2,11 +2,17 @@
|
||||||
|
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "serial.h"
|
#include "serial.h"
|
||||||
|
#include "userland.h"
|
||||||
|
|
||||||
struct page_directory_entry *page_dir; // = 0x3000000; //__attribute__((aligned(4096)));
|
struct page_directory_entry *page_dir; // = 0x3000000; //__attribute__((aligned(4096)));
|
||||||
struct page_table_entry *page_table; // = 0x3010000; //__attribute__((aligned(4096)));
|
struct page_table_entry *page_table; // = 0x3010000; //__attribute__((aligned(4096)));
|
||||||
u8 page_avl[131072] = {0};
|
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)
|
int find_page_avl(void)
|
||||||
{
|
{
|
||||||
|
@ -14,7 +20,7 @@ int find_page_avl(void)
|
||||||
for (int j = 0; j < 8; j++) {
|
for (int j = 0; j < 8; j++) {
|
||||||
if ((page_avl[i] & (1 << j)) == 0) {
|
if ((page_avl[i] & (1 << j)) == 0) {
|
||||||
page_avl_index = i;
|
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)
|
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 {
|
struct page_directory_param {
|
||||||
|
@ -95,24 +107,27 @@ struct page_table_entry create_page_table_entry(struct page_table_param param)
|
||||||
return page_table;
|
return page_table;
|
||||||
}
|
}
|
||||||
|
|
||||||
int make_page(void)
|
int create_kernel_page(void)
|
||||||
{
|
{
|
||||||
page_dir = (struct page_directory_entry *) 0x3000000;
|
page_dir = (struct page_directory_entry *) KERNEL_PAGE_DIR;
|
||||||
page_table = (struct page_table_entry *) 0x3010000;
|
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) {
|
for (int j = 0; j < 1024; j++)
|
||||||
.P = 1, .R_W = 1, .U = 1, .PWT = 0, .PCD = 0,
|
{
|
||||||
|
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,
|
.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) {
|
for (int i = NB_KERNEL_PAGE_DIR; i < 1024; i++)
|
||||||
.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++)
|
|
||||||
{
|
{
|
||||||
page_dir[i] = create_page_directory_entry((struct page_directory_param) {
|
page_dir[i] = create_page_directory_entry((struct page_directory_param) {
|
||||||
.P = 0, .R_W = 0, .U = 0, .PWT = 0, .PCD = 0,
|
.P = 0, .R_W = 0, .U = 0, .PWT = 0, .PCD = 0,
|
||||||
|
@ -167,3 +182,112 @@ int make_page(void)
|
||||||
|
|
||||||
return 0;
|
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;
|
u32 address : 20;
|
||||||
} __attribute__((packed));
|
} __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_directory_entry page_dir[1024];
|
||||||
// extern struct page_table_entry page_table[1024];
|
// extern struct page_table_entry page_table[1024];
|
||||||
|
|
|
@ -24,6 +24,14 @@ int init_serial()
|
||||||
|
|
||||||
int write_serial_nb(int nb, int ln)
|
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)
|
if (nb < 10)
|
||||||
{
|
{
|
||||||
while ((inb(PORT + 5) & 0x20) == 0);
|
while ((inb(PORT + 5) & 0x20) == 0);
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
#include "userland.h"
|
#include "userland.h"
|
||||||
|
|
||||||
|
struct userlands_data *userland_data = 0x3020000;
|
||||||
|
|
||||||
// void userland(void)
|
// void userland(void)
|
||||||
// {
|
// {
|
||||||
// int res = 0;
|
// int res = 0;
|
||||||
|
|
|
@ -1,6 +1,25 @@
|
||||||
#ifndef USERLAND_H
|
#ifndef USERLAND_H
|
||||||
#define 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);
|
void userland(void);
|
||||||
|
|
||||||
#endif /* !USERLAND_H */
|
#endif /* !USERLAND_H */
|
||||||
|
|
Loading…
Reference in New Issue