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 OmniOS Community Edition (OmniOSce) Association. 27 28 marker task-menu-commands.4th 29 30 include /boot/forth/menusets.4th 31 32 only forth definitions 33 34 variable osconsole_state 35 variable acpi_state 36 variable kernel_state 37 variable root_state 38 variable kmdb_state 39 variable debug_state 40 0 kmdb_state ! 41 0 debug_state ! 42 0 osconsole_state ! 43 0 acpi_state ! 44 0 kernel_state ! 45 0 root_state ! 46 47 also menu-namespace also menu-command-helpers 48 49 \ 50 \ Boot 51 \ 52 53 : init_boot ( N -- N ) 54 dup 55 s" smartos" getenv? if 56 s" set menu_keycode[N]=98" \ base command to execute 57 else 58 s" boot_single" getenv -1 <> if 59 drop ( n n c-addr -- n n ) \ unused 60 toggle_menuitem ( n n -- n n ) 61 s" set menu_keycode[N]=115" \ base command to execute 62 else 63 s" set menu_keycode[N]=98" \ base command to execute 64 then 65 then 66 17 +c! \ replace 'N' with ASCII numeral 67 evaluate 68 ; 69 70 \ 71 \ Alternate Boot 72 \ 73 74 : init_altboot ( N -- N ) 75 dup 76 s" smartos" getenv? if 77 s" set menu_keycode[N]=114" \ base command to execute 78 else 79 s" boot_single" getenv -1 <> if 80 drop ( n c-addr -- n ) \ unused 81 toggle_menuitem ( n -- n ) 82 s" set menu_keycode[N]=109" \ base command to execute 83 else 84 s" set menu_keycode[N]=115" \ base command to execute 85 then 86 then 87 17 +c! \ replace 'N' with ASCII numeral 88 evaluate 89 ; 90 91 : altboot ( N -- NOTREACHED ) 92 s" smartos" getenv? if 93 s" alt-boot-args" getenv dup -1 <> if 94 s" boot-args" setenv ( c-addr/u -- ) 95 then 96 ." NoInstall/Recovery mode boot. login/pw: root/root" cr 97 else 98 s" boot_single" 2dup getenv -1 <> if 99 drop ( c-addr/u c-addr -- c-addr/u ) \ unused 100 unsetenv ( c-addr/u -- ) 101 else 102 2drop ( c-addr/u -- ) \ unused 103 s" set boot_single=YES" evaluate 104 then 105 then 106 0 boot ( state -- ) 107 ; 108 109 \ 110 \ Single User Mode 111 \ 112 113 : singleuser_enabled? ( -- flag ) 114 s" boot_single" getenv -1 <> dup if 115 swap drop ( c-addr flag -- flag ) 116 then 117 ; 118 119 : singleuser_enable ( -- ) 120 s" set boot_single=YES" evaluate 121 ; 122 123 : singleuser_disable ( -- ) 124 s" boot_single" unsetenv 125 ; 126 127 : init_singleuser ( N -- N ) 128 singleuser_enabled? if 129 toggle_menuitem ( n -- n ) 130 then 131 ; 132 133 : toggle_singleuser ( N -- N TRUE ) 134 toggle_menuitem 135 menu-redraw 136 137 \ Now we're going to make the change effective 138 139 dup toggle_stateN @ 0= if 140 singleuser_disable 141 else 142 singleuser_enable 143 then 144 145 TRUE \ loop menu again 146 ; 147 148 \ 149 \ Verbose Boot 150 \ 151 152 : verbose_enabled? ( -- flag ) 153 s" boot_verbose" getenv -1 <> dup if 154 swap drop ( c-addr flag -- flag ) 155 then 156 ; 157 158 : verbose_enable ( -- ) 159 s" set boot_verbose=YES" evaluate 160 ; 161 162 : verbose_disable ( -- ) 163 s" boot_verbose" unsetenv 164 ; 165 166 : init_verbose ( N -- N ) 167 verbose_enabled? if 168 toggle_menuitem ( n -- n ) 169 then 170 ; 171 172 : toggle_verbose ( N -- N TRUE ) 173 toggle_menuitem 174 menu-redraw 175 176 \ Now we're going to make the change effective 177 178 dup toggle_stateN @ 0= if 179 verbose_disable 180 else 181 verbose_enable 182 then 183 184 TRUE \ loop menu again 185 ; 186 187 \ 188 \ kmdb 189 \ 190 191 : kmdb_enabled? ( -- flag ) 192 s" boot_kmdb" getenv -1 <> dup if 193 swap drop ( c-addr flag -- flag ) 194 then 195 ; 196 197 : kmdb_enable ( -- ) 198 s" set boot_kmdb=YES" evaluate 199 ; 200 201 : kmdb_disable ( -- ) 202 s" boot_kmdb" unsetenv 203 s" boot_debug" unsetenv 204 ; 205 206 : init_kmdb ( N -- N ) 207 dup kmdb_state ! \ store entry number for kmdb+debug 208 kmdb_enabled? if 209 toggle_menuitem ( n -- n ) 210 then 211 ; 212 213 : toggle_kmdb ( N -- N TRUE ) 214 toggle_menuitem 215 dup toggle_stateN @ 0= if ( kmdb is not set ) 216 debug_state @ if ( debug is set? ) 217 debug_state @ toggle_stateN @ if ( debug is enabled? ) 218 debug_state @ toggle_menuitem drop 219 then 220 then 221 then 222 menu-redraw 223 224 \ Now we're going to make the change effective 225 226 dup toggle_stateN @ 0= if 227 kmdb_disable 228 else 229 kmdb_enable 230 then 231 232 TRUE \ loop menu again 233 ; 234 235 \ 236 \ kmdb + debug 237 \ 238 239 : debug_disable ( -- ) 240 s" boot_debug" unsetenv 241 ; 242 243 : debug_enabled? ( -- flag ) 244 \ -d is only allowed with -k 245 s" boot_debug" getenv -1 <> kmdb_enabled? and dup if 246 swap drop ( c-addr flag -- flag ) 247 else 248 debug_disable \ make sure env is not set 249 then 250 ; 251 252 : debug_enable ( -- ) 253 kmdb_enable 254 s" set boot_debug=YES" evaluate 255 ; 256 257 : init_debug ( N -- N ) 258 dup debug_state ! \ store entry number for kmdb 259 kmdb_enabled? debug_enabled? and if 260 toggle_menuitem ( n -- n ) 261 then 262 ; 263 264 : toggle_debug ( N -- N TRUE ) 265 toggle_menuitem 266 kmdb_enabled? 0= if 267 kmdb_state @ toggle_menuitem drop 268 then 269 menu-redraw 270 271 \ Now we're going to make the change effective 272 273 dup toggle_stateN @ 0= if 274 debug_disable 275 else 276 debug_enable 277 then 278 279 TRUE \ loop menu again 280 ; 281 282 \ 283 \ Reconfiguration boot 284 \ 285 286 : reconfigure_enabled? ( -- flag ) 287 s" boot_reconfigure" getenv -1 <> dup if 288 swap drop ( c-addr flag -- flag ) 289 then 290 ; 291 292 : reconfigure_enable ( -- ) 293 s" set boot_reconfigure=YES" evaluate 294 ; 295 296 : reconfigure_disable ( -- ) 297 s" boot_reconfigure" unsetenv 298 ; 299 300 : init_reconfigure ( N -- N ) 301 reconfigure_enabled? if 302 toggle_menuitem ( n -- n ) 303 then 304 ; 305 306 : toggle_reconfigure ( N -- N TRUE ) 307 toggle_menuitem 308 menu-redraw 309 310 \ Now we're going to make the change effective 311 312 dup toggle_stateN @ 0= if 313 reconfigure_disable 314 else 315 reconfigure_enable 316 then 317 318 TRUE \ loop menu again 319 ; 320 321 \ 322 \ Escape to Prompt 323 \ 324 325 : goto_prompt ( N -- N FALSE ) 326 327 s" set autoboot_delay=NO" evaluate 328 329 cr 330 ." To get back to the menu, type `menu' and press ENTER" cr 331 ." or type `boot' and press ENTER to start illumos." cr 332 cr 333 334 FALSE \ exit the menu 335 ; 336 337 \ 338 \ Cyclestate (used by osconsole/acpi/kernel/root below) 339 \ 340 341 : init_cyclestate ( N K -- N ) 342 over cycle_stateN ( n k -- n k addr ) 343 begin 344 tuck @ ( n k addr -- n addr k c ) 345 over <> ( n addr k c -- n addr k 0|-1 ) 346 while 347 rot ( n addr k -- addr k n ) 348 cycle_menuitem 349 swap rot ( addr k n -- n k addr ) 350 repeat 351 2drop ( n k addr -- n ) 352 ; 353 354 \ 355 \ OS Console 356 \ getenv os_console, if not set getenv console, if not set, default to "text" 357 \ allowed serial consoles: ttya .. ttyd 358 \ if new console will be added (graphics?), this section needs to be updated 359 \ 360 : init_osconsole ( N -- N ) 361 s" os_console" getenv dup -1 = if 362 drop 363 s" console" getenv dup -1 = if 364 drop 0 \ default to text 365 then 366 then ( n c-addr/u | n 0 ) 367 368 dup 0<> if ( n c-addr/u ) 369 2dup s" ttyd" compare 0= if 370 2drop 4 371 else 2dup s" ttyc" compare 0= if 372 2drop 3 373 else 2dup s" ttyb" compare 0= if 374 2drop 2 375 else 2dup s" ttya" compare 0= if 376 2drop 1 377 else 378 2drop 0 \ anything else defaults to text 379 then then then then 380 then 381 osconsole_state ! 382 ; 383 384 : activate_osconsole ( N -- N ) 385 dup cycle_stateN @ ( n -- n n2 ) 386 dup osconsole_state ! ( n n2 -- n n2 ) \ copy for re-initialization 387 388 case 389 0 of s" text" endof 390 1 of s" ttya" endof 391 2 of s" ttyb" endof 392 3 of s" ttyc" endof 393 4 of s" ttyd" endof 394 dup s" unknown state: " type . cr 395 endcase 396 s" os_console" setenv 397 ; 398 399 : cycle_osconsole ( N -- N TRUE ) 400 cycle_menuitem \ cycle cycle_stateN to next value 401 activate_osconsole \ apply current cycle_stateN 402 menu-redraw \ redraw menu 403 TRUE \ loop menu again 404 ; 405 406 \ 407 \ ACPI 408 \ 409 : init_acpi ( N -- N ) 410 s" acpi-user-options" getenv dup -1 <> if 411 evaluate \ use ?number parse step 412 413 \ translate option to cycle state 414 case 415 1 of 1 acpi_state ! endof 416 2 of 2 acpi_state ! endof 417 4 of 3 acpi_state ! endof 418 8 of 4 acpi_state ! endof 419 0 acpi_state ! 420 endcase 421 else 422 drop 423 then 424 ; 425 426 : activate_acpi ( N -- N ) 427 dup cycle_stateN @ ( n -- n n2 ) 428 dup acpi_state ! ( n n2 -- n n2 ) \ copy for re-initialization 429 430 \ if N == 0, it's default, just unset env. 431 dup 0= if 432 drop 433 s" acpi-user-options" unsetenv 434 else 435 case 436 1 of s" 1" endof 437 2 of s" 2" endof 438 3 of s" 4" endof 439 4 of s" 8" endof 440 endcase 441 s" acpi-user-options" setenv 442 then 443 ; 444 445 : cycle_acpi ( N -- N TRUE ) 446 cycle_menuitem \ cycle cycle_stateN to next value 447 activate_acpi \ apply current cycle_stateN 448 menu-redraw \ redraw menu 449 TRUE \ loop menu again 450 ; 451 452 \ 453 \ Kernel 454 \ 455 456 : init_kernel ( N -- N ) 457 kernel_state @ ( n -- n k ) 458 init_cyclestate ( n k -- n ) 459 ; 460 461 : activate_kernel ( N -- N ) 462 dup cycle_stateN @ ( n -- n n2 ) 463 dup kernel_state ! ( n n2 -- n n2 ) \ copy for re-initialization 464 48 + ( n n2 -- n n2' ) \ kernel_state to ASCII num 465 466 s" set kernel=${kernel_prefix}${kernel[N]}${kernel_suffix}" 467 36 +c! ( n n2 c-addr/u -- n c-addr/u ) \ 'N' to ASCII num 468 evaluate ( n c-addr/u -- n ) \ sets $kernel to full kernel-path 469 ; 470 471 : cycle_kernel ( N -- N TRUE ) 472 cycle_menuitem \ cycle cycle_stateN to next value 473 activate_kernel \ apply current cycle_stateN 474 menu-redraw \ redraw menu 475 TRUE \ loop menu again 476 ; 477 478 \ 479 \ Root 480 \ 481 482 : init_root ( N -- N ) 483 root_state @ ( n -- n k ) 484 init_cyclestate ( n k -- n ) 485 ; 486 487 : activate_root ( N -- N ) 488 dup cycle_stateN @ ( n -- n n2 ) 489 dup root_state ! ( n n2 -- n n2 ) \ copy for re-initialization 490 48 + ( n n2 -- n n2' ) \ root_state to ASCII num 491 492 s" set root=${root_prefix}${root[N]}${root_suffix}" 493 30 +c! ( n n2 c-addr/u -- n c-addr/u ) \ 'N' to ASCII num 494 evaluate ( n c-addr/u -- n ) \ sets $root to full kernel-path 495 ; 496 497 : cycle_root ( N -- N TRUE ) 498 cycle_menuitem \ cycle cycle_stateN to next value 499 activate_root \ apply current cycle_stateN 500 menu-redraw \ redraw menu 501 TRUE \ loop menu again 502 ; 503 504 \ 505 \ Menusets 506 \ 507 508 : goto_menu ( N M -- N TRUE ) 509 menu-unset 510 menuset-loadsetnum ( n m -- n ) 511 menu-redraw 512 TRUE \ Loop menu again 513 ; 514 515 \ 516 \ Defaults 517 \ 518 519 : unset_boot_options 520 0 acpi_state ! 521 s" acpi-user-options" unsetenv 522 s" boot-args" unsetenv 523 s" boot_ask" unsetenv 524 singleuser_disable 525 verbose_disable 526 kmdb_disable \ disables debug as well 527 reconfigure_disable 528 ; 529 530 : set_default_boot_options ( N -- N TRUE ) 531 unset_boot_options 532 2 goto_menu 533 ; 534 535 \ 536 \ Set boot environment defaults 537 \ 538 539 540 : init_bootenv ( -- ) 541 s" set menu_caption[1]=${bemenu_current}${zfs_be_active}" evaluate 542 s" set ansi_caption[1]=${beansi_current}${zfs_be_active}" evaluate 543 s" set menu_caption[2]=${bemenu_bootfs}${currdev}" evaluate 544 s" set ansi_caption[2]=${beansi_bootfs}${currdev}" evaluate 545 s" set menu_caption[3]=${bemenu_page}${zfs_be_currpage}${bemenu_pageof}${zfs_be_pages}" evaluate 546 s" set ansi_caption[3]=${beansi_page}${zfs_be_currpage}${bemenu_pageof}${zfs_be_pages}" evaluate 547 ; 548 549 \ 550 \ Redraw the entire screen. A long BE name can corrupt the menu 551 \ 552 553 : be_draw_screen 554 clear \ Clear the screen (in screen.4th) 555 print_version \ print version string (bottom-right; see version.4th) 556 draw-beastie \ Draw FreeBSD logo at right (in beastie.4th) 557 draw-brand \ Draw brand.4th logo at top (in brand.4th) 558 menu-init \ Initialize menu and draw bounding box (in menu.4th) 559 ; 560 561 \ 562 \ Select a boot environment 563 \ 564 565 : set_bootenv ( N -- N TRUE ) 566 dup s" bootenv_root[E]" 13 +c! getenv 567 s" currdev" getenv compare 0= if 568 s" zfs_be_active" getenv type ." is already active" 569 else 570 dup s" set currdev=${bootenv_root[E]}" 27 +c! evaluate 571 dup s" bootenvmenu_caption[E]" 20 +c! getenv 572 s" zfs_be_active" setenv 573 ." Activating " s" currdev" getenv type cr 574 s" unload" evaluate 575 free-module-options 576 unset_boot_options 577 s" /boot/defaults/loader.conf" read-conf 578 s" /boot/loader.conf" read-conf 579 s" /boot/loader.conf.local" read-conf 580 init_bootenv 581 582 s" 1" s" zfs_be_currpage" setenv 583 s" be-set-page" evaluate 584 then 585 586 500 ms \ sleep so user can see the message 587 be_draw_screen 588 menu-redraw 589 TRUE 590 ; 591 592 \ 593 \ Chainload this entry. Normally we do not return, in case of error 594 \ from chain load, we continue with normal menu code. 595 \ 596 597 : set_be_chain ( N -- no return | N TRUE ) 598 dup s" chain ${bootenv_root[E]}" 21 +c! evaluate catch drop 599 600 menu-redraw 601 TRUE 602 ; 603 604 \ 605 \ Switch to the next page of boot environments 606 \ 607 608 : set_be_page ( N -- N TRUE ) 609 s" zfs_be_currpage" getenv dup -1 = if 610 drop s" 1" 611 else 612 s2n 613 1+ \ increment the page number 614 dup 615 s" zfs_be_pages" getenv 616 s2n 617 > if drop 1 then 618 n2s 619 then 620 621 s" zfs_be_currpage" setenv 622 s" be-set-page" evaluate 623 3 goto_menu 624 ; 625 626 only forth definitions