Implement page allocation
This commit is contained in:
parent
0930f2664a
commit
6cb8b4372a
@ -9,3 +9,11 @@ void *memcpy(void *dst, const void *src, size_t n)
|
|||||||
}
|
}
|
||||||
return dst;
|
return dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void *memset(void *src, int c, size_t n)
|
||||||
|
{
|
||||||
|
for (char *ptr = (char *)src; n > 0; n--, ptr++) {
|
||||||
|
*ptr = (char)c;
|
||||||
|
}
|
||||||
|
return src;
|
||||||
|
}
|
||||||
|
@ -2,3 +2,4 @@
|
|||||||
#include "stdarg.h"
|
#include "stdarg.h"
|
||||||
|
|
||||||
void *memcpy(void *dest, const void *src, size_t n );
|
void *memcpy(void *dest, const void *src, size_t n );
|
||||||
|
void *memset(void *s, int c, size_t n);
|
||||||
|
15
core/main.c
15
core/main.c
@ -4,20 +4,21 @@
|
|||||||
#include "interrupt.h"
|
#include "interrupt.h"
|
||||||
#include "io.h"
|
#include "io.h"
|
||||||
#include "irq.h"
|
#include "irq.h"
|
||||||
|
#include "klibc.h"
|
||||||
#include "mem.h"
|
#include "mem.h"
|
||||||
#include "multiboot.h"
|
#include "multiboot.h"
|
||||||
#include "pit.h"
|
#include "pit.h"
|
||||||
#include "stdarg.h"
|
#include "stdarg.h"
|
||||||
#include "vga.h"
|
#include "vga.h"
|
||||||
|
|
||||||
#define CHECK_FLAG(flags,bit) ((flags) & (1 << (bit)))
|
#define CHECK_FLAG(flags, bit) ((flags) & (1 << (bit)))
|
||||||
void cpuid(int code, uint32_t *a, uint32_t *d)
|
void cpuid(int code, uint32_t *a, uint32_t *d)
|
||||||
{
|
{
|
||||||
asm volatile("cpuid" : "=a"(*a), "=d"(*d) : "0"(code) : "ebx", "ecx");
|
asm volatile("cpuid" : "=a"(*a), "=d"(*d) : "0"(code) : "ebx", "ecx");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Multiboot information available here :
|
||||||
// Multiboot information available here : https://www.gnu.org/software/grub/manual/multiboot/multiboot.html#kernel_002ec
|
// https://www.gnu.org/software/grub/manual/multiboot/multiboot.html#kernel_002ec
|
||||||
void kmain(unsigned long magic, unsigned long addr)
|
void kmain(unsigned long magic, unsigned long addr)
|
||||||
{
|
{
|
||||||
unsigned long upper_mem = 0;
|
unsigned long upper_mem = 0;
|
||||||
@ -31,23 +32,23 @@ void kmain(unsigned long magic, unsigned long addr)
|
|||||||
if (magic == MULTIBOOT_BOOTLOADER_MAGIC) { // Get loaded by Grub wuth mutliboot version 1
|
if (magic == MULTIBOOT_BOOTLOADER_MAGIC) { // Get loaded by Grub wuth mutliboot version 1
|
||||||
multiboot_info_t *mbi = (multiboot_info_t *)addr;
|
multiboot_info_t *mbi = (multiboot_info_t *)addr;
|
||||||
/* Are mem_* valid? */
|
/* Are mem_* valid? */
|
||||||
if (CHECK_FLAG(mbi->flags, 0)){
|
if (CHECK_FLAG(mbi->flags, 0)) {
|
||||||
printf("mem_lower = %dKB mem_upper %dKB\n", mbi->mem_lower, mbi->mem_upper);
|
printf("mem_lower = %dKB mem_upper %dKB\n", mbi->mem_lower, mbi->mem_upper);
|
||||||
upper_mem = mbi->mem_upper;
|
upper_mem = mbi->mem_upper;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Is boot_device valid? */
|
/* Is boot_device valid? */
|
||||||
if (CHECK_FLAG(mbi->flags, 1)){
|
if (CHECK_FLAG(mbi->flags, 1)) {
|
||||||
printf("boot_device = %d\n", mbi->boot_device);
|
printf("boot_device = %d\n", mbi->boot_device);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Is the command line passed? */
|
/* Is the command line passed? */
|
||||||
if (CHECK_FLAG(mbi->flags, 2)){
|
if (CHECK_FLAG(mbi->flags, 2)) {
|
||||||
printf("cmdline = %s\n", (char *)mbi->cmdline);
|
printf("cmdline = %s\n", (char *)mbi->cmdline);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(upper_mem == 0){
|
if (upper_mem == 0) {
|
||||||
printf("Cannot get upper phy mem bound. Using default value 32MB\n");
|
printf("Cannot get upper phy mem bound. Using default value 32MB\n");
|
||||||
upper_mem = 32 * 1024;
|
upper_mem = 32 * 1024;
|
||||||
}
|
}
|
||||||
|
54
core/mem.c
54
core/mem.c
@ -1,22 +1,68 @@
|
|||||||
#include "mem.h"
|
#include "mem.h"
|
||||||
|
#include "list.h"
|
||||||
#include "vga.h"
|
#include "vga.h"
|
||||||
|
|
||||||
struct mem_desc *page_desc = (struct mem_desc *)&__ld_kernel_end;
|
static struct mem_desc *page_desc = (struct mem_desc *)&__ld_kernel_end;
|
||||||
|
static struct mem_desc *free_page;
|
||||||
|
static struct mem_desc *used_page;
|
||||||
|
static unsigned long bottom_mem;
|
||||||
|
static unsigned long top_mem;
|
||||||
|
|
||||||
|
|
||||||
int memInit(unsigned long upper_mem)
|
int memInit(unsigned long upper_mem)
|
||||||
{
|
{
|
||||||
printf("Free Mem going from %d to %d\n", &__ld_kernel_end, upper_mem *1024);
|
printf("Free Mem going from %d to %d\n", &__ld_kernel_end, upper_mem * 1024);
|
||||||
unsigned long memdesc_end =
|
unsigned long memdesc_end =
|
||||||
(unsigned long)page_desc +
|
(unsigned long)page_desc +
|
||||||
((upper_mem) / (PAGE_SIZE / 1024)) * sizeof(struct mem_desc);
|
((upper_mem) / (PAGE_SIZE / 1024)) * sizeof(struct mem_desc);
|
||||||
uint lastUsed = (memdesc_end >> PAGE_SHIFT) + 1;
|
uint lastUsed = (memdesc_end >> PAGE_SHIFT) + 1;
|
||||||
|
list_init(free_page);
|
||||||
|
list_init(used_page);
|
||||||
|
bottom_mem = lastUsed;
|
||||||
|
top_mem = upper_mem;
|
||||||
for (uint i = 0; i < (upper_mem / (PAGE_SIZE / 1024)); i++) {
|
for (uint i = 0; i < (upper_mem / (PAGE_SIZE / 1024)); i++) {
|
||||||
struct mem_desc *mem = &page_desc[i];
|
struct mem_desc *mem = &page_desc[i];
|
||||||
if (i < lastUsed)
|
if (i < lastUsed) {
|
||||||
mem->ref = 1;
|
mem->ref = 1;
|
||||||
else
|
list_add_tail(used_page, mem);
|
||||||
|
} else {
|
||||||
mem->ref = 0;
|
mem->ref = 0;
|
||||||
|
list_add_tail(free_page, mem);
|
||||||
|
}
|
||||||
mem->phy_addr = i * PAGE_SIZE;
|
mem->phy_addr = i * PAGE_SIZE;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct mem_desc *addr2memDesc(unsigned long addr)
|
||||||
|
{
|
||||||
|
if (addr > top_mem || addr < bottom_mem)
|
||||||
|
return NULL;
|
||||||
|
int idx = addr >> PAGE_SHIFT;
|
||||||
|
return page_desc + idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unsigned long allocPage(void)
|
||||||
|
{
|
||||||
|
if (list_is_empty(free_page))
|
||||||
|
return (unsigned long)NULL;
|
||||||
|
struct mem_desc *mem = list_pop_head(free_page);
|
||||||
|
mem->ref = 1;
|
||||||
|
list_add_tail(used_page, mem);
|
||||||
|
return mem->phy_addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
int unrefPage(unsigned long addr)
|
||||||
|
{
|
||||||
|
struct mem_desc *mem = addr2memDesc(addr);
|
||||||
|
if (!mem) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
mem->ref--;
|
||||||
|
if (mem->ref == 0) {
|
||||||
|
list_add_tail(free_page, mem);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@ -12,7 +12,10 @@ extern uint32_t __ld_kernel_end;
|
|||||||
struct mem_desc{
|
struct mem_desc{
|
||||||
unsigned long phy_addr;
|
unsigned long phy_addr;
|
||||||
unsigned long ref;
|
unsigned long ref;
|
||||||
|
struct mem_desc *next, *prev;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
int memInit(unsigned long upper_mem);
|
int memInit(unsigned long upper_mem);
|
||||||
|
unsigned long allocPage(void);
|
||||||
|
int unrefPage(unsigned long addr);
|
||||||
|
Loading…
Reference in New Issue
Block a user