forked from xuos/xiuos
Add buddy phymem manager #1
|
|
@ -2,5 +2,5 @@
|
|||
*.o
|
||||
*libmusl.a
|
||||
*liblwip.a
|
||||
*/build/*
|
||||
*build/*
|
||||
.DS_Store
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
|
||||
#include "memlayout.h"
|
||||
#include "mmu.h"
|
||||
|
||||
#include "vm.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ static void _sys_irq_init()
|
|||
|
||||
// initialize the stacks for different mode
|
||||
for (i = 0; i < sizeof(modes) / sizeof(uint32_t); i++) {
|
||||
if (!(xizi_trap_driver.mode_stack_pages[i] = (uint32_t*)kalloc())) {
|
||||
if (!(xizi_trap_driver.mode_stack_pages[i] = (uint32_t*)kalloc(PAGE_SIZE))) {
|
||||
// panic("irq stack allocation failed");
|
||||
}
|
||||
init_stack(modes[i], (uint32_t)xizi_trap_driver.mode_stack_pages[i]);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,80 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "list.h"
|
||||
#include "memlayout.h"
|
||||
#include "spinlock.h"
|
||||
#include "vm.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define MAX_BUDDY_ORDER (10)
|
||||
|
||||
#define FREE_LIST_INDEX(order) \
|
||||
(1 << order)
|
||||
|
||||
#define IS_BUDDY_PAGE(buddy, order) \
|
||||
(buddy->order == order && buddy->node.next != &buddy->node)
|
||||
|
||||
#define BUDDY_PAGE_INDEX(page_idx, order) \
|
||||
(page_idx ^ (FREE_LIST_INDEX(order)))
|
||||
|
||||
#define COMBINED_PAGE_INDEX(page_idx, order) \
|
||||
(page_idx & ~(FREE_LIST_INDEX(order)))
|
||||
|
||||
#define CALCULATE_NPAGES(size) \
|
||||
(ALIGNUP(size, PAGE_SIZE) >> PTE_SHIFT)
|
||||
|
||||
|
||||
struct KPage
|
||||
{
|
||||
struct double_list_node node;
|
||||
union {
|
||||
uint32_t order;
|
||||
struct KPage *page_node;
|
||||
};
|
||||
};
|
||||
|
||||
struct KFreeList
|
||||
{
|
||||
uint32_t n_free_pages;
|
||||
struct double_list_node list_head;
|
||||
};
|
||||
|
||||
struct KBuddy {
|
||||
uint32_t n_pages;
|
||||
uint32_t use_lock;
|
||||
struct spinlock lock;
|
||||
struct KFreeList free_list[MAX_BUDDY_ORDER];
|
||||
struct KPage *first_page;
|
||||
};
|
||||
|
||||
/*********************************************
|
||||
* Buddy system public functions
|
||||
*********************************************/
|
||||
/*
|
||||
* Buddy system init function
|
||||
* @param void
|
||||
* @return void
|
||||
*/
|
||||
void KBuddySysInit();
|
||||
|
||||
/*
|
||||
* Continuous pages alloc by size
|
||||
* @param size(uint32_t) size of need alloc
|
||||
* @return NULL or v_addr (char*) return NULL if alloc failed, or return virtual page's addr
|
||||
*/
|
||||
char* KBuddyAlloc(uint32_t size);
|
||||
|
||||
/*
|
||||
* Continuous pages free from vaddr
|
||||
* @param vaddr(char*) virtual addr
|
||||
* @param isFreeSuccess(bool) return false if free failed, or return true
|
||||
*/
|
||||
bool KBuddyFree(char* vaddr);
|
||||
|
||||
/*
|
||||
* Print current free pages for debug.
|
||||
*/
|
||||
void KFreePagesInfo();
|
||||
|
|
@ -4,5 +4,55 @@ struct list_node {
|
|||
struct list_node* next;
|
||||
};
|
||||
|
||||
struct double_list_node {
|
||||
struct double_list_node *next;
|
||||
struct double_list_node *prev;
|
||||
};
|
||||
|
||||
#define CONTAINER_OF(item, type, member) \
|
||||
((type*)((char*)(item) - (unsigned long)(&((type*)0)->member)))
|
||||
|
||||
#define IS_DOUBLE_LIST_EMPTY(head) \
|
||||
((head)->next == (head))
|
||||
|
||||
/*********************************************
|
||||
*
|
||||
* Double linked list operation functions
|
||||
*
|
||||
*********************************************/
|
||||
__attribute__((always_inline))
|
||||
static void inline doubleListNodeInit(struct double_list_node *list)
|
||||
{
|
||||
list->next = list;
|
||||
list->prev = list;
|
||||
}
|
||||
|
||||
__attribute__((always_inline))
|
||||
static void inline _double_list_add(struct double_list_node* new, struct double_list_node* prev, struct double_list_node* next)
|
||||
{
|
||||
next->prev = new;
|
||||
new->next = next;
|
||||
new->prev = prev;
|
||||
prev->next = new;
|
||||
}
|
||||
|
||||
__attribute__((always_inline))
|
||||
static void inline _double_list_del(struct double_list_node *prev, struct double_list_node *next)
|
||||
{
|
||||
next->prev = prev;
|
||||
prev->next = next;
|
||||
}
|
||||
|
||||
__attribute__((always_inline))
|
||||
static void inline doubleListAddOnHead(struct double_list_node *new, struct double_list_node *head)
|
||||
{
|
||||
_double_list_add(new, head, head->next);
|
||||
}
|
||||
|
||||
__attribute__((always_inline))
|
||||
static void inline doubleListDel(struct double_list_node *entry)
|
||||
{
|
||||
_double_list_del(entry->prev, entry->next);
|
||||
entry->next = entry;
|
||||
entry->prev = entry;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,10 +6,13 @@ extern void KPrintf(char* fmt, ...);
|
|||
KPrintf("LOG: [%s] ", __func__); \
|
||||
KPrintf(f, ##args)
|
||||
|
||||
#define DEBUG(f, args...) \
|
||||
KPrintf("DEBUG: [%s] ", __func__); \
|
||||
#define DEBUG_PRINTF(f, args...) \
|
||||
KPrintf(f, ##args)
|
||||
|
||||
#define DEBUG(f, args...) \
|
||||
DEBUG_PRINTF("DEBUG: [%s] ", __func__); \
|
||||
DEBUG_PRINTF(f, ##args)
|
||||
|
||||
#define ERROR(f, args...) \
|
||||
KPrintf("ERROR: [%s] ", __func__); \
|
||||
KPrintf(f, ##args)
|
||||
|
|
|
|||
|
|
@ -1,28 +1,11 @@
|
|||
#pragma once
|
||||
|
||||
#include "memlayout.h"
|
||||
#include "mmu.h"
|
||||
|
||||
#include "spinlock.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
struct run {
|
||||
struct run* next;
|
||||
};
|
||||
|
||||
struct {
|
||||
struct spinlock lock;
|
||||
// int use_lock;
|
||||
struct run* freelist;
|
||||
} kmem;
|
||||
|
||||
extern int nr_free_pages;
|
||||
#include "vm.h"
|
||||
|
||||
void phymem_init();
|
||||
|
||||
void freerange(void* vstart, void* vend);
|
||||
bool kfree(char* vaddr);
|
||||
|
||||
void kfree(char* v);
|
||||
char* kalloc(uint32_t size);
|
||||
|
||||
char* kalloc(void);
|
||||
void show_phymem_info();
|
||||
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#define ALIGNUP(sz, al) (((uint32_t)(sz) + (uint32_t)(al)-1) & ~((uint32_t)(al)-1))
|
||||
#define ALIGNDOWN(sz, al) ((uint32_t)(sz) & ~((uint32_t)(al)-1))
|
||||
|
|
@ -14,6 +15,8 @@
|
|||
#define PTE_IDX(v) (((uintptr_t)(v) >> PTE_SHIFT) & (NUM_PTE - 1))
|
||||
#define PTE_ADDR(v) ALIGNDOWN(v, PTE_SZ)
|
||||
|
||||
#define PAGE_SIZE PTE_SZ
|
||||
|
||||
#define PDE_SHIFT 20
|
||||
// mem range represented by 1 pde
|
||||
#define PDE_SZ (1 << PDE_SHIFT)
|
||||
|
|
|
|||
|
|
@ -39,6 +39,8 @@ extern void proc_switch(struct context**, struct context*);
|
|||
void kmain(void)
|
||||
{
|
||||
phymem_init();
|
||||
LOG("Buddy System Init Done.\r\n");
|
||||
show_phymem_info();
|
||||
|
||||
xizi_kern_driver_init();
|
||||
|
||||
|
|
@ -51,26 +53,28 @@ void kmain(void)
|
|||
struct PCB* pcb = 0;
|
||||
|
||||
DEBUG("Begin| nr_free_pcb: %d\r\n", xizi_proc_maintainer.nr_pcb_free);
|
||||
DEBUG("Begin| nr_free_pages: %d\r\n", nr_free_pages);
|
||||
show_phymem_info();
|
||||
pcb = xizi_proc_maintainer.new_pcb();
|
||||
|
||||
DEBUG("New PCB| nr_free_pages: %d\r\n", nr_free_pages);
|
||||
show_phymem_info();
|
||||
DEBUG("New PCB| nr_free_pcb: %d\r\n", xizi_proc_maintainer.nr_pcb_free);
|
||||
|
||||
extern char _binary_initcode_start[], _binary_initcode_end[];
|
||||
DEBUG("initcode start: %x, initcode end: %x\r\n", _binary_initcode_start, _binary_initcode_end);
|
||||
|
||||
xizi_pager.map_pages(&pcb->pgdir, 0, (uintptr_t)_binary_initcode_start, (uintptr_t)(_binary_initcode_end - _binary_initcode_start), AP_KU);
|
||||
DEBUG("Map pages| nr_free_pages: %d\r\n", nr_free_pages);
|
||||
show_phymem_info();
|
||||
|
||||
xizi_proc_maintainer.free_pcb(pcb);
|
||||
DEBUG("Free PCB| nr_free_pages: %d\r\n", nr_free_pages);
|
||||
show_phymem_info();
|
||||
DEBUG("Free PCB| nr_free_pcb: %d\r\n", xizi_proc_maintainer.nr_pcb_free);
|
||||
|
||||
LOG("kernel init done.\r\n");
|
||||
|
||||
struct PCB* proc = first_proc();
|
||||
|
||||
show_phymem_info();
|
||||
|
||||
struct CPU* cpu = cur_cpu();
|
||||
cpu->proc = proc;
|
||||
proc_switch(&cpu->scheduler, proc->main_thread.context);
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
SRC_FILES:= phymem.c pager.c
|
||||
SRC_FILES:= phymem.c pager.c buddy.c
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
|
|
|
|||
|
|
@ -0,0 +1,224 @@
|
|||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file: buddy.c
|
||||
* @brief: the buddy management of system memory
|
||||
* @version: 3.0
|
||||
* @author: AIIT XUOS Lab
|
||||
* @date: 2023/4/27
|
||||
*
|
||||
*/
|
||||
|
||||
#include "buddy.h"
|
||||
#include "log.h"
|
||||
|
||||
struct KBuddy global_KBuddy;
|
||||
static uint32_t v_manager_mem_start;
|
||||
extern char kern_end[];
|
||||
|
||||
static void _buddy_split_page(struct KPage* page, uint32_t low_order, uint32_t high_order, struct KFreeList* list)
|
||||
{
|
||||
uint32_t size = (1 << high_order);
|
||||
while (high_order > low_order) {
|
||||
list--;
|
||||
size >>= 1;
|
||||
doubleListAddOnHead(&page[size].node, &list->list_head);
|
||||
list->n_free_pages++;
|
||||
high_order--;
|
||||
}
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static void inline _buddy_set_pages_order(struct KPage* page, int order)
|
||||
{
|
||||
int i;
|
||||
struct KPage* p = NULL;
|
||||
page->order = order;
|
||||
for (i = 1; i < FREE_LIST_INDEX(order); i++) {
|
||||
p = page + i;
|
||||
p->page_node = page;
|
||||
}
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static void inline _buddy_page_to_vaddr(struct KPage* page, char** vaddr)
|
||||
{
|
||||
uint32_t offset = page - global_KBuddy.first_page;
|
||||
*vaddr = (char*)(v_manager_mem_start + (offset << PTE_SHIFT));
|
||||
return;
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static void inline _buddy_vaddr_to_page(struct KPage** page, char* vaddr)
|
||||
{
|
||||
uint32_t offset = (uint32_t)vaddr - v_manager_mem_start;
|
||||
*page = (struct KPage*)(global_KBuddy.first_page + (offset >> PTE_SHIFT));
|
||||
return;
|
||||
}
|
||||
|
||||
// find free page and split it to small page if need
|
||||
static struct KPage* KBuddyPagesAlloc(int nPages)
|
||||
{
|
||||
struct KPage* page = NULL;
|
||||
struct KFreeList* list = NULL;
|
||||
int i = 0, order = 0;
|
||||
|
||||
spinlock_lock(&global_KBuddy.lock);
|
||||
|
||||
// find order
|
||||
for (order = 0; (FREE_LIST_INDEX(order)) < nPages; order++)
|
||||
;
|
||||
|
||||
// find the free page list
|
||||
for (i = order; i < MAX_BUDDY_ORDER; i++) {
|
||||
list = global_KBuddy.free_list + i;
|
||||
if (IS_DOUBLE_LIST_EMPTY(&list->list_head)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// find the page
|
||||
page = CONTAINER_OF(list->list_head.next, struct KPage, node);
|
||||
doubleListDel(&page->node);
|
||||
list->n_free_pages--;
|
||||
|
||||
// split the page to some small pages
|
||||
_buddy_split_page(page, order, i, list);
|
||||
|
||||
// set the pages' order
|
||||
_buddy_set_pages_order(page, order);
|
||||
|
||||
spinlock_unlock(&global_KBuddy.lock);
|
||||
return page;
|
||||
}
|
||||
|
||||
// there is no enough free page to satisfy the nPages
|
||||
spinlock_unlock(&global_KBuddy.lock);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// free continuous pages from page pointer
|
||||
static void KBuddyPagesFree(struct KPage* page)
|
||||
{
|
||||
struct KPage* buddy = NULL;
|
||||
uint32_t order = (page->order >= MAX_BUDDY_ORDER) ? 0 : page->order;
|
||||
uint32_t buddy_idx = 0, new_buddy_idx = 0;
|
||||
uint32_t page_idx = page - global_KBuddy.first_page;
|
||||
|
||||
spinlock_lock(&global_KBuddy.lock);
|
||||
|
||||
for (; order < MAX_BUDDY_ORDER - 1; order++) {
|
||||
// find and delete buddy to combine
|
||||
buddy_idx = BUDDY_PAGE_INDEX(page_idx, order);
|
||||
if (buddy_idx > global_KBuddy.n_pages - 1) {
|
||||
break;
|
||||
}
|
||||
buddy = page + (buddy_idx - page_idx);
|
||||
if (!IS_BUDDY_PAGE(buddy, order)) {
|
||||
break;
|
||||
}
|
||||
// remove buddy
|
||||
doubleListDel(&buddy->node);
|
||||
global_KBuddy.free_list[order].n_free_pages--;
|
||||
buddy->order = MAX_BUDDY_ORDER;
|
||||
// update page and page_idx after combined
|
||||
new_buddy_idx = COMBINED_PAGE_INDEX(page_idx, order);
|
||||
page = page + (new_buddy_idx - page_idx);
|
||||
page_idx = new_buddy_idx;
|
||||
}
|
||||
page->order = order;
|
||||
doubleListAddOnHead(&page->node, &global_KBuddy.free_list[order].list_head);
|
||||
global_KBuddy.free_list[order].n_free_pages++;
|
||||
|
||||
spinlock_unlock(&global_KBuddy.lock);
|
||||
return;
|
||||
}
|
||||
|
||||
void KBuddySysInit()
|
||||
{
|
||||
uint32_t i = 0;
|
||||
struct KPage* page = NULL;
|
||||
struct KFreeList* free_list = NULL;
|
||||
|
||||
// init spinlock
|
||||
spinlock_init(&global_KBuddy.lock, "kbuddy");
|
||||
|
||||
// init global kernel Buddy system
|
||||
uint32_t n_page_total = ALIGNDOWN(((uint32_t)P2V(PHYSTOP) - (uint32_t)&kern_end), PAGE_SIZE) >> PTE_SHIFT;
|
||||
uint32_t k_page_size = ALIGNUP((n_page_total * sizeof(struct KPage)), PAGE_SIZE);
|
||||
uint32_t n_k_page = k_page_size >> PTE_SHIFT;
|
||||
global_KBuddy.n_pages = n_page_total - n_k_page;
|
||||
|
||||
v_manager_mem_start = (uint32_t)&kern_end + k_page_size;
|
||||
global_KBuddy.first_page = (struct KPage*)&kern_end;
|
||||
memset(global_KBuddy.first_page, 0, k_page_size);
|
||||
|
||||
// init each free page list from 2^0 to 2^8
|
||||
for (; i < MAX_BUDDY_ORDER; i++) {
|
||||
free_list = global_KBuddy.free_list + i;
|
||||
doubleListNodeInit(&free_list->list_head);
|
||||
free_list->n_free_pages = 0;
|
||||
}
|
||||
|
||||
// init and free each page
|
||||
for (i = 0; i < global_KBuddy.n_pages; i++) {
|
||||
page = global_KBuddy.first_page + i;
|
||||
page->order = MAX_BUDDY_ORDER;
|
||||
}
|
||||
for (i = 0; i < global_KBuddy.n_pages; i++) {
|
||||
page = global_KBuddy.first_page + i;
|
||||
doubleListNodeInit(&page->node);
|
||||
KBuddyPagesFree(page);
|
||||
}
|
||||
}
|
||||
|
||||
char* KBuddyAlloc(uint32_t size)
|
||||
{
|
||||
int nPages = CALCULATE_NPAGES(size);
|
||||
struct KPage* page = KBuddyPagesAlloc(nPages);
|
||||
if (page == NULL)
|
||||
return NULL;
|
||||
|
||||
char* v_addr = NULL;
|
||||
_buddy_page_to_vaddr(page, &v_addr);
|
||||
|
||||
return v_addr;
|
||||
}
|
||||
|
||||
bool KBuddyFree(char* vaddr)
|
||||
{
|
||||
struct KPage* page = NULL;
|
||||
|
||||
if ((uint32_t)vaddr % (PAGE_SIZE)) {
|
||||
ERROR("kbuddyfree - unaligned\r\n");
|
||||
return false;
|
||||
}
|
||||
if ((uint32_t)vaddr < (uint32_t)&kern_end) {
|
||||
ERROR("kbuddyfree - under kern_end\r\n");
|
||||
return false;
|
||||
}
|
||||
if (V2P(vaddr) >= PHYSTOP) {
|
||||
ERROR("kbuddyfree - over PHYSTOP\r\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
_buddy_vaddr_to_page(&page, vaddr);
|
||||
KBuddyPagesFree(page);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void KFreePagesInfo()
|
||||
{
|
||||
DEBUG("Buddy structure:");
|
||||
for (int j = 0; j < MAX_BUDDY_ORDER; j++) {
|
||||
DEBUG_PRINTF(" %d ", global_KBuddy.free_list[j].n_free_pages);
|
||||
}
|
||||
DEBUG_PRINTF("\r\n");
|
||||
}
|
||||
|
|
@ -8,7 +8,7 @@
|
|||
static bool _new_user_pgdir(struct PageDirectory* pgdir, uintptr_t vrange)
|
||||
{
|
||||
void* new_pgdir_addr = 0;
|
||||
if ((new_pgdir_addr = kalloc()) == NULL) {
|
||||
if ((new_pgdir_addr = kalloc(4 * PAGE_SIZE)) == NULL) {
|
||||
LOG("new pgdir address: %x\r\n", new_pgdir_addr);
|
||||
return false;
|
||||
}
|
||||
|
|
@ -29,12 +29,12 @@ static uintptr_t* _page_walk(struct PageDirectory* pgdir, uintptr_t vaddr, bool
|
|||
if (*pde != 0) {
|
||||
pgtbl_vaddr = P2V(PTE_ADDR(*pde));
|
||||
} else {
|
||||
if (!alloc || !(pgtbl_vaddr = (uintptr_t*)kalloc())) {
|
||||
if (!alloc || !(pgtbl_vaddr = (uintptr_t*)kalloc(sizeof(uintptr_t) * NUM_PTE))) {
|
||||
return 0;
|
||||
}
|
||||
LOG("alloc %x for pgtbl\r\n", pgtbl_vaddr);
|
||||
|
||||
memset(pgtbl_vaddr, 0, PGSIZE);
|
||||
memset(pgtbl_vaddr, 0, sizeof(uintptr_t) * NUM_PTE);
|
||||
*pde = V2P(pgtbl_vaddr) | PDE_COARSE;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,71 +18,26 @@
|
|||
* @date: 2023/4/27
|
||||
*
|
||||
*/
|
||||
#include <stdint.h>
|
||||
|
||||
#include "phymem.h"
|
||||
|
||||
extern char kern_end[]; // first address after kernel loaded from ELF file
|
||||
// defined by the kernel linker script in kernel.ld
|
||||
int nr_free_pages;
|
||||
|
||||
extern void KPrintf(char* fmt, ...);
|
||||
#include "buddy.h"
|
||||
|
||||
void phymem_init()
|
||||
{
|
||||
spinlock_init(&kmem.lock, "kmem");
|
||||
nr_free_pages = 0;
|
||||
// kmem.use_lock = 0;
|
||||
freerange(kern_end, P2V(PHYSTOP));
|
||||
KBuddySysInit();
|
||||
}
|
||||
|
||||
void freerange(void* vstart, void* vend)
|
||||
bool kfree(char* vaddr)
|
||||
{
|
||||
char* p;
|
||||
p = (char*)ALIGNUP((uint32_t)vstart, 4 * PGSIZE);
|
||||
for (; p + 4 * PGSIZE <= (char*)vend; p += 4 * PGSIZE) {
|
||||
kfree(p);
|
||||
}
|
||||
return KBuddyFree(vaddr);
|
||||
}
|
||||
|
||||
void kfree(char* v)
|
||||
char* kalloc(uint32_t size)
|
||||
{
|
||||
struct run* r;
|
||||
|
||||
if ((uint32_t)v % (4 * PGSIZE))
|
||||
KPrintf("kfree - unaligned\r\n");
|
||||
if (v < kern_end)
|
||||
KPrintf("kfree - under kern_end\r\n");
|
||||
if ((uint32_t)V2P(v) >= (uint32_t)PHYSTOP)
|
||||
KPrintf("kfree - over PHYSTOP, v: %x, p: %x\r\n", v, V2P(v));
|
||||
|
||||
// Fill with junk to catch dangling refs.
|
||||
memset(v, 0, 4 * PGSIZE);
|
||||
|
||||
// freeing a page
|
||||
spinlock_lock(&kmem.lock);
|
||||
|
||||
r = (struct run*)v;
|
||||
r->next = kmem.freelist;
|
||||
kmem.freelist = r;
|
||||
|
||||
nr_free_pages += 1;
|
||||
|
||||
spinlock_unlock(&kmem.lock);
|
||||
return KBuddyAlloc(size);
|
||||
}
|
||||
|
||||
char* kalloc(void)
|
||||
void show_phymem_info()
|
||||
{
|
||||
struct run* r = NULL;
|
||||
|
||||
spinlock_lock(&kmem.lock);
|
||||
|
||||
if ((r = kmem.freelist))
|
||||
kmem.freelist = r->next;
|
||||
|
||||
nr_free_pages -= 1;
|
||||
|
||||
spinlock_unlock(&kmem.lock);
|
||||
|
||||
return (char*)r;
|
||||
KFreePagesInfo();
|
||||
}
|
||||
|
|
@ -8,14 +8,14 @@ struct CPU global_cpus[NR_CPU];
|
|||
// return: number of PCBs stored in one page
|
||||
static int _alloc_page_for_pcb()
|
||||
{
|
||||
void* proc_addr = kalloc();
|
||||
void* proc_addr = kalloc(PAGE_SIZE);
|
||||
if (proc_addr == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
LOG("proc page addr: %x\r\n", proc_addr);
|
||||
|
||||
void* proc_end = proc_addr + PGSIZE - sizeof(struct PCB);
|
||||
void* proc_end = proc_addr + PAGE_SIZE - sizeof(struct PCB);
|
||||
|
||||
spinlock_lock(&xizi_proc_maintainer.lock);
|
||||
|
||||
|
|
@ -139,7 +139,7 @@ static struct PCB* _new_pcb()
|
|||
// init main thread of proc
|
||||
pcb->main_thread.proc = pcb;
|
||||
// alloc stack page for proc
|
||||
if ((void*)(pcb->main_thread.stack_addr = (uintptr_t)kalloc()) == NULL) {
|
||||
if ((void*)(pcb->main_thread.stack_addr = (uintptr_t)kalloc(PAGE_SIZE)) == NULL) {
|
||||
_dealloc_pcb(pcb);
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue