phil-opp / blog_os

Writing an OS in Rust

Home Page:http://os.phil-opp.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

data-layout error when running cargo build

georgewoodall82 opened this issue · comments

When trying to cargo build with the x86_64-blog_os.json file, I get the following error:

error: data-layout for target `x86_64-blog_os-6585274978445825374`,
`e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128`,
differs from LLVM target's `x86_64-unknown-none` default layout,
`e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128`

If I change the data-layout in the json file to the default layout, it compiles, but then when I run cargo bootimage the error comes back:

error: data-layout for target `x86_64-blog_os-6585274978445825374`,
`e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128`,
differs from LLVM target's `x86_64-unknown-none` default layout,
`e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128`

Why is this happening?

You need the same target spec change as rust-osdev/bootloader#420 LLVM recently changed the alignment of 128bit ints to match GCC and rustc updated to this too. The data layout (sizes and alignments of primitive types) needs to match between the target spec and what LLVM knows.

@bjorn3 I tried updating the data-layout in the target file but ended up with the following error:

cargo build 
error: failed to run `rustc` to learn about target-specific information

Caused by:
  process didn't exit successfully: `/home/ayush/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/bin/rustc - --crate-name ___ --print=file-names --target /home/ayush/genesis_os-rs/x86_64_genesis.json --crate-type bin --crate-type rlib --crate-type dylib --crate-type cdylib --crate-type staticlib --crate-type proc-macro --print=sysroot --print=split-debuginfo --print=crate-name --print=cfg` (exit status: 1)
  --- stderr
  error: inconsistent target specification: "data-layout" claims pointers are 32-bit, while "target-pointer-width" is `64`

Target JSON:

{
  "llvm-target": "x86_64-unknown-none",
  "executables": true,
  "data-layout": "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i128:128-f64:32:64-f80:32-n8:16:32-S128",
  "arch": "x86_64",
  "target-endian": "little",
  "target-pointer-width": "64",
  "target-c-int-width": "32",
  "os": "none",
  "executables": true,
  "linker-flavor": "ld.lld",
  "linker": "rust-lld",
  "panic-strategy": "abort",
  "disable-redzone": true,
  "features": "-mmx,-sse,+soft-float"
}

e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128 should be the correct data layput.

Now the cargo bootimage command fails:

cargo bootimage          
WARNING: `CARGO_MANIFEST_DIR` env variable not set
Building kernel
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.02s
Building bootloader
   Compiling compiler_builtins v0.1.108
   Compiling core v0.0.0 (/home/ayush/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core)
   Compiling serde v1.0.116
   Compiling bitflags v1.2.1
   Compiling x86_64 v0.14.7
   Compiling llvm-tools v0.1.1
   Compiling toml v0.5.6
   Compiling bootloader v0.9.24 (/home/ayush/.cargo/registry/src/index.crates.io-6f17d22bba15001f/bootloader-0.9.24)
   Compiling rustc-std-workspace-core v1.99.0 (/home/ayush/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/rustc-std-workspace-core)
error: data-layout for target `x86_64-bootloader-15639772412341111525`, `e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128`, differs from LLVM target's `x86_64-unknown-none-gnu` default layout, `e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128`

error: could not compile `rustc-std-workspace-core` (lib) due to 1 previous error
warning: build failed, waiting for other jobs to finish...
error: could not compile `core` (lib) due to 1 previous error
error: could not compile `compiler_builtins` (lib) due to 1 previous error
Error: Bootloader build failed.
Stderr: 

Cargo bootimage version:

cargo bootimage --version
bootimage 0.10.3

I am on the following part if that helps:
https://os.phil-opp.com/minimal-rust-kernel/

e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128 should be the correct data layput.

I made this change not just to my x84_64-bootloader.json, but also to bootloader-0.9.24/x86_64-bootloader.json in .cargo.

qemu does show up but the following way:
Screenshot 2024-02-16 at 9 04 31 AM

Is this because of the UD2 instruction that's causing this?
The Output on the above QEMU screen shows:
panicked at src/main.rs:286.6:okernel mapping failed: Mapping(PageAlreadyMapped(PhysFrame4KiB))

Thanks for the details! I think the ud2 instruction only happens with the v0.11 versions of the bootloader, the v0. 9 versions don't seem to be affected. I try to release a new v0.9 release today to fix the data layout error.

Regarding the weird QEMU display: We already had a few reports of this, mostly by people on recent macOS versions. It seems to be a bug in QEMU because once you enter full-screen in QEMU, all content is visible.

I'm not sure sure what causes the map error yet. Probably the default linker script in LLVM changed and it no longer pads sections to page boundaries. I'll look into it.

I compile this entire project on my x86_64 linux with the same QEMU version (8.2.1) and it reports no such errors as I mentioned above. No data layout error as well (used the old data layout).

I say this because my nightly rustc compiler was outdated on my x86 system (compiled successfully with that). I run "rustup update" and re-compiled this project. And now it throws the same error all over again. Even QEMU displays:

panicked at src/main.rs:286.6:okernel mapping failed: Mapping(PageAlreadyMapped(PhysFrame{4KiB}(0x416000)))

Could it be an issue with rustc?

Also could you help me explain how did we reach this address 0x416000 ? Because I had a peak into the bootloader-0.9.2/src/main.rs and at line number 95:
let kernel_start = 0x400000;

According to that error: My assumption is we are trying to map the kernel again to a different address? Please do correct me if I am wong. I am new to all these concepts.

panicked at src/main.rs:286.6:okernel mapping failed: Mapping(PageAlreadyMapped(PhysFrame{4KiB}(0x416000)))

This issue should be fixed with rust-osdev/bootloader#422.

Thank you so much for the fix! Great tutorial by the way, enjoying every post!

Thanks :)