1
0
mirror of https://git.FreeBSD.org/src.git synced 2025-01-21 15:45:02 +00:00

First tackle at trying to handle the New Deal on kernels.

Load the first of the following kernels to be found:

${kernel} if ${kernel} is an absolute path
/boot/${kernel}/${kernel}
/boot/${kernel}/${bootfile}
${kernel}/${kernel}
${kernel}/${bootfile}
${kernel}
${bootfile}

The last instance of ${kernel} and ${bootfile} will be treated as a
list of semicolon separated file names, and each will be tried in turn,
from left to right.

Also, for each filename loader(8) will try filename, filename.ko,
filename.gz, filename.ko.gz, in that order, but that's not related
to this code.

This resulted in a major reorganization of the code, and much of what
was accumulating on loader.4th was rightly transfered to support.4th.

The semantics of boot-conf and boot also changed. Both will try to load
a kernel the same as above.

After a kernel was loaded, the variable module_path may get changed. Such
change will happen if the kernel was found with a directory prefix. In
that case, the module path will be set to ${directory};${module_path}.

Next, the modules are loaded as usual.

This is intended so kernel="xyzzy" in /boot/loader.conf will load
/boot/xyzzy/kernel.ko, load system modules from /boot/xyzzy/, and
load third party modules from /boot/modules or /modules. If that doesn't
work, it's a bug.

Also, fix a breakage of "boot" which was recently introduced. Boot without
any arguments would fail. No longer. Also, boot will only unload/reload
if the first argument is a path. If no argument exists or the first
argument is a flag, boot will use whatever is already loaded. I hope this
is POLA. That behavior is markedly different from that of boot-conf, which
will always unload/reload.

The semantics introduced here are experimental. Even if the code works,
we might decide this is not the prefered behavior. If you feel so, send
your feedback. (Yeah, this belongs in a HEADS UP or something, but I've
been working for the past 16 hours on this stuff, so gimme a break.)
This commit is contained in:
Daniel C. Sobral 2000-09-09 04:52:34 +00:00
parent 1b73d196cb
commit 88a7f9eb70
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=65630
3 changed files with 280 additions and 118 deletions

View File

