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 kern.eventtimer.periodic=1" evaluate 131 s" set kern.geom.part.check_integrity=0" evaluate 132; 133 134: safemode_disable ( -- ) 135 s" kern.smp.disabled" unsetenv 136 s" hw.ata.ata_dma" unsetenv 137 s" hw.ata.atapi_dma" unsetenv 138 s" hw.ata.wc" unsetenv 139 s" kern.eventtimer.periodic" unsetenv 140 s" kern.geom.part.check_integrity" unsetenv 141; 142 143: init_safemode ( N -- N ) 144 safemode_enabled? if 145 toggle_menuitem ( n -- n ) 146 then 147; 148 149: toggle_safemode ( N -- N TRUE ) 150 toggle_menuitem 151 152 \ Now we're going to make the change effective 153 154 dup toggle_stateN @ 0= if 155 safemode_disable 156 else 157 safemode_enable 158 then 159 160 menu-redraw 161 162 TRUE \ loop menu again 163; 164 165\ 166\ Single User Mode 167\ 168 169: singleuser_enabled? ( -- flag ) 170 s" boot_single" getenv -1 <> dup if 171 swap drop ( c-addr flag -- flag ) 172 then 173; 174 175: singleuser_enable ( -- ) 176 s" set boot_single=YES" evaluate 177; 178 179: singleuser_disable ( -- ) 180 s" boot_single" unsetenv 181; 182 183: init_singleuser ( N -- N ) 184 singleuser_enabled? if 185 toggle_menuitem ( n -- n ) 186 then 187; 188 189: toggle_singleuser ( N -- N TRUE ) 190 toggle_menuitem 191 menu-redraw 192 193 \ Now we're going to make the change effective 194 195 dup toggle_stateN @ 0= if 196 singleuser_disable 197 else 198 singleuser_enable 199 then 200 201 TRUE \ loop menu again 202; 203 204\ 205\ Verbose Boot 206\ 207 208: verbose_enabled? ( -- flag ) 209 s" boot_verbose" getenv -1 <> dup if 210 swap drop ( c-addr flag -- flag ) 211 then 212; 213 214: verbose_enable ( -- ) 215 s" set boot_verbose=YES" evaluate 216; 217 218: verbose_disable ( -- ) 219 s" boot_verbose" unsetenv 220; 221 222: init_verbose ( N -- N ) 223 verbose_enabled? if 224 toggle_menuitem ( n -- n ) 225 then 226; 227 228: toggle_verbose ( N -- N TRUE ) 229 toggle_menuitem 230 menu-redraw 231 232 \ Now we're going to make the change effective 233 234 dup toggle_stateN @ 0= if 235 verbose_disable 236 else 237 verbose_enable 238 then 239 240 TRUE \ loop menu again 241; 242 243\ 244\ Escape to Prompt 245\ 246 247: goto_prompt ( N -- N FALSE ) 248 249 s" set autoboot_delay=NO" evaluate 250 251 cr 252 ." To get back to the menu, type `menu' and press ENTER" cr 253 ." or type `boot' and press ENTER to start FreeBSD." cr 254 cr 255 256 FALSE \ exit the menu 257; 258 259\ 260\ Cyclestate (used by kernel/root below) 261\ 262 263: init_cyclestate ( N K -- N ) 264 over cycle_stateN ( n k -- n k addr ) 265 begin 266 tuck @ ( n k addr -- n addr k c ) 267 over <> ( n addr k c -- n addr k 0|-1 ) 268 while 269 rot ( n addr k -- addr k n ) 270 cycle_menuitem 271 swap rot ( addr k n -- n k addr ) 272 repeat 273 2drop ( n k addr -- n ) 274; 275 276\ 277\ Kernel 278\ 279 280: init_kernel ( N -- N ) 281 kernel_state @ ( n -- n k ) 282 init_cyclestate ( n k -- n ) 283; 284 285: activate_kernel ( N -- N ) 286 dup cycle_stateN @ ( n -- n n2 ) 287 dup kernel_state ! ( n n2 -- n n2 ) \ copy for re-initialization 288 48 + ( n n2 -- n n2' ) \ kernel_state to ASCII num 289 290 s" set kernel=${kernel_prefix}${kernel[N]}${kernel_suffix}" 291 36 +c! ( n n2 c-addr/u -- n c-addr/u ) \ 'N' to ASCII num 292 evaluate ( n c-addr/u -- n ) \ sets $kernel to full kernel-path 293; 294 295: cycle_kernel ( N -- N TRUE ) 296 cycle_menuitem \ cycle cycle_stateN to next value 297 activate_kernel \ apply current cycle_stateN 298 menu-redraw \ redraw menu 299 TRUE \ loop menu again 300; 301 302\ 303\ Root 304\ 305 306: init_root ( N -- N ) 307 root_state @ ( n -- n k ) 308 init_cyclestate ( n k -- n ) 309; 310 311: activate_root ( N -- N ) 312 dup cycle_stateN @ ( n -- n n2 ) 313 dup root_state ! ( n n2 -- n n2 ) \ copy for re-initialization 314 48 + ( n n2 -- n n2' ) \ root_state to ASCII num 315 316 s" set root=${root_prefix}${root[N]}${root_suffix}" 317 30 +c! ( n n2 c-addr/u -- n c-addr/u ) \ 'N' to ASCII num 318 evaluate ( n c-addr/u -- n ) \ sets $root to full kernel-path 319; 320 321: cycle_root ( N -- N TRUE ) 322 cycle_menuitem \ cycle cycle_stateN to next value 323 activate_root \ apply current cycle_stateN 324 menu-redraw \ redraw menu 325 TRUE \ loop menu again 326; 327 328\ 329\ Menusets 330\ 331 332: goto_menu ( N M -- N TRUE ) 333 menu-unset 334 menuset-loadsetnum ( n m -- n ) 335 menu-redraw 336 TRUE \ Loop menu again 337; 338 339\ 340\ Defaults 341\ 342 343: set_default_boot_options ( N -- N TRUE ) 344 acpi_enable 345 safemode_disable 346 singleuser_disable 347 verbose_disable 348 2 goto_menu 349; 350 351\ 352\ Set boot environment defaults 353\ 354 355: init_bootenv ( -- ) 356 s" set menu_caption[1]=${bemenu_current}${vfs.root.mountfrom}" evaluate 357 s" set ansi_caption[1]=${beansi_current}${vfs.root.mountfrom}" evaluate 358 s" set menu_caption[2]=${bemenu_bootfs}${zfs_be_active}" evaluate 359 s" set ansi_caption[2]=${beansi_bootfs}${zfs_be_active}" evaluate 360 s" set menu_caption[3]=${bemenu_page}${zfs_be_currpage}${bemenu_pageof}${zfs_be_pages}" evaluate 361 s" set ansi_caption[3]=${beansi_page}${zfs_be_currpage}${bemenu_pageof}${zfs_be_pages}" evaluate 362; 363 364\ 365\ Redraw the entire screen. A long BE name can corrupt the menu 366\ 367 368: be_draw_screen 369 clear \ Clear the screen (in screen.4th) 370 print_version \ print version string (bottom-right; see version.4th) 371 draw-beastie \ Draw FreeBSD logo at right (in beastie.4th) 372 draw-brand \ Draw brand.4th logo at top (in brand.4th) 373 menu-init \ Initialize menu and draw bounding box (in menu.4th) 374; 375 376\ 377\ Select a boot environment 378\ 379 380: set_bootenv ( N -- N TRUE ) 381 dup s" set vfs.root.mountfrom=${bootenv_root[E]}" 38 +c! evaluate 382 s" set currdev=${vfs.root.mountfrom}:" evaluate 383 s" unload" evaluate 384 free-module-options 385 s" /boot/defaults/loader.conf" read-conf 386 s" /boot/loader.conf" read-conf 387 s" /boot/loader.conf.local" read-conf 388 init_bootenv 389 be_draw_screen 390 menu-redraw 391 TRUE 392; 393 394\ 395\ Switch to the next page of boot environments 396\ 397 398: set_be_page ( N -- N TRUE ) 399 s" zfs_be_currpage" getenv dup -1 = if 400 drop s" 1" 401 else 402 0 s>d 2swap 403 >number ( ud caddr/u -- ud' caddr'/u' ) \ convert string to numbers 404 2drop \ drop the string 405 1 um/mod ( ud u1 -- u2 u3 ) \ convert double ud' to single u3' and remainder u2 406 swap drop ( ud2 u3 -- u3 ) \ drop the remainder u2 407 1+ \ increment the page number 408 s>d <# #s #> \ convert back to a string 409 then 410 s" zfs_be_currpage" setenv 411 s" reloadbe" evaluate 412 3 goto_menu 413; 414 415only forth definitions 416