Search code examples
rustoperating-systemkerneldynamic-memory-allocationosdev

How to define different [global_allocator]s for a monolithic os kernel and its applications


We're currently working on a monolithic operating system (x86) in Rust. Our cargo workspace looks roughly like this:

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

During the compilation of the project workspace we create a initrd containing the flattened binaries of the user directory. (Flattened using objcopy -O binary --set-section-flags .bss=alloc,load,contents <app> <flat binary>) The kernel later copies these binaries at runtime from the initrd into their corresponding address space.
Now we want to use different heap allocators for the userspace applications and the kernel. We created a heap allocator for our kernel within our kernelspace (<32MiB):

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

The issue arises when we try to create a #[global_allocator] in one of our applications now:

#![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];
}

This triggers a pagefault at a memory location within the section where our kernel image resides. So how do we need to change our setup/code to enable the user space applications to use a different heap so they can make use of the alloc crate.

One option would be to not declare a #[global_allocator] for our kernel and use the new_in(...) unstable functions of the alloc crate's structs. However this is a workaround rather than a solution.
We've also tried compiling the user applications in a completely different workspace, under the assumption that the combined workspace was the root of this problem, but this didn't help.
Help would be greatly appreciated!


Solution

  • After many hours of head-scratching I finally found the root of the problem. When I defined a #[global_allocator] in a user application, the compiler placed the eh_frame_hdr section right where the text section usually sits. This could be fixed by editing the linker script, moving the eh_frame_hdr section further down.