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