From 34b6756a381dd41dd87d98b7dfec652e76aadd4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maxime=20Ch=C3=A9ramy?= Date: Sat, 24 Jan 2015 00:15:55 +0100 Subject: [PATCH] mmap: Ajout gestion read/write. --- applications/test.c | 8 ++++---- kernel/drivers/char/vesa.c | 4 ++-- kernel/include/mmap.h | 11 +++++++++++ kernel/include/pagination.h | 2 +- kernel/include/vmm.h | 2 +- kernel/kpanic.c | 2 +- kernel/kprocess.c | 2 +- kernel/mmap.c | 2 +- kernel/pagination.c | 10 +++++----- kernel/vmm.c | 10 +++++----- libc/include/sys/mman.h | 11 +++++++++++ 11 files changed, 43 insertions(+), 21 deletions(-) diff --git a/applications/test.c b/applications/test.c index f6682a2f..2fbafbe1 100644 --- a/applications/test.c +++ b/applications/test.c @@ -32,13 +32,13 @@ int main() { - int* t = mmap(0, 800000, 0, 0, -1, 0); - t[20000] = 42; + int* t = mmap(NULL, 800000, PROT_READ , MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + //t[20000] = 42; printf("%u %d\n", t, t[20000]); - int* t2 = mmap(0, 800000, 0, 0, -1, 0); + int* t2 = mmap(NULL, 800000, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); t2[20000] = 42; printf("%u %d\n", t2, t2[20000]); return 0; -} +} diff --git a/kernel/drivers/char/vesa.c b/kernel/drivers/char/vesa.c index 950c46c6..661e6207 100644 --- a/kernel/drivers/char/vesa.c +++ b/kernel/drivers/char/vesa.c @@ -85,7 +85,7 @@ static void remap_backbuffer(paddr_t p_addr_base) { unsigned int page; for (page = 0; page < back_buffer_size/PAGE_SIZE; page++) { unmap(V_BACKBUFFER_BASE + page * PAGE_SIZE); - map(p_addr_base + page * PAGE_SIZE, V_BACKBUFFER_BASE + page * PAGE_SIZE, 1); + map(p_addr_base + page * PAGE_SIZE, V_BACKBUFFER_BASE + page * PAGE_SIZE, 1, 1); } } @@ -168,6 +168,6 @@ void init_vesa() { size_t video_mem_size = 16 * 1024 * 1024; // 16Mio unsigned int page; for (page = 0; page < video_mem_size/PAGE_SIZE; page++) { - map(p_lfb_base + page*PAGE_SIZE, V_BACKBUFFER_BASE + page*PAGE_SIZE, 1); + map(p_lfb_base + page*PAGE_SIZE, V_BACKBUFFER_BASE + page*PAGE_SIZE, 1, 1); } } diff --git a/kernel/include/mmap.h b/kernel/include/mmap.h index 2b348ab9..35229096 100644 --- a/kernel/include/mmap.h +++ b/kernel/include/mmap.h @@ -33,6 +33,17 @@ #include #include +#define PROT_NONE 0x00 /* No access. */ +#define PROT_READ 0x04 /* Pages can be read. */ +#define PROT_WRITE 0x02 /* Pages can be written. */ +#define PROT_EXEC 0x01 /* Pages can be executed. */ + +#define MAP_PRIVATE 0x00 +#define MAP_SHARED 0x10 /* Share changes. */ +#define MAP_FIXED 0x20 +#define MAP_ANONYMOUS 0x02 +#define MAP_FILE 0x01 + struct mmap_data { void *addr; size_t length; diff --git a/kernel/include/pagination.h b/kernel/include/pagination.h index 135c9646..8c5d7ee7 100644 --- a/kernel/include/pagination.h +++ b/kernel/include/pagination.h @@ -97,7 +97,7 @@ void pagination_setup(); void pagination_init_page_directory(struct page_directory_entry * pd); void pagination_init_page_directory_copy_kernel_only(struct page_directory_entry *pd, paddr_t pd_paddr); -void pagination_map(struct page_directory_entry * pagination_kernel, paddr_t page_addr, vaddr_t v_page_addr, int u_s); +void pagination_map(struct page_directory_entry * pagination_kernel, paddr_t page_addr, vaddr_t v_page_addr, int u_s, int r_w); int pagination_create_page_dir(struct page_directory_entry *pagination_kernel, int index_pd, int u_s); static inline void pagination_load_page_directory(struct page_directory_entry * pd) __attribute__((always_inline)); diff --git a/kernel/include/vmm.h b/kernel/include/vmm.h index eb41564e..f987c62f 100644 --- a/kernel/include/vmm.h +++ b/kernel/include/vmm.h @@ -106,7 +106,7 @@ void sys_vmm(uint32_t min_size, void **alloc, size_t *real_alloc_size); struct page_table_entry *get_pte(int dir, int table); paddr_t vmm_get_page_paddr(vaddr_t vaddr); -int map(paddr_t phys_page_addr, vaddr_t virt_page_addr, int u_s); +int map(paddr_t phys_page_addr, vaddr_t virt_page_addr, int u_s, int r_w); void unmap(vaddr_t virt_page_addr); #endif diff --git a/kernel/kpanic.c b/kernel/kpanic.c index 46d87fc4..d148d1b0 100644 --- a/kernel/kpanic.c +++ b/kernel/kpanic.c @@ -206,7 +206,7 @@ static void kpanic_main_report(uint32_t error_id, uint32_t error_code, process_t static void kpanic_handler(uint32_t error_id, uint32_t error_code) { - if (error_id == EXCEPTION_PAGE_FAULT) { + if (error_id == EXCEPTION_PAGE_FAULT && !(error_code & 1)) { uint32_t address; /* On récupère le registre cr2 qui contient l'addresse virtuelle à l'origine de l'exception */ asm("mov %%cr2, %%eax":"=a"(address)); diff --git a/kernel/kprocess.c b/kernel/kprocess.c index 5d712d2b..bedf1083 100644 --- a/kernel/kprocess.c +++ b/kernel/kprocess.c @@ -353,7 +353,7 @@ static process_t* create_process_elf(process_init_data_t* init_data) // Allocation stack (attention à ne pas dépasser 8 Mio en l'état) for(i = 1; i <= stack_pages; i++) - map(memory_reserve_page_frame(), USER_PROCESS_STACK - i*PAGE_SIZE, 1); + map(memory_reserve_page_frame(), USER_PROCESS_STACK - i*PAGE_SIZE, 1, 1); /* Copie du programme au bon endroit */ memcpy((void*)USER_PROCESS_BASE, (void*)init_data_dup->data, init_data_dup->mem_size); diff --git a/kernel/mmap.c b/kernel/mmap.c index 03428c7b..ef8a8d18 100644 --- a/kernel/mmap.c +++ b/kernel/mmap.c @@ -59,7 +59,7 @@ int is_mmaped(vaddr_t addr) { if (aux->addr + aux->length > addr) { int page_addr = addr & ~(PAGE_SIZE - 1); // mmap anonyme pour le moment : - map(memory_reserve_page_frame(), page_addr,1); + map(memory_reserve_page_frame(), page_addr, 1, (aux->prot & PROT_WRITE) > 0); memset((void*)page_addr, 0, PAGE_SIZE); return 1; } diff --git a/kernel/pagination.c b/kernel/pagination.c index 3772026e..0acc2edb 100644 --- a/kernel/pagination.c +++ b/kernel/pagination.c @@ -64,7 +64,7 @@ int pagination_create_page_dir(struct page_directory_entry *pagination_kernel, i //} // On map la table de page - pagination_map(pagination_kernel, pt_addr, get_page_table_vaddr(index_pd), 1); + pagination_map(pagination_kernel, pt_addr, get_page_table_vaddr(index_pd), 1, 1); struct page_table_entry *pt; if (pagination_activated) { @@ -79,7 +79,7 @@ int pagination_create_page_dir(struct page_directory_entry *pagination_kernel, i return 0; } -void pagination_map(struct page_directory_entry * pagination_kernel, paddr_t page_addr, vaddr_t v_page_addr, int u_s) { +void pagination_map(struct page_directory_entry * pagination_kernel, paddr_t page_addr, vaddr_t v_page_addr, int u_s, int r_w) { int index_pd = v_page_addr >> 22; int index_pt = (v_page_addr & 0x003FF000) >> 12; @@ -98,7 +98,7 @@ void pagination_map(struct page_directory_entry * pagination_kernel, paddr_t pag pte->present = 1; pte->page_addr = page_addr >> 12; - pte->r_w = 1; + pte->r_w = r_w; pte->u_s = u_s; } @@ -112,7 +112,7 @@ void pagination_map(struct page_directory_entry * pagination_kernel, paddr_t pag * @param page_addr */ static void pagination_identity_map_addr(struct page_directory_entry * pagination_kernel, paddr_t page_addr) { - pagination_map(pagination_kernel, page_addr, page_addr, 1); + pagination_map(pagination_kernel, page_addr, page_addr, 1, 1); } static void pagination_create_page_table_for_kernel(struct page_directory_entry *pagination_kernel) { @@ -139,7 +139,7 @@ void pagination_setup() { pagination_init_page_directory(pagination_kernel); pagination_map(pagination_kernel, (paddr_t) pagination_kernel, - page_dir_vaddr, 1); + page_dir_vaddr, 1, 1); // identity mapping : paddr_t current_page; diff --git a/kernel/vmm.c b/kernel/vmm.c index a4f3f981..bd42eab6 100644 --- a/kernel/vmm.c +++ b/kernel/vmm.c @@ -137,9 +137,9 @@ vaddr_t get_linear_address(int dir, int table, int offset) // Map dans le répertoire des pages une nouvelle page -int map(paddr_t phys_page_addr, vaddr_t virt_page_addr, int u_s) +int map(paddr_t phys_page_addr, vaddr_t virt_page_addr, int u_s, int r_w) { - pagination_map((struct page_directory_entry *) PDE_MAGIC, phys_page_addr, virt_page_addr, u_s); + pagination_map((struct page_directory_entry *) PDE_MAGIC, phys_page_addr, virt_page_addr, u_s, r_w); return 0; } @@ -161,7 +161,7 @@ void init_vmm(struct virtual_mem *kvm) { vaddr_t page_sup_end_kernel = memory_get_kernel_top(); - map(memory_reserve_page_frame(), page_sup_end_kernel, 0); + map(memory_reserve_page_frame(), page_sup_end_kernel, 0, 1); kvm->free_slabs.begin = (struct slab *) page_sup_end_kernel; kvm->free_slabs.begin->prev = NULL; @@ -182,7 +182,7 @@ void init_process_vm(struct virtual_mem *vm, int init_nb_pages) vaddr_t vm_begin = _PAGINATION_KERNEL_TOP; for(i = 0; i < (init_nb_pages+1); i++) - map(memory_reserve_page_frame(), vm_begin + i*PAGE_SIZE, 1); //XXX: u_s = 0 ? + map(memory_reserve_page_frame(), vm_begin + i*PAGE_SIZE, 1, 1); //XXX: u_s = 0 ? //vm->used_slabs.begin = (struct slab *) vm_begin; vm->used_slabs.begin = (struct slab *) (vm_begin + init_nb_pages*PAGE_SIZE - sizeof(struct slab)); @@ -209,7 +209,7 @@ static int increase_heap(struct virtual_mem *vm, unsigned int nb_pages, int u_s) for (i = 0; i < nb_pages; i++){ paddr_t paddr = memory_reserve_page_frame(); - if(!paddr || map(paddr, vm->vmm_top, u_s) == -1) + if(!paddr || map(paddr, vm->vmm_top, u_s, 1) == -1) return -1; vm->vmm_top += PAGE_SIZE; } diff --git a/libc/include/sys/mman.h b/libc/include/sys/mman.h index f67c2ea4..50ba081a 100644 --- a/libc/include/sys/mman.h +++ b/libc/include/sys/mman.h @@ -32,6 +32,17 @@ #include +#define PROT_NONE 0x00 /* No access. */ +#define PROT_READ 0x04 /* Pages can be read. */ +#define PROT_WRITE 0x02 /* Pages can be written. */ +#define PROT_EXEC 0x01 /* Pages can be executed. */ + +#define MAP_PRIVATE 0x00 +#define MAP_SHARED 0x10 /* Share changes. */ +#define MAP_FIXED 0x20 +#define MAP_ANONYMOUS 0x02 +#define MAP_FILE 0x01 + void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset); int munmap(void *addr, size_t length);