kern

diff src/mem.c @ 20:369adbbd4bdd

added a few comments in mem.c
author John Tsiombikas <nuclear@member.fsf.org>
date Wed, 30 Mar 2011 23:14:29 +0300
parents 8be069e6bb05
children 3ba93d8f586c
line diff
     1.1 --- a/src/mem.c	Wed Mar 30 22:42:16 2011 +0300
     1.2 +++ b/src/mem.c	Wed Mar 30 23:14:29 2011 +0300
     1.3 @@ -18,9 +18,18 @@
     1.4  /* end of kernel image */
     1.5  extern int _end;
     1.6  
     1.7 +/* A bitmap is used to track which physical memory pages are used or available
     1.8 + * for allocation by alloc_phys_page.
     1.9 + *
    1.10 + * last_alloc_idx keeps track of the last 32bit element in the bitmap array
    1.11 + * where a free page was found. It's guaranteed that all the elements before
    1.12 + * this have no free pages, but it doesn't imply that there will be another
    1.13 + * free page there. So it's used as a starting point for the search.
    1.14 + */
    1.15  static uint32_t *bitmap;
    1.16  static int bmsize, last_alloc_idx;
    1.17  
    1.18 +
    1.19  void init_mem(struct mboot_info *mb)
    1.20  {
    1.21  	int i, num_pages, max_pg = 0;
    1.22 @@ -29,12 +38,19 @@
    1.23  	num_pages = 0;
    1.24  	last_alloc_idx = 0;
    1.25  
    1.26 +	/* the allocation bitmap starts right at the end of the ELF image */
    1.27  	bitmap = (uint32_t*)&_end;
    1.28  
    1.29 -	/* start by marking all posible pages as used */
    1.30 +	/* start by marking all posible pages (2**20) as used. We do not "reserve"
    1.31 +	 * all this space. Pages beyond the end of the useful bitmap area
    1.32 +	 * ((char*)bitmap + bmsize), which will be determined after we traverse the
    1.33 +	 * memory map, are going to be marked as available for allocation.
    1.34 +	 */
    1.35  	memset(bitmap, 0xff, 1024 * 1024 / 8);
    1.36  
    1.37 -	/* build the memory map */
    1.38 +	/* if the bootloader gave us an available memory map, traverse it and mark
    1.39 +	 * all the corresponding pages as free.
    1.40 +	 */
    1.41  	if(mb->flags & MB_MMAP) {
    1.42  		struct mboot_mmap *mem, *mmap_end;
    1.43  
    1.44 @@ -62,16 +78,20 @@
    1.45  			mem = (struct mboot_mmap*)((char*)mem + mem->skip + sizeof mem->skip);
    1.46  		}
    1.47  	} else if(mb->flags & MB_MEM) {
    1.48 +		/* if we don't have a detailed memory map, just use the lower and upper
    1.49 +		 * memory block sizes to determine which pages should be available.
    1.50 +		 */
    1.51  		add_memory(0, mb->mem_lower);
    1.52  		add_memory(0x100000, mb->mem_upper * 1024);
    1.53  		max_pg = mb->mem_upper / 4;
    1.54  
    1.55  		printf("lower memory: %ukb, upper mem: %ukb\n", mb->mem_lower, mb->mem_upper);
    1.56  	} else {
    1.57 +		/* I don't think this should ever happen with a multiboot-compliant boot loader */
    1.58  		panic("didn't get any memory info from the boot loader, I give up\n");
    1.59  	}
    1.60  
    1.61 -	bmsize = max_pg / 8;	/* size of the bitmap in bytes */
    1.62 +	bmsize = max_pg / 8;	/* size of the useful bitmap in bytes */
    1.63  
    1.64  	/* mark all the used pages as ... well ... used */
    1.65  	used_end = ((uint32_t)bitmap + bmsize - 1);
    1.66 @@ -83,14 +103,12 @@
    1.67  	for(i=0; i<=used_end; i++) {
    1.68  		mark_page(i, USED);
    1.69  	}
    1.70 -
    1.71 -	/*for(i=0; i<bmsize / 4; i++) {
    1.72 -		printf("%3d [%x]\n", i, bitmap[i]);
    1.73 -		asm("hlt");
    1.74 -	}
    1.75 -	putchar('\n');*/
    1.76  }
    1.77  
    1.78 +/* alloc_phys_page finds the first available page of physical memory,
    1.79 + * marks it as used in the bitmap, and returns its address. If there's
    1.80 + * no unused physical page, 0 is returned.
    1.81 + */
    1.82  uint32_t alloc_phys_page(void)
    1.83  {
    1.84  	int i, idx, max;
    1.85 @@ -120,10 +138,17 @@
    1.86  		idx++;
    1.87  	}
    1.88  
    1.89 -	panic("alloc_phys_page(): out of memory\n");
    1.90  	return 0;
    1.91  }
    1.92  
    1.93 +/* free_phys_page marks the physical page which corresponds to the specified
    1.94 + * address as free in the allocation bitmap.
    1.95 + *
    1.96 + * CAUTION: no checks are done that this page should actually be freed or not.
    1.97 + * If you call free_phys_page with the address of some part of memory that was
    1.98 + * originally reserved due to it being in a memory hole or part of the kernel
    1.99 + * image or whatever, it will be subsequently allocatable by alloc_phys_page.
   1.100 + */
   1.101  void free_phys_page(uint32_t addr)
   1.102  {
   1.103  	int pg = ADDR_TO_PAGE(addr);
   1.104 @@ -139,6 +164,9 @@
   1.105  	}
   1.106  }
   1.107  
   1.108 +/* this is only ever used by the VM init code to find out what the extends of
   1.109 + * the kernel image are, in order to map them 1-1 before enabling paging.
   1.110 + */
   1.111  void get_kernel_mem_range(uint32_t *start, uint32_t *end)
   1.112  {
   1.113  	if(start) {
   1.114 @@ -155,6 +183,9 @@
   1.115  	}
   1.116  }
   1.117  
   1.118 +/* adds a range of physical memory to the available pool. used during init_mem
   1.119 + * when traversing the memory map.
   1.120 + */
   1.121  static void add_memory(uint32_t start, size_t sz)
   1.122  {
   1.123  	int i, szpg, pg;
   1.124 @@ -167,6 +198,7 @@
   1.125  	}
   1.126  }
   1.127  
   1.128 +/* maps a page as used or free in the allocation bitmap */
   1.129  static void mark_page(int pg, int used)
   1.130  {
   1.131  	int idx = BM_IDX(pg);