fix: remapping en mode paginé du Framebuffer dans l'espace noyau, correction diverses malloc...etc

This commit is contained in:
Nicolas Hordé 2018-11-29 13:42:07 +01:00
parent f399a6bf5c
commit 6fa1bd6c2e
9 changed files with 59 additions and 20 deletions

View File

@ -20,13 +20,14 @@
#define KERNEL_CODE_ADDR 0x00100000 /* adresse du code du noyau */ #define KERNEL_CODE_ADDR 0x00100000 /* adresse du code du noyau */
#define KERNEL_PAGES 0x00800000 /* adresse des pages */ #define KERNEL_PAGES 0x00800000 /* adresse des pages */
#define KERNEL_HEAP 0x10000000 /* adresse du heap */ #define KERNEL_HEAP 0x10000000 /* adresse du heap */
#define VESA_FBMEM 0x38000000 /* adresse du framebuffer VESA */
#define USER_CODE 0x40000000 /* adresse du code utilisateur */ #define USER_CODE 0x40000000 /* adresse du code utilisateur */
#define USER_STACK 0xE0000000 /* adresse de la pile utilisateur */ #define USER_STACK 0xE0000000 /* adresse de la pile utilisateur */
/* limites de la mémoire 32 bits */ /* limites de la mémoire 32 bits */
#define MAXMEMSIZE 0x100000000 #define MAXMEMSIZE 0x100000000
#define MAXMEMPAGE 1024*1024 #define MAXMEMPAGE 1024*1024
#define MAXHEAPSIZE USER_CODE-KERNEL_HEAP #define MAXHEAPSIZE VESA_FBMEM-KERNEL_HEAP
#define MAXPAGESSIZE KERNEL_HEAP-KERNEL_PAGES #define MAXPAGESSIZE KERNEL_HEAP-KERNEL_PAGES
/* page directory */ /* page directory */
@ -36,7 +37,7 @@
#define PAGE_ALL 0b000000100 /* accessible user & supervisor */ #define PAGE_ALL 0b000000100 /* accessible user & supervisor */
#define PAGE_WTROUGH 0b000001000 /* write-through cache */ #define PAGE_WTROUGH 0b000001000 /* write-through cache */
#define PAGE_NOCACHE 0b000010000 /* cache desactivé */ #define PAGE_NOCACHE 0b000010000 /* cache desactivé */
#define PAGE_ACCESS 0b000100000 /* cache desactivé */ #define PAGE_ACCESS 0b000100000 /* page accedée */
#define PAGE_4MB 0b010000000 /* page de 4mb au lieu de 4k (NECESSITE PSE)*/ #define PAGE_4MB 0b010000000 /* page de 4mb au lieu de 4k (NECESSITE PSE)*/
/* page table */ /* page table */

View File

