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