diff --git a/sys/boot/forth/loader.4th b/sys/boot/forth/loader.4th index 132633af6e45..1ea36ba6bdb4 100644 --- a/sys/boot/forth/loader.4th +++ b/sys/boot/forth/loader.4th @@ -32,11 +32,129 @@ only forth definitions also support-functions \ \ Prepares to boot as specified by loaded configuration files. -: boot-conf - load_kernel - load_modules - 0 autoboot +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 +; + +only forth also support-functions also builtins definitions + +: boot-conf ( args 1 | 0 "args" -- flag ) + 0 1 unload drop + + 0= if ( interpreted ) + \ Get next word on the command line + bl word count + ?dup 0= if ( there wasn't anything ) + drop 0 + else ( put in the number of strings ) + 1 + then + then ( interpreted ) + + if ( there are arguments ) + \ Try to load the kernel + s" kernel_options" getenv dup -1 = if drop 2dup 1 else 2over 2 then + + 1 load if ( load command failed ) + \ Remove garbage from the stack + + \ 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} ${kernel_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} ${kernel_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 + + \ Call autoboot to perform the booting + 0 1 autoboot + + \ 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} ${kernel_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 + + \ Call autoboot to perform the booting + 0 1 autoboot +; + +also forth definitions +builtin: boot-conf +only forth definitions also support-functions \ ***** check-password \