如何为单片操作系统内核及其应用程序定义不同的[global_allocator]

问题描述 投票:0回答:1

我们目前正在使用 Rust 开发单片操作系统 (x86)。我们的货物工作区大致如下所示:

project dir
|--src (contains all kernel related code, omitted here)
|  |--main.rs
|
|--user
|  |--arch
|  |  |--link.ld
|  |--bin
|     |--app1.rs
|     |--app2.rs
|
|--Cargo.toml
|--build.rs

在项目工作区的编译过程中,我们创建一个包含用户目录的扁平化二进制文件的 initrd。 (使用

objcopy -O binary --set-section-flags .bss=alloc,load,contents <app> <flat binary>
压平) 内核稍后在运行时将这些二进制文件从 initrd 复制到相应的地址空间中。
现在我们想为用户空间应用程序和内核使用不同的堆分配器。我们在内核空间中为内核创建了一个堆分配器(<32MiB):

#[global_allocator]
static ALLOCATOR: LockedHeap = LockedHeap::empty();

当我们现在尝试在其中一个应用程序中创建

#[global_allocator]
时,就会出现问题:

#![no_std]
#![no_main]

#[global_allocator]
static ALLOCATOR: LockedHeap = LockedHeap::empty();

#[no_mangle]
pub extern "C" fn start() -> ! {
    let mem_size = 3 * Page::SIZE;
    let mem = syscall::mmap(mem_size);
    unsafe {
        ALLOCATOR.lock().init(mem, mem_size);
    }
    
    let v = vec![1, 2, 3];
}

这会在内核映像所在部分的内存位置触发页面错误。 那么我们需要如何更改设置/代码以使用户空间应用程序能够使用不同的堆,以便它们可以使用

alloc
板条箱。

一种选择是不为我们的内核声明

#[global_allocator]
并使用
new_in(...)
板条箱结构的
alloc
不稳定函数。然而,这是一种解决方法,而不是解决方案。
我们还尝试在完全不同的工作区中编译用户应用程序,假设组合工作区是此问题的根源,但这没有帮助。
我们将不胜感激!

rust operating-system kernel dynamic-memory-allocation osdev
1个回答
0
投票

经过几个小时的绞尽脑汁,我终于找到了问题的根源。 当我在用户应用程序中定义

#[global_allocator]
时,编译器将
eh_frame_hdr
部分放置在
text
部分通常所在的位置。这可以通过编辑链接器脚本,将 eh_frame_hdr 部分进一步向下移动来修复。

© www.soinside.com 2019 - 2024. All rights reserved.