- /* Kernel static code and data, in 4 kB pages.
-
- We can figure this out because the linker records the start
- and end of the kernel as _start and _end. See
- kernel.lds. */
- extern char _start, _end;
- size_t kernel_pages = (&_end - &_start + 4095) / 4096;
-
- /* Then we know how much is available to allocate. */
- uninit_start = ptov (LOADER_KERN_BASE + kernel_pages * PGSIZE);
- uninit_end = ptov (ram_pages * PGSIZE);
-
- /* Initialize other variables. */
- lock_init (&lock, "palloc");
- list_init (&free_pages);
+ /* used_map from 1 MB as long as necessary. */
+ size_t bitmap_start = 1024;
+ size_t bitmap_pages = DIV_ROUND_UP (bitmap_needed_bytes (ram_pages), PGSIZE);
+
+ /* Free space from the bitmap to the end of RAM. */
+ size_t free_start = bitmap_start + bitmap_pages;
+ size_t free_pages = ram_pages - free_start;
+
+ /* Kernel and user get half of free space each.
+ User space can be limited by max_user_pages. */
+ size_t half_free = free_pages / 2;
+ size_t kernel_pages = half_free;
+ size_t user_pages = half_free < max_user_pages ? half_free : max_user_pages;
+
+ used_map = bitmap_create_preallocated (ram_pages,
+ ptov (bitmap_start * PGSIZE),
+ bitmap_pages * PGSIZE);
+ init_pool (&kernel_pool, free_start, kernel_pages, "kernel pool");
+ init_pool (&user_pool, free_start + kernel_pages, user_pages, "use pool");
+ lock_init (&used_map_lock, "used_map");
+}
+
+/* Initializes POOL to start (named NAME) at physical page number
+ FIRST_PAGE and continue for PAGE_CNT pages. */
+static void
+init_pool (struct pool *pool, size_t first_page, size_t page_cnt,
+ const char *name)
+{
+ printf ("%zu pages available in %s.\n", page_cnt, name);
+ pool->first_page = first_page;
+ pool->page_cnt = page_cnt;