Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Load kernel at specific address in v0.11 #427

Closed
jxors opened this issue Feb 20, 2024 · 6 comments · Fixed by #428
Closed

Load kernel at specific address in v0.11 #427

jxors opened this issue Feb 20, 2024 · 6 comments · Fixed by #428

Comments

@jxors
Copy link

jxors commented Feb 20, 2024

Is there any way to load the kernel at a specific address? With v0.10 I was using link-arg=--image-base=0x00001eecb3620000 to ensure that the kernel was always located at 0x00001eecb3620000, but v0.11 no longer seems to respect the offsets in the ELF file.

I'm guessing it's probably because of this code. I'm happy to write a PR that adds a config option to override the address chosen there.

@Freax13
Copy link
Member

Freax13 commented Feb 20, 2024

I'm guessing it's probably because of this code. I'm happy to write a PR that adds a config option to override the address chosen there.

The line you mentioned is only active for kernel compiled as position-independent executables. If you want your kernel to be loaded at a specific address you'll have to compile it with -C relocation-model=static.

@jxors
Copy link
Author

jxors commented Feb 21, 2024

Thank you for responding! I'm having some trouble compiling with the flag you mentioned.

When I compile with RUSTFLAGS="-Crelocation-model=static -Ccode-model=large -Clink-arg=--image-base=0x00001eecb3620000" cargo build --target x86_64-unknown-none -Z build-std=core,alloc I get the following error:

  = note: rust-lld: error: /[..]/target/x86_64-unknown-none/debug/deps/vmimage_x86_64-bca14057c3e0cdc3.3vq7oiz3rrtsr935.rcgu.o:(function _start: .ltext._start+0x23): relocation R_X86_64_32 out of range: 34001970711948 is not in [0, 4294967295]; references section '.bootloader-config'
          >>> referenced by lib.rs:129 (/[..]/bootloader/api/src/lib.rs:129)

Which I think refers to here

@Freax13
Copy link
Member

Freax13 commented Feb 21, 2024

This is caused by a bug related to the large code model:
AFAICT when the large relocation model is used, all functions and global variables that contain references to other functions and global variables outside what's reachable by the small code model are put in special .ltext, .lrodata and .ldata sections instead the regular .text, .rodata and .data sections. The bootloader_api crate internally uses a special .bootloader-config section to tell the bootloader how to boot the kernel. It seems to me that some part of the compiler is confused by this section. My guess is that the compiler will use 32-bit relocations by default and only use 64-bit relocations when referencing something in a .ltext, .lrodata, or .ldata section. Since .bootloader-config is not one of those, it uses a 32-bit relocation, but this fails because .bootloader-config cannot be referenced with a 32-bit relocation.

Freax13 added a commit to Freax13/bootloader that referenced this issue Feb 21, 2024
As explained in my comment in rust-osdev#427, the compiler seems to have trouble
emitting relocations for references to global variables in custom
sections. For custom sections, it always emits 32-bit relocations even
when a 64-bit relocation would be required. This patch works around
that by never referencing the global in the custom section directly
from code, but only through a pointer from another global variable in
the non-custom .data section. The relocation used for the pointer in
the global variable will always use a 64-bit relocation.
@Freax13
Copy link
Member

Freax13 commented Feb 21, 2024

I opened #428 to work around the compiler bug.

@daihuasheng
Copy link

In v0.11 kernel is placed as a workspace member of the whole project. In this case, how could I pass -Crelocation-model=static to the kernel without affecting bootloader?

@Freax13
Copy link
Member

Freax13 commented Jul 26, 2024

In v0.11 kernel is placed as a workspace member of the whole project. In this case, how could I pass -Crelocation-model=static to the kernel without affecting bootloader?

See this example.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants