From 38112a883cf677fc8be9251bab674456a4775652 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maxime=20Ch=C3=A9ramy?= Date: Sat, 24 Jan 2015 15:21:29 +0100 Subject: [PATCH] mmap sur fichier (lecture) ref #207 --- applications/test.c | 6 +++++- kernel/include/memory.h | 14 ++++---------- kernel/kmalloc.c | 2 +- kernel/memory.c | 16 ++++------------ kernel/mmap.c | 17 ++++++++--------- 5 files changed, 22 insertions(+), 33 deletions(-) diff --git a/applications/test.c b/applications/test.c index a8403b56..b3952829 100644 --- a/applications/test.c +++ b/applications/test.c @@ -43,7 +43,11 @@ int main() int fd = open("/tacos/README", O_RDONLY); char* t3 = mmap(NULL, 100, PROT_READ, MAP_PRIVATE | MAP_FILE, fd, 0); - printf("%u %c\n", t3, t3[0]); + int i; + for (i = 0; i < 100; i++) { + printf("%c", t3[i]); + } + printf("\n"); return 0; } diff --git a/kernel/include/memory.h b/kernel/include/memory.h index 9fb1612b..db67ad12 100644 --- a/kernel/include/memory.h +++ b/kernel/include/memory.h @@ -154,26 +154,20 @@ paddr_t memory_next_page(struct physical_page_descr ** iterator); /** * @brief Adresse du cadre de page en arrondissant à l'inférieur. * - * Prend en argument une adresse physique et donne l'adresse du cadre + * Prend en argument une adresse et donne l'adresse du cadre * correspondant en arrondissant à l'inférieur. * - * @param value l'adresse physique à arrondir. - * - * @return l'adresse physique arrondie. */ -paddr_t memory_align_page_inf(paddr_t value); +#define ALIGN_PAGE_INF(addr) ((uint32_t)(addr) & ~(PAGE_SIZE - 1)) /** * @brief Adresse du cadre de page en arrondissant au supérieur. * - * Prend en argument une adresse physique et donne l'adresse du cadre + * Prend en argument une adresse et donne l'adresse du cadre * correspondant en arrondissant au supérieur. * - * @param value l'adresse physique à arrondir. - * - * @return l'adresse physique arrondie. */ -paddr_t memory_align_page_sup(paddr_t value); +#define ALIGN_PAGE_SUP(addr) (((uint32_t)(addr) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)) /** * @ Premier cadre de page libre au dessus du kernel diff --git a/kernel/kmalloc.c b/kernel/kmalloc.c index 7badbe91..79f305a4 100644 --- a/kernel/kmalloc.c +++ b/kernel/kmalloc.c @@ -142,7 +142,7 @@ void *kmalloc_one_aligned_page() { uint32_t tmp; allocate_new_pages(&kvm, 2, (void **) &tmp, 0); - return (void *) memory_align_page_sup((paddr_t) tmp); + return (void *) ALIGN_PAGE_SUP(tmp); } static int is_empty(struct mem_list *list) diff --git a/kernel/memory.c b/kernel/memory.c index 5b066899..b11aa40b 100644 --- a/kernel/memory.c +++ b/kernel/memory.c @@ -38,14 +38,6 @@ extern char _start, __e_kernel; static struct physical_page_descr * phys_page_descr_array; static paddr_t kernel_top; -paddr_t memory_align_page_inf(paddr_t value) { - return value - value%PAGE_SIZE; -} - -paddr_t memory_align_page_sup(paddr_t value) { - return (value + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1); -} - void memory_print_used_pages() { struct physical_page_descr *p; int c = 0; @@ -147,19 +139,19 @@ paddr_t memory_next_page(struct physical_page_descr ** iterator) { * que de cadres. */ void memory_setup(size_t ram_size) { - ram_size = memory_align_page_inf(ram_size); /* On abandonne un petit bout de mémoire pour avoir que des pages completes */ + ram_size = ALIGN_PAGE_INF(ram_size); /* On abandonne un petit bout de mémoire pour avoir que des pages completes */ /* On place le tableau de pages juste après la fin du kernel. */ - phys_page_descr_array = (struct physical_page_descr*) memory_align_page_sup((size_t)(& __e_kernel)); + phys_page_descr_array = (struct physical_page_descr*) ALIGN_PAGE_SUP((size_t)(& __e_kernel)); size_t phys_mem_base = PAGE_SIZE; /* La page d'adresse 0 est réservée pour les erreurs. (c'est un choix arbitraire) */ size_t phys_mem_top = ram_size; /* Maintenant on va récupérer les pages qui chevauchent l'emplacement où est le * kernel ainsi que la table qui contient les pages. On va les marquer utilisées. */ - paddr_t kernel_base = memory_align_page_inf((paddr_t)(& _start)); + paddr_t kernel_base = (paddr_t) ALIGN_PAGE_INF(& _start); uint32_t n_pages = ram_size / PAGE_SIZE; /* ram_size est un multiple de PAGE_SIZE ! */ - kernel_top = (paddr_t)phys_page_descr_array + memory_align_page_sup(n_pages * sizeof(struct physical_page_descr)); + kernel_top = (paddr_t)phys_page_descr_array + ALIGN_PAGE_SUP(n_pages * sizeof(struct physical_page_descr)); struct physical_page_descr *phys_page_descr = (struct physical_page_descr*) phys_page_descr_array; paddr_t phys_page_addr = phys_mem_base; /* Adresse d'une page */ diff --git a/kernel/mmap.c b/kernel/mmap.c index 4f51af0f..118fc43b 100644 --- a/kernel/mmap.c +++ b/kernel/mmap.c @@ -61,7 +61,7 @@ int is_mmaped(vaddr_t addr) { if (aux) { if (aux->addr + aux->length > addr) { - vaddr_t page_addr = addr & ~(PAGE_SIZE - 1); + vaddr_t page_addr = ALIGN_PAGE_INF(addr); map(memory_reserve_page_frame(), page_addr, 1, (aux->prot & PROT_WRITE) > 0); if (aux->flags & MAP_ANONYMOUS) { @@ -70,10 +70,10 @@ int is_mmaped(vaddr_t addr) { } else if(aux->fd > -1) { open_file_descriptor* ofd = process->fd[aux->fd]; if (ofd) { - // FIXME: l'offset n'est pas correct. - ofd->f_ops->seek(ofd, aux->offset, SEEK_SET); - // FIXME: ne peut pas lire depuis une exception... + asm("sti"); /* Et on tente de revenir au choses normales */ + ofd->f_ops->seek(ofd, aux->offset + page_addr - aux->addr, SEEK_SET); ofd->f_ops->read(ofd, (void*) page_addr, PAGE_SIZE); + asm("cli"); return 1; } else { return 0; @@ -95,9 +95,9 @@ SYSCALL_HANDLER2(sys_mmap, struct mmap_data* data, void** ret) { struct mmap_region* aux = process->list_regions; while (aux) { - vaddr_t last = aux->addr + aux->length; + vaddr_t last = ALIGN_PAGE_SUP(aux->addr + aux->length); - if (current - last > data->length) { + if (current - last >= data->length) { break; } @@ -105,14 +105,13 @@ SYSCALL_HANDLER2(sys_mmap, struct mmap_data* data, void** ret) { aux = aux->next; } - if (current - top_heap < data->length) { + *ret = (void*) ALIGN_PAGE_INF(current - data->length); + if ((vaddr_t)*ret < top_heap) { klog("out of mem"); *ret = NULL; return; } - *ret = (void*) (current - data->length); - add_region(process, (vaddr_t)*ret, data); print_regions(process);