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 \ Copyright 2015 Toomas Soome <tsoome@me.com>
26 \ Copyright 2019 OmniOS Community Edition (OmniOSce) Association.
27
28 marker task-menu-commands.4th
29
30 include /boot/forth/menusets.4th
31
32 only forth definitions
33
34 variable osconsole_state
35 variable acpi_state
36 variable kernel_state
37 variable root_state
38 variable kmdb_state
39 variable debug_state
40 0 kmdb_state !
41 0 debug_state !
42 0 osconsole_state !
43 0 acpi_state !
44 0 kernel_state !
45 0 root_state !
46
47 also menu-namespace also menu-command-helpers
48
49 \
50 \ Boot
51 \
52
53 : init_boot ( N -- N )
54 dup
55 s" smartos" getenv? if
56 s" set menu_keycode[N]=98" \ base command to execute
57 else
58 s" boot_single" getenv -1 <> if
59 drop ( n n c-addr -- n n ) \ unused
60 toggle_menuitem ( n n -- n n )
61 s" set menu_keycode[N]=115" \ base command to execute
62 else
63 s" set menu_keycode[N]=98" \ base command to execute
64 then
65 then
66 17 +c! \ replace 'N' with ASCII numeral
67 evaluate
68 ;
69
70 \
71 \ Alternate Boot
72 \
73
74 : init_altboot ( N -- N )
75 dup
76 s" smartos" getenv? if
77 s" set menu_keycode[N]=114" \ base command to execute
78 else
79 s" boot_single" getenv -1 <> if
80 drop ( n c-addr -- n ) \ unused
81 toggle_menuitem ( n -- n )
82 s" set menu_keycode[N]=109" \ base command to execute
83 else
84 s" set menu_keycode[N]=115" \ base command to execute
85 then
86 then
87 17 +c! \ replace 'N' with ASCII numeral
88 evaluate
89 ;
90
91 : altboot ( N -- NOTREACHED )
92 s" smartos" getenv? if
93 s" alt-boot-args" getenv dup -1 <> if
94 s" boot-args" setenv ( c-addr/u -- )
95 then
96 ." NoInstall/Recovery mode boot. login/pw: root/root" cr
97 else
98 s" boot_single" 2dup getenv -1 <> if
99 drop ( c-addr/u c-addr -- c-addr/u ) \ unused
100 unsetenv ( c-addr/u -- )
101 else
102 2drop ( c-addr/u -- ) \ unused
103 s" set boot_single=YES" evaluate
104 then
105 then
106 0 boot ( state -- )
107 ;
108
109 \
110 \ Single User Mode
111 \
112
113 : singleuser_enabled? ( -- flag )
114 s" boot_single" getenv -1 <> dup if
115 swap drop ( c-addr flag -- flag )
116 then
117 ;
118
119 : singleuser_enable ( -- )
120 s" set boot_single=YES" evaluate
121 ;
122
123 : singleuser_disable ( -- )
124 s" boot_single" unsetenv
125 ;
126
127 : init_singleuser ( N -- N )
128 singleuser_enabled? if
129 toggle_menuitem ( n -- n )
130 then
131 ;
132
133 : toggle_singleuser ( N -- N TRUE )
134 toggle_menuitem
135 menu-redraw
136
137 \ Now we're going to make the change effective
138
139 dup toggle_stateN @ 0= if
140 singleuser_disable
141 else
142 singleuser_enable
143 then
144
145 TRUE \ loop menu again
146 ;
147
148 \
149 \ Verbose Boot
150 \
151
152 : verbose_enabled? ( -- flag )
153 s" boot_verbose" getenv -1 <> dup if
154 swap drop ( c-addr flag -- flag )
155 then
156 ;
157
158 : verbose_enable ( -- )
159 s" set boot_verbose=YES" evaluate
160 ;
161
162 : verbose_disable ( -- )
163 s" boot_verbose" unsetenv
164 ;
165
166 : init_verbose ( N -- N )
167 verbose_enabled? if
168 toggle_menuitem ( n -- n )
169 then
170 ;
171
172 : toggle_verbose ( N -- N TRUE )
173 toggle_menuitem
174 menu-redraw
175
176 \ Now we're going to make the change effective
177
178 dup toggle_stateN @ 0= if
179 verbose_disable
180 else
181 verbose_enable
182 then
183
184 TRUE \ loop menu again
185 ;
186
187 \
188 \ kmdb
189 \
190
191 : kmdb_enabled? ( -- flag )
192 s" boot_kmdb" getenv -1 <> dup if
193 swap drop ( c-addr flag -- flag )
194 then
195 ;
196
197 : kmdb_enable ( -- )
198 s" set boot_kmdb=YES" evaluate
199 ;
200
201 : kmdb_disable ( -- )
202 s" boot_kmdb" unsetenv
203 s" boot_debug" unsetenv
204 ;
205
206 : init_kmdb ( N -- N )
207 dup kmdb_state ! \ store entry number for kmdb+debug
208 kmdb_enabled? if
209 toggle_menuitem ( n -- n )
210 then
211 ;
212
213 : toggle_kmdb ( N -- N TRUE )
214 toggle_menuitem
215 dup toggle_stateN @ 0= if ( kmdb is not set )
216 debug_state @ if ( debug is set? )
217 debug_state @ toggle_stateN @ if ( debug is enabled? )
218 debug_state @ toggle_menuitem drop
219 then
220 then
221 then
222 menu-redraw
223
224 \ Now we're going to make the change effective
225
226 dup toggle_stateN @ 0= if
227 kmdb_disable
228 else
229 kmdb_enable
230 then
231
232 TRUE \ loop menu again
233 ;
234
235 \
236 \ kmdb + debug
237 \
238
239 : debug_disable ( -- )
240 s" boot_debug" unsetenv
241 ;
242
243 : debug_enabled? ( -- flag )
244 \ -d is only allowed with -k
245 s" boot_debug" getenv -1 <> kmdb_enabled? and dup if
246 swap drop ( c-addr flag -- flag )
247 else
248 debug_disable \ make sure env is not set
249 then
250 ;
251
252 : debug_enable ( -- )
253 kmdb_enable
254 s" set boot_debug=YES" evaluate
255 ;
256
257 : init_debug ( N -- N )
258 dup debug_state ! \ store entry number for kmdb
259 kmdb_enabled? debug_enabled? and if
260 toggle_menuitem ( n -- n )
261 then
262 ;
263
264 : toggle_debug ( N -- N TRUE )
265 toggle_menuitem
266 kmdb_enabled? 0= if
267 kmdb_state @ toggle_menuitem drop
268 then
269 menu-redraw
270
271 \ Now we're going to make the change effective
272
273 dup toggle_stateN @ 0= if
274 debug_disable
275 else
276 debug_enable
277 then
278
279 TRUE \ loop menu again
280 ;
281
282 \
283 \ Reconfiguration boot
284 \
285
286 : reconfigure_enabled? ( -- flag )
287 s" boot_reconfigure" getenv -1 <> dup if
288 swap drop ( c-addr flag -- flag )
289 then
290 ;
291
292 : reconfigure_enable ( -- )
293 s" set boot_reconfigure=YES" evaluate
294 ;
295
296 : reconfigure_disable ( -- )
297 s" boot_reconfigure" unsetenv
298 ;
299
300 : init_reconfigure ( N -- N )
301 reconfigure_enabled? if
302 toggle_menuitem ( n -- n )
303 then
304 ;
305
306 : toggle_reconfigure ( N -- N TRUE )
307 toggle_menuitem
308 menu-redraw
309
310 \ Now we're going to make the change effective
311
312 dup toggle_stateN @ 0= if
313 reconfigure_disable
314 else
315 reconfigure_enable
316 then
317
318 TRUE \ loop menu again
319 ;
320
321 \
322 \ Escape to Prompt
323 \
324
325 : goto_prompt ( N -- N FALSE )
326
327 s" set autoboot_delay=NO" evaluate
328
329 cr
330 ." To get back to the menu, type `menu' and press ENTER" cr
331 ." or type `boot' and press ENTER to start illumos." cr
332 cr
333
334 FALSE \ exit the menu
335 ;
336
337 \
338 \ Cyclestate (used by osconsole/acpi/kernel/root below)
339 \
340
341 : init_cyclestate ( N K -- N )
342 over cycle_stateN ( n k -- n k addr )
343 begin
344 tuck @ ( n k addr -- n addr k c )
345 over <> ( n addr k c -- n addr k 0|-1 )
346 while
347 rot ( n addr k -- addr k n )
348 cycle_menuitem
349 swap rot ( addr k n -- n k addr )
350 repeat
351 2drop ( n k addr -- n )
352 ;
353
354 \
355 \ OS Console
356 \ getenv os_console, if not set getenv console, if not set, default to "text"
357 \ allowed serial consoles: ttya .. ttyd
358 \ if new console will be added (graphics?), this section needs to be updated
359 \
360 : init_osconsole ( N -- N )
361 s" os_console" getenv dup -1 = if
362 drop
363 s" console" getenv dup -1 = if
364 drop 0 \ default to text
365 then
366 then ( n c-addr/u | n 0 )
367
368 dup 0<> if ( n c-addr/u )
369 2dup s" ttyd" compare 0= if
370 2drop 4
371 else 2dup s" ttyc" compare 0= if
372 2drop 3
373 else 2dup s" ttyb" compare 0= if
374 2drop 2
375 else 2dup s" ttya" compare 0= if
376 2drop 1
377 else
378 2drop 0 \ anything else defaults to text
379 then then then then
380 then
381 osconsole_state !
382 ;
383
384 : activate_osconsole ( N -- N )
385 dup cycle_stateN @ ( n -- n n2 )
386 dup osconsole_state ! ( n n2 -- n n2 ) \ copy for re-initialization
387
388 case
389 0 of s" text" endof
390 1 of s" ttya" endof
391 2 of s" ttyb" endof
392 3 of s" ttyc" endof
393 4 of s" ttyd" endof
394 dup s" unknown state: " type . cr
395 endcase
396 s" os_console" setenv
397 ;
398
399 : cycle_osconsole ( N -- N TRUE )
400 cycle_menuitem \ cycle cycle_stateN to next value
401 activate_osconsole \ apply current cycle_stateN
402 menu-redraw \ redraw menu
403 TRUE \ loop menu again
404 ;
405
406 \
407 \ ACPI
408 \
409 : init_acpi ( N -- N )
410 s" acpi-user-options" getenv dup -1 <> if
411 evaluate \ use ?number parse step
412
413 \ translate option to cycle state
414 case
415 1 of 1 acpi_state ! endof
416 2 of 2 acpi_state ! endof
417 4 of 3 acpi_state ! endof
418 8 of 4 acpi_state ! endof
419 0 acpi_state !
420 endcase
421 else
422 drop
423 then
424 ;
425
426 : activate_acpi ( N -- N )
427 dup cycle_stateN @ ( n -- n n2 )
428 dup acpi_state ! ( n n2 -- n n2 ) \ copy for re-initialization
429
430 \ if N == 0, it's default, just unset env.
431 dup 0= if
432 drop
433 s" acpi-user-options" unsetenv
434 else
435 case
436 1 of s" 1" endof
437 2 of s" 2" endof
438 3 of s" 4" endof
439 4 of s" 8" endof
440 endcase
441 s" acpi-user-options" setenv
442 then
443 ;
444
445 : cycle_acpi ( N -- N TRUE )
446 cycle_menuitem \ cycle cycle_stateN to next value
447 activate_acpi \ apply current cycle_stateN
448 menu-redraw \ redraw menu
449 TRUE \ loop menu again
450 ;
451
452 \
453 \ Kernel
454 \
455
456 : init_kernel ( N -- N )
457 kernel_state @ ( n -- n k )
458 init_cyclestate ( n k -- n )
459 ;
460
461 : activate_kernel ( N -- N )
462 dup cycle_stateN @ ( n -- n n2 )
463 dup kernel_state ! ( n n2 -- n n2 ) \ copy for re-initialization
464 48 + ( n n2 -- n n2' ) \ kernel_state to ASCII num
465
466 s" set kernel=${kernel_prefix}${kernel[N]}${kernel_suffix}"
467 36 +c! ( n n2 c-addr/u -- n c-addr/u ) \ 'N' to ASCII num
468 evaluate ( n c-addr/u -- n ) \ sets $kernel to full kernel-path
469 ;
470
471 : cycle_kernel ( N -- N TRUE )
472 cycle_menuitem \ cycle cycle_stateN to next value
473 activate_kernel \ apply current cycle_stateN
474 menu-redraw \ redraw menu
475 TRUE \ loop menu again
476 ;
477
478 \
479 \ Root
480 \
481
482 : init_root ( N -- N )
483 root_state @ ( n -- n k )
484 init_cyclestate ( n k -- n )
485 ;
486
487 : activate_root ( N -- N )
488 dup cycle_stateN @ ( n -- n n2 )
489 dup root_state ! ( n n2 -- n n2 ) \ copy for re-initialization
490 48 + ( n n2 -- n n2' ) \ root_state to ASCII num
491
492 s" set root=${root_prefix}${root[N]}${root_suffix}"
493 30 +c! ( n n2 c-addr/u -- n c-addr/u ) \ 'N' to ASCII num
494 evaluate ( n c-addr/u -- n ) \ sets $root to full kernel-path
495 ;
496
497 : cycle_root ( N -- N TRUE )
498 cycle_menuitem \ cycle cycle_stateN to next value
499 activate_root \ apply current cycle_stateN
500 menu-redraw \ redraw menu
501 TRUE \ loop menu again
502 ;
503
504 \
505 \ Menusets
506 \
507
508 : goto_menu ( N M -- N TRUE )
509 menu-unset
510 menuset-loadsetnum ( n m -- n )
511 menu-redraw
512 TRUE \ Loop menu again
513 ;
514
515 \
516 \ Defaults
517 \
518
519 : unset_boot_options
520 0 acpi_state !
521 s" acpi-user-options" unsetenv
522 s" boot-args" unsetenv
523 s" boot_ask" unsetenv
524 singleuser_disable
525 verbose_disable
526 kmdb_disable \ disables debug as well
527 reconfigure_disable
528 ;
529
530 : set_default_boot_options ( N -- N TRUE )
531 unset_boot_options
532 2 goto_menu
533 ;
534
535 \
536 \ Set boot environment defaults
537 \
538
539
540 : init_bootenv ( -- )
541 s" set menu_caption[1]=${bemenu_current}${zfs_be_active}" evaluate
542 s" set ansi_caption[1]=${beansi_current}${zfs_be_active}" evaluate
543 s" set menu_caption[2]=${bemenu_bootfs}${currdev}" evaluate
544 s" set ansi_caption[2]=${beansi_bootfs}${currdev}" evaluate
545 s" set menu_caption[3]=${bemenu_page}${zfs_be_currpage}${bemenu_pageof}${zfs_be_pages}" evaluate
546 s" set ansi_caption[3]=${beansi_page}${zfs_be_currpage}${bemenu_pageof}${zfs_be_pages}" evaluate
547 ;
548
549 \
550 \ Redraw the entire screen. A long BE name can corrupt the menu
551 \
552
553 : be_draw_screen
554 clear \ Clear the screen (in screen.4th)
555 print_version \ print version string (bottom-right; see version.4th)
556 draw-beastie \ Draw FreeBSD logo at right (in beastie.4th)
557 draw-brand \ Draw brand.4th logo at top (in brand.4th)
558 menu-init \ Initialize menu and draw bounding box (in menu.4th)
559 ;
560
561 \
562 \ Select a boot environment
563 \
564
565 : set_bootenv ( N -- N TRUE )
566 dup s" bootenv_root[E]" 13 +c! getenv
567 s" currdev" getenv compare 0= if
568 s" zfs_be_active" getenv type ." is already active"
569 else
570 dup s" set currdev=${bootenv_root[E]}" 27 +c! evaluate
571 dup s" bootenvmenu_caption[E]" 20 +c! getenv
572 s" zfs_be_active" setenv
573 ." Activating " s" currdev" getenv type cr
574 s" unload" evaluate
575 free-module-options
576 unset_boot_options
577 s" /boot/defaults/loader.conf" read-conf
578 s" /boot/loader.conf" read-conf
579 s" /boot/loader.conf.local" read-conf
580 init_bootenv
581
582 s" 1" s" zfs_be_currpage" setenv
583 s" be-set-page" evaluate
584 then
585
586 500 ms \ sleep so user can see the message
587 be_draw_screen
588 menu-redraw
589 TRUE
590 ;
591
592 \
593 \ Chainload this entry. Normally we do not return, in case of error
594 \ from chain load, we continue with normal menu code.
595 \
596
597 : set_be_chain ( N -- no return | N TRUE )
598 dup s" chain ${bootenv_root[E]}" 21 +c! evaluate catch drop
599
600 menu-redraw
601 TRUE
602 ;
603
604 \
605 \ Switch to the next page of boot environments
606 \
607
608 : set_be_page ( N -- N TRUE )
609 s" zfs_be_currpage" getenv dup -1 = if
610 drop s" 1"
611 else
612 s2n
613 1+ \ increment the page number
614 dup
615 s" zfs_be_pages" getenv
616 s2n
617 > if drop 1 then
618 n2s
619 then
620
621 s" zfs_be_currpage" setenv
622 s" be-set-page" evaluate
623 3 goto_menu
624 ;
625
626 only forth definitions