]> git.corax.cc Git - corax/commitdiff
kernel/arch: Add comments describing how the _phys_alloc(), pg_frame_alloc_start...
authorMatthias Kruk <m@m10k.eu>
Fri, 31 Jul 2020 19:52:59 +0000 (04:52 +0900)
committerMatthias Kruk <m@m10k.eu>
Fri, 31 Jul 2020 19:52:59 +0000 (04:52 +0900)
kernel/arch/paging.c

index 7509d27723c1668451c0318df185e43cdc759a31..d0eb3c4202393ea48766ec499d23f8ad6a311abb 100644 (file)
@@ -66,6 +66,40 @@ int _pg_dir_pagesize(pg_dir_t*, u32_t, u32_t*);
 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;
@@ -88,6 +122,32 @@ static void* _phys_alloc(u32_t size, u32_t align)
        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;
@@ -112,6 +172,28 @@ void* pg_frame_alloc_start(void)
        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;
@@ -134,6 +216,33 @@ void* pg_frame_alloc_end(void)
        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);