Skip to content

Commit d5163f4

Browse files
committed
解耦 bitmap 与 buddy 分配器, 补充项目说明文档.
1 parent a8d45c0 commit d5163f4

File tree

5 files changed

+181
-124
lines changed

5 files changed

+181
-124
lines changed

docs/zh_cn/kernel_module.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
目前已有内核模块:
1111

1212
- `extfs` - ext 文件系统实现
13+
- `e1000` - e1000 网卡驱动实现
14+
- `nvme` - nvme 硬盘驱动实现
1315

1416
## 源码目录
1517

docs/zh_cn/subsystem.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,11 @@
2929

3030
- heap/: 内核堆分配器实现, 由 `copi143` 编写的 `plalloc` 分配器.
3131
- lazyalloc.c: 懒分配器实现.
32-
- frame.c: 物理页框分配器实现.
32+
- frame.c: 物理页框分配器上层抽象接口.
3333
- memstats.c: 内存统计实现.
3434
- page.c: 页表管理相关实现.
35-
- bitmap.c: 位图实现, 页框分配器使用位图来管理物理内存.
35+
- bitmap.c: 位图分配策略的实现.
36+
- buddy.c: 伙伴分配策略的实现.(CP_Kernel 3.7 后的默认物理页框分配策略)
3637
- hhdm.c: 有关于高半部映射的内存偏移获取以及一些虚实地址转换.
3738

3839
## Interrupt and Clock Subsystem (中断与时钟子系统)
@@ -77,6 +78,8 @@
7778
- pipe.c: 管道实现, 提供进程间通信的管道机制.
7879
- modfs.c: 模块文件系统实现, 提供内核模块的加载与管理功能.
7980
- partition.c: 分区管理实现, 提供对磁盘分区的识别与操作功能, 并将识别到的分区作为虚拟块设备挂载到 `devfs`.
81+
- cpio/cpfs.c: `initramfs` 挂载虚拟文件系统处理层
82+
- cpio/cpio.c: `initramfs` 挂载器实现.
8083

8184
## Services and Modules (服务与模块)
8285

src/x86_64/include/bitmap.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,19 @@ void bitmap_set_range(Bitmap *bitmap, size_t start, size_t end, bool value);
1919
size_t bitmap_find_range(const Bitmap *bitmap, size_t length, bool value);
2020

2121
bool bitmap_range_all(const Bitmap *bitmap, size_t start, size_t end, bool value);
22+
23+
void bitmap_free_frames(uint64_t addr, size_t count);
24+
25+
void bitmap_free_frame(uint64_t addr);
26+
27+
void bitmap_free_frames_2M(uint64_t addr);
28+
29+
void bitmap_free_frames_1G(uint64_t addr);
30+
31+
uint64_t bitmap_alloc_frames(size_t count);
32+
33+
uint64_t bitmap_alloc_frames_2M(size_t count);
34+
35+
uint64_t bitmap_alloc_frames_1G(size_t count);
36+
37+
void init_frame_bitmap();

src/x86_64/mem/bitmap.c

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
11
#include "bitmap.h"
2+
#include "boot.h"
3+
#include "frame.h"
4+
#include "hhdm.h"
5+
#include "klog.h"
6+
7+
extern FrameAllocator frame_allocator;
8+
extern uint64_t memory_size;
29

