menu-commands.4th revision 199767f8919635c4928607450d9e0abb932109ce
\ Copyright (c) 2006-2015 Devin Teske <dteske@FreeBSD.org>
\ All rights reserved.
\
\ Redistribution and use in source and binary forms, with or without
\ modification, are permitted provided that the following conditions
\ are met:
\ 1. Redistributions of source code must retain the above copyright
\ notice, this list of conditions and the following disclaimer.
\ 2. Redistributions in binary form must reproduce the above copyright
\ notice, this list of conditions and the following disclaimer in the
\ documentation and/or other materials provided with the distribution.
\
\ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
\ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
\ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
\ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
\ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
\ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
\ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
\ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
\ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
\ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
\ SUCH DAMAGE.
\
\ Copyright 2015 Toomas Soome <tsoome@me.com>
marker task-menu-commands.4th
include /boot/forth/menusets.4th
only forth definitions
variable osconsole_state
variable acpi_state
variable kernel_state
variable root_state
variable kmdb_state
variable debug_state
0 kmdb_state !
0 debug_state !
0 osconsole_state !
0 acpi_state !
0 kernel_state !
0 root_state !
also menu-namespace also menu-command-helpers
\
\ Boot
\
: init_boot ( N -- N )
dup
s" smartos" getenv? if
s" set menu_keycode[N]=98" \ base command to execute
else
s" boot_single" getenv -1 <> if
drop ( n n c-addr -- n n ) \ unused
toggle_menuitem ( n n -- n n )
s" set menu_keycode[N]=115" \ base command to execute
else
s" set menu_keycode[N]=98" \ base command to execute
then
then
17 +c! \ replace 'N' with ASCII numeral
evaluate
;
\
\ Alternate Boot
\
: init_altboot ( N -- N )
dup
s" smartos" getenv? if
s" set menu_keycode[N]=114" \ base command to execute
else
s" boot_single" getenv -1 <> if
drop ( n c-addr -- n ) \ unused
toggle_menuitem ( n -- n )
s" set menu_keycode[N]=109" \ base command to execute
else
s" set menu_keycode[N]=115" \ base command to execute
then
then
17 +c! \ replace 'N' with ASCII numeral
evaluate
;
: altboot ( N -- NOTREACHED )
s" smartos" getenv? if
s" alt-boot-args" getenv dup -1 <> if
s" boot-args" setenv ( c-addr/u -- )
then
." NoInstall/Recovery mode boot. login/pw: root/root" cr
else
s" boot_single" 2dup getenv -1 <> if
drop ( c-addr/u c-addr -- c-addr/u ) \ unused
unsetenv ( c-addr/u -- )
else
2drop ( c-addr/u -- ) \ unused
s" set boot_single=YES" evaluate
then
then
0 boot ( state -- )
;
\
\ Single User Mode
\
: singleuser_enabled? ( -- flag )
s" boot_single" getenv -1 <> dup if
swap drop ( c-addr flag -- flag )
then
;
: singleuser_enable ( -- )
s" set boot_single=YES" evaluate
;
: singleuser_disable ( -- )
s" boot_single" unsetenv
;
: init_singleuser ( N -- N )
singleuser_enabled? if
toggle_menuitem ( n -- n )
then
;
: toggle_singleuser ( N -- N TRUE )
toggle_menuitem
menu-redraw
\ Now we're going to make the change effective
dup toggle_stateN @ 0= if
singleuser_disable
else
singleuser_enable
then
TRUE \ loop menu again
;
\
\ Verbose Boot
\
: verbose_enabled? ( -- flag )
s" boot_verbose" getenv -1 <> dup if
swap drop ( c-addr flag -- flag )
then
;
: verbose_enable ( -- )
s" set boot_verbose=YES" evaluate
;
: verbose_disable ( -- )
s" boot_verbose" unsetenv
;
: init_verbose ( N -- N )
verbose_enabled? if
toggle_menuitem ( n -- n )
then
;
: toggle_verbose ( N -- N TRUE )
toggle_menuitem
menu-redraw
\ Now we're going to make the change effective
dup toggle_stateN @ 0= if
verbose_disable
else
verbose_enable
then
TRUE \ loop menu again
;
\
\ kmdb
\
: kmdb_enabled? ( -- flag )
s" boot_kmdb" getenv -1 <> dup if
swap drop ( c-addr flag -- flag )
then
;
: kmdb_enable ( -- )
s" set boot_kmdb=YES" evaluate
;
: kmdb_disable ( -- )
s" boot_kmdb" unsetenv
s" boot_debug" unsetenv
;
: init_kmdb ( N -- N )
dup kmdb_state ! \ store entry number for kmdb+debug
kmdb_enabled? if
toggle_menuitem ( n -- n )
then
;
: toggle_kmdb ( N -- N TRUE )
toggle_menuitem
dup toggle_stateN @ 0= if ( kmdb is not set )
debug_state @ if ( debug is set? )
debug_state @ toggle_stateN @ if ( debug is enabled? )
debug_state @ toggle_menuitem drop
then
then
then
menu-redraw
\ Now we're going to make the change effective
dup toggle_stateN @ 0= if
kmdb_disable
else
kmdb_enable
then
TRUE \ loop menu again
;
\
\ kmdb + debug
\
: debug_disable ( -- )
s" boot_debug" unsetenv
;
: debug_enabled? ( -- flag )
\ -d is only allowed with -k
s" boot_debug" getenv -1 <> kmdb_enabled? and dup if
swap drop ( c-addr flag -- flag )
else
debug_disable \ make sure env is not set
then
;
: debug_enable ( -- )
kmdb_enable
s" set boot_debug=YES" evaluate
;
: init_debug ( N -- N )
dup debug_state ! \ store entry number for kmdb
kmdb_enabled? debug_enabled? and if
toggle_menuitem ( n -- n )
then
;
: toggle_debug ( N -- N TRUE )
toggle_menuitem
kmdb_enabled? 0= if
kmdb_state @ toggle_menuitem drop
then
menu-redraw
\ Now we're going to make the change effective
dup toggle_stateN @ 0= if
debug_disable
else
debug_enable
then
TRUE \ loop menu again
;
\
\ Reconfiguration boot
\
: reconfigure_enabled? ( -- flag )
s" boot_reconfigure" getenv -1 <> dup if
swap drop ( c-addr flag -- flag )
then
;
: reconfigure_enable ( -- )
s" set boot_reconfigure=YES" evaluate
;
: reconfigure_disable ( -- )
s" boot_reconfigure" unsetenv
;
: init_reconfigure ( N -- N )
reconfigure_enabled? if
toggle_menuitem ( n -- n )
then
;
: toggle_reconfigure ( N -- N TRUE )
toggle_menuitem
menu-redraw
\ Now we're going to make the change effective
dup toggle_stateN @ 0= if
reconfigure_disable
else
reconfigure_enable
then
TRUE \ loop menu again
;
\
\ Escape to Prompt
\
: goto_prompt ( N -- N FALSE )
s" set autoboot_delay=NO" evaluate
cr
." To get back to the menu, type `menu' and press ENTER" cr
." or type `boot' and press ENTER to start illumos." cr
cr
FALSE \ exit the menu
;
\
\ Cyclestate (used by osconsole/acpi/kernel/root below)
\
: init_cyclestate ( N K -- N )
over cycle_stateN ( n k -- n k addr )
begin
tuck @ ( n k addr -- n addr k c )
over <> ( n addr k c -- n addr k 0|-1 )
while
rot ( n addr k -- addr k n )
cycle_menuitem
swap rot ( addr k n -- n k addr )
repeat
2drop ( n k addr -- n )
;
\
\ OS Console
\ getenv os_console, if not set getenv console, if not set, default to "text"
\ allowed serial consoles: ttya .. ttyd
\ if new console will be added (graphics?), this section needs to be updated
\
: init_osconsole ( N -- N )
s" os_console" getenv dup -1 = if
drop
s" console" getenv dup -1 = if
drop 0 \ default to text
then
then ( n c-addr/u | n 0 )
dup 0<> if ( n c-addr/u )
2dup s" ttyd" compare 0= if
2drop 4
else 2dup s" ttyc" compare 0= if
2drop 3
else 2dup s" ttyb" compare 0= if
2drop 2
else 2dup s" ttya" compare 0= if
2drop 1
else
2drop 0 \ anything else defaults to text
then then then then
then
osconsole_state !
;
: activate_osconsole ( N -- N )
dup cycle_stateN @ ( n -- n n2 )
dup osconsole_state ! ( n n2 -- n n2 ) \ copy for re-initialization
case
0 of s" text" endof
1 of s" ttya" endof
2 of s" ttyb" endof
3 of s" ttyc" endof
4 of s" ttyd" endof
dup s" unknown state: " type . cr
endcase
s" os_console" setenv
;
: cycle_osconsole ( N -- N TRUE )
cycle_menuitem \ cycle cycle_stateN to next value
activate_osconsole \ apply current cycle_stateN
menu-redraw \ redraw menu
TRUE \ loop menu again
;
\
\ ACPI
\
: init_acpi ( N -- N )
s" acpi-user-options" getenv dup -1 <> if
evaluate \ use ?number parse step
\ translate option to cycle state
case
1 of 1 acpi_state ! endof
2 of 2 acpi_state ! endof
4 of 3 acpi_state ! endof
8 of 4 acpi_state ! endof
0 acpi_state !
endcase
else
drop
then
;
: activate_acpi ( N -- N )
dup cycle_stateN @ ( n -- n n2 )
dup acpi_state ! ( n n2 -- n n2 ) \ copy for re-initialization
\ if N == 0, it's default, just unset env.
dup 0= if
drop
s" acpi-user-options" unsetenv
else
case
1 of s" 1" endof
2 of s" 2" endof
3 of s" 4" endof
4 of s" 8" endof
endcase
s" acpi-user-options" setenv
then
;
: cycle_acpi ( N -- N TRUE )
cycle_menuitem \ cycle cycle_stateN to next value
activate_acpi \ apply current cycle_stateN
menu-redraw \ redraw menu
TRUE \ loop menu again
;
\
\ Kernel
\
: init_kernel ( N -- N )
kernel_state @ ( n -- n k )
init_cyclestate ( n k -- n )
;
: activate_kernel ( N -- N )
dup cycle_stateN @ ( n -- n n2 )
dup kernel_state ! ( n n2 -- n n2 ) \ copy for re-initialization
48 + ( n n2 -- n n2' ) \ kernel_state to ASCII num
s" set kernel=${kernel_prefix}${kernel[N]}${kernel_suffix}"
36 +c! ( n n2 c-addr/u -- n c-addr/u ) \ 'N' to ASCII num
evaluate ( n c-addr/u -- n ) \ sets $kernel to full kernel-path
;
: cycle_kernel ( N -- N TRUE )
cycle_menuitem \ cycle cycle_stateN to next value
activate_kernel \ apply current cycle_stateN
menu-redraw \ redraw menu
TRUE \ loop menu again
;
\
\ Root
\
: init_root ( N -- N )
root_state @ ( n -- n k )
init_cyclestate ( n k -- n )
;
: activate_root ( N -- N )
dup cycle_stateN @ ( n -- n n2 )
dup root_state ! ( n n2 -- n n2 ) \ copy for re-initialization
48 + ( n n2 -- n n2' ) \ root_state to ASCII num
s" set root=${root_prefix}${root[N]}${root_suffix}"
30 +c! ( n n2 c-addr/u -- n c-addr/u ) \ 'N' to ASCII num
evaluate ( n c-addr/u -- n ) \ sets $root to full kernel-path
;
: cycle_root ( N -- N TRUE )
cycle_menuitem \ cycle cycle_stateN to next value
activate_root \ apply current cycle_stateN
menu-redraw \ redraw menu
TRUE \ loop menu again
;
\
\ Menusets
\
: goto_menu ( N M -- N TRUE )
menu-unset
menuset-loadsetnum ( n m -- n )
menu-redraw
TRUE \ Loop menu again
;
\
\ Defaults
\
: set_default_boot_options ( N -- N TRUE )
0 acpi_state !
s" acpi-user-options" unsetenv
singleuser_disable
verbose_disable
kmdb_disable \ disables debug as well
reconfigure_disable
2 goto_menu
;
\
\ Set boot environment defaults
\
: init_bootenv ( -- )
s" set menu_caption[1]=${bemenu_current}${zfs_be_active}" evaluate
s" set ansi_caption[1]=${beansi_current}${zfs_be_active}" evaluate
s" set menu_caption[2]=${bemenu_bootfs}${currdev}" evaluate
s" set ansi_caption[2]=${beansi_bootfs}${currdev}" evaluate
s" set menu_caption[3]=${bemenu_page}${zfs_be_currpage}${bemenu_pageof}${zfs_be_pages}" evaluate
s" set ansi_caption[3]=${beansi_page}${zfs_be_currpage}${bemenu_pageof}${zfs_be_pages}" evaluate
;
\
\ Redraw the entire screen. A long BE name can corrupt the menu
\
: be_draw_screen
clear \ Clear the screen (in screen.4th)
print_version \ print version string (bottom-right; see version.4th)
draw-beastie \ Draw FreeBSD logo at right (in beastie.4th)
draw-brand \ Draw brand.4th logo at top (in brand.4th)
menu-init \ Initialize menu and draw bounding box (in menu.4th)
;
\
\ Select a boot environment
\
: set_bootenv ( N -- N TRUE )
dup s" bootenv_root[E]" 13 +c! getenv
s" currdev" getenv compare 0= if
s" zfs_be_active" getenv type ." is already active"
500 ms \ sleep
else
dup s" set currdev=${bootenv_root[E]}" 27 +c! evaluate
dup s" bootenvmenu_caption[E]" 20 +c! getenv
s" zfs_be_active" setenv
." Activating " s" currdev" getenv type cr
s" unload" evaluate
free-module-options
s" /boot/defaults/loader.conf" read-conf
s" /boot/loader.conf" read-conf
s" /boot/loader.conf.local" read-conf
init_bootenv
then
be_draw_screen
menu-redraw
TRUE
;
\
\ Switch to the next page of boot environments
\
: set_be_page ( N -- N TRUE )
s" zfs_be_currpage" getenv dup -1 = if
drop s" 1"
else
0 s>d 2swap
>number ( ud caddr/u -- ud' caddr'/u' )
2drop
1 um/mod ( ud u1 -- u2 u3 )
swap drop ( ud2 u3 -- u3 )
1+ \ increment the page number
dup
s" zfs_be_pages" getenv
0 s>d 2swap
>number ( ud caddr/u -- ud' caddr'/u' )
2drop
1 um/mod ( ud u1 -- u2 u3 )
swap drop ( ud2 u3 -- u3 )
> if drop 1 then
s>d <# #s #> \ convert back to a string
then
s" zfs_be_currpage" setenv
s" be-set-page" evaluate
3 goto_menu
;
only forth definitions