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