2个版本
使用旧的Rust 2015
0.1.2 | 2016年9月18日 |
---|---|
0.1.0 | 2015年11月8日 |
#421 in 内存管理
30KB
394 行
alloc_buddy_simple
: 用于裸金属Rust的简单“伙伴分配器”
您是否在使用裸金属上的Rust? malloc
和 free
是否甚至都没有可用?您是否希望有一个兼容Rust的分配器,它可以与 libcollections
一起工作?
警告: 好吧,您不应该在内核空间中用 libcollections
做任何严肃的事情,因为如果您耗尽内存,它将会崩溃。但是,如果您只想在启动时使用一个或两个 Vec
,在一个非常熟悉系统上,这将非常方便,也许您愿意接受后果。
这是一个简单的 伙伴分配器,您可以用它替换Rust的常规分配器。它是高度实验性的,可能会损坏您的数据,使您的机器崩溃等。但它似乎足以让 Vec::push
在极端有限的测试中正常工作。
有一个测试套件,它尝试分配和释放大量内存,并试图确保每次都将所有内容放置在内存中的预期位置。
使用此分配器
您可以使用以下命令将其拉入Cargo构建:
[dependencies.alloc_buddy_simple]
git = "https://github.com/emk/toyos-rs"
features = ["use-as-rust-allocator"]
然后您需要在某处为您的堆分配一些内存。这需要在4096字节边界上对齐,并且它的大小必须是2的幂。您可以使用以下声明与 nasm
一起使用
section .bss
align 4096
HEAP_BOTTOM:
resb 4*1024*1024
HEAP_TOP:
从那里,您需要做的只是(1)声明一个足够空间的空闲列表数组
extern crate alloc_buddy_simple;
use alloc_buddy_simple::{FreeBlock, initialize_allocator};
static mut FREE_LISTS: [*mut FreeBlock; 19] = [0 as *mut _; 19];
这里的难点在于 19
。这决定了可分配的最小块大小,它将是 heap_size >> (19 - 1)
。您最小的块大小必须至少与一个 FreeBlock
一样大。
关于调用 initialize_allocator
,请参阅toyos 的 heap.rs
文件中的示例代码。在尝试使用您的堆之前,请先执行此操作,否则您可能会遇到 Rust 的 panic!
编译自定义 libcollections
您需要手动编译 rust/src
目录中的多个库,并将它们复制到 ~/.multirust/toolchains/nightly/lib/rustlib/$(target)/lib
或您系统上的等效目录。有关示例代码,请参阅toyos 的 Makefile
。
如果您的内核空间不支持浮点数,您可能还需要将barebones nofp 补丁应用于 libcore
。
警告
此代码仅在内存的“低半区”运行过,如果您的堆存储在内存范围的“高半区”,您可能会遇到一些与 isize
与 usize
相关的问题。
许可
根据您的选择,在Apache License, Version 2.0 或 MIT 许可证下授权。这是一些高度实验性的“按原样提供”的代码,可能会对您的计算机或数据造成严重破坏。但如果你在使用随机不安全、不稳定的 Rust 库在内核空间实现 malloc
的崩溃版本,你可能已经知道了这一点。
依赖关系
约 40KB