@ -7,6 +7,7 @@
#define STATE 0x3da #define STATE 0x3da
/* fonction obligatoires */ /* fonction obligatoires */
void VESA_remap_memory(u32 vaddr);
u8 *VESA_detect_hardware (void); u8 *VESA_detect_hardware (void);
u8 VESA_setvideo_mode (u8 mode); u8 VESA_setvideo_mode (u8 mode);
u8 *VESA_getvideo_drivername (void); u8 *VESA_getvideo_drivername (void);
@ -23,6 +24,7 @@ void VESA_dummy ();
static videofonction vesafonctions = static videofonction vesafonctions =
{ {
&VESA_remap_memory,
&VESA_detect_hardware, &VESA_detect_hardware,
&VESA_setvideo_mode, &VESA_setvideo_mode,
&VESA_getvideo_drivername, &VESA_getvideo_drivername,

View File

@ -6,7 +6,7 @@
#define TEXTSCREEN 0xB8000 /* debut de la memoire video texte*/ #define TEXTSCREEN 0xB8000 /* debut de la memoire video texte*/
#define GRPHSCREEN 0xA0000 /* debut de la memoire video graphique*/ #define GRPHSCREEN 0xA0000 /* debut de la memoire video graphique*/
#define ENDOFVMEM 0xC0000
/* Registres VGAs */ /* Registres VGAs */
@ -93,6 +93,7 @@ typedef struct vgamode {
} vgamode __attribute__ ((packed)); } vgamode __attribute__ ((packed));
/* fonction obligatoires */ /* fonction obligatoires */
void VGA_remap_memory(u32 vaddr);
u8 *VGA_detect_hardware (void); u8 *VGA_detect_hardware (void);
u8 VGA_setvideo_mode (u8 mode); u8 VGA_setvideo_mode (u8 mode);
u8 *VGA_getvideo_drivername (void); u8 *VGA_getvideo_drivername (void);
@ -117,6 +118,7 @@ void VGA_blink_disable (void);
static videofonction vgafonctions = static videofonction vgafonctions =
{ {
&VGA_remap_memory,
&VGA_detect_hardware, &VGA_detect_hardware,
&VGA_setvideo_mode, &VGA_setvideo_mode,
&VGA_getvideo_drivername, &VGA_getvideo_drivername,

View File

@ -42,6 +42,7 @@ typedef struct videoinfos {
} videoinfos __attribute__ ((packed)); } videoinfos __attribute__ ((packed));
typedef struct videofonction { typedef struct videofonction {
void (*remap_memory)();
u8 *(*detect_hardware)(); u8 *(*detect_hardware)();
u8 (*setvideo_mode) (); u8 (*setvideo_mode) ();
u8 *(*getvideo_drivername) (); u8 *(*getvideo_drivername) ();
@ -150,6 +151,7 @@ void apply_driver(u8* name);
void apply_nextvideomode(void); void apply_nextvideomode(void);
/* Fonctions du pilote */ /* Fonctions du pilote */
void (*remap_memory) (u32 vaddr);
u8 *(*detect_hardware) (void); u8 *(*detect_hardware) (void);
u8 (*setvideo_mode) (u8 mode); u8 (*setvideo_mode) (u8 mode);
u8 *(*getvideo_drivername) (void); u8 *(*getvideo_drivername) (void);

View File

@ -7,7 +7,7 @@
#include "queue.h" #include "queue.h"
#include "asm.h" #include "asm.h"
static u8 *kernelheap=NULL; /* pointeur vers le heap noyau */ static u8 *kernelcurrentheap=NULL; /* pointeur vers le heap noyau */
static u8 bitmap[MAXMEMPAGE / 8]; /* bitmap */ static u8 bitmap[MAXMEMPAGE / 8]; /* bitmap */
static vrange_t vrange_head; static vrange_t vrange_head;
@ -27,10 +27,11 @@ tmalloc *mallocpage(u8 size)
tmalloc *chunk; tmalloc *chunk;
u8 *paddr; u8 *paddr;
u32 realsize=size * PAGESIZE; u32 realsize=size * PAGESIZE;
if ((kernelheap - KERNEL_HEAP + realsize) > MAXHEAPSIZE) if ((kernelcurrentheap - KERNEL_HEAP + realsize) > MAXHEAPSIZE)
panic("Plus de memoire noyau heap disponible a allouer !\n"); panic("Plus de memoire noyau heap disponible a allouer !\n");
chunk = (tmalloc *) kernelheap; chunk = (tmalloc *) kernelcurrentheap;
virtual_range_new_kernel(kernelheap, realsize); virtual_range_new_kernel(kernelcurrentheap, realsize);
kernelcurrentheap += realsize;
chunk->size = realsize; chunk->size = realsize;
chunk->used = 0; chunk->used = 0;
return chunk; return chunk;
@ -46,15 +47,15 @@ void *vmalloc(u32 size)
realsize = sizeof(tmalloc) + size; realsize = sizeof(tmalloc) + size;
if (realsize < MALLOC_MINIMUM) if (realsize < MALLOC_MINIMUM)
realsize = MALLOC_MINIMUM; realsize = MALLOC_MINIMUM;
chunk = kernelheap; chunk = KERNEL_HEAP;
while (chunk->used || chunk->size < realsize) { while (chunk->used || chunk->size < realsize) {
if (chunk->size == 0) if (chunk->size == 0)
panic(sprintf("Element du heap %x defectueux avec une taille nulle (heap %x) !",chunk, kernelheap)); panic(sprintf("Element du heap %x defectueux avec une taille nulle (heap %x) !",chunk, kernelcurrentheap));
chunk = chunk + chunk->size; chunk = chunk + chunk->size;
if (chunk == (tmalloc *) kernelheap) if (chunk == (tmalloc *) kernelcurrentheap)
mallocpage((realsize / PAGESIZE) + 1); mallocpage((realsize / PAGESIZE) + 1);
else if (chunk > (tmalloc *) kernelheap) else if (chunk > (tmalloc *) kernelcurrentheap)
panic (sprintf("Element du heap %x depassant la limite %x !",chunk, kernelheap)); panic (sprintf("Element du heap %x depassant la limite %x !",chunk, kernelcurrentheap));
} }
if (chunk->size - realsize < MALLOC_MINIMUM) if (chunk->size - realsize < MALLOC_MINIMUM)
chunk->used = 1; chunk->used = 1;
@ -76,7 +77,7 @@ void vfree(void *vaddr)
tmalloc *chunk, *new; tmalloc *chunk, *new;
chunk = (tmalloc *) (vaddr - sizeof(tmalloc)); chunk = (tmalloc *) (vaddr - sizeof(tmalloc));
chunk->used = 0; chunk->used = 0;
while ((new = (tmalloc *) chunk + chunk->size) && new < (tmalloc *) kernelheap && new->used == 0) while ((new = (tmalloc *) chunk + chunk->size) && new < (tmalloc *) kernelcurrentheap && new->used == 0)
chunk->size += new->size; chunk->size += new->size;
} }
@ -311,6 +312,7 @@ u8* virtual_to_physical(u8 *vaddr)
/*******************************************************************************/ /*******************************************************************************/
/* Détermine une plage virtuelle de mémoire comme étant mappé aux adresses physiques spécifiées GENERIQUE*/ /* Détermine une plage virtuelle de mémoire comme étant mappé aux adresses physiques spécifiées GENERIQUE*/
void virtual_range_use(pd *dst, u8 *vaddr, u8 *paddr, u64 len, u32 flags) void virtual_range_use(pd *dst, u8 *vaddr, u8 *paddr, u64 len, u32 flags)
{ {
u64 i; u64 i;
@ -322,13 +324,17 @@ void virtual_range_use(pd *dst, u8 *vaddr, u8 *paddr, u64 len, u32 flags)
pg = (page *) vmalloc(sizeof(page)); pg = (page *) vmalloc(sizeof(page));
pg->paddr = paddr+i*PAGESIZE; pg->paddr = paddr+i*PAGESIZE;
pg->vaddr = vaddr+i*PAGESIZE; pg->vaddr = vaddr+i*PAGESIZE;
TAILQ_INSERT_TAIL(&dst->page_head, pg, tailq); if (dst!=NULL)
TAILQ_INSERT_TAIL(&dst->page_head, pg, tailq);
else
vfree(pg);
virtual_pd_page_add(dst, pg->vaddr, pg->paddr, flags); virtual_pd_page_add(dst, pg->vaddr, pg->paddr, flags);
} }
} }
/*******************************************************************************/ /*******************************************************************************/
/* Supprime une plage virtuelle de mémoire GENERIQUE */ /* Supprime une plage virtuelle de mémoire GENERIQUE */
void virtual_range_free(pd *dst, u8 *vaddr, u64 len) void virtual_range_free(pd *dst, u8 *vaddr, u64 len)
{ {
u64 i; u64 i;
@ -343,6 +349,7 @@ void virtual_range_free(pd *dst, u8 *vaddr, u64 len)
/*******************************************************************************/ /*******************************************************************************/
/* Détermine une plage virtuelle de mémoire en attribuant de la mémoire physique GENERIQUE */ /* Détermine une plage virtuelle de mémoire en attribuant de la mémoire physique GENERIQUE */
void virtual_range_new(pd *dst, u8 *vaddr, u64 len, u32 flags) void virtual_range_new(pd *dst, u8 *vaddr, u64 len, u32 flags)
{ {
u64 i; u64 i;
@ -354,7 +361,10 @@ void virtual_range_new(pd *dst, u8 *vaddr, u64 len, u32 flags)
pg = (page *) vmalloc(sizeof(page)); pg = (page *) vmalloc(sizeof(page));
pg->paddr = physical_page_getfree(); pg->paddr = physical_page_getfree();
pg->vaddr = (u8 *) (vaddr+i*PAGESIZE); pg->vaddr = (u8 *) (vaddr+i*PAGESIZE);
TAILQ_INSERT_TAIL(&dst->page_head, pg, tailq); if (dst!=NULL)
TAILQ_INSERT_TAIL(&dst->page_head, pg, tailq);
else
vfree(pg);
virtual_pd_page_add(dst, pg->vaddr, pg->paddr, flags); virtual_pd_page_add(dst, pg->vaddr, pg->paddr, flags);
} }
} }
@ -443,15 +453,16 @@ void virtual_pd_destroy(pd *dst)
/*******************************************************************************/ /*******************************************************************************/
/* Initialise une pages virtuelles (size) pour le heap du noyau */ /* Initialise une pages virtuelles (size) pour le heap du noyau */
void malloc_init(void) void malloc_init(void)
{ {
kernelheap=KERNEL_HEAP;
tmalloc *chunk; tmalloc *chunk;
chunk = (tmalloc *) kernelheap; chunk = (tmalloc *) KERNEL_HEAP;
virtual_pd_page_add(NULL, KERNEL_HEAP, physical_page_getfree(), PAGE_NOFLAG); virtual_pd_page_add(NULL, KERNEL_HEAP, physical_page_getfree(), PAGE_NOFLAG);
kernelcurrentheap=KERNEL_HEAP+PAGESIZE;
chunk->size = PAGESIZE; chunk->size = PAGESIZE;
chunk->used = 0; chunk->used = 0;
//virtual_range_new_kernel(kernelheap, chunk->size, PAGE_NOFLAG); //virtual_range_new_kernel(kernelcurrentheap, chunk->size, PAGE_NOFLAG);
} }
@ -461,7 +472,7 @@ void malloc_init(void)
void virtual_init(void) void virtual_init(void)
{ {
vrange *vpages = (vrange*) vmalloc(sizeof(vrange)); vrange *vpages = (vrange*) vmalloc(sizeof(vrange));
vpages->vaddrlow = (u8 *) KERNEL_HEAP+1; vpages->vaddrlow = (u8 *) KERNEL_HEAP+PAGESIZE;
vpages->vaddrhigh = (u8 *) KERNEL_HEAP+MAXHEAPSIZE; vpages->vaddrhigh = (u8 *) KERNEL_HEAP+MAXHEAPSIZE;
TAILQ_INIT(&vrange_head); TAILQ_INIT(&vrange_head);
TAILQ_INSERT_TAIL(&vrange_head, vpages, tailq); TAILQ_INSERT_TAIL(&vrange_head, vpages, tailq);

View File

@ -14,9 +14,20 @@ static capabilities vesacapabilities[] = {
{0xFF,000,000,false, 0, 0}, {0xFF,000,000,false, 0, 0},
}; };
/*******************************************************************************/
/* Deplace l'adresse virtuelle en mode paginee */
void VESA_remap_memory(u32 vaddr) {
struct multiboot_tag_framebuffer *tagfb = getgrubinfo_fb();
u32 len=infos.pagesize*2;
u32 paddr=tagfb->common.framebuffer_addr;
virtual_range_use_kernel(vaddr, paddr, len, PAGE_NOFLAG);
infos.baseaddress=vaddr;
}
/*******************************************************************************/ /*******************************************************************************/
/* Detecte si le hardware est disponible, return NULL ou pointeur sur le type de pilote */ /* Detecte si le hardware est disponible, return NULL ou pointeur sur le type de pilote */
u8 *VESA_detect_hardware(void) { u8 *VESA_detect_hardware(void) {
struct multiboot_tag_framebuffer *tagfb = getgrubinfo_fb(); struct multiboot_tag_framebuffer *tagfb = getgrubinfo_fb();
switch (tagfb->common.framebuffer_type) switch (tagfb->common.framebuffer_type)

View File

@ -10,6 +10,13 @@
static videoinfos infos; static videoinfos infos;
/*******************************************************************************/
/* Deplace l'adresse virtuelle en mode paginee */
void VGA_remap_memory(u32 vaddr) {
virtual_range_use_kernel(vaddr, GRPHSCREEN, ENDOFVMEM-GRPHSCREEN, PAGE_NOFLAG);
}
/*******************************************************************************/ /*******************************************************************************/
/* Detecte si le hardware est disponible, return NULL ou pointeur sur le type de pilote */ /* Detecte si le hardware est disponible, return NULL ou pointeur sur le type de pilote */
u8 *VGA_detect_hardware(void) { u8 *VGA_detect_hardware(void) {

View File

@ -396,6 +396,7 @@ void apply_driver(u8* name)
u32 i=0; u32 i=0;
while (registred[i].nom!=NULL && i<MAXDRIVERS) { while (registred[i].nom!=NULL && i<MAXDRIVERS) {
if (strcmp(name,registred[i].nom)==0) { if (strcmp(name,registred[i].nom)==0) {
remap_memory=registred[i].pointer->remap_memory;
detect_hardware=registred[i].pointer->detect_hardware; detect_hardware=registred[i].pointer->detect_hardware;
setvideo_mode=registred[i].pointer->setvideo_mode; setvideo_mode=registred[i].pointer->setvideo_mode;
getvideo_drivername=registred[i].pointer->getvideo_drivername; getvideo_drivername=registred[i].pointer->getvideo_drivername;
@ -497,7 +498,7 @@ void fill(u8 attrib)
} }
else else
{ {
mem_to_video(0x0,0,vinfo->pagesize, false); mem_to_video(0x0,0,vinfo->pagesize>>2, false);
} }
} }

View File

@ -15,6 +15,7 @@
#include "shell.h" #include "shell.h"
#include "syscall.h" #include "syscall.h"
#include "multiboot2.h" #include "multiboot2.h"
#include "memory.h"
static u8 warnmsg[] = static u8 warnmsg[] =
"\033[150C\033[8D\033[37m\033[1m[ \033[36mNON\033[37m ]\033[0m"; "\033[150C\033[8D\033[37m\033[1m[ \033[36mNON\033[37m ]\033[0m";
@ -70,6 +71,7 @@ int main(u32 magic, u32 addr)
print("\033[37m\033[0m -Initilisation de la pagination (PAGING)"); print("\033[37m\033[0m -Initilisation de la pagination (PAGING)");
initpaging(); initpaging();
remap_memory(VESA_FBMEM);
ok(); ok();
print("\033[37m\033[0m -Initilisation des interruptions (IDT/PIC)"); print("\033[37m\033[0m -Initilisation des interruptions (IDT/PIC)");