@ -58,32 +58,6 @@ only forth definitions also support-functions
also support-functions definitions also support-functions definitions
: bootpath s" /boot/" ;
: modulepath s" module_path" ;
: saveenv ( addr len | 0 -1 -- addr' len | 0 -1 )
dup -1 = if exit then
dup allocate abort" Out of memory"
swap 2dup 2>r
move
2r>
;
: freeenv ( addr len | 0 -1 )
-1 = if drop else free abort" Freeing error" then
;
: restoreenv ( addr len | 0 -1 -- )
dup -1 = if ( it wasn't set )
2drop
modulepath unsetenv
else
over >r
modulepath setenv
r> free abort" Freeing error"
then
;
: set-tempoptions ( addrN lenN ... addr1 len1 N -- addr len 1 | 0 ) : set-tempoptions ( addrN lenN ... addr1 len1 N -- addr len 1 | 0 )
\ No options, set the default ones \ No options, set the default ones
dup 0= if dup 0= if
@ -166,105 +140,33 @@ also support-functions definitions
also builtins also builtins
: load-kernel ( addr len -- addr len error? )
s" temp_options" getenv dup -1 = if
drop 2dup 1
else
2over 2
then
1 load
;
: load-conf ( args 1 | 0 "args" -- flag ) : load-conf ( args 1 | 0 "args" -- flag )
0 1 unload drop
0= if ( interpreted ) get-arguments then 0= if ( interpreted ) get-arguments then
set-tempoptions set-tempoptions
s" temp_options" getenv -1 <> if 2swap 2 else 1 then
if ( there are arguments ) load_kernel_and_modules
load-kernel if ( load command failed )
\ Set the environment variable module_path, and try loading
\ the kernel again.
\ First, save module_path value
modulepath getenv saveenv dup -1 = if 0 swap then 2>r
\ Sets the new value
2dup modulepath setenv
\ Try to load the kernel
s" load ${kernel} ${temp_options}" ['] evaluate catch
if ( load failed yet again )
\ Remove garbage from the stack
2drop
\ Try prepending /boot/
bootpath 2over nip over + allocate
if ( out of memory )
2drop 2drop
2r> restoreenv
100 exit
then
0 2swap strcat 2swap strcat
2dup modulepath setenv
drop free if ( freeing memory error )
2drop
2r> restoreenv
100 exit
then
\ Now, once more, try to load the kernel
s" load ${kernel} ${temp_options}" ['] evaluate catch
if ( failed once more )
2drop
2r> restoreenv
100 exit
then
else ( we found the kernel on the path passed )
2drop ( discard command line arguments )
then ( could not load kernel from directory passed )
\ Load the remaining modules, if the kernel was loaded at all
['] load_modules catch if 2r> restoreenv 100 exit then
\ Return 0 to indicate success
0
\ Keep new module_path
2r> freeenv
exit
then ( could not load kernel with name passed )
2drop ( discard command line arguments )
else ( try just a straight-forward kernel load )
s" load ${kernel} ${temp_options}" ['] evaluate catch
if ( kernel load failed ) 2drop 100 exit then
then ( there are command line arguments )
\ Load the remaining modules, if the kernel was loaded at all
['] load_modules catch if 100 exit then
\ Return 0 to indicate success
0
; ;
only forth also support-functions also builtins definitions only forth also support-functions also builtins definitions
: boot : boot
\ Unload only if a path was passed
>in @ parse-word rot >in !
if
c@ [char] - <> if
0 1 unload drop
else
get-arguments 1 boot exit
then
else
0 1 boot exit
then
load-conf load-conf
?dup 0= if 0 1 boot then ?dup 0= if 0 1 boot then
; ;
: boot-conf : boot-conf
0 1 unload drop
load-conf load-conf
?dup 0= if 0 1 autoboot then ?dup 0= if 0 1 autoboot then
; ;

View File

@ -43,10 +43,10 @@ bitmap_type="splash_image_data"
############################################################## ##############################################################
#autoboot_delay="10" # Delay in seconds before autobooting #autoboot_delay="10" # Delay in seconds before autobooting
#bootfile="kernel,kernel.old" # Set the default boot file set bootfile="kernel" # Set the default boot file set
#console="vidconsole" # Set the current console #console="vidconsole" # Set the current console
#currdev="disk1s1a" # Set the current device #currdev="disk1s1a" # Set the current device
#module_path="/boot/modules;/modules;/boot/kernel" # Set the module search path module_path="/boot/modules;/modules;/boot/kernel" # Set the module search path
#prompt="\\${interpret}" # Set the command prompt #prompt="\\${interpret}" # Set the command prompt
#root_disk_unit="0" # Force the root disk unit number #root_disk_unit="0" # Force the root disk unit number
#rootdev="disk1s1a" # Set the root filesystem #rootdev="disk1s1a" # Set the root filesystem

View File

@ -1218,17 +1218,277 @@ variable current_conf_files
repeat repeat
; ;
\ Additional functions used in "start" \ h00h00 magic used to try loading either a kernel with a given name,
\ or a kernel with the default name in a directory of a given name
\ (the pain!)
: bootpath s" /boot/" ;
: modulepath s" module_path" ;
\ Functions used to save and restore module_path's value.
: saveenv ( addr len | -1 -- addr' len | 0 -1 )
dup -1 = if 0 swap exit then
strdup
;
: freeenv ( addr len | 0 -1 )
-1 = if drop else free abort" Freeing error" then
;
: restoreenv ( addr len | 0 -1 -- )
dup -1 = if ( it wasn't set )
2drop
modulepath unsetenv
else
over >r
modulepath setenv
r> free abort" Freeing error"
then
;
: clip_args \ Drop second string if only one argument is passed
1 = if
2swap 2drop
1
else
2
then
;
also builtins
\ Parse filename from a comma-separated list
: parse-; ( addr len -- addr' len-x addr x )
over 0 2swap
begin
dup 0 <>
while
over c@ [char] ; <>
while
1- swap 1+ swap
2swap 1+ 2swap
repeat then
dup 0 <> if
1- swap 1+ swap
then
2swap
;
\ Try loading one of multiple kernels specified
: try_multiple_kernels ( addr len addr' len' args -- flag )
>r
begin
parse-; 2>r
2over 2r>
r@ clip_args 1 load
while
dup 0=
until
1 >r \ Failure
else
0 >r \ Success
then
2drop 2drop
r>
r> drop
;
\ Try to load a kernel; the kernel name is taken from one of
\ the following lists, as ordered:
\
\ 1. The "kernel" environment variable
\ 2. The "bootfile" environment variable
\
\ Flags are passed, if available. The parameter args must be 2
\ if flags are being passed, or 1 if they should be ignored.
\ Dummy flags and len must be passed in the latter case.
\
\ The kernel gets loaded from the current module_path.
: load_a_kernel ( flags len args -- flag )
local args
2local flags
0 0 2local kernel
end-locals
\ Check if a default kernel name exists at all, exits if not
s" kernel" getenv dup -1 <> if
to kernel
flags kernel args try_multiple_kernels
dup 0= if exit then
then
drop
s" bootfile" getenv dup -1 <> if
to kernel
else
drop
1 exit \ Failure
then
\ Try all default kernel names
flags kernel args try_multiple_kernels
;
\ Try to load a kernel; the kernel name is taken from one of
\ the following lists, as ordered:
\
\ 1. The "kernel" environment variable
\ 2. The "bootfile" environment variable
\
\ Flags are passed, if provided.
\
\ The kernel will be loaded from a directory computed from the
\ path given. Two directories will be tried in the following order:
\
\ 1. /boot/path
\ 2. path
\
\ The module_path variable is overridden if load is succesful, by
\ prepending the successful path.
: load_from_directory ( path len 1 | flags len' path len 2 -- flag )
local args
2local path
args 1 = if 0 0 then
2local flags
0 0 2local oldmodulepath
0 0 2local newmodulepath
end-locals
\ Set the environment variable module_path, and try loading
\ the kernel again.
modulepath getenv saveenv to oldmodulepath
\ Try prepending /boot/ first
bootpath nip path nip +
oldmodulepath nip dup -1 = if
drop
else
1+ +
then
allocate
if ( out of memory )
1 exit
then
0
bootpath strcat
path strcat
2dup to newmodulepath
modulepath setenv
\ Try all default kernel names
flags args load_a_kernel
0= if ( success )
oldmodulepath nip -1 <> if
newmodulepath s" ;" strcat
oldmodulepath strcat
modulepath setenv
newmodulepath drop free-memory
oldmodulepath drop free-memory
then
0 exit
then
\ Well, try without the prepended /boot/
path newmodulepath drop swap move
path nip
2dup to newmodulepath
modulepath setenv
\ Try all default kernel names
flags args load_a_kernel
if ( failed once more )
oldmodulepath restoreenv
newmodulepath drop free-memory
1
else
oldmodulepath nip -1 <> if
newmodulepath s" ;" strcat
oldmodulepath strcat
modulepath setenv
newmodulepath drop free-memory
oldmodulepath drop free-memory
then
0
then
;
\ Try to load a kernel; the kernel name is taken from one of
\ the following lists, as ordered:
\
\ 1. The "kernel" environment variable
\ 2. The "bootfile" environment variable
\ 3. The "path" argument
\
\ Flags are passed, if provided.
\
\ The kernel will be loaded from a directory computed from the
\ path given. Two directories will be tried in the following order:
\
\ 1. /boot/path
\ 2. path
\
\ Unless "path" is meant to be kernel name itself. In that case, it
\ will first be tried as a full path, and, next, search on the
\ directories pointed by module_path.
\
\ The module_path variable is overridden if load is succesful, by
\ prepending the successful path.
: load_directory_or_file ( path len 1 | flags len' path len 2 -- flag )
local args
2local path
args 1 = if 0 0 then
2local flags
end-locals
\ First, assume path is an absolute path to a directory
flags path args clip_args load_from_directory
dup 0= if exit else drop then
\ Next, assume path points to the kernel
flags path args try_multiple_kernels
;
: load_kernel_and_modules ( flags len path len' 2 | path len' 1 -- flag )
load_directory_or_file
0= if ['] load_modules catch then
;
: initialize ( addr len -- ) : initialize ( addr len -- )
strdup conf_files .len ! conf_files .addr ! strdup conf_files .len ! conf_files .addr !
; ;
: load_kernel ( -- ) ( throws: abort ) : kernel_options ( -- addr len 2 | 0 0 1 )
s" load ${kernel} ${kernel_options}" ['] evaluate catch s" kernel_options" getenv
if s" echo Unable to load kernel: ${kernel}" evaluate abort then dup -1 = if 0 0 1 else 2 then
; ;
: kernel_and_options
kernel_options
s" kernel" getenv
rot
;
: load_kernel ( -- ) ( throws: abort )
s" kernel" getenv
dup -1 = if
\ If unset, try any kernel
drop
kernel_options load_a_kernel
else
\ If set, try first directory, next file name
kernel_options >r 2swap r> clip_args load_from_directory
dup if
drop
kernel_and_options try_multiple_kernels
then
then
abort" Unable to load a kernel!"
;
: read-password { size | buf len -- } : read-password { size | buf len -- }
size allocate if out_of_memory throw then size allocate if out_of_memory throw then
to buf to buf