menu-commands.4th revision 293001
1280937Sdteske\ Copyright (c) 2006-2015 Devin Teske <dteske@FreeBSD.org> 2222417Sjulian\ All rights reserved. 3222417Sjulian\ 4222417Sjulian\ Redistribution and use in source and binary forms, with or without 5222417Sjulian\ modification, are permitted provided that the following conditions 6222417Sjulian\ are met: 7222417Sjulian\ 1. Redistributions of source code must retain the above copyright 8222417Sjulian\ notice, this list of conditions and the following disclaimer. 9222417Sjulian\ 2. Redistributions in binary form must reproduce the above copyright 10222417Sjulian\ notice, this list of conditions and the following disclaimer in the 11222417Sjulian\ documentation and/or other materials provided with the distribution. 12222417Sjulian\ 13222417Sjulian\ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 14222417Sjulian\ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15222417Sjulian\ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16222417Sjulian\ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 17222417Sjulian\ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18222417Sjulian\ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19222417Sjulian\ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20222417Sjulian\ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21222417Sjulian\ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22222417Sjulian\ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23222417Sjulian\ SUCH DAMAGE. 24222417Sjulian\ 25222417Sjulian\ $FreeBSD: head/sys/boot/forth/menu-commands.4th 293001 2015-12-31 20:00:53Z allanjude $ 26222417Sjulian 27222417Sjulianmarker task-menu-commands.4th 28222417Sjulian 29242667Sdteskeinclude /boot/menusets.4th 30242667Sdteske 31280937Sdteskeonly forth definitions 32280937Sdteske 33241523Sdteskevariable kernel_state 34241523Sdteskevariable root_state 35257650Sdteske0 kernel_state ! 36257650Sdteske0 root_state ! 37241523Sdteske 38280937Sdteskealso menu-namespace also menu-command-helpers 39280937Sdteske 40243114Sdteske\ 41243660Sdteske\ Boot 42243660Sdteske\ 43243660Sdteske 44243660Sdteske: init_boot ( N -- N ) 45243660Sdteske dup 46243660Sdteske s" boot_single" getenv -1 <> if 47243660Sdteske drop ( n n c-addr -- n n ) \ unused 48243660Sdteske toggle_menuitem ( n n -- n n ) 49243660Sdteske s" set menu_keycode[N]=115" \ base command to execute 50243660Sdteske else 51243660Sdteske s" set menu_keycode[N]=98" \ base command to execute 52243660Sdteske then 53243660Sdteske 17 +c! \ replace 'N' with ASCII numeral 54243660Sdteske evaluate 55243660Sdteske; 56243660Sdteske 57243660Sdteske\ 58243660Sdteske\ Alternate Boot 59243660Sdteske\ 60243660Sdteske 61243660Sdteske: init_altboot ( N -- N ) 62243660Sdteske dup 63243660Sdteske s" boot_single" getenv -1 <> if 64243660Sdteske drop ( n c-addr -- n ) \ unused 65243660Sdteske toggle_menuitem ( n -- n ) 66243660Sdteske s" set menu_keycode[N]=109" \ base command to execute 67243660Sdteske else 68243660Sdteske s" set menu_keycode[N]=115" \ base command to execute 69243660Sdteske then 70243660Sdteske 17 +c! \ replace 'N' with ASCII numeral 71243660Sdteske evaluate 72243660Sdteske; 73243660Sdteske 74280931Sdteske: altboot ( N -- NOTREACHED ) 75243660Sdteske s" boot_single" 2dup getenv -1 <> if 76243660Sdteske drop ( c-addr/u c-addr -- c-addr/u ) \ unused 77243660Sdteske unsetenv ( c-addr/u -- ) 78243660Sdteske else 79243660Sdteske 2drop ( c-addr/u -- ) \ unused 80243660Sdteske s" set boot_single=YES" evaluate 81243660Sdteske then 82243660Sdteske 0 boot ( state -- ) 83243660Sdteske; 84243660Sdteske 85243660Sdteske\ 86243114Sdteske\ ACPI 87243114Sdteske\ 88243114Sdteske 89222417Sjulian: acpi_enable ( -- ) 90222417Sjulian s" set acpi_load=YES" evaluate \ XXX deprecated but harmless 91222417Sjulian s" set hint.acpi.0.disabled=0" evaluate 92222417Sjulian s" loader.acpi_disabled_by_user" unsetenv 93222417Sjulian; 94222417Sjulian 95222417Sjulian: acpi_disable ( -- ) 96222417Sjulian s" acpi_load" unsetenv \ XXX deprecated but harmless 97222417Sjulian s" set hint.acpi.0.disabled=1" evaluate 98222417Sjulian s" set loader.acpi_disabled_by_user=1" evaluate 99222417Sjulian; 100222417Sjulian 101222417Sjulian: toggle_acpi ( N -- N TRUE ) 102222417Sjulian 103222417Sjulian \ Make changes effective _before_ calling menu-redraw 104222417Sjulian 105222417Sjulian acpienabled? if 106222417Sjulian acpi_disable 107222417Sjulian else 108222417Sjulian acpi_enable 109222417Sjulian then 110222417Sjulian 111222417Sjulian menu-redraw 112222417Sjulian 113222417Sjulian TRUE \ loop menu again 114222417Sjulian; 115222417Sjulian 116243114Sdteske\ 117243114Sdteske\ Safe Mode 118243114Sdteske\ 119243114Sdteske 120243114Sdteske: safemode_enabled? ( -- flag ) 121243114Sdteske s" kern.smp.disabled" getenv -1 <> dup if 122243114Sdteske swap drop ( c-addr flag -- flag ) 123243114Sdteske then 124243114Sdteske; 125243114Sdteske 126243114Sdteske: safemode_enable ( -- ) 127243114Sdteske s" set kern.smp.disabled=1" evaluate 128243114Sdteske s" set hw.ata.ata_dma=0" evaluate 129243114Sdteske s" set hw.ata.atapi_dma=0" evaluate 130243114Sdteske s" set hw.ata.wc=0" evaluate 131243114Sdteske s" set hw.eisa_slots=0" evaluate 132243114Sdteske s" set kern.eventtimer.periodic=1" evaluate 133243114Sdteske s" set kern.geom.part.check_integrity=0" evaluate 134243114Sdteske; 135243114Sdteske 136243114Sdteske: safemode_disable ( -- ) 137243114Sdteske s" kern.smp.disabled" unsetenv 138243114Sdteske s" hw.ata.ata_dma" unsetenv 139243114Sdteske s" hw.ata.atapi_dma" unsetenv 140243114Sdteske s" hw.ata.wc" unsetenv 141243114Sdteske s" hw.eisa_slots" unsetenv 142243114Sdteske s" kern.eventtimer.periodic" unsetenv 143243114Sdteske s" kern.geom.part.check_integrity" unsetenv 144243114Sdteske; 145243114Sdteske 146241523Sdteske: init_safemode ( N -- N ) 147243114Sdteske safemode_enabled? if 148241523Sdteske toggle_menuitem ( n -- n ) 149241523Sdteske then 150241523Sdteske; 151241523Sdteske 152222417Sjulian: toggle_safemode ( N -- N TRUE ) 153222417Sjulian toggle_menuitem 154222417Sjulian 155222417Sjulian \ Now we're going to make the change effective 156222417Sjulian 157243114Sdteske dup toggle_stateN @ 0= if 158243114Sdteske safemode_disable 159222417Sjulian else 160243114Sdteske safemode_enable 161222417Sjulian then 162222417Sjulian 163222417Sjulian menu-redraw 164222417Sjulian 165222417Sjulian TRUE \ loop menu again 166222417Sjulian; 167222417Sjulian 168243114Sdteske\ 169243114Sdteske\ Single User Mode 170243114Sdteske\ 171243114Sdteske 172243114Sdteske: singleuser_enabled? ( -- flag ) 173243114Sdteske s" boot_single" getenv -1 <> dup if 174243114Sdteske swap drop ( c-addr flag -- flag ) 175243114Sdteske then 176243114Sdteske; 177243114Sdteske 178243114Sdteske: singleuser_enable ( -- ) 179243114Sdteske s" set boot_single=YES" evaluate 180243114Sdteske; 181243114Sdteske 182243114Sdteske: singleuser_disable ( -- ) 183243114Sdteske s" boot_single" unsetenv 184243114Sdteske; 185243114Sdteske 186241523Sdteske: init_singleuser ( N -- N ) 187243114Sdteske singleuser_enabled? if 188241523Sdteske toggle_menuitem ( n -- n ) 189241523Sdteske then 190241523Sdteske; 191241523Sdteske 192222417Sjulian: toggle_singleuser ( N -- N TRUE ) 193222417Sjulian toggle_menuitem 194222417Sjulian menu-redraw 195222417Sjulian 196222417Sjulian \ Now we're going to make the change effective 197222417Sjulian 198243114Sdteske dup toggle_stateN @ 0= if 199243114Sdteske singleuser_disable 200222417Sjulian else 201243114Sdteske singleuser_enable 202222417Sjulian then 203222417Sjulian 204222417Sjulian TRUE \ loop menu again 205222417Sjulian; 206222417Sjulian 207243114Sdteske\ 208243114Sdteske\ Verbose Boot 209243114Sdteske\ 210243114Sdteske 211243114Sdteske: verbose_enabled? ( -- flag ) 212243114Sdteske s" boot_verbose" getenv -1 <> dup if 213243114Sdteske swap drop ( c-addr flag -- flag ) 214243114Sdteske then 215243114Sdteske; 216243114Sdteske 217243114Sdteske: verbose_enable ( -- ) 218243114Sdteske s" set boot_verbose=YES" evaluate 219243114Sdteske; 220243114Sdteske 221243114Sdteske: verbose_disable ( -- ) 222243114Sdteske s" boot_verbose" unsetenv 223243114Sdteske; 224243114Sdteske 225241523Sdteske: init_verbose ( N -- N ) 226243114Sdteske verbose_enabled? if 227241523Sdteske toggle_menuitem ( n -- n ) 228241523Sdteske then 229241523Sdteske; 230241523Sdteske 231222417Sjulian: toggle_verbose ( N -- N TRUE ) 232222417Sjulian toggle_menuitem 233222417Sjulian menu-redraw 234222417Sjulian 235222417Sjulian \ Now we're going to make the change effective 236222417Sjulian 237243114Sdteske dup toggle_stateN @ 0= if 238243114Sdteske verbose_disable 239222417Sjulian else 240243114Sdteske verbose_enable 241222417Sjulian then 242222417Sjulian 243222417Sjulian TRUE \ loop menu again 244222417Sjulian; 245222417Sjulian 246243114Sdteske\ 247243114Sdteske\ Escape to Prompt 248243114Sdteske\ 249243114Sdteske 250222417Sjulian: goto_prompt ( N -- N FALSE ) 251222417Sjulian 252222417Sjulian s" set autoboot_delay=NO" evaluate 253222417Sjulian 254222417Sjulian cr 255222417Sjulian ." To get back to the menu, type `menu' and press ENTER" cr 256222417Sjulian ." or type `boot' and press ENTER to start FreeBSD." cr 257222417Sjulian cr 258222417Sjulian 259222417Sjulian FALSE \ exit the menu 260222417Sjulian; 261222417Sjulian 262243114Sdteske\ 263243114Sdteske\ Cyclestate (used by kernel/root below) 264243114Sdteske\ 265243114Sdteske 266241523Sdteske: init_cyclestate ( N K -- N ) 267243114Sdteske over cycle_stateN ( n k -- n k addr ) 268241523Sdteske begin 269241523Sdteske tuck @ ( n k addr -- n addr k c ) 270241523Sdteske over <> ( n addr k c -- n addr k 0|-1 ) 271241523Sdteske while 272241523Sdteske rot ( n addr k -- addr k n ) 273241523Sdteske cycle_menuitem 274241523Sdteske swap rot ( addr k n -- n k addr ) 275241523Sdteske repeat 276241523Sdteske 2drop ( n k addr -- n ) 277241523Sdteske; 278241523Sdteske 279243114Sdteske\ 280243114Sdteske\ Kernel 281243114Sdteske\ 282243114Sdteske 283241523Sdteske: init_kernel ( N -- N ) 284241523Sdteske kernel_state @ ( n -- n k ) 285241523Sdteske init_cyclestate ( n k -- n ) 286241523Sdteske; 287241523Sdteske 288257650Sdteske: activate_kernel ( N -- N ) 289257650Sdteske dup cycle_stateN @ ( n -- n n2 ) 290257650Sdteske dup kernel_state ! ( n n2 -- n n2 ) \ copy for re-initialization 291257650Sdteske 48 + ( n n2 -- n n2' ) \ kernel_state to ASCII num 292222417Sjulian 293222417Sjulian s" set kernel=${kernel_prefix}${kernel[N]}${kernel_suffix}" 294257650Sdteske 36 +c! ( n n2 c-addr/u -- n c-addr/u ) \ 'N' to ASCII num 295257650Sdteske evaluate ( n c-addr/u -- n ) \ sets $kernel to full kernel-path 296257650Sdteske; 297222417Sjulian 298257650Sdteske: cycle_kernel ( N -- N TRUE ) 299257650Sdteske cycle_menuitem \ cycle cycle_stateN to next value 300257650Sdteske activate_kernel \ apply current cycle_stateN 301257650Sdteske menu-redraw \ redraw menu 302257650Sdteske TRUE \ loop menu again 303222417Sjulian; 304222417Sjulian 305243114Sdteske\ 306243114Sdteske\ Root 307243114Sdteske\ 308243114Sdteske 309241523Sdteske: init_root ( N -- N ) 310241523Sdteske root_state @ ( n -- n k ) 311241523Sdteske init_cyclestate ( n k -- n ) 312241523Sdteske; 313241523Sdteske 314257650Sdteske: activate_root ( N -- N ) 315257650Sdteske dup cycle_stateN @ ( n -- n n2 ) 316257650Sdteske dup root_state ! ( n n2 -- n n2 ) \ copy for re-initialization 317257650Sdteske 48 + ( n n2 -- n n2' ) \ root_state to ASCII num 318222417Sjulian 319241367Sdteske s" set root=${root_prefix}${root[N]}${root_suffix}" 320257650Sdteske 30 +c! ( n n2 c-addr/u -- n c-addr/u ) \ 'N' to ASCII num 321257650Sdteske evaluate ( n c-addr/u -- n ) \ sets $root to full kernel-path 322257650Sdteske; 323222417Sjulian 324257650Sdteske: cycle_root ( N -- N TRUE ) 325257650Sdteske cycle_menuitem \ cycle cycle_stateN to next value 326257650Sdteske activate_root \ apply current cycle_stateN 327257650Sdteske menu-redraw \ redraw menu 328257650Sdteske TRUE \ loop menu again 329222417Sjulian; 330242667Sdteske 331243114Sdteske\ 332243114Sdteske\ Menusets 333243114Sdteske\ 334243114Sdteske 335242667Sdteske: goto_menu ( N M -- N TRUE ) 336242667Sdteske menu-unset 337242667Sdteske menuset-loadsetnum ( n m -- n ) 338242667Sdteske menu-redraw 339242667Sdteske TRUE \ Loop menu again 340242667Sdteske; 341243660Sdteske 342243660Sdteske\ 343243660Sdteske\ Defaults 344243660Sdteske\ 345243660Sdteske 346243660Sdteske: set_default_boot_options ( N -- N TRUE ) 347243660Sdteske acpi_enable 348243660Sdteske safemode_disable 349243660Sdteske singleuser_disable 350243660Sdteske verbose_disable 351243660Sdteske 2 goto_menu 352243660Sdteske; 353280937Sdteske 354293001Sallanjude\ 355293001Sallanjude\ Set boot environment defaults 356293001Sallanjude\ 357293001Sallanjude 358293001Sallanjude: init_bootenv ( -- ) 359293001Sallanjude s" set menu_caption[1]=${bemenu_current}${vfs.root.mountfrom}" evaluate 360293001Sallanjude s" set ansi_caption[1]=${beansi_current}${vfs.root.mountfrom}" evaluate 361293001Sallanjude s" set menu_caption[2]=${bemenu_bootfs}${zfs_be_active}" evaluate 362293001Sallanjude s" set ansi_caption[2]=${beansi_bootfs}${zfs_be_active}" evaluate 363293001Sallanjude s" set menu_caption[3]=${bemenu_page}${zfs_be_currpage}${bemenu_pageof}${zfs_be_pages}" evaluate 364293001Sallanjude s" set ansi_caption[3]=${beansi_page}${zfs_be_currpage}${bemenu_pageof}${zfs_be_pages}" evaluate 365293001Sallanjude; 366293001Sallanjude 367293001Sallanjude\ 368293001Sallanjude\ Redraw the entire screen. A long BE name can corrupt the menu 369293001Sallanjude\ 370293001Sallanjude 371293001Sallanjude: be_draw_screen 372293001Sallanjude clear \ Clear the screen (in screen.4th) 373293001Sallanjude print_version \ print version string (bottom-right; see version.4th) 374293001Sallanjude draw-beastie \ Draw FreeBSD logo at right (in beastie.4th) 375293001Sallanjude draw-brand \ Draw brand.4th logo at top (in brand.4th) 376293001Sallanjude menu-init \ Initialize menu and draw bounding box (in menu.4th) 377293001Sallanjude; 378293001Sallanjude 379293001Sallanjude\ 380293001Sallanjude\ Select a boot environment 381293001Sallanjude\ 382293001Sallanjude 383293001Sallanjude: set_bootenv ( N -- N TRUE ) 384293001Sallanjude dup s" set vfs.root.mountfrom=${bootenv_root[E]}" 38 +c! evaluate 385293001Sallanjude s" set currdev=${vfs.root.mountfrom}:" evaluate 386293001Sallanjude s" unload" evaluate 387293001Sallanjude free-module-options 388293001Sallanjude s" /boot/defaults/loader.conf" read-conf 389293001Sallanjude s" /boot/loader.conf" read-conf 390293001Sallanjude s" /boot/loader.conf.local" read-conf 391293001Sallanjude init_bootenv 392293001Sallanjude be_draw_screen 393293001Sallanjude menu-redraw 394293001Sallanjude TRUE 395293001Sallanjude; 396293001Sallanjude 397293001Sallanjude\ 398293001Sallanjude\ Switch to the next page of boot environments 399293001Sallanjude\ 400293001Sallanjude 401293001Sallanjude: set_be_page ( N -- N TRUE ) 402293001Sallanjude s" zfs_be_currpage" getenv dup -1 = if 403293001Sallanjude drop s" 1" 404293001Sallanjude else 405293001Sallanjude 0 s>d 2swap 406293001Sallanjude >number ( ud caddr/u -- ud' caddr'/u' ) \ convert string to numbers 407293001Sallanjude 2drop \ drop the string 408293001Sallanjude 1 um/mod ( ud u1 -- u2 u3 ) \ convert double ud' to single u3' and remainder u2 409293001Sallanjude swap drop ( ud2 u3 -- u3 ) \ drop the remainder u2 410293001Sallanjude 1+ \ increment the page number 411293001Sallanjude s>d <# #s #> \ convert back to a string 412293001Sallanjude then 413293001Sallanjude s" zfs_be_currpage" setenv 414293001Sallanjude s" reloadbe" evaluate 415293001Sallanjude 3 goto_menu 416293001Sallanjude; 417293001Sallanjude 418280937Sdteskeonly forth definitions 419