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

Allow bootloader to react to certain keys #187

Closed
grahamperrin opened this issue Mar 20, 2021 · 17 comments
Closed

Allow bootloader to react to certain keys #187

grahamperrin opened this issue Mar 20, 2021 · 17 comments
Labels
enhancement New feature or request freebsd Needs FreeBSD expertise and/or work help wanted Extra attention is needed

Comments

@grahamperrin
Copy link
Contributor

Safe mode

From #103 (comment):

… At the time when the boot command prompt shows it is probably already too late to change this by setting/unsetting the environment variable.

Possibly there is a way to load the boot loader menu on the Live system …

Boot environments

From #55 (comment):

  • We need a way to select BEs from the bootloader, which means we need to work on the bootloader to be completely silent unless a key combo (e.g., Command-B-E for Boot Environments) is held down

Until user-friendly silence can be achieved with helloSystem:

  • there should be a method – any method – of breaking silence, to present the normal FreeBSD loader, when required, for BE purposes.

Blocking normal presentation:

35e19f2

Reference

https://cgit.freebsd.org/src/tree/stand/forth/loader.4th

https://cgit.freebsd.org/src/tree/stand/forth/beastie.4th

beastie.4th(8)

FreeBSD bug 254431 – beastie.4th(8) is no longer ASCII art

@probonopd
Copy link
Member

probonopd commented Mar 20, 2021

The desired behavior is described in https://support.apple.com/en-us/HT201255

  • By default, no boot loader messages should be shown at all
  • If the user holds down Command+V (for verbose) during boot, then unset boot_mute and boot -v should happen (in the bootloader, Ctrl, Windows, and Alt should all act as Command)
  • If the user holds down Command+B (for bootloader) during boot, then Beastie menu should be shown

Do you know how to achieve this in Forth?

@probonopd probonopd changed the title Boot time boot options: determine a method to allow appearance of the beastie.4th boot loader Allow bootloader to react to command+... keys Mar 20, 2021
@grahamperrin
Copy link
Contributor Author

grahamperrin commented Mar 20, 2021

Why did you change my title?

We need something sooner than the luxury of snag keys. 35e19f2 reduces the usability of boot environments; makes things potentially difficult for end users.

Command+B (for bootloader)

Why not Alt?

@probonopd
Copy link
Member

probonopd commented Mar 20, 2021

Because Command+S stands for safe mode.

If technically possible, it would be great if we could use Command+B+Et o go to the Boot Environments screen directly.

(On PC keyboards, we use Alt as the Command key. On Mac keyboards, we use the Apple key as the Command key. Command stands for "the key on the left side to the space bar" as far as I am concerned.)

@grahamperrin
Copy link
Contributor Author

grahamperrin commented Mar 20, 2021

For a moment, forget the Command key.

Alt is used by Apple with Apple keyboards with Mac hardware.

@probonopd
Copy link
Member

probonopd commented Mar 20, 2021

Actually, https://support.apple.com/en-us/HT201255 says

  • Shift (⇧): Start up in safe mode.
  • Command-S: Start up in single-user mode

@grahamperrin
Copy link
Contributor Author

Some disorientation from the change of title, which was not intended to focus on safe mode or single user mode.

To refocus on what was originally in my title, I simply want a method to present:

  • the beastie.4th boot loader

– from there, people can step to safe mode, single user mode and so on; most importantly, boot environments.

Corrected above. It's Alt (not Alt-S):

image

(The mid-sentence uppercase S is quite un-British. I misread it as part of the shortcut.)

@probonopd
Copy link
Member

I agree that this would be cool.

@probonopd
Copy link
Member

https://github.com/freebsd/freebsd-src/blob/839fdcfc0c1dba34f728813d9756515ad82ff58a/stand/common/boot.c#L215

has printf("%s\n", (prompt == NULL) ? "Hit [Enter] to boot immediately, or any other key for command prompt." : prompt); - so we could hook in there and do something else if specific keys were pressed.

But the question is, can we do everything in Forth without compilation?

That would probably mean to not skip Beastie altogether, but to modify Beastie to show up even if beastie_disable is selected in case the the Alt key is pressed?

Probably we would have to hook this in around here:
https://github.com/freebsd/freebsd-src/blob/839fdcfc0c1dba34f728813d9756515ad82ff58a/stand/forth/beastie.4th#L91-L101

Does anyone know any Forth?

@probonopd

This comment has been minimized.

@probonopd
Copy link
Member

Got this information:

Guys, just letting you know that the kernel loader in FreeBSD 12 and 13 uses Lua as a scripting language.
The loader in FreeBSD 11 and previous versions uses Forth.
Scripts whose names end in .4th are Forth scripts. The Lua scripts have names ending in .lua and they are to be found in the /boot/lua directory.
The documentation for the FreeBSD loader is not up-to-date.

