Add: multiple process memory allocation
This commit is contained in:
		@@ -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 */
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user