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

Cleanup attributes, macros, and memory layout #23

Closed
wants to merge 9 commits into from

Conversation

josephlr
Copy link
Contributor

@josephlr josephlr commented Nov 12, 2019

This PR makes a number of cleanups to the code:

  • All the unneeded #[cfg(not(test))] attributes are removed
    • Only ~5 instances are actually requried
    • Replaced with a single #![cfg_attr(test, allow(dead_code))]
  • The log! macro now always appends a newline.
    • Also we now log! on panic (so we can figure out what the panic is).
  • Move all assembly to a separate asm/ram64.s file.
    • New entry point ram64_start is now in this file.
    • Explicitly handle SSE enabling and setting the stack before jumping to Rust code.
    • Use a common halt_loop
  • Be explicit with handling memory regions for stack and page tables
    • Now the stack and PML2 tables are mapped above 1 MiB
    • Fixes Page table creation clobbers provided command line #10
    • All non-Rust memory regions are recorded in layout.ld file.
    • setup_pagetables() now uses extern arrays with MemoryRegion::from_slice
    • This is a bigger change that I can split out if necessary

Signed-off-by: Joe Richey joerichey@google.com

The vast majority of these are not needed. This also makes it easier to:
  - Add code
  - Tell which sections actually are testing-dependent
This makes it harder to forget to append "\n" to log statments.
efi::console is also modified to take the lock outside of the loop.

Signed-off-by: Joe Richey <joerichey@google.com>
The pml2 tables and stack are now explictly allocated about 1 MiB.

Signed-off-by: Joe Richey <joerichey@google.com>
This allows us to define all of our long-mode assembly in a separate
file, making maintaince easier.

Signed-off-by: Joe Richey <joerichey@google.com>
Copy link
Member

@rbradford rbradford left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good but the build has failed...

src/main.rs Outdated
}

#[cfg(not(test))]
/// Setup page tables to provide an identity mapping over the full 4GiB range
fn setup_pagetables() {
const ADDRESS_SPACE_GIB: u64 = 64;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI, we don't need this to be 64 for Cloud Hypervisor any more (4GiB is sufficient)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome! I'll change it to 4, do you know why it needed to be 4GiB?

@rbradford
Copy link
Member

Interesting it builds fine locally for me :-)

It turns out we don't need MMIO devices above 4 GiB.

Signed-off-by: Joe Richey <joerichey@google.com>
The asm files use symbols in layout.ld, which won't exsist when tests
are run on the host (as it uses the host's linker script). This isn't an
issue for Rust code, as we have LTO enabled.

Signed-off-by: Joe Richey <joerichey@google.com>
@josephlr
Copy link
Contributor Author

Interesting it builds fine locally for me :-)

So the build failure is simply a weird way of saying ram_max is not defined. As the value of this symbol is only known at link-time, it comes from our custom linker script. Thus, when building on the host for cargo test it doesn't exist.

The reason it worked locally for you (and for me) it that newer versions of ld will garbage collect sections before linking them, so the .ram64 section was getting removed (as nothing referenced it) before any issue happened. I guess the old version of ld in Travis (which is using Ubuntu 16.04) couldn't firgure out that ram64.s could be removed from the final binary.

Note that this doesn't happen with Rust code as we always have lto = true. I fixed this by just telling it to not compile ram64.s when running tests, which is a good call regardless.

@rbradford the CI is now green, so this should be good to merge.

We can just get the address_space_gib symbol from the linker, which lets
us avoid the need for a separate ADDRESS_SPACE_GIB constant.

Signed-off-by: Joe Richey <joerichey@google.com>
@josephlr
Copy link
Contributor Author

@rbradford I also added 12c1679 which gets address_space_gib from the linker. Ideally, we would define this constant in Rust and have the linker use it, but I cannot figure out a way to do that.

Logging to serial outputs on all panics significantly increases code
size. We add two (on by default) features to disable serial logging:
  - Everywhere
  - Just in panics

Signed-off-by: Joe Richey <joerichey@google.com>
@josephlr
Copy link
Contributor Author

josephlr commented Nov 13, 2019

@rbradford I noticed adding serial logging on panics, while useful for debugging, make the binary much bigger. So I added 0669ebe to allow disabling of serial logging.

Binary sizes (release build, in bytes):

log-serial = true,  log-panic = true:  84488
log-serial = true,  log-panic = false: 58600
log-serial = false, log-panic = false: 47640

Does this feature gating seem worth it or reasonable? Note that serial logging and panic logging are enabled by default.

@rbradford
Copy link
Member

@rbradford I noticed adding serial logging on panics, while useful for debugging, make the binary much bigger. So I added 0669ebe to allow disabling of serial logging.

Binary sizes (release build, in bytes):

log-serial = true,  log-panic = true:  84488
log-serial = true,  log-panic = false: 58600
log-serial = false, log-panic = false: 47640

Does this feature gating seem worth it or reasonable? Note that serial logging and panic logging are enabled by default.

This is absolutely fine for now. However long term I think we will need to draw a distinction between logging for the firmware (which could/should go to I/O port 0x402 like QEMU and OVMF) and output that is from the bootloader (i.e. via the EFI stdout.) The latter case should always be shown.

@rbradford
Copy link
Member

This was embedded in PR #25 so can now be closed.

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 this pull request may close these issues.

Page table creation clobbers provided command line
2 participants