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 26marker task-menu-commands.4th 27 28include /boot/menusets.4th 29 30only forth definitions 31 32variable kernel_state 33variable root_state 340 kernel_state ! 350 root_state ! 36 37also menu-namespace also menu-command-helpers 38 39\ 40\ Boot 41\ 42 43: init_boot ( N -- N ) 44 dup 45 s" boot_single" getenv -1 <> if 46 drop ( n n c-addr -- n n ) \ unused 47 toggle_menuitem ( n n -- n n ) 48 s" set menu_keycode[N]=115" \ base command to execute 49 else 50 s" set menu_keycode[N]=98" \ base command to execute 51 then 52 17 +c! \ replace 'N' with ASCII numeral 53 evaluate 54; 55 56\ 57\ Alternate Boot 58\ 59 60: init_altboot ( N -- N ) 61 dup 62 s" boot_single" getenv -1 <> if 63 drop ( n c-addr -- n ) \ unused 64 toggle_menuitem ( n -- n ) 65 s" set menu_keycode[N]=109" \ base command to execute 66 else 67 s" set menu_keycode[N]=115" \ base command to execute 68 then 69 17 +c! \ replace 'N' with ASCII numeral 70 evaluate 71; 72 73: altboot ( N -- NOTREACHED ) 74 s" boot_single" 2dup getenv -1 <> if 75 drop ( c-addr/u c-addr -- c-addr/u ) \ unused 76 unsetenv ( c-addr/u -- ) 77 else 78 2drop ( c-addr/u -- ) \ unused 79 s" set boot_single=YES" evaluate 80 then 81 0 boot ( state -- ) 82; 83 84\ 85\ ACPI 86\ 87 88: acpi_enable ( -- ) 89 s" set acpi_load=YES" evaluate \ XXX deprecated but harmless 90 s" set hint.acpi.0.disabled=0" evaluate 91 s" loader.acpi_disabled_by_user" unsetenv 92; 93 94: acpi_disable ( -- ) 95 s" acpi_load" unsetenv \ XXX deprecated but harmless 96 s" set hint.acpi.0.disabled=1" evaluate 97 s" set loader.acpi_disabled_by_user=1" evaluate 98; 99 100: toggle_acpi ( N -- N TRUE ) 101 102 \ Make changes effective _before_ calling menu-redraw 103 104 acpienabled? if 105 acpi_disable 106 else 107 acpi_enable 108 then 109 110 menu-redraw 111 112 TRUE \ loop menu again 113; 114 115\ 116\ Safe Mode 117\ 118 119: safemode_enabled? ( -- flag ) 120 s" kern.smp.disabled" getenv -1 <> dup if 121 swap drop ( c-addr flag -- flag ) 122 then 123; 124 125: safemode_enable ( -- ) 126 s" set kern.smp.disabled=1" evaluate 127 s" set hw.ata.ata_dma=0" evaluate 128 s" set hw.ata.atapi_dma=0" evaluate 129 s" set hw.ata.wc=0" evaluate 130 s" set hw.eisa_slots=0" evaluate 131 s" set kern.eventtimer.periodic=1" evaluate 132 s" set kern.geom.part.check_integrity=0" evaluate 133; 134 135: safemode_disable ( -- ) 136 s" kern.smp.disabled" unsetenv 137 s" hw.ata.ata_dma" unsetenv 138 s" hw.ata.atapi_dma" unsetenv 139 s" hw.ata.wc" unsetenv 140 s" hw.eisa_slots" unsetenv 141 s" kern.eventtimer.periodic" unsetenv 142 s" kern.geom.part.check_integrity" unsetenv 143; 144 145: init_safemode ( N -- N ) 146 safemode_enabled? if 147 toggle_menuitem ( n -- n ) 148 then 149; 150 151: toggle_safemode ( N -- N TRUE ) 152 toggle_menuitem 153 154 \ Now we're going to make the change effective 155 156 dup toggle_stateN @ 0= if 157 safemode_disable 158 else 159 safemode_enable 160 then 161 162 menu-redraw 163 164 TRUE \ loop menu again 165; 166 167\ 168\ Single User Mode 169\ 170 171: singleuser_enabled? ( -- flag ) 172 s" boot_single" getenv -1 <> dup if 173 swap drop ( c-addr flag -- flag ) 174 then 175; 176 177: singleuser_enable ( -- ) 178 s" set boot_single=YES" evaluate 179; 180 181: singleuser_disable ( -- ) 182 s" boot_single" unsetenv 183; 184 185: init_singleuser ( N -- N ) 186 singleuser_enabled? if 187 toggle_menuitem ( n -- n ) 188 then 189; 190 191: toggle_singleuser ( N -- N TRUE ) 192 toggle_menuitem 193 menu-redraw 194 195 \ Now we're going to make the change effective 196 197 dup toggle_stateN @ 0= if 198 singleuser_disable 199 else 200 singleuser_enable 201 then 202 203 TRUE \ loop menu again 204; 205 206\ 207\ Verbose Boot 208\ 209 210: verbose_enabled? ( -- flag ) 211 s" boot_verbose" getenv -1 <> dup if 212 swap drop ( c-addr flag -- flag ) 213 then 214; 215 216: verbose_enable ( -- ) 217 s" set boot_verbose=YES" evaluate 218; 219 220: verbose_disable ( -- ) 221 s" boot_verbose" unsetenv 222; 223 224: init_verbose ( N -- N ) 225 verbose_enabled? if 226 toggle_menuitem ( n -- n ) 227 then 228; 229 230: toggle_verbose ( N -- N TRUE ) 231 toggle_menuitem 232 menu-redraw 233 234 \ Now we're going to make the change effective 235 236 dup toggle_stateN @ 0= if 237 verbose_disable 238 else 239 verbose_enable 240 then 241 242 TRUE \ loop menu again 243; 244 245\ 246\ Escape to Prompt 247\ 248 249: goto_prompt ( N -- N FALSE ) 250 251 s" set autoboot_delay=NO" evaluate 252 253 cr 254 ." To get back to the menu, type `menu' and press ENTER" cr 255 ." or type `boot' and press ENTER to start FreeBSD." cr 256 cr 257 258 FALSE \ exit the menu 259; 260 261\ 262\ Cyclestate (used by kernel/root below) 263\ 264 265: init_cyclestate ( N K -- N ) 266 over cycle_stateN ( n k -- n k addr ) 267 begin 268 tuck @ ( n k addr -- n addr k c ) 269 over <> ( n addr k c -- n addr k 0|-1 ) 270 while 271 rot ( n addr k -- addr k n ) 272 cycle_menuitem 273 swap rot ( addr k n -- n k addr ) 274 repeat 275 2drop ( n k addr -- n ) 276; 277 278\ 279\ Kernel 280\ 281 282: init_kernel ( N -- N ) 283 kernel_state @ ( n -- n k ) 284 init_cyclestate ( n k -- n ) 285; 286 287: activate_kernel ( N -- N ) 288 dup cycle_stateN @ ( n -- n n2 ) 289 dup kernel_state ! ( n n2 -- n n2 ) \ copy for re-initialization 290 48 + ( n n2 -- n n2' ) \ kernel_state to ASCII num 291 292 s" set kernel=${kernel_prefix}${kernel[N]}${kernel_suffix}" 293 36 +c! ( n n2 c-addr/u -- n c-addr/u ) \ 'N' to ASCII num 294 evaluate ( n c-addr/u -- n ) \ sets $kernel to full kernel-path 295; 296 297: cycle_kernel ( N -- N TRUE ) 298 cycle_menuitem \ cycle cycle_stateN to next value 299 activate_kernel \ apply current cycle_stateN 300 menu-redraw \ redraw menu 301 TRUE \ loop menu again 302; 303 304\ 305\ Root 306\ 307 308: init_root ( N -- N ) 309 root_state @ ( n -- n k ) 310 init_cyclestate ( n k -- n ) 311; 312 313: activate_root ( N -- N ) 314 dup cycle_stateN @ ( n -- n n2 ) 315 dup root_state ! ( n n2 -- n n2 ) \ copy for re-initialization 316 48 + ( n n2 -- n n2' ) \ root_state to ASCII num 317 318 s" set root=${root_prefix}${root[N]}${root_suffix}" 319 30 +c! ( n n2 c-addr/u -- n c-addr/u ) \ 'N' to ASCII num 320 evaluate ( n c-addr/u -- n ) \ sets $root to full kernel-path 321; 322 323: cycle_root ( N -- N TRUE ) 324 cycle_menuitem \ cycle cycle_stateN to next value 325 activate_root \ apply current cycle_stateN 326 menu-redraw \ redraw menu 327 TRUE \ loop menu again 328; 329 330\ 331\ Menusets 332\ 333 334: goto_menu ( N M -- N TRUE ) 335 menu-unset 336 menuset-loadsetnum ( n m -- n ) 337 menu-redraw 338 TRUE \ Loop menu again 339; 340 341\ 342\ Defaults 343\ 344 345: set_default_boot_options ( N -- N TRUE ) 346 acpi_enable 347 safemode_disable 348 singleuser_disable 349 verbose_disable 350 2 goto_menu 351; 352 353\ 354\ Set boot environment defaults 355\ 356 357: init_bootenv ( -- ) 358 s" set menu_caption[1]=${bemenu_current}${vfs.root.mountfrom}" evaluate 359 s" set ansi_caption[1]=${beansi_current}${vfs.root.mountfrom}" evaluate 360 s" set menu_caption[2]=${bemenu_bootfs}${zfs_be_active}" evaluate 361 s" set ansi_caption[2]=${beansi_bootfs}${zfs_be_active}" evaluate 362 s" set menu_caption[3]=${bemenu_page}${zfs_be_currpage}${bemenu_pageof}${zfs_be_pages}" evaluate 363 s" set ansi_caption[3]=${beansi_page}${zfs_be_currpage}${bemenu_pageof}${zfs_be_pages}" evaluate 364; 365 366\ 367\ Redraw the entire screen. A long BE name can corrupt the menu 368\ 369 370: be_draw_screen 371 clear \ Clear the screen (in screen.4th) 372 print_version \ print version string (bottom-right; see version.4th) 373 draw-beastie \ Draw FreeBSD logo at right (in beastie.4th) 374 draw-brand \ Draw brand.4th logo at top (in brand.4th) 375 menu-init \ Initialize menu and draw bounding box (in menu.4th) 376; 377 378\ 379\ Select a boot environment 380\ 381 382: set_bootenv ( N -- N TRUE ) 383 dup s" set vfs.root.mountfrom=${bootenv_root[E]}" 38 +c! evaluate 384 s" set currdev=${vfs.root.mountfrom}:" evaluate 385 s" unload" evaluate 386 free-module-options 387 s" /boot/defaults/loader.conf" read-conf 388 s" /boot/loader.conf" read-conf 389 s" /boot/loader.conf.local" read-conf 390 init_bootenv 391 be_draw_screen 392 menu-redraw 393 TRUE 394; 395 396\ 397\ Switch to the next page of boot environments 398\ 399 400: set_be_page ( N -- N TRUE ) 401 s" zfs_be_currpage" getenv dup -1 = if 402 drop s" 1" 403 else 404 0 s>d 2swap 405 >number ( ud caddr/u -- ud' caddr'/u' ) \ convert string to numbers 406 2drop \ drop the string 407 1 um/mod ( ud u1 -- u2 u3 ) \ convert double ud' to single u3' and remainder u2 408 swap drop ( ud2 u3 -- u3 ) \ drop the remainder u2 409 1+ \ increment the page number 410 s>d <# #s #> \ convert back to a string 411 then 412 s" zfs_be_currpage" setenv 413 s" reloadbe" evaluate 414 3 goto_menu 415; 416 417only forth definitions 418