int vmspace_init(vmspace_t *vms, uintptr_t addr, uintptr_t sz) { /* FIXME: Assert starts and finishes on a page boundary! */ range_t r; r.start = addr; r.extent = sz; vms->start = addr; vms->size = sz; spinlock_init(&vms->lock); size_t overhead = round_to_page_size(buddy_calc_overhead(r)); size_t npages = overhead >> get_page_shift(); uintptr_t start = r.start + r.extent - overhead; int ok = map(start, alloc_pages(PAGE_REQ_NONE, npages), npages, PAGE_WRITE); assert(ok == 0 && "map() failed in vmspace_init!"); r.extent -= overhead; buddy_init(&vms->allocator, (uint8_t*)start, r, /*start_freed=*/0); buddy_free_range(&vms->allocator, r); return 0; }
int buddy_init(buddy_t *bd, uint8_t *overhead_storage, range_t r, int start_freed) { bd->start = r.start; bd->size = r.extent; for (unsigned i = 0; i < NUM_BUDDY_BUCKETS; ++i) { unsigned nbits = bd->size >> (MIN_BUDDY_SZ_LOG2 + i); bitmap_init(&bd->orders[i], overhead_storage, nbits); overhead_storage += nbits / 8 + 1; } if (start_freed != 0) buddy_free_range(bd, r); return 0; }