int _pg_dir_xfer(pg_dir_t*, void*, pg_dir_t*, void*, u32_t);
static int _pg_dir_heap_map(pg_dir_t*, u32_t);
+/*
+ * _phys_alloc() - Dynamic memory allocator for linear memory
+ *
+ * SYNOPSIS
+ * void* _phys_alloc(u32_t size, u32_t align);
+ *
+ * DESCRIPTION
+ * The _phys_alloc() function dynamically allocates linear memory. This function is intended
+ * to be used for memory allocations before the kernel heap has been initialized. This memory
+ * allocator is very primitive and is meant for allocations that will never be freed, such as
+ * the kernel page directory. Allocations made by this allocator will be placed in memory after
+ * ther kernel's BSS segment. Once the kernel page directory has been created, this memory
+ * region will be included in the kernel heap segment. However, the kernel heap structures will
+ * be allocated in memory behind all physical alocations, which means that they will not be
+ * accounted for by the kernel heap.
+ * This function will allocate `size' bytes of memory from linear memory (which means physical
+ * memory in absence of paging). If alignment is desired (i.e. `align' is non-zero), the start
+ * of the allocation will be increased until the start address is aligned correctly, in creating
+ * an (`align' - 1) bytes sized memory hole in the worst case. The allocated memory will be
+ * zeroed by the allocator.
+ * This allocator does not perform any error checking. If there are problems with this allocator,
+ * that means that the machine does not have enough memory to allocate the kernel page directory.
+ * Since paging was introduced with the Intel 486 and my first one had 4MB of memory, it's fair to
+ * say that this is unlikely to happen on any machine.
+ *
+ * You should not be using this function. If you find yourself using this allocator, you are almost
+ * certainly doing something wrong.
+ *
+ * RETURN VALUE
+ * The start address of the memory allocation
+ *
+ * ERRORS
+ * This function does not return errors.
+ */
static void* _phys_alloc(u32_t size, u32_t align)
{
extern u32_t _mem_start;
return(addr);
}
+/*
+ * pg_frame_alloc_start - Allocate a page frame from the start of the frame map
+ *
+ * SYNOPSIS
+ * void* pg_frame_alloc_start(void);
+ *
+ * DESCRIPTION
+ * The pg_frame_alloc_start() function attempts to allocate a page frame (i.e. a physical
+ * page) from the start of the frame map. The frame map is a global structure that tracks
+ * the availability of every 4KB page frame in the machine. Simply speaking, the first bit
+ * in the frame map represents the page frame at address 0x0, the second bit represents the
+ * page frame at address 0x1000, and so on.
+ * What this function does is, get the first zero bit in the frame map, set the bit, and
+ * return the address of the page frame.
+ *
+ * This function is used exclusively to allocate heap space for the kernel. It should never
+ * be called directly, except from the code that is responsible for the kernel heap. For
+ * page frame allocations for processes, pg_frame_alloc_end() must be used instead.
+ *
+ * RETURN VALUE
+ * On success, the linear address of the newly allocated page frame is returned. In the case
+ * of an error, NULL will be returned.
+ *
+ * ERRORS
+ * This function does not return additional information about error conditions.
+ */
void* pg_frame_alloc_start(void)
{
u32_t frm;
return(NULL);
}
+/*
+ * pg_frame_alloc_end - Allocate a page frame from the end of the frame map
+ *
+ * SYNOPSIS
+ * void* pg_frame_alloc_end(void);
+ *
+ * DESCRIPTION
+ * The pg_frame_alloc_end() function attempts to allocate a page frame (i.e. a physical
+ * page) from the end of the frame map. This function works essentially the same way as
+ * pg_frame_alloc_start(), except that it scans the frame map backwards.
+ * This function is intended to allocate page frames for processes. This function should
+ * be used exclusively from code that is managing the page directories, page tables, and
+ * page allocations of processes. For page frame allocations for the kernel heap, the
+ * pg_frame_alloc_start() function must be used instead.
+ *
+ * RETURN VALUE
+ * On success, the linear address of the newly allocated page frame is returned. In the case
+ * of an error, NULL will be returned.
+ *
+ * ERRORS
+ * This function does not return additional information about error conditions.
+ */
void* pg_frame_alloc_end(void)
{
u32_t frm;
return(NULL);
}
+/*
+ * pg_frame_free() - Release a page frame
+ *
+ * SYNOPSIS
+ * void pg_frame_free(void *addr);
+ *
+ * DESCRIPTION
+ * The pg_frame_free() function releases the page frame that corresponds to the address
+ * passed in `addr'. This function clears the respective bit in the frame map, so that
+ * it may be allocated for other purposes. The position in the frame map is determined
+ * by means of a simple division, which means that any address that points into the frame
+ * may be passed to this function in order to free the frame. For example, passing any
+ * address in [0, 0x1000) will cause the first page frame to be released.
+ * This function may be used to release page frames obtained through either of the
+ * pg_frame_alloc_start() and pg_frame_alloc_end() functions.
+ *
+ * This function does not perform any error checking. The caller is responsible not to
+ * pass any addresses that cause array accesses outside of the frame map. In other words,
+ * care should be taken not to pass values other than those obtained through either of the
+ * allocation functions.
+ *
+ * RETURN VALUE
+ * void
+ *
+ * ERRORS
+ * This function does not signal any errors.
+ */
void pg_frame_free(void *addr)
{
_frame_clear((u32_t)addr);