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