feat: gestion mémoire paginée, ajout de nouvelles fonctions
This commit is contained in:
parent
f0a64729ee
commit
b6f238ff8a
|
@ -5,7 +5,9 @@
|
||||||
#include "queue.h"
|
#include "queue.h"
|
||||||
|
|
||||||
#define TOPAGE(addr) (addr) >> 12
|
#define TOPAGE(addr) (addr) >> 12
|
||||||
|
#define TOPD(addr) ((addr) & 0xFFC00000) >> 22
|
||||||
|
#define TOPT(addr) ((addr) & 0x003FF000) >> 12
|
||||||
|
#define TOPG(addr) (addr) & 0x00000FFF
|
||||||
|
|
||||||
#define PAGESIZE 4096 /* Taille d'une page */
|
#define PAGESIZE 4096 /* Taille d'une page */
|
||||||
#define PAGENUMBER 1024 /* Nombre de pages */
|
#define PAGENUMBER 1024 /* Nombre de pages */
|
||||||
|
@ -61,11 +63,9 @@ typedef TAILQ_HEAD(page_s, page) page_t;
|
||||||
/* Page directory, pour la gestion de la mémoire virtuelle */
|
/* Page directory, pour la gestion de la mémoire virtuelle */
|
||||||
typedef struct pd {
|
typedef struct pd {
|
||||||
page *addr;
|
page *addr;
|
||||||
TAILQ_ENTRY(pd) tailq;
|
page_t page_head;
|
||||||
} __attribute__ ((packed)) pd;
|
} __attribute__ ((packed)) pd;
|
||||||
|
|
||||||
typedef TAILQ_HEAD(pd_s, pd) pd_t;
|
|
||||||
|
|
||||||
/* vaddrrange, pour la gestion des pages de la mémoire virtuelle */
|
/* vaddrrange, pour la gestion des pages de la mémoire virtuelle */
|
||||||
typedef struct vrange {
|
typedef struct vrange {
|
||||||
u8 *vaddrlow;
|
u8 *vaddrlow;
|
||||||
|
@ -99,9 +99,7 @@ pd *virtual_pd_create();
|
||||||
Fonction à ajouter...pour gestion mémoire virtuelle
|
Fonction à ajouter...pour gestion mémoire virtuelle
|
||||||
u8* virtual_to_physical(u8 *vaddr)
|
u8* virtual_to_physical(u8 *vaddr)
|
||||||
|
|
||||||
pd *virtual_pd_create(void)
|
|
||||||
|
|
||||||
void virtual_pd_destroy(pd *dst)
|
|
||||||
|
|
||||||
void virtual_pd_page_remove(pd *dst, u8* vaddr)
|
void virtual_pd_page_remove(pd *dst, u8* vaddr)
|
||||||
|
|
||||||
|
@ -115,9 +113,9 @@ void virtual_range_new(pd *dst, u8 vaddr, u8 len)
|
||||||
|
|
||||||
page *virtual_page_getfree(void)
|
page *virtual_page_getfree(void)
|
||||||
|
|
||||||
void virtual_page_free(u8* vaddr)
|
void virtual_page_free(pd *dst, u8* vaddr)
|
||||||
|
|
||||||
void virtual_page_use(u8* vaddr)
|
void virtual_page_use(pd *dst, u8* vaddr)
|
||||||
|
|
||||||
void virtual_init(void)
|
void virtual_init(void)
|
||||||
|
|
||||||
|
|
85
lib/memory.c
85
lib/memory.c
|
@ -10,7 +10,7 @@
|
||||||
static pd *kerneldirectory=NULL; /* pointeur vers le page directory noyau */
|
static pd *kerneldirectory=NULL; /* pointeur vers le page directory noyau */
|
||||||
static u8 *kernelheap=NULL; /* pointeur vers le heap noyau */
|
static u8 *kernelheap=NULL; /* pointeur vers le heap noyau */
|
||||||
static u8 bitmap[MAXMEMPAGE / 8]; /* bitmap */
|
static u8 bitmap[MAXMEMPAGE / 8]; /* bitmap */
|
||||||
static vrange_t freepages;
|
static vrange_t vrange_head;
|
||||||
|
|
||||||
/*******************************************************************************/
|
/*******************************************************************************/
|
||||||
/* Erreur fatale */
|
/* Erreur fatale */
|
||||||
|
@ -199,6 +199,7 @@ void physical_init(void)
|
||||||
}
|
}
|
||||||
/*******************************************************************************/
|
/*******************************************************************************/
|
||||||
/* Allocation de page virtuelle de mémoire */
|
/* Allocation de page virtuelle de mémoire */
|
||||||
|
|
||||||
page *virtual_page_getfree(void)
|
page *virtual_page_getfree(void)
|
||||||
{
|
{
|
||||||
page *pg;
|
page *pg;
|
||||||
|
@ -207,13 +208,13 @@ page *virtual_page_getfree(void)
|
||||||
paddr = physical_page_getfree();
|
paddr = physical_page_getfree();
|
||||||
if (paddr == NULL)
|
if (paddr == NULL)
|
||||||
panic ("Plus de memoire physique disponible !\n");
|
panic ("Plus de memoire physique disponible !\n");
|
||||||
if (TAILQ_EMPTY(&freepages))
|
if (TAILQ_EMPTY(&vrange_head))
|
||||||
panic("Plus de place disponible dans la reserve de page !\n");
|
panic("Plus de place disponible dans la reserve de page !\n");
|
||||||
vpages = TAILQ_FIRST(&freepages);
|
vpages = TAILQ_FIRST(&vrange_head);
|
||||||
vaddr = vpages->vaddrlow;
|
vaddr = vpages->vaddrlow;
|
||||||
vpages->vaddrlow += PAGESIZE;
|
vpages->vaddrlow += PAGESIZE;
|
||||||
if (vpages->vaddrlow == vpages->vaddrhigh) {
|
if (vpages->vaddrlow == vpages->vaddrhigh) {
|
||||||
TAILQ_REMOVE(&freepages, vpages, tailq);
|
TAILQ_REMOVE(&vrange_head, vpages, tailq);
|
||||||
vfree(vpages);
|
vfree(vpages);
|
||||||
}
|
}
|
||||||
virtual_pd_page_add(kerneldirectory,vaddr,paddr, 0);
|
virtual_pd_page_add(kerneldirectory,vaddr,paddr, 0);
|
||||||
|
@ -243,23 +244,81 @@ pd *virtual_pd_create()
|
||||||
pdir[i] = 0;
|
pdir[i] = 0;
|
||||||
pdir[1023] = ((u32) new->addr->paddr | (PAGE_PRESENT | PAGE_WRITE));
|
pdir[1023] = ((u32) new->addr->paddr | (PAGE_PRESENT | PAGE_WRITE));
|
||||||
}
|
}
|
||||||
//TAILQ_INIT(&new->addr);
|
TAILQ_INIT(&new->page_head);
|
||||||
return new;
|
return new;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
/* Renvoie l'adresse physique de la page virtuel */
|
||||||
|
|
||||||
|
u8* virtual_to_physical(u8 *vaddr)
|
||||||
|
{
|
||||||
|
u32 *pdir;
|
||||||
|
u32 *ptable;
|
||||||
|
|
||||||
|
pdir = (u32 *) (0xFFFFF000 | (((u32) vaddr & 0xFFC00000) >> 20));
|
||||||
|
if ((*pdir & PAGE_PRESENT)) {
|
||||||
|
ptable = (u32 *) (0xFFC00000 | (((u32) vaddr & 0xFFFFF000) >> 10));
|
||||||
|
if ((*ptable & PAGE_PRESENT))
|
||||||
|
return (u8 *) ((*ptable & 0xFFFFF000) + (TOPG((u32) vaddr)));
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
/* Libère une page virtuelle de la mémoire */
|
||||||
|
|
||||||
|
void virtual_page_free(u8* vaddr)
|
||||||
|
{
|
||||||
|
vrange *next, *prev, *new;
|
||||||
|
u8 *paddr;
|
||||||
|
paddr = virtual_to_physical(vaddr);
|
||||||
|
if (paddr)
|
||||||
|
virtual_page_free(paddr);
|
||||||
|
else {
|
||||||
|
printf("Aucune page associee a l'adresse virtuelle %x\n", vaddr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
virtual_pd_page_remove(vaddr);
|
||||||
|
TAILQ_FOREACH(next, &vrange_head, tailq) {
|
||||||
|
if (next->vaddrlow > vaddr)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
prev = TAILQ_PREV(next, vrange_s, tailq);
|
||||||
|
if (prev->vaddrhigh == vaddr) {
|
||||||
|
prev->vaddrhigh += PAGESIZE;
|
||||||
|
if (prev->vaddrhigh == next->vaddrlow) {
|
||||||
|
prev->vaddrhigh = next->vaddrhigh;
|
||||||
|
TAILQ_REMOVE(&vrange_head, next, tailq);
|
||||||
|
vfree(next);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (next->vaddrlow == vaddr + PAGESIZE) {
|
||||||
|
next->vaddrlow = vaddr;
|
||||||
|
}
|
||||||
|
else if (next->vaddrlow > vaddr + PAGESIZE) {
|
||||||
|
new = (vrange*) vmalloc(sizeof(vrange));
|
||||||
|
new->vaddrlow = vaddr;
|
||||||
|
new->vaddrhigh = vaddr + PAGESIZE;
|
||||||
|
TAILQ_INSERT_BEFORE(prev, new, tailq);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
panic("Liste chainee corrompue !\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*******************************************************************************/
|
/*******************************************************************************/
|
||||||
/* Destruction d'un directory pour la gestion virtuelle de la mémoire */
|
/* Destruction d'un directory pour la gestion virtuelle de la mémoire */
|
||||||
|
|
||||||
void pd_destroy(pd *dst)
|
void virtual_pd_destroy(pd *dst)
|
||||||
{
|
{
|
||||||
page *pg;
|
page *pg;
|
||||||
list_for_each_safe(p, n, &pd->pt) {
|
TAILQ_FOREACH(pg, &dst->page_head, tailq) {
|
||||||
pg = list_entry(p, struct page, list);
|
virtual_page_free(pg->vaddr);
|
||||||
release_page_from_heap(pg->vaddr);
|
TAILQ_REMOVE(&dst->page_head, pg, tailq);
|
||||||
list_del(p);
|
|
||||||
vfree(pg);
|
vfree(pg);
|
||||||
}
|
}
|
||||||
release_page_from_heap(dst->add->vaddr);
|
virtual_page_free(dst->addr->vaddr);
|
||||||
vfree(dst);
|
vfree(dst);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -273,8 +332,8 @@ void virtual_init(void)
|
||||||
vrange *vpages = (vrange*) vmalloc(sizeof(vrange));
|
vrange *vpages = (vrange*) vmalloc(sizeof(vrange));
|
||||||
vpages->vaddrlow = (u8 *) KERNEL_HEAP;
|
vpages->vaddrlow = (u8 *) KERNEL_HEAP;
|
||||||
vpages->vaddrhigh = (u8 *) KERNEL_HEAP+MAXHEAPSIZE;
|
vpages->vaddrhigh = (u8 *) KERNEL_HEAP+MAXHEAPSIZE;
|
||||||
TAILQ_INIT(&freepages);
|
TAILQ_INIT(&vrange_head);
|
||||||
TAILQ_INSERT_TAIL(&freepages, vpages, tailq);
|
TAILQ_INSERT_TAIL(&vrange_head, vpages, tailq);
|
||||||
kerneldirectory=virtual_pd_create();
|
kerneldirectory=virtual_pd_create();
|
||||||
virtual_range_use_kernel(0x00000000, 0x00000000, KERNELSIZE);
|
virtual_range_use_kernel(0x00000000, 0x00000000, KERNELSIZE);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue