| #include <stdlib.h> |
| #include <errno.h> |
| #include <string.h> |
| #include "malloc.h" |
| #include "core.h" |
| #include <syslinux/memscan.h> |
| #include <dprintf.h> |
| |
| struct free_arena_header __core_malloc_head[NHEAP]; |
| |
| //static __hugebss char main_heap[128 << 10]; |
| extern char __lowmem_heap[]; |
| extern char free_high_memory[]; |
| |
| #define E820_MEM_MAX 0xfff00000 /* 4 GB - 1 MB */ |
| int scan_highmem_area(void *data, addr_t start, addr_t len, |
| enum syslinux_memmap_types type) |
| { |
| struct free_arena_header *fp; |
| |
| (void)data; |
| |
| dprintf("start = %x, len = %x, type = %d", start, len, type); |
| |
| if (start < 0x100000 || start > E820_MEM_MAX |
| || type != SMT_FREE) |
| return 0; |
| |
| if (start < __com32.cs_memsize) { |
| len -= __com32.cs_memsize - start; |
| start = __com32.cs_memsize; |
| } |
| if (len > E820_MEM_MAX - start) |
| len = E820_MEM_MAX - start; |
| |
| if (len >= 2 * sizeof(struct arena_header)) { |
| fp = (struct free_arena_header *)start; |
| fp->a.attrs = ARENA_TYPE_USED | (HEAP_MAIN << ARENA_HEAP_POS); |
| #ifdef DEBUG_MALLOC |
| fp->a.magic = ARENA_MAGIC; |
| #endif |
| ARENA_SIZE_SET(fp->a.attrs, len); |
| dprintf("will inject a block start:0x%x size 0x%x", start, len); |
| __inject_free_block(fp); |
| } |
| |
| __com32.cs_memsize = start + len; /* update the HighMemSize */ |
| return 0; |
| } |
| |
| #if 0 |
| static void mpool_dump(enum heap heap) |
| { |
| struct free_arena_header *head = &__core_malloc_head[heap]; |
| struct free_arena_header *fp; |
| int size, type, i = 0; |
| addr_t start, end; |
| |
| fp = head->next_free; |
| while (fp != head) { |
| size = ARENA_SIZE_GET(fp->a.attrs); |
| type = ARENA_TYPE_GET(fp->a.attrs); |
| start = (addr_t)fp; |
| end = start + size; |
| printf("area[%d]: start = 0x%08x, end = 0x%08x, type = %d\n", |
| i++, start, end, type); |
| fp = fp->next_free; |
| } |
| } |
| #endif |
| |
| uint16_t *bios_free_mem; |
| void mem_init(void) |
| { |
| struct free_arena_header *fp; |
| int i; |
| |
| //dprintf("enter"); |
| |
| /* Initialize the head nodes */ |
| fp = &__core_malloc_head[0]; |
| for (i = 0 ; i < NHEAP ; i++) { |
| fp->a.next = fp->a.prev = fp->next_free = fp->prev_free = fp; |
| fp->a.attrs = ARENA_TYPE_HEAD | (i << ARENA_HEAP_POS); |
| fp->a.tag = MALLOC_HEAD; |
| fp++; |
| } |
| |
| //dprintf("__lowmem_heap = 0x%p bios_free = 0x%p", |
| // __lowmem_heap, *bios_free_mem); |
| |
| /* Initialize the lowmem heap */ |
| fp = (struct free_arena_header *)__lowmem_heap; |
| fp->a.attrs = ARENA_TYPE_USED | (HEAP_LOWMEM << ARENA_HEAP_POS); |
| ARENA_SIZE_SET(fp->a.attrs, (*bios_free_mem << 10) - (uintptr_t)fp); |
| #ifdef DEBUG_MALLOC |
| fp->a.magic = ARENA_MAGIC; |
| #endif |
| __inject_free_block(fp); |
| |
| /* Initialize the main heap */ |
| __com32.cs_memsize = (size_t)free_high_memory; |
| syslinux_scan_memory(scan_highmem_area, NULL); |
| } |