1\ Copyright (c) 2006-2015 Devin Teske <dteske@FreeBSD.org> 2\ All rights reserved. 3\ 4\ Redistribution and use in source and binary forms, with or without 5\ modification, are permitted provided that the following conditions 6\ are met: 7\ 1. Redistributions of source code must retain the above copyright 8\ notice, this list of conditions and the following disclaimer. 9\ 2. Redistributions in binary form must reproduce the above copyright 10\ notice, this list of conditions and the following disclaimer in the 11\ documentation and/or other materials provided with the distribution. 12\ 13\ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 14\ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15\ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16\ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 17\ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18\ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19\ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20\ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21\ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22\ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23\ SUCH DAMAGE. 24\ 25\ Copyright 2015 Toomas Soome <tsoome@me.com> 26\ Copyright 2019 Joyent, Inc. 27\ Copyright 2020 OmniOS Community Edition (OmniOSce) Association. 28 29marker task-menu-commands.4th 30 31include /boot/forth/menusets.4th 32 33only forth definitions 34 35variable osconsole_state 36variable acpi_state 37variable kmdb_state 380 osconsole_state ! 390 acpi_state ! 400 kmdb_state ! 41 42also menu-namespace also menu-command-helpers 43 44\ 45\ Boot 46\ 47 48: init_boot ( N -- N ) 49 dup 50 s" smartos" getenv? if 51 s" set menu_keycode[N]=98" \ base command to execute 52 else 53 s" boot_single" getenv -1 <> if 54 drop ( n n c-addr -- n n ) \ unused 55 toggle_menuitem ( n n -- n n ) 56 s" set menu_keycode[N]=115" \ base command to execute 57 else 58 s" set menu_keycode[N]=98" \ base command to execute 59 then 60 then 61 17 +c! \ replace 'N' with ASCII numeral 62 evaluate 63; 64 65\ 66\ Alternate Boot 67\ 68 69: init_altboot ( N -- N ) 70 dup 71 s" smartos" getenv? if 72 s" set menu_keycode[N]=114" \ base command to execute 73 else 74 s" boot_single" getenv -1 <> if 75 drop ( n c-addr -- n ) \ unused 76 toggle_menuitem ( n -- n ) 77 s" set menu_keycode[N]=109" \ base command to execute 78 else 79 s" set menu_keycode[N]=115" \ base command to execute 80 then 81 then 82 17 +c! \ replace 'N' with ASCII numeral 83 evaluate 84; 85 86: altboot ( N -- NOTREACHED ) 87 s" smartos" getenv? if 88 s" alt-boot-args" getenv dup -1 <> if 89 s" boot-args" setenv ( c-addr/u -- ) 90 then 91 ." NoInstall/Recovery mode boot. login/pw: root/root" cr 92 else 93 s" boot_single" 2dup getenv -1 <> if 94 drop ( c-addr/u c-addr -- c-addr/u ) \ unused 95 unsetenv ( c-addr/u -- ) 96 else 97 2drop ( c-addr/u -- ) \ unused 98 s" set boot_single=YES" evaluate 99 then 100 then 101 0 boot ( state -- ) 102; 103 104\ 105\ Single User Mode 106\ 107 108: singleuser_enabled? ( -- flag ) 109 s" boot_single" getenv -1 <> dup if 110 swap drop ( c-addr flag -- flag ) 111 then 112; 113 114: singleuser_enable ( -- ) 115 s" set boot_single=YES" evaluate 116; 117 118: singleuser_disable ( -- ) 119 s" boot_single" unsetenv 120; 121 122: init_singleuser ( N -- N ) 123 singleuser_enabled? if 124 toggle_menuitem ( n -- n ) 125 then 126; 127 128: toggle_singleuser ( N -- N TRUE ) 129 toggle_menuitem 130 menu-redraw 131 132 \ Now we're going to make the change effective 133 134 dup toggle_stateN @ 0= if 135 singleuser_disable 136 else 137 singleuser_enable 138 then 139 140 TRUE \ loop menu again 141; 142 143\ 144\ Verbose Boot 145\ 146 147: verbose_enabled? ( -- flag ) 148 s" boot_verbose" getenv -1 <> dup if 149 swap drop ( c-addr flag -- flag ) 150 then 151; 152 153: verbose_enable ( -- ) 154 s" set boot_verbose=YES" evaluate 155; 156 157: verbose_disable ( -- ) 158 s" boot_verbose" unsetenv 159; 160 161: init_verbose ( N -- N ) 162 verbose_enabled? if 163 toggle_menuitem ( n -- n ) 164 then 165; 166 167: toggle_verbose ( N -- N TRUE ) 168 toggle_menuitem 169 menu-redraw 170 171 \ Now we're going to make the change effective 172 173 dup toggle_stateN @ 0= if 174 verbose_disable 175 else 176 verbose_enable 177 then 178 179 TRUE \ loop menu again 180; 181 182\ 183\ Reconfiguration boot 184\ 185 186: reconfigure_enabled? ( -- flag ) 187 s" boot_reconfigure" getenv -1 <> dup if 188 swap drop ( c-addr flag -- flag ) 189 then 190; 191 192: reconfigure_enable ( -- ) 193 s" set boot_reconfigure=YES" evaluate 194; 195 196: reconfigure_disable ( -- ) 197 s" boot_reconfigure" unsetenv 198; 199 200: init_reconfigure ( N -- N ) 201 reconfigure_enabled? if 202 toggle_menuitem ( n -- n ) 203 then 204; 205 206: toggle_reconfigure ( N -- N TRUE ) 207 toggle_menuitem 208 menu-redraw 209 210 \ Now we're going to make the change effective 211 212 dup toggle_stateN @ 0= if 213 reconfigure_disable 214 else 215 reconfigure_enable 216 then 217 218 TRUE \ loop menu again 219; 220 221\ 222\ Framebuffer 223\ 224 225: init_framebuffer ( N -- N ) 226 framebuffer? if 227 toggle_menuitem ( n -- n ) 228 then 229; 230 231: toggle_framebuffer ( N -- N TRUE ) 232 toggle_menuitem 233 234 dup toggle_stateN @ 0= if 235 s" off" 236 else 237 s" on" 238 then 1 framebuffer 239 240 draw-beastie 241 draw-brand 242 menu-init \ needed to reset menu position 243 menu-redraw 244 245 TRUE \ loop menu again 246; 247 248\ 249\ Escape to Prompt 250\ 251 252: goto_prompt ( N -- N FALSE ) 253 254 s" set autoboot_delay=NO" evaluate 255 256 cr 257 ." To get back to the menu, type `menu' and press ENTER" cr 258 ." or type `boot' and press ENTER to start illumos." cr 259 cr 260 261 FALSE \ exit the menu 262; 263 264\ 265\ Cyclestate (used by osconsole/acpi/kmdb below) 266\ 267 268: init_cyclestate ( N K -- N ) 269 over cycle_stateN ( n k -- n k addr ) 270 begin 271 tuck @ ( n k addr -- n addr k c ) 272 over <> ( n addr k c -- n addr k 0|-1 ) 273 while 274 rot ( n addr k -- addr k n ) 275 cycle_menuitem 276 swap rot ( addr k n -- n k addr ) 277 repeat 278 2drop ( n k addr -- n ) 279; 280 281\ 282\ OS Console 283\ getenv os_console, if not set getenv console, if not set, default to "text" 284\ allowed serial consoles: ttya .. ttyd 285\ if new console will be added (graphics?), this section needs to be updated 286\ 287: init_osconsole ( N -- N ) 288 s" os_console" getenv dup -1 = if 289 drop 290 s" console" getenv dup -1 = if 291 drop 0 \ default to text 292 then 293 then ( n c-addr/u | n 0 ) 294 295 dup 0<> if ( n c-addr/u ) 296 2dup s" ttyd" compare 0= if 297 2drop 4 298 else 2dup s" ttyc" compare 0= if 299 2drop 3 300 else 2dup s" ttyb" compare 0= if 301 2drop 2 302 else 2dup s" ttya" compare 0= if 303 2drop 1 304 else 305 2drop 0 \ anything else defaults to text 306 then then then then 307 then 308 osconsole_state ! 309; 310 311: activate_osconsole ( N -- N ) 312 dup cycle_stateN @ ( n -- n n2 ) 313 dup osconsole_state ! ( n n2 -- n n2 ) \ copy for re-initialization 314 315 case 316 0 of s" text" endof 317 1 of s" ttya" endof 318 2 of s" ttyb" endof 319 3 of s" ttyc" endof 320 4 of s" ttyd" endof 321 dup s" unknown state: " type . cr 322 endcase 323 s" os_console" setenv 324; 325 326: cycle_osconsole ( N -- N TRUE ) 327 cycle_menuitem \ cycle cycle_stateN to next value 328 activate_osconsole \ apply current cycle_stateN 329 menu-redraw \ redraw menu 330 TRUE \ loop menu again 331; 332 333\ 334\ ACPI 335\ 336: init_acpi ( N -- N ) 337 s" acpi-user-options" getenv dup -1 <> if 338 evaluate \ use ?number parse step 339 340 \ translate option to cycle state 341 case 342 1 of 1 acpi_state ! endof 343 2 of 2 acpi_state ! endof 344 4 of 3 acpi_state ! endof 345 8 of 4 acpi_state ! endof 346 0 acpi_state ! 347 endcase 348 else 349 drop 350 then 351; 352 353: activate_acpi ( N -- N ) 354 dup cycle_stateN @ ( n -- n n2 ) 355 dup acpi_state ! ( n n2 -- n n2 ) \ copy for re-initialization 356 357 \ if N == 0, it's default, just unset env. 358 dup 0= if 359 drop 360 s" acpi-user-options" unsetenv 361 else 362 case 363 1 of s" 1" endof 364 2 of s" 2" endof 365 3 of s" 4" endof 366 4 of s" 8" endof 367 endcase 368 s" acpi-user-options" setenv 369 then 370; 371 372: cycle_acpi ( N -- N TRUE ) 373 cycle_menuitem \ cycle cycle_stateN to next value 374 activate_acpi \ apply current cycle_stateN 375 menu-redraw \ redraw menu 376 TRUE \ loop menu again 377; 378 379\ 380\ kmdb 381\ 382 383: kmdb_disable 384 s" boot_kmdb" unsetenv 385 s" boot_drop_into_kmdb" unsetenv 386; 387 388: init_kmdb ( N -- N ) 389 \ Retrieve the contents of "nmi" or default to "panic" 390 ( N -- N c-addr/u ) 391 s" nmi" getenv dup -1 <> if else drop s" panic" then 392 \ Store the string in "nmi_initial" if not already set 393 \ (to support re-entering the menu from the loader prompt) 394 s" nmi_initial" getenv? if else 395 2dup s" nmi_initial" setenv 396 then 397 ( N caddr/u -- N flag ) 398 s" kmdb" compare if false else true then 399 400 s" boot_kmdb" getenv -1 <> if 401 drop 402 s" boot_drop_into_kmdb" getenv -1 <> if 403 drop 404 if 4 else 3 then 405 else 406 if 2 else 1 then 407 then 408 else 409 drop \ drop flag 410 0 411 then 412 kmdb_state ! 413; 414 415: activate_kmdb ( N -- N ) 416 dup cycle_stateN @ ( n -- n n2 ) 417 dup kmdb_state ! ( n n2 -- n n2 ) 418 419 \ Reset "nmi" to its initial value 420 s" nmi_initial" getenv s" nmi" setenv 421 422 case 4 of \ drop + nmi=kmdb 423 s" set boot_kmdb=YES" evaluate 424 s" set boot_drop_into_kmdb=YES" evaluate 425 s" set nmi=kmdb" evaluate 426 endof 3 of \ drop 427 s" set boot_kmdb=YES" evaluate 428 s" set boot_drop_into_kmdb=YES" evaluate 429 endof 2 of \ load + nmi=kmdb 430 s" set boot_kmdb=YES" evaluate 431 s" boot_drop_into_kmdb" unsetenv 432 s" set nmi=kmdb" evaluate 433 endof 1 of \ load 434 s" set boot_kmdb=YES" evaluate 435 s" boot_drop_into_kmdb" unsetenv 436 endof 437 kmdb_disable 438 endcase 439; 440 441: cycle_kmdb ( N -- N TRUE ) 442 cycle_menuitem \ cycle cycle_stateN to next value 443 activate_kmdb \ apply current cycle_stateN 444 menu-redraw \ redraw menu 445 TRUE \ loop menu again 446; 447 448\ 449\ Menusets 450\ 451 452: goto_menu ( N M -- N TRUE ) 453 menu-unset 454 menuset-loadsetnum ( n m -- n ) 455 menu-redraw 456 TRUE \ Loop menu again 457; 458 459\ 460\ Defaults 461\ 462 463: unset_boot_options 464 0 acpi_state ! 465 s" acpi-user-options" unsetenv 466 s" boot-args" unsetenv 467 s" boot_ask" unsetenv 468 singleuser_disable 469 verbose_disable 470 kmdb_disable \ disables drop_into_kmdb as well 471 reconfigure_disable 472; 473 474: set_default_boot_options ( N -- N TRUE ) 475 unset_boot_options 476 2 goto_menu 477; 478 479\ 480\ Set boot environment defaults 481\ 482 483 484: init_bootenv ( -- ) 485 s" set menu_caption[1]=${bemenu_current}${zfs_be_active}" evaluate 486 s" set ansi_caption[1]=${beansi_current}${zfs_be_active}" evaluate 487 s" set menu_caption[2]=${bemenu_bootfs}${currdev}" evaluate 488 s" set ansi_caption[2]=${beansi_bootfs}${currdev}" evaluate 489 s" set menu_caption[3]=${bemenu_page}${zfs_be_currpage}${bemenu_pageof}${zfs_be_pages}" evaluate 490 s" set ansi_caption[3]=${beansi_page}${zfs_be_currpage}${bemenu_pageof}${zfs_be_pages}" evaluate 491; 492 493\ 494\ Redraw the entire screen. A long BE name can corrupt the menu 495\ 496 497: be_draw_screen 498 clear \ Clear the screen (in screen.4th) 499 print_version \ print version string (bottom-right; see version.4th) 500 draw-beastie \ Draw FreeBSD logo at right (in beastie.4th) 501 draw-brand \ Draw brand.4th logo at top (in brand.4th) 502 menu-init \ Initialize menu and draw bounding box (in menu.4th) 503; 504 505\ 506\ Select a boot environment 507\ 508 509: set_bootenv ( N -- N TRUE ) 510 dup s" bootenv_root[E]" 13 +c! getenv 511 s" currdev" getenv compare 0= if 512 s" zfs_be_active" getenv type ." is already active" 513 else 514 dup s" set currdev=${bootenv_root[E]}" 27 +c! evaluate 515 dup s" bootenvmenu_caption[E]" 20 +c! getenv 516 s" zfs_be_active" setenv 517 ." Activating " s" currdev" getenv type cr 518 s" unload" evaluate 519 free-module-options 520 unset_boot_options 521 s" /boot/defaults/loader.conf" read-conf 522 s" /boot/loader.conf" read-conf 523 s" /boot/loader.conf.local" read-conf 524 init_bootenv 525 526 s" 1" s" zfs_be_currpage" setenv 527 s" be-set-page" evaluate 528 then 529 530 500 ms \ sleep so user can see the message 531 be_draw_screen 532 menu-redraw 533 TRUE 534; 535 536\ 537\ Chainload this entry. Normally we do not return, in case of error 538\ from chain load, we continue with normal menu code. 539\ 540 541: set_be_chain ( N -- no return | N TRUE ) 542 dup s" chain ${bootenv_root[E]}" 21 +c! evaluate catch drop 543 544 menu-redraw 545 TRUE 546; 547 548\ 549\ Switch to the next page of boot environments 550\ 551 552: set_be_page ( N -- N TRUE ) 553 s" zfs_be_currpage" getenv dup -1 = if 554 drop s" 1" 555 else 556 s2n 557 1+ \ increment the page number 558 dup 559 s" zfs_be_pages" getenv 560 s2n 561 > if drop 1 then 562 n2s 563 then 564 565 s" zfs_be_currpage" setenv 566 s" be-set-page" evaluate 567 3 goto_menu 568; 569 570only forth definitions 571