MCPcopy Create free account
hub / github.com/bendudson/EuraliOS / init

Method init

kernel/src/memory/frame_allocator.rs:103–189  ·  view source on GitHub ↗

Initialise a bitmap allocator This function is unsafe because the caller must guarantee that the memory map and physical memory offset is correct.

(memory_map: &'static MemoryMap,
                       physical_memory_offset: VirtAddr)

Source from the content-addressed store, hash-verified

101 /// This function is unsafe because the caller must guarantee
102 /// that the memory map and physical memory offset is correct.
103 pub unsafe fn init(memory_map: &'static MemoryMap,
104 physical_memory_offset: VirtAddr) -> Self {
105 // get usable regions from memory map
106 let mut usable_regions = memory_map
107 .iter()
108 .filter(|r| r.region_type == MemoryRegionType::Usable);
109
110 _ = usable_regions.next(); // Discard the first region
111 let region = usable_regions.next().unwrap();
112
113 let start_addr = region.range.start_addr();
114 let end_addr = region.range.end_addr();
115 let nframes = region.range.end_frame_number - region.range.start_frame_number;
116 let nlevels = num_levels_needed(nframes);
117
118 let mut bitmap_virt_addr = [VirtAddr::new(0); FRAME_ALLOCATOR_MAX_LEVELS];
119 let mut level_start_addr = start_addr;
120 let mut nbits = nframes; // Number of bits needed at each level
121 for level in 0..nlevels {
122 bitmap_virt_addr[level] = physical_memory_offset + level_start_addr;
123 let level_ptr = bitmap_virt_addr[level].as_mut_ptr() as *mut u32;
124
125 let num_full_chunks = nbits >> 5;
126 for i in 0..num_full_chunks {
127 *(level_ptr.offset(i as isize)) = 0xFFFF_FFFF;
128 }
129
130 // May need final part-filled chunk
131 let num_extra_bits = nbits & 31;
132 if num_extra_bits > 0 {
133 // Fill with ones, then shift to zero missing frames
134 // note: Missing frames correspond to high bits so shift right
135 *(level_ptr.offset(num_full_chunks as isize)) =
136 0xFFFF_FFFF >> (32 - num_extra_bits);
137 }
138
139 // Total number of chunks i.e. bits at next level
140 nbits = num_full_chunks + if num_extra_bits > 0 {1} else {0};
141
142 // Start address of the next level
143 level_start_addr += nbits * 4u64;
144 }
145 // Number of bytes needed to store all bitmaps
146 let bitmap_size_bytes = level_start_addr - start_addr;
147 // Round up number of frames needed by adding 4095 and dividing by 4096
148 let bitmap_size_frames = (bitmap_size_bytes + 4095) >> 12;
149
150 println!("Region: {:#016X} - {:#016X}", start_addr, end_addr);
151 println!("Frames: {} Levels: {} Reserved frames: {}",
152 nframes, nlevels, bitmap_size_frames);
153
154 // Mark frames where bitmaps are stored as used
155 // - Clear low bits in bitmaps corresponding to the used frames
156 // - May need to clear multiple chunks and levels if the
157 // bitmap fills more than one chunk (32 frames).
158 let mut nbits = bitmap_size_frames; // Number of bits to clear
159 for level in 0..nlevels {
160 let ptr = bitmap_virt_addr[level].as_mut_ptr() as *mut u32;

Callers 2

initFunction · 0.80
init_heapFunction · 0.80

Calls 4

num_levels_neededFunction · 0.85
iterMethod · 0.80
as_mut_ptrMethod · 0.80
nextMethod · 0.45

Tested by

no test coverage detected