mirror of
https://github.com/edera-dev/sprout.git
synced 2026-02-04 08:40:17 +00:00
feat(boot): clear screen before boot handoff, if --retain-boot-console is not specified on the command-line (#51)
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
use crate::context::SproutContext;
|
use crate::context::SproutContext;
|
||||||
|
use crate::phases::before_handoff;
|
||||||
use crate::utils;
|
use crate::utils;
|
||||||
use alloc::boxed::Box;
|
use alloc::boxed::Box;
|
||||||
use alloc::rc::Rc;
|
use alloc::rc::Rc;
|
||||||
@@ -88,6 +89,10 @@ pub fn chainload(context: Rc<SproutContext>, configuration: &ChainloadConfigurat
|
|||||||
BootloaderInterface::mark_exec(context.root().timer())
|
BootloaderInterface::mark_exec(context.root().timer())
|
||||||
.context("unable to mark execution of boot entry in bootloader interface")?;
|
.context("unable to mark execution of boot entry in bootloader interface")?;
|
||||||
|
|
||||||
|
// Since we are about to hand off control to another image, we need to execute the handoff hook.
|
||||||
|
// This will perform operations like clearing the screen.
|
||||||
|
before_handoff(&context).context("unable to execute before handoff hook")?;
|
||||||
|
|
||||||
// Start the loaded image.
|
// Start the loaded image.
|
||||||
// This call might return, or it may pass full control to another image that will never return.
|
// This call might return, or it may pass full control to another image that will never return.
|
||||||
// Capture the result to ensure we can return an error if the image fails to start, but only
|
// Capture the result to ensure we can return an error if the image fails to start, but only
|
||||||
|
|||||||
@@ -24,6 +24,8 @@ pub struct SproutOptions {
|
|||||||
pub force_menu: bool,
|
pub force_menu: bool,
|
||||||
/// The timeout for the boot menu in seconds.
|
/// The timeout for the boot menu in seconds.
|
||||||
pub menu_timeout: Option<u64>,
|
pub menu_timeout: Option<u64>,
|
||||||
|
/// Retains the boot console before boot.
|
||||||
|
pub retain_boot_console: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The default Sprout options.
|
/// The default Sprout options.
|
||||||
@@ -35,6 +37,7 @@ impl Default for SproutOptions {
|
|||||||
boot: None,
|
boot: None,
|
||||||
force_menu: false,
|
force_menu: false,
|
||||||
menu_timeout: None,
|
menu_timeout: None,
|
||||||
|
retain_boot_console: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -42,7 +45,7 @@ impl Default for SproutOptions {
|
|||||||
/// The options parser mechanism for Sprout.
|
/// The options parser mechanism for Sprout.
|
||||||
impl SproutOptions {
|
impl SproutOptions {
|
||||||
/// Produces [SproutOptions] from the arguments provided by the UEFI core.
|
/// Produces [SproutOptions] from the arguments provided by the UEFI core.
|
||||||
/// Internally we utilize the `jaarg` argument parser which has excellent no_std support.
|
/// Internally, we use the `jaarg` argument parser which has excellent no_std support.
|
||||||
pub fn parse() -> Result<Self> {
|
pub fn parse() -> Result<Self> {
|
||||||
enum ArgID {
|
enum ArgID {
|
||||||
Help,
|
Help,
|
||||||
@@ -51,6 +54,7 @@ impl SproutOptions {
|
|||||||
Boot,
|
Boot,
|
||||||
ForceMenu,
|
ForceMenu,
|
||||||
MenuTimeout,
|
MenuTimeout,
|
||||||
|
RetainBootConsole,
|
||||||
}
|
}
|
||||||
|
|
||||||
// All the options for the Sprout executable.
|
// All the options for the Sprout executable.
|
||||||
@@ -65,6 +69,8 @@ impl SproutOptions {
|
|||||||
Opt::flag(ArgID::ForceMenu, &["--force-menu"]).help_text("Force showing the boot menu"),
|
Opt::flag(ArgID::ForceMenu, &["--force-menu"]).help_text("Force showing the boot menu"),
|
||||||
Opt::value(ArgID::MenuTimeout, &["--menu-timeout"], "TIMEOUT")
|
Opt::value(ArgID::MenuTimeout, &["--menu-timeout"], "TIMEOUT")
|
||||||
.help_text("Boot menu timeout, in seconds"),
|
.help_text("Boot menu timeout, in seconds"),
|
||||||
|
Opt::flag(ArgID::RetainBootConsole, &["--retain-boot-console"])
|
||||||
|
.help_text("Retain boot console before boot"),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Acquire the arguments as determined by the UEFI core.
|
// Acquire the arguments as determined by the UEFI core.
|
||||||
@@ -99,6 +105,10 @@ impl SproutOptions {
|
|||||||
// The timeout for the boot menu in seconds.
|
// The timeout for the boot menu in seconds.
|
||||||
result.menu_timeout = Some(value.parse::<u64>()?);
|
result.menu_timeout = Some(value.parse::<u64>()?);
|
||||||
}
|
}
|
||||||
|
ArgID::RetainBootConsole => {
|
||||||
|
// Retain the boot console before booting.
|
||||||
|
result.retain_boot_console = true;
|
||||||
|
}
|
||||||
ArgID::Help => {
|
ArgID::Help => {
|
||||||
let ctx = HelpWriterContext {
|
let ctx = HelpWriterContext {
|
||||||
options: &OPTIONS,
|
options: &OPTIONS,
|
||||||
|
|||||||
@@ -24,3 +24,13 @@ pub fn phase(context: Rc<SproutContext>, phase: &[PhaseConfiguration]) -> Result
|
|||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Manual hook called by code in the bootloader that hands off to another image.
|
||||||
|
/// This is used to perform actions like clearing the screen.
|
||||||
|
pub fn before_handoff(context: &SproutContext) -> Result<()> {
|
||||||
|
// If we have not been asked to retain the boot console, then we should clear the screen.
|
||||||
|
if !context.root().options().retain_boot_console {
|
||||||
|
uefi::system::with_stdout(|stdout| stdout.reset(true)).context("unable to clear screen")?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user