NOVA
Stripped down NOVA kernel for the OSY course
Public Types | Public Member Functions | Static Public Member Functions | Static Public Attributes | List of all members
Kalloc Class Reference

Public Types

enum  Fill { NOFILL = 0 , FILL_0 , FILL_1 }
 

Public Member Functions

 Kalloc (mword virt_begin, mword virt_end)
 
void * alloc (unsigned size)
 
void * alloc_page (unsigned count, Fill fill=NOFILL)
 Allocate count virtually contiguous pages and optionally fill them with 0x00 or 0xFF. More...
 
void free_page (void *)
 Free a page previously allocated with Kalloc::alloc_page(). More...
 

Static Public Member Functions

static void * phys2virt (mword)
 Returns the virtual address that can be used to access memory with physical address phys. More...
 
static mword virt2phys (void *)
 Return the physical address that is mapped from the virtual address virt (opposite of phys2virt).
 

Static Public Attributes

static Kalloc allocator
 

Member Function Documentation

◆ alloc_page()

void * Kalloc::alloc_page ( unsigned  count,
Fill  fill = NOFILL 
)

Allocate count virtually contiguous pages and optionally fill them with 0x00 or 0xFF.

Returns
Virtual address of the first allocated page
47 {
48  unsigned found = 0, first = 0;
49 
50  for (unsigned i = 0; i < ((end - begin) >> PAGE_BITS) && found < count; i++) {
51  if (page_bitmap[i >> 5] == 0xffffffff) {
52  i += 31;
53  found = 0;
54  continue;
55  }
56  if (!is_page_allocated(i)) {
57  if (found++ == 0)
58  first = i;
59  } else {
60  found = 0;
61  }
62  }
63 
64  if (found != count)
65  return NULL;
66 
67  for (unsigned i = 0; i < count; i++)
68  mark_page_allocated(first + i, true);
69 
70  void * p = reinterpret_cast<void *>(begin + first * PAGE_SIZE);
71  if (fill)
72  memset (p, fill == FILL_0 ? 0 : ~0, count * PAGE_SIZE);
73 
74  return p;
75 }

◆ free_page()

void Kalloc::free_page ( void *  virt)

Free a page previously allocated with Kalloc::alloc_page().

Parameters
[in]virtVirtual address of the page to free.
83 {
84  mword p = reinterpret_cast<mword>(virt);
85  if (p < begin || p >= end || (p & (PAGE_SIZE - 1)) != 0 ||
86  !is_page_allocated((p - begin) >> PAGE_BITS))
87  panic ("kernel: attempt to free invalid page\n");
88 
89  mark_page_allocated((p - begin) >> PAGE_BITS, false);
90 }

◆ phys2virt()

void * Kalloc::phys2virt ( mword  phys)
static

Returns the virtual address that can be used to access memory with physical address phys.

Even kernel can only access virtual memory, it cannot access physical memory directly. However, CPU and bootloader work with physical addresses, so we sometimes need to access memory via its physical addresses.

To resolve this, part of the physical memory is mapped 1:1 to a sequential block of virtual memory addresses at a known offset OFFSET, so that the physical address X is accessible at the virtual address OFFSET + X. This mapping is configured during kernel startup at kern/src/start.S (section SETUP BOOT PAGE TABLE).

93 {
94  mword virt = phys + reinterpret_cast<mword>(&OFFSET);
95  return reinterpret_cast<void*>(virt);
96 }

The documentation for this class was generated from the following files: