1 \ Copyright (c) 1999 Daniel C. Sobral <dcs@FreeBSD.org>
2 \ Copyright (c) 2011-2015 Devin Teske <dteske@FreeBSD.org>
5 \ Redistribution and use in source and binary forms, with or without
6 \ modification, are permitted provided that the following conditions
8 \ 1. Redistributions of source code must retain the above copyright
9 \ notice, this list of conditions and the following disclaimer.
10 \ 2. Redistributions in binary form must reproduce the above copyright
11 \ notice, this list of conditions and the following disclaimer in the
12 \ documentation and/or other materials provided with the distribution.
14 \ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 \ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 \ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 \ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 \ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 \ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 \ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 \ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 \ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 \ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 only forth definitions
30 s" arch-i386" environment? [if] [if]
31 s" loader_version" environment? [if]
33 .( Loader version 1.1+ required) cr
37 .( Could not get loader version!) cr
42 include /boot/forth/support.4th
43 include /boot/forth/color.4th
44 include /boot/forth/delay.4th
45 include /boot/forth/check-password.4th
47 only forth definitions
50 loader_color? dup ( -- bool bool )
58 \ menu-unset may not be present
59 s" beastie_disable" getenv
61 s" YES" compare-insensitive 0= if
81 only forth also support-functions also builtins definitions
83 \ the boot-args was parsed to individual options while loaded
84 \ now compose boot-args, so the boot can set kernel arguments
85 \ note the command line switched for boot command will cause
86 \ environment variable boot-args to be ignored
87 \ There are 2 larger strings, acpi-user-options and existing boot-args
88 \ other switches are 1 byte each, so allocate boot-args+acpi + extra bytes
89 \ for rest. Be sure to review this, if more options are to be added into
92 : set-boot-args { | addr len baddr blen aaddr alen -- }
93 s" boot-args" getenv dup -1 <> if
98 s" acpi-user-options" getenv dup -1 <> if
104 \ allocate temporary space. max is:
106 \ 26 for acpi, so use 40 for safety
107 blen alen 40 + + allocate abort" out of memory"
109 \ boot-addr may have file name before options, copy it to addr
111 baddr c@ [char] - <> if
112 baddr blen [char] - strchr ( addr len )
113 dup 0= if \ no options, copy all
124 baddr addr len move ( addr )
125 to baddr \ baddr points now to first option
129 \ now add kernel switches
131 bl addr len + c! len 1+ to len
133 [char] - addr len + c! len 1+ to len
135 s" boot_single" getenv dup -1 <> if
136 s" YES" compare-insensitive 0= if
137 [char] s addr len + c! len 1+ to len
142 s" boot_verbose" getenv dup -1 <> if
143 s" YES" compare-insensitive 0= if
144 [char] v addr len + c! len 1+ to len
149 s" boot_kmdb" getenv dup -1 <> if
150 s" YES" compare-insensitive 0= if
151 [char] k addr len + c! len 1+ to len
156 s" boot_debug" getenv dup -1 <> if
157 s" YES" compare-insensitive 0= if
158 [char] d addr len + c! len 1+ to len
163 s" boot_reconfigure" getenv dup -1 <> if
164 s" YES" compare-insensitive 0= if
165 [char] r addr len + c! len 1+ to len
170 s" boot_ask" getenv dup -1 <> if
171 s" YES" compare-insensitive 0= if
172 [char] a addr len + c! len 1+ to len
178 \ now add remining boot args if blen != 0.
179 \ baddr[0] is '-', if baddr[1] != 'B' append to addr,
180 \ otherwise add space then copy
182 baddr 1+ c@ [char] B = if
183 addr len + 1- c@ [char] - = if \ if addr[len -1] == '-'
187 bl addr len + c! len 1+ to len
193 baddr addr len + blen move
198 \ last part - add acpi.
200 addr len + 1- c@ [char] - <> if
201 bl addr len + c! len 1+ to len
202 [char] - addr len + c! len 1+ to len
204 s" B acpi-user-options=" dup -rot ( len addr len )
205 addr len + swap move ( len )
207 aaddr addr len + alen move
211 \ check for left over '-'
212 addr len 1- + c@ [char] - = if
214 \ but now we may also have left over ' '
216 addr len 1- + c@ bl = if
222 \ if len != 0, set boot-args
224 addr len s" boot-args" setenv
230 0= if ( interpreted ) get_arguments then
233 \ Unload only if a path was passed. Paths start with /
239 s" kernelname" getenv? if ( a kernel has been loaded )
243 load_kernel_and_modules
246 bootmsg 0 1 boot exit
249 s" kernelname" getenv? if ( a kernel has been loaded )
253 load_kernel_and_modules
256 bootmsg 0 1 boot exit
258 load_kernel_and_modules
259 ?dup 0= if bootmsg 0 1 boot then
264 \ Prepares to boot as specified by loaded configuration files.
267 0= if ( interpreted ) get_arguments then
269 load_kernel_and_modules
270 ?dup 0= if 0 1 autoboot then
273 also forth definitions previous
278 only forth definitions also support-functions
281 \ in case the boot-args is set, parse it and extract following options:
283 \ -s to boot_single=YES
284 \ -v to boot_verbose=YES
285 \ -k to boot_kmdb=YES
286 \ -d to boot_debug=YES
287 \ -r to boot_reconfigure=YES
288 \ -B acpi-user-options=X to acpi-user-options=X
290 \ This is needed so that the menu can manage these options. Unfortunately, this
291 \ also means that boot-args will override previously set options, but we have no
292 \ way to control the processing order here. boot-args will be rebuilt at boot.
294 \ NOTE: The best way to address the order is to *not* set any above options
297 : parse-boot-args { | baddr blen -- }
298 s" boot-args" getenv dup -1 = if drop exit then
304 \ loop over all instances of switch blocks, starting with '-'
307 2dup to blen to baddr
309 while ( addr len ) \ points to -
310 \ block for switch B. keep it on top of the stack for case
311 \ the property list will get empty.
313 over 1+ c@ [char] B = if
314 2dup \ save "-B ...." in case options is empty
315 2 - swap 2 + ( addr len len-2 addr+2 ) \ skip -B
323 ( addr len len' addr' )
324 \ its 3 cases now: end of string, -switch, or option list
326 over 0= if \ end of string, remove trailing -B
328 swap 0 swap c! \ store 0 at -B
329 blen swap ( blen len )
331 baddr swap ( addr rem )
333 s" boot-args" unsetenv
339 over ( addr rem addr )
340 over + 1- ( addr rem addr+rem-1 )
343 1- swap ( rem-1 addr )
344 over ( rem-1 addr rem-1 )
345 over + ( rem-1 addr addr+rem-1 )
353 ( addr len len' addr' )
354 dup c@ [char] - = if \ it is switch. set to boot-args
355 swap s" boot-args" setenv
360 ( addr len len' addr' )
361 \ its options string "option1,option2,... -..."
362 \ cut acpi-user-options=xxx and restart the parser
363 \ or skip to next option block
365 dup c@ dup 0<> swap bl <> and \ stop if space or 0
367 dup 18 s" acpi-user-options=" compare 0= if \ matched
368 ( addr len len' addr' )
369 \ addr' points to acpi options, find its end [',' or ' ' or 0 ]
370 \ set it as acpi-user-options and move remaining to addr'
371 2dup ( addr len len' addr' len' addr' )
372 \ skip to next option in list
373 \ loop to first , or bl or 0
375 dup c@ [char] , <> >r
377 dup c@ 0<> r> r> and and
381 ( addr len len' addr' len" addr" )
382 >r >r ( addr len len' addr' R: addr" len" )
383 over r@ - ( addr len len' addr' proplen R: addr" len" )
384 dup 5 + ( addr len len' addr' proplen proplen+5 )
385 allocate abort" out of memory"
387 0 s" set " strcat ( addr len len' addr' proplen caddr clen )
388 >r >r 2dup r> r> 2swap strcat ( addr len len' addr' proplen caddr clen )
389 2dup + 0 swap c! \ terminate with 0
390 2dup evaluate drop free drop
391 ( addr len len' addr' proplen R: addr" len" )
392 \ acpi-user-options is set, now move remaining string to its place.
393 \ addr: -B, addr': acpi... addr": reminder
394 swap ( addr len len' proplen addr' )
395 r> r> ( addr len len' proplen addr' len" addr" )
397 \ skip , and move addr" to addr'
398 1+ swap 1- ( addr len len' proplen addr' addr" len" )
399 rot swap 1+ move ( addr len len' proplen )
400 else \ its bl or 0 ( addr len len' proplen addr' len" addr" )
401 \ for both bl and 0 we need to copy to addr'-1 to remove
402 \ comma, then reset boot-args, and recurse will clear -B
403 \ if there are no properties left.
405 2drop ( addr len len' proplen addr' )
406 1- 0 swap c! ( addr len len' proplen )
408 >r >r ( addr len len' proplen addr' R: addr" len" )
410 r> r> ( addr len len' proplen addr' len" addr" )
411 rot rot move ( addr len len' proplen )
415 2swap 2drop ( len' proplen )
422 ( addr len len' addr' )
423 \ not acpi option, skip to next option in list
424 \ loop to first , or bl or 0
426 dup c@ [char] , <> >r
428 dup c@ 0<> r> r> and and
432 \ if its ',', skip over
438 ( addr len len' addr' )
439 \ this block is done, remove addr and len from stack
443 over c@ [char] - = if ( addr len )
444 2dup 1- swap 1+ ( addr len len' addr' )
445 begin \ loop till ' ' or 0
446 dup c@ dup 0<> swap bl <> and
449 s" set boot_single=YES" evaluate TRUE
450 else dup c@ [char] v = if
451 s" set boot_verbose=YES" evaluate TRUE
452 else dup c@ [char] k = if
453 s" set boot_kmdb=YES" evaluate TRUE
454 else dup c@ [char] d = if
455 s" set boot_debug=YES" evaluate TRUE
456 else dup c@ [char] r = if
457 s" set boot_reconfigure=YES" evaluate TRUE
458 else dup c@ [char] a = if
459 s" set boot_ask=YES" evaluate TRUE
460 then then then then then then
463 dup >r ( addr len len' addr' R: addr' )
464 1+ swap 1- ( addr len addr'+1 len'-1 R: addr' )
465 r> swap move ( addr len )
468 \ check if we have space after '-', if so, drop '- '
469 swap dup 1+ c@ bl = if
474 dup dup 0= swap 1 = or if \ empty or only '-' is left.
476 s" boot-args" unsetenv
488 dup c@ 0= if \ end of string
502 \ Initializes support.4th global variables, sets loader_conf_files,
503 \ processes conf files, and, if any one such file was succesfully
504 \ read to the end, loads kernel and modules.
506 : start ( -- ) ( throws: abort & user-defined )
507 s" /boot/defaults/loader.conf" initialize
512 \ Will *NOT* try to load kernel and modules if no configuration file
513 \ was succesfully loaded!
515 s" loader_delay" getenv -1 = if
521 ." Loading Kernel and Modules (Ctrl-C to Abort)" cr
522 s" also support-functions" evaluate
523 s" set delay_command='load_xen_throw load_kernel load_modules'" evaluate
524 s" set delay_showdots" evaluate
532 \ Overrides support.4th initialization word with one that does
533 \ everything start one does, short of loading the kernel and
534 \ modules. Returns a flag
536 : initialize ( -- flag )
537 s" /boot/defaults/loader.conf" initialize
547 \ Read a configuration file, whose name was specified on the command
548 \ line, if interpreted, or given on the stack, if compiled in.
550 : (read-conf) ( addr len -- )
552 include_conf_files \ Will recurse on new loader_conf_files definitions
555 : read-conf ( <filename> | addr len -- ) ( throws: abort & user-defined )
565 \ show, enable, disable, toggle module loading. They all take module from
568 : set-module-flag ( module_addr val -- ) \ set and print flag
570 dup module.name strtype
571 module.flag @ if ." will be loaded" else ." will not be loaded" then cr
574 : enable-module find-module ?dup if true set-module-flag then ;
576 : disable-module find-module ?dup if false set-module-flag then ;
578 : toggle-module find-module ?dup if dup module.flag @ 0= set-module-flag then ;
582 \ Show loading information about a module.
584 : show-module ( <module> -- ) find-module ?dup if show-one-module then ;
586 \ Words to be used inside configuration files
588 : retry false ; \ For use in load error commands
589 : ignore true ; \ For use in load error commands
591 \ Return to strict forth vocabulary
599 : .? 2 spaces 2swap 15 #type 2 spaces type cr ;
603 s" boot-conf" s" load kernel and modules, then autoboot" .?
604 s" read-conf" s" read a configuration file" .?
605 s" enable-module" s" enable loading of a module" .?
606 s" disable-module" s" disable loading of a module" .?
607 s" toggle-module" s" toggle loading of a module" .?
608 s" show-module" s" show module load data" .?
609 s" try-include" s" try to load/interpret files" .?
610 s" beadm" s" list or activate Boot Environments" .?
613 : try-include ( -- ) \ see loader.4th(8)
614 ['] include ( -- xt ) \ get the execution token of `include'
615 catch ( xt -- exception# | 0 ) if \ failed
616 LF parse ( c -- s-addr/u ) 2drop \ advance >in to EOL (drop data)
617 \ ... prevents words unused by `include' from being interpreted
619 ; immediate \ interpret immediately for access to `source' (aka tib)
621 include /boot/forth/beadm.4th
622 only forth definitions