1281843Sdteske\ 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: releng/10.3/sys/boot/forth/menu-commands.4th 293802 2016-01-13 01:50:02Z allanjude $ 26222417Sjulian 27222417Sjulianmarker task-menu-commands.4th 28222417Sjulian 29242667Sdteskeinclude /boot/menusets.4th 30242667Sdteske 31281843Sdteskeonly forth definitions 32281843Sdteske 33241523Sdteskevariable kernel_state 34241523Sdteskevariable root_state 35262701Sdteske0 kernel_state ! 36262701Sdteske0 root_state ! 37241523Sdteske 38281843Sdteskealso menu-namespace also menu-command-helpers 39281843Sdteske 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 74281843Sdteske: 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 288262701Sdteske: activate_kernel ( N -- N ) 289262701Sdteske dup cycle_stateN @ ( n -- n n2 ) 290262701Sdteske dup kernel_state ! ( n n2 -- n n2 ) \ copy for re-initialization 291262701Sdteske 48 + ( n n2 -- n n2' ) \ kernel_state to ASCII num 292222417Sjulian 293222417Sjulian s" set kernel=${kernel_prefix}${kernel[N]}${kernel_suffix}" 294262701Sdteske 36 +c! ( n n2 c-addr/u -- n c-addr/u ) \ 'N' to ASCII num 295262701Sdteske evaluate ( n c-addr/u -- n ) \ sets $kernel to full kernel-path 296262701Sdteske; 297222417Sjulian 298262701Sdteske: cycle_kernel ( N -- N TRUE ) 299262701Sdteske cycle_menuitem \ cycle cycle_stateN to next value 300262701Sdteske activate_kernel \ apply current cycle_stateN 301262701Sdteske menu-redraw \ redraw menu 302262701Sdteske 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 314262701Sdteske: activate_root ( N -- N ) 315262701Sdteske dup cycle_stateN @ ( n -- n n2 ) 316262701Sdteske dup root_state ! ( n n2 -- n n2 ) \ copy for re-initialization 317262701Sdteske 48 + ( n n2 -- n n2' ) \ root_state to ASCII num 318222417Sjulian 319241367Sdteske s" set root=${root_prefix}${root[N]}${root_suffix}" 320262701Sdteske 30 +c! ( n n2 c-addr/u -- n c-addr/u ) \ 'N' to ASCII num 321262701Sdteske evaluate ( n c-addr/u -- n ) \ sets $root to full kernel-path 322262701Sdteske; 323222417Sjulian 324262701Sdteske: cycle_root ( N -- N TRUE ) 325262701Sdteske cycle_menuitem \ cycle cycle_stateN to next value 326262701Sdteske activate_root \ apply current cycle_stateN 327262701Sdteske menu-redraw \ redraw menu 328262701Sdteske 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; 353281843Sdteske 354293802Sallanjude\ 355293802Sallanjude\ Set boot environment defaults 356293802Sallanjude\ 357293802Sallanjude 358293802Sallanjude: init_bootenv ( -- ) 359293802Sallanjude s" set menu_caption[1]=${bemenu_current}${vfs.root.mountfrom}" evaluate 360293802Sallanjude s" set ansi_caption[1]=${beansi_current}${vfs.root.mountfrom}" evaluate 361293802Sallanjude s" set menu_caption[2]=${bemenu_bootfs}${zfs_be_active}" evaluate 362293802Sallanjude s" set ansi_caption[2]=${beansi_bootfs}${zfs_be_active}" evaluate 363293802Sallanjude s" set menu_caption[3]=${bemenu_page}${zfs_be_currpage}${bemenu_pageof}${zfs_be_pages}" evaluate 364293802Sallanjude s" set ansi_caption[3]=${beansi_page}${zfs_be_currpage}${bemenu_pageof}${zfs_be_pages}" evaluate 365293802Sallanjude; 366293802Sallanjude 367293802Sallanjude\ 368293802Sallanjude\ Redraw the entire screen. A long BE name can corrupt the menu 369293802Sallanjude\ 370293802Sallanjude 371293802Sallanjude: be_draw_screen 372293802Sallanjude clear \ Clear the screen (in screen.4th) 373293802Sallanjude print_version \ print version string (bottom-right; see version.4th) 374293802Sallanjude draw-beastie \ Draw FreeBSD logo at right (in beastie.4th) 375293802Sallanjude draw-brand \ Draw brand.4th logo at top (in brand.4th) 376293802Sallanjude menu-init \ Initialize menu and draw bounding box (in menu.4th) 377293802Sallanjude; 378293802Sallanjude 379293802Sallanjude\ 380293802Sallanjude\ Select a boot environment 381293802Sallanjude\ 382293802Sallanjude 383293802Sallanjude: set_bootenv ( N -- N TRUE ) 384293802Sallanjude dup s" set vfs.root.mountfrom=${bootenv_root[E]}" 38 +c! evaluate 385293802Sallanjude s" set currdev=${vfs.root.mountfrom}:" evaluate 386293802Sallanjude s" unload" evaluate 387293802Sallanjude free-module-options 388293802Sallanjude s" /boot/defaults/loader.conf" read-conf 389293802Sallanjude s" /boot/loader.conf" read-conf 390293802Sallanjude s" /boot/loader.conf.local" read-conf 391293802Sallanjude init_bootenv 392293802Sallanjude be_draw_screen 393293802Sallanjude menu-redraw 394293802Sallanjude TRUE 395293802Sallanjude; 396293802Sallanjude 397293802Sallanjude\ 398293802Sallanjude\ Switch to the next page of boot environments 399293802Sallanjude\ 400293802Sallanjude 401293802Sallanjude: set_be_page ( N -- N TRUE ) 402293802Sallanjude s" zfs_be_currpage" getenv dup -1 = if 403293802Sallanjude drop s" 1" 404293802Sallanjude else 405293802Sallanjude 0 s>d 2swap 406293802Sallanjude >number ( ud caddr/u -- ud' caddr'/u' ) \ convert string to numbers 407293802Sallanjude 2drop \ drop the string 408293802Sallanjude 1 um/mod ( ud u1 -- u2 u3 ) \ convert double ud' to single u3' and remainder u2 409293802Sallanjude swap drop ( ud2 u3 -- u3 ) \ drop the remainder u2 410293802Sallanjude 1+ \ increment the page number 411293802Sallanjude s>d <# #s #> \ convert back to a string 412293802Sallanjude then 413293802Sallanjude s" zfs_be_currpage" setenv 414293802Sallanjude s" reloadbe" evaluate 415293802Sallanjude 3 goto_menu 416293802Sallanjude; 417293802Sallanjude 418281843Sdteskeonly forth definitions 419