310
void bitmap_init(Bitmap *bitmap, uint8_t *buffer, size_t size) {
411
bitmap->buffer = buffer;
@@ -88,3 +95,146 @@ bool bitmap_range_all(const Bitmap *bitmap, size_t start, size_t end, bool value
8895
}
8996
return true;
9097
}
98+
99+
void bitmap_free_frames(uint64_t addr, size_t count) {
100+
if (addr == 0 || count == 0) return;
101+
size_t frame_index = addr / 4096;
102+
if (frame_index == 0) return;
103+
Bitmap *bitmap = &frame_allocator.bitmap;
104+
bitmap_set_range(bitmap, frame_index, frame_index + count, true);
105+
}
106+
107+
void bitmap_free_frame(uint64_t addr) {
108+
if (addr == 0) return;
109+
size_t frame_index = addr / 4096;
110+
if (frame_index == 0) return;
111+
Bitmap *bitmap = &frame_allocator.bitmap;
112+
bitmap_set(bitmap, frame_index, true);
113+
}
114+
115+
void bitmap_free_frames_2M(uint64_t addr) {
116+
if (addr == 0) return;
117+
size_t frame_index = addr / 4096;
118+
if (frame_index == 0) return;
119+
Bitmap *bitmap = &frame_allocator.bitmap;
120+
for (size_t i = 0; i < 512; i++) {
121+
bitmap_set(bitmap, frame_index + i, true);
122+
}
123+
}
124+
125+
void bitmap_free_frames_1G(uint64_t addr) {
126+
if (addr == 0) return;
127+
size_t frame_index = addr / 4096;
128+
if (frame_index == 0) return;
129+
Bitmap *bitmap = &frame_allocator.bitmap;
130+
for (size_t i = 0; i < 262144; i++) {
131+
bitmap_set(bitmap, frame_index + i, true);
132+
}
133+
}
134+
135+
uint64_t bitmap_alloc_frames(size_t count) {
136+
Bitmap *bitmap = &frame_allocator.bitmap;
137+
size_t frame_index = bitmap_find_range(bitmap, count, true);
138+
139+
if (frame_index == (size_t)-1) return 0;
140+
bitmap_set_range(bitmap, frame_index, frame_index + count, false);
141+
frame_allocator.usable_frames -= count;
142+
143+
return frame_index * 4096;
144+
}
145+
146+
uint64_t bitmap_alloc_frames_2M(size_t count) {
147+
Bitmap *bitmap = &frame_allocator.bitmap;
148+
size_t frames_per_2mb = 512;
149+
size_t total_frames = count * frames_per_2mb;
150+
151+
for (size_t i = 0; i < bitmap->length; i += frames_per_2mb) {
152+
if (i + total_frames > bitmap->length) break;
153+
154+
if (bitmap_range_all(bitmap, i, i + total_frames, true)) {
155+
bitmap_set_range(bitmap, i, i + total_frames, false);
156+
frame_allocator.usable_frames -= total_frames;
157+
return i * 4096;
158+
}
159+
}
160+
161+
return 0;
162+
}
163+
164+
uint64_t bitmap_alloc_frames_1G(size_t count) {
165+
Bitmap *bitmap = &frame_allocator.bitmap;
166+
size_t frames_per_1gb = 262144;
167+
size_t total_frames = count * frames_per_1gb;
168+
169+
for (size_t i = 0; i < bitmap->length; i += frames_per_1gb) {
170+
if (i + total_frames > bitmap->length) break;
171+
172+
if (bitmap_range_all(bitmap, i, i + total_frames, true)) {
173+
bitmap_set_range(bitmap, i, i + total_frames, false);
174+
frame_allocator.usable_frames -= total_frames;
175+
return i * 4096;
176+
}
177+
}
178+
179+
return 0;
180+
}
181+
182+
void init_frame_bitmap() {
183+
struct limine_memmap_response *memory_map = get_memory_map();
184+
memory_size = get_memory_size();
185+
186+
extern uint64_t reserved_memory;
187+
extern uint64_t bad_memory;
188+
extern uint64_t all_memory;
189+
190+
size_t bitmap_size = (memory_size / 4096 + 7) / 8;
191+
uint64_t bitmap_address = 0;
192+
193+
for (uint64_t i = 0; i < memory_map->entry_count; i++) {
194+
struct limine_memmap_entry *region = memory_map->entries[i];
195+
if (region->type == LIMINE_MEMMAP_USABLE && region->length >= bitmap_size) {
196+
bitmap_address = region->base;
197+
break;
198+
}
199+
}
200+
201+
if (!bitmap_address) return;
202+
203+
Bitmap *bitmap = &frame_allocator.bitmap;
204+
bitmap_init(bitmap, phys_to_virt(bitmap_address), bitmap_size);
205+
206+
size_t origin_frames = 0;
207+
for (uint64_t i = 0; i < memory_map->entry_count; i++) {
208+
struct limine_memmap_entry *region = memory_map->entries[i];
209+
210+
switch (region->type) {
211+
case LIMINE_MEMMAP_USABLE:
212+
size_t start_frame = region->base / 4096;
213+
size_t frame_count = region->length / 4096;
214+
origin_frames += frame_count;
215+
bitmap_set_range(bitmap, start_frame, start_frame + frame_count, true);
216+
all_memory += region->length;
217+
break;
218+
case LIMINE_MEMMAP_RESERVED:
219+
case LIMINE_MEMMAP_ACPI_NVS:
220+
case LIMINE_MEMMAP_ACPI_RECLAIMABLE:
221+
reserved_memory += region->length;
222+
all_memory += region->length;
223+
break;
224+
case LIMINE_MEMMAP_BAD_MEMORY:
225+
bad_memory += region->length;
226+
all_memory += region->length;
227+
break;
228+
}
229+
}
230+
231+
size_t bitmap_frame_start = bitmap_address / 4096;
232+
size_t bitmap_frame_count = (bitmap_size + 4095) / 4096;
233+
size_t bitmap_frame_end = bitmap_frame_start + bitmap_frame_count;
234+
bitmap_set_range(bitmap, bitmap_frame_start, bitmap_frame_end, false);
235+
236+
frame_allocator.origin_frames = origin_frames;
237+
frame_allocator.usable_frames = origin_frames - bitmap_frame_count;
238+
239+
logkf("Available memory: %lld MiB\n", (origin_frames / 256));
240+
}

0 commit comments

Comments
 (0)