printk("pfn_min: %d pfn_max: %d\n", bootmem_data.min_pfn, bootmem_data.max_pfn);
- bootmem_data.last_hit_pfn = bootmem_data.min_pfn;
+ bootmem_data.prepare_alloc_pfn = bootmem_data.min_pfn;
}
void register_bootmem_pages() {
bootmem_data_t *pbd = &bootmem_data;
// 从该处开始查找空闲区间
- unsigned long search_bgn_pfn = pbd->min_pfn;
+ unsigned long search_bgn_pfn = pbd->prepare_alloc_pfn;
find_next_block:
// 先找到第一个空闲的pfn
reserve_bootmem(bgn_pfn, end_pfn);
region = pfn2va(bgn_pfn);
- return region;
-}
-
-void *alloc_bootmem(unsigned long size, unsigned long align) {
- bootmem_data_t *pbd = &bootmem_data;
-
- assert(size != 0);
- assert((align & (align - 1)) == 0); // must be power of 2
-
- unsigned long fallback = 0;
- unsigned long bgn_pfn, end_pfn, step;
-
- step = align >> PAGE_SHIFT;
- step = step > 0 ? step : 1;
-
- bgn_pfn = ALIGN(pbd->min_pfn, step);
- end_pfn = pbd->max_pfn;
-
- // start from last position
- if (pbd->last_hit_pfn > bgn_pfn) {
- fallback = bgn_pfn + 1;
- bgn_pfn = ALIGN(pbd->last_hit_pfn, step);
- }
-
- while (1) {
- int merge;
- void *region;
- unsigned long i, search_end_pfn;
- unsigned long start_off, end_off;
-
- find_block:
-
- bgn_pfn = find_next_zero_bit(pbd->bitmap, end_pfn, bgn_pfn);
- bgn_pfn = ALIGN(bgn_pfn, step);
-
- search_end_pfn = bgn_pfn + PFN_UP(size);
-
- if (bgn_pfn >= end_pfn || search_end_pfn > end_pfn) break;
+ pbd->prepare_alloc_pfn = end_pfn;
- for (i = bgn_pfn; i < search_end_pfn; ++i) {
- if (bootmem_page_state(i) != BOOTMEM_PAGE_FREE) { // space not enough
- bgn_pfn = ALIGN(i, step);
- if (bgn_pfn == i) bgn_pfn += step;
-
- goto find_block;
- }
- }
-
- // try to use the unused part of last page
- if (pbd->last_offset & (PAGE_SIZE - 1) && PFN_DW(pbd->last_offset) + 1 == bgn_pfn)
- start_off = ALIGN(pbd->last_offset, align);
- else
- start_off = pfn2pa(bgn_pfn);
-
- merge = PFN_DW(start_off) < bgn_pfn;
- end_off = start_off + size;
-
- pbd->last_offset = end_off;
- pbd->last_hit_pfn = PFN_UP(end_off);
-
- reserve_bootmem(PFN_DW(start_off) + merge, PFN_UP(end_off));
-
- region = pa2va(start_off);
-
- memset(region, 0, size);
-
- return region;
- }
-
- if (fallback) {
- bgn_pfn = ALIGN(fallback - 1, step);
- fallback = 0;
- goto find_block;
- }
-
- return 0;
+ return region;
}
\ No newline at end of file