@probonopd
Copy link
Member

probonopd commented Apr 1, 2021

I would like to allow users to boot in verbose mode by just pressing the v (ASCII 76) key.

Added a file /boot/lua/local.lua that contains:

if io.ischar() then
        local ch = io.getchar()
        if ch == 76 then
                loader.perform("unset boot_mute")
                loader.perform("boot -v")
        end
end

Unfortunately I can't seem to get it to work.
What am I doing wrong?

(/boot/loader_lua.efi seems ot be able to do a similar thing to what I want, namely if you press e.g., backspace while the kernel is being loaded, then it drops the user to a OK> prompt... so maybe we need to edit its souce code to achieve such a thing?)

@probonopd probonopd changed the title Allow bootloader to react to command+... keys Allow bootloader to react to certain keys Apr 1, 2021
@probonopd probonopd added enhancement New feature or request help wanted Extra attention is needed labels Apr 1, 2021
@probonopd
Copy link
Member

probonopd commented Apr 7, 2021

Maybe we need to patch stand/common/boot.c with something like this:

                                if ((c == 'V') || (c == 'v')) {
                                        yes = 1;
                                        argv[0] = "boot -v";
                                        argv[1] = NULL;
                                        return(command_boot(1, argv));
                                        break;
                                }

@probonopd
Copy link
Member

probonopd commented Nov 22, 2021

     <-- User should be able to press 'v' or 's' here

    Hit [Enter] to boot immediately, or any other key for command prompt.
    Booting [kernel] in 1 seconds
    
    Type '?' for a list of commands, 'help' for more detailed help.
    OK

Out of the box, pressing s or v while the early stages of the bootloader are running prevents autoboot from happening and dumps one to an OK prompt. This prevents us from solving this (purely) by Lua scripting. Even if Lua could get the content of the keyboard buffer, the boot would end before that at the OK prompt.

The bootloader probably needs to be changed so that the OK prompt only shows up in case a certain key had been pressed, e.g., backspace.

"The bootloader" being

grep -r "for more detailed help" /boot
Binary file /boot/loader_simp.efi matches
Binary file /boot/loader matches
Binary file /boot/loader_simp matches
Binary file /boot/loader_lua matches
Binary file /boot/loader_lua.efi matches
Binary file /boot/zfsloader matches
Binary file /boot/userboot.so matches
Binary file /boot/loader.efi matches
Binary file /boot/pxeboot matches
Binary file /boot/loader_4th matches
Binary file /boot/userboot_4th.so matches
Binary file /boot/userboot_lua.so matches
Binary file /boot/loader_4th.efi matches

Is "freebsd-src/stand" the source of the bootloader? (What does stand stand for?)

Maybe @kevans91 knows how to do that?

@probonopd
Copy link
Member

probonopd commented Nov 22, 2021

By the way, LOADER.CONF(5) says about autoboot_delay:

If set to "0", no delay is inserted, but any keys pressed while the kernel and modules are loaded will enter interactive mode.

That does not seem to work for me. Hence I set it to 1.
The objective is to waste no precious seconds but still to be able to get to the OK prompt by pressing backspace here:

     <-- User should be able to press backspace here

    Hit [Enter] to boot immediately, or any other key for command prompt.
    Booting [kernel] in 1 seconds
    
    Type '?' for a list of commands, 'help' for more detailed help.
    OK

@kevans91
Copy link

Yes, stand/ is where the loader lives ([stand]alone, iirc). I definitely haven't implemented any sort of key tracking while loadelf is operating in lualoader (stand/lua substantially), so it makes sense that that doesn't work. You can still solve that entirely in lualoader, we just don't do that at the moment; lualoader's what handles the interrupt of autoboot typically.

@probonopd
Copy link
Member

probonopd commented Nov 22, 2021

Time to learn Lua then. Has been on my TODO list for a long time anyway :-)

Just to be sure:

When I press any key before the "Loading kernel..." message, then I am still able to catch that in Lua without being dropped to the OK prompt?

@probonopd
Copy link
Member

probonopd commented Feb 26, 2023

Finally came around to wrapping my head around lua. It's great! Thanks a lot @kevans91.

if io.ischar() then
local ch = io.getchar()

The way it is working right now is that the user has to press one of the keys s, v, backspace as soon as the local.lua script runs.

Only thing I didn't figure out is how to get at the keyboard buffer, so that I could detect whether certain keys had been pressed by the user before the start of the execution of my lua script.

I think the bootloader can do that for detecting whether backspace had been pressed by the user, even before the bootloader runs...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request freebsd Needs FreeBSD expertise and/or work help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

3 participants