Index: head/sys/boot/common/help.common =================================================================== --- head/sys/boot/common/help.common (revision 45880) +++ head/sys/boot/common/help.common (revision 45881) @@ -1,294 +1,303 @@ ################################################################################ # Thelp DDisplay command help help [topic [subtopic]] ? The help command displays help on commands and their usage. In command help, a term enclosed with <...> indicates a value as described by the term. A term enclosed with [...] is optional, and may not be required by all forms of the command. Some commands may not be availalble. Use the '?' command to list most available commands. ################################################################################ # Tautoboot DBoot after a delay autoboot [ []] Displays or a default prompt, and counts down seconds before attempting to boot. If is not specified, the default value is 10. ################################################################################ # Tboot DBoot immediately boot [] [- ...] Boot the system. If arguments are specified, they are added to the arguments for the kernel. If is specified, and a kernel has not already been loaded, it will be booted instead of the default kernel. ################################################################################ # Techo DEcho arguments echo [-n] [] Emits , with no trailing newline if -n is specified. This is most useful in conjunction with scripts and the '@' line prefix. Variables are substituted by prefixing them with $, eg. echo Current device is $currdev will print the current device. ################################################################################ # Tload DLoad a kernel or module load [-t ] Loads the module contained in into memory. If no other modules are loaded, must be a kernel or the command will fail. If -t is specified, the module is loaded as raw data of , for later use by the kernel or other modules. may be any string. ################################################################################ # Tls DList files ls [-l] [] Displays a listing of files in the directory , or the root directory of the current device if is not specified. The -l argument displays file sizes as well; the process of obtaining file sizes on some media may be very slow. ################################################################################ # Tlsdev DList devices lsdev [-v] List all of the devices from which it may be possible to load modules. If -v is specified, print more details. ################################################################################ # Tlsmod DList modules lsmod [-v] List loaded modules. If [-v] is specified, print more details. ################################################################################ # Tmore DPage files more [ ...] Show contents of text files. When displaying the contents of more, than one file, if the user elects to quit displaying a file, the remaining files will not be shown. ################################################################################ # Tpnpscan DScan for PnP devices pnpscan [-v] Scan for Plug-and-Play devices. This command is normally automatically run as part of the boot process, in order to dynamically load modules required for system operation. If the -v argument is specified, details on the devices found will be printed. ################################################################################ # Tset DSet a variable set set = The set command is used to set variables. ################################################################################ # Tset Sautoboot_delay DSet the default autoboot delay set autoboot_delay= Sets the default delay for the autoboot command to seconds. ################################################################################ # Tset Sbootfile DSet the default boot file set set bootfile=[,...] The default search path for bootable kernels is /kernel,/kernel.old. It may be overridden by setting the bootfile variable to a semicolon-separated list of paths, which will be searched for in turn. ################################################################################ # Tset Sboot_askname DPrompt for root device set boot_askname Instructs the kernel to prompt the user for the name of the root device when the kernel is booted. ################################################################################ # Tset Sboot_ddb DDrop to the kernel debugger (DDB) set boot_ddb Instructs the kernel to start in the DDB debugger, rather than proceeding to initialise when booted. ################################################################################ # Tset Sboot_gdb DSelect gdb-remote mode set boot_gdb Selects gdb-remote mode for the kernel debugger by default. ################################################################################ # Tset Sboot_single DStart system in single-user mode set boot_single Prevents the kernel from initiating a multi-user startup, single-user mode will be entered when the kernel has finished device probes. ################################################################################ # Tset Sboot_verbose DVerbose boot messages set boot_verbose Setting this variable causes extra debugging information to be printed by the kernel during the boot phase. ################################################################################ # Tset Sconsole DSet the current console set console[=] Sets the current console. If is omitted, a list of valid consoles will be displayed. ################################################################################ # Tset Scurrdev DSet the current device set currdev= Selects the default device. Syntax for devices is odd. ################################################################################ +# Tset Sinit_path DSet the list of init candidates + + set init_path=[;...] + + Sets the list of binaries which the kernel will try to run as initial + process. + + +################################################################################ # Tset Smodule_path DSet the module search path - set module_path=[,...] + set module_path=[;...] Sets the list of directories which will be searched in for modules named in a load command or implicitly required by a dependancy. ################################################################################ # Tset Sprompt DSet the command prompt set prompt= The command prompt is displayed when the loader is waiting for input. Variable substitution is performed on the prompt. The default prompt can be set with: set prompt=\$currdev> ################################################################################ # Tset Srootdev DSet the root filesystem set rootdev= By default the value of $currdev is used to set the root filesystem when the kernel is booted. This can be overridden by setting $rootdev explicitly. ################################################################################ # Tset Stunables DSet kernel tunable values Various kernel tunable parameters can be overriden by specifying new values in the environment. set kern.ipc.nmbclusters= NMBCLUSTERS Set the number of mbuf clusters to be allocated. The value cannot be set below the default determined when the kernel was compiled. set kern.vm.kmem.size= VM_KMEM_SIZE Sets the size of kernel memory (bytes). This overrides completely the value determined when the kernel was compiled. set machdep.pccard.pcic_irq= Overrides the IRQ normally assigned to a PCCARD controller. Typically the first available interrupt will be allocated, which may conflict with other hardware. If this value is set to 0, an interrupt will not be assigned and the controller will operate in polled mode only. set net.inet.tcp.tcbhashsize= TCBHASHSIZE Overrides the compile-time set value of TCBHASHSIZE or the preset default of 512. Must be a power of 2. ################################################################################ # Tshow DShow the values of variables show [] Displays the value of , or all variables if not specified. Multiple paths can be separated with a semicolon. See the set command for a list of some variables. ################################################################################ # Tinclude DRead commands from a script file include [ ...] The entire contents of are read into memory before executing commands, so it is safe to source a file from removable media. ################################################################################ # Tread DRead input from the terminal read [-t ] [-p ] [] The read command reads a line of input from the terminal. If the -t argument is specified, it will return nothing if no input has been received after seconds. (Any keypress will cancel the timeout). If -p is specified, is printed before reading input. No newline is emitted after the prompt. If a variable name is supplied, the variable is set to the value read, less any terminating newline. ################################################################################ # Tunload DRemove all modules from memory unload This command removes any kernel and all loaded modules from memory. ################################################################################ # Tunset DUnset a variable unset If allowed, the named variable's value is discarded and the variable is removed. ################################################################################ Index: head/sys/boot/common/loader.8 =================================================================== --- head/sys/boot/common/loader.8 (revision 45880) +++ head/sys/boot/common/loader.8 (revision 45881) @@ -1,747 +1,751 @@ .\" Copyright (c) 1999 Daniel C. Sobral .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" .\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE .\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $Id$ +.\" $Id: loader.8,v 1.1 1999/03/15 08:52:23 dcs Exp $ .\" .\" Note: The date here should be updated whenever a non-trivial .\" change is made to the manual page. .Dd March 14, 1999 .Dt LOADER 8 .Os .Sh NAME .Nm loader .Nd system bootstrap stage three .Sh DESCRIPTION The program called .Nm is the third stage of FreeBSD's three stage bootstrap. It is a .Pa BTX client linked statically to libstand(3) and usually located in the directory .Pa /boot . .Pp It provides a scripting language that can be used to automate tasks, do pre-configuration or assist in recovery procedures. This scripting language is roughly divided in two main components. The smaller one is a set of commands designed for direct use by the casual user, called "builtin commands" for historical reasons. The main drive behind these commands is user-friendlyness. The bigger component is an .Tn ANS Forth compatible Forth interpreter based on ficl, by .An John Sadler . .Pp During initialization, .Nm will probe for a console and set the .Va console variable, or set it to serial console .Pq Dq comconsole if the previous boot stage used that. Then, devices are probed, .Va currdev and .Va loaddev are set, and .Va LINES is set to 24 . Next, .Tn FICL is initialized, the builtin words are added to it's vocabulary, and .Pa /boot/boot.4th will be processed if it exists. No disk switching is possible while that file is being read. The inner interpreter .Nm will use with .Tn FICL is then set to .Ic interpret , which is .Tn FICL Ns 's default. After that, .Pa /boot/loader.rc is processed if available, and, failing that, .Pa /boot/boot.conf will be read for historical reasons. These files are processed through the .Ic include command, which read all of them into memory before processing them, making disk changes possible. .Pp At this point, if an .Ic autoboot has not been tried, and if .Va autoboot_delay is not set to .Dq NO (not case sensitive), then an .Ic autoboot will be tried. If the system gets past this point, .Va prompt will be set and .Nm will engage interactive mode. .Sh BUILTIN COMMANDS .Nm Loader Ns No 's builtin commands take it's parameters from the command line. Presently, the only way to call them from a script is by using .Pa evaluate on a string. If an error condition occurs, an exception will be generated, which can be intercepted using .Tn ANS Forth exception handling words. If not intercepted, an error message will be displayed and the interpreter's state will be reset, emptying the stack and restoring interpreting mode. .Pp The builtin commands available are: .Pp .Bl -tag -width Ds -compact -offset indent .It Ic autoboot Op Ar seconds Proceeds to bootstrap the system after a number of seconds, if not interrupted by the user. Displays a countdown prompt warning the user the system is about to be booted, unless interrupted by a key press. The kernel will be loaded first if necessary. Defaults to 10 seconds. .Pp .It Ic bcachestat Displays statistics about disk cache usage. For depuration only. .Pp .It Ic boot .It Ic boot Ar kernelname Op Cm ... .It Ic boot Fl flag Cm ... Immediately proceeds to bootstrap the system, loading the kernel if necessary. Any flags or arguments are passed to the kernel, but they must precede the kernel name, if a kernel name is provided. .Pp .It Ic echo Xo .Op Fl n .Op Aq message .Xc Displays a text on the screen. A new line will be printed unless .Fl n is specified. .Pp .It Ic heap Displays memory usage statistics. For debugging purposes only. .Pp .It Ic help Op topic Op subtopic Shows help messages read from .Pa /boot/loader.help . The special topic .Em index will list the topics available. .Pp .It Ic include Ar file Op Ar Process script files. Each file is, at a turn, completely read into memory, and then have each of it's lines passed to the command line interpreter. If any error is returned by the interpreter, the include commands aborts immediately, without reading any other files, and returns an error itself (see .Sx ERRORS ) . .Pp .It Ic load Xo .Op Fl t Ar type .Ar file Cm ... .Xc Loads a kernel, kernel loadable module (kld), or a file of opaque contents tagged as being of the type .Ar type . Kernel and modules can be either in a.out or elf format. Any arguments passed after the name of the file to be loaded will be passed as arguments to that file. Notice, though, that, at the present, this does not work for the kernel. .Pp .It Ic ls Xo .Op Fl l .Op Ar path .Xc Displays a listing of files in the directory .Ar path , or the root directory if .Ar path is not specified. If .Fl l is specified, file sizes will be shown too. .Pp .It Ic lsdev Op Fl v Lists all of the devices from which it may be possible to load modules. If .Fl v is specified, more details are printed. .Pp .It Ic lsmod Op Fl v Displays loaded modules. If .Fl v is specified, more details are shown. .Pp .It Ic more Ar file Op Ar Display the files specified, with a pause at each .Va LINES displayed. .Pp .It Ic pnpscan Op Fl v Scans for Plug-and-Play devices. This is not functional at the present. .Pp .It Ic read Xo .Op Fl t Ar seconds .Op Fl p Ar prompt .Op Va variable .Xc Reads a line of input from the terminal, storing it in .Va variable if specified. A timeout can be specified with .Fl t , though it will be canceled at the first key pressed. A prompt may also be displayed through the .Fl p flag. .Pp .It Ic reboot Immediately reboots the system. .Pp .It Ic set Ar variable .It Ic set Ar variable Ns = Ns Ar value Set loader's environment variables. .Pp .It Ic show Op Va variable Displays the specified variable's value, or all variables and their values if .Va variable is not specified. .Pp .It Ic unload Remove all modules from memory. .Pp .It Ic unset Va variable Removes .Va variable from the environment. .Pp .It Ic \&? Same as .Dq help index . .Pp .El .Ss BUILTIN ENVIRONMENT VARIABLES The .Nm has actually two different kinds of .Sq environment variables. There are ANS Forth's .Em environmental queries , and a separate space of environment variables used by builtins, which are not directly available to Forth words. It is the later ones that this session covers. .Pp Environment variables can be set and unset through the use of the .Ic set and .Ic unset builtins, and have their value interactively examined through the use of the .Ic show builtin. Their values can also be accessed as described in .Sx BUILTIN PARSER . .Pp Notice that this environment variables are not inherited by any shell after the system has been booted. .Pp A few variables are set automatically by .Nm . Others can affect either .Nm or kernel's behavior at boot. While some of these may require a value, others define behavior just by being set. These are described below. .Bl -tag -width bootfile -offset indent .It Va autoboot_delay Number of seconds .Ic autoboot will wait before booting. If this variable is not defined, .Ic autoboot will default to 10 seconds. .Pp If set to .Dq NO , no .Ic autoboot will be automatically attempted after processing .Pa /boot/loader.rc , though explict .Ic autoboot Ns 's will be processed normally, defaulting to 10 seconds delay. .It Va boot_askname Instructs the kernel to prompt the user for the name of the root device when the kernel is booted. .It Va boot_ddb Instructs the kernel to start in the DDB debugger, rather than proceeding to initialise when booted. .It Va boot_gdb Selects gdb-remote mode for the kernel debugger by default. .It Va boot_single Prevents the kernel from initiating a multi-user startup, single-user mode will be entered when the kernel has finished device probes. .It Va boot_userconfig Requests that the kernel's interactive device configuration program be run when the kernel is booted. .It Va boot_verbose Setting this variable causes extra debugging information to be printed by the kernel during the boot phase. .It Va bootfile List of semicolon-separated search path for bootable kernels. The default is .Li Dq kernel;kernel.old . .It Va console Defines the current console. .It Va currdev Selects the default device. Syntax for devices is odd. +.It Va init_path +Sets the list of binaries which the kernel will try to run as initial +process. The default is +.Li Dq /sbin/init;/sbin/oinit;/sbin/init.bak;/stand/sysinstall . .It Va interpret Has the value .Li Dq ok if the Forth's current state is interpreting. .It Va LINES Define the number of lines on the screen, to be used by the pager. .It Va module_path Sets the list of directories which will be searched in for modules named in a load command or implicitly required by a dependancy. The default value for this variable is .Li Dq /;/boot;/modules . .It Va num_ide_disks Sets the number of IDE disks as a work around for some problems in finding the root disk at boot. This has been deprecated in favour of .Va root_disk_unit . .It Va prompt Value of .Nm Ns No 's prompt. Defaults to .Li Dq "${currdev}>" . .It Va root_disk_unit If the code which detects the disk unit number for the root disk is confused, eg. by a mix of SCSI and IDE disks, or IDE disks with gaps in the sequence (eg. no primary slave), the unit number can be forced by setting this variable. .It Va rootdev By default the value of .Va currdev is used to set the root filesystem when the kernel is booted. This can be overridden by setting .Va rootdev explicitly. .El .Pp Other variables are used to override kernel tunnable parameters. The following tunables are available: .Bl -tag -width Va -offset indent .It Va kern.ipc.nmbclusters Set the number of mbuf clusters to be allocated. The value cannot be set below the default determined when the kernel was compiled. Modifies .Va NMBCLUSTERS . .It Va kern.vm.kmem.size Sets the size of kernel memory (bytes). This overrides completely the value determined when the kernel was compiled. Modifies .Va VM_KMEM_SIZE . .It Va machdep.pccard.pcic_irq Overrides the IRQ normally assigned to a PCCARD controller. Typically the first available interrupt will be allocated, which may conflict with other hardware. If this value is set to 0, an interrupt will not be assigned and the controller will operate in polled mode only. .It Va net.inet.tcp.tcbhashsize Overrides the compile-time set value of .Va TCBHASHSIZE or the preset default of 512. Must be a power of 2. .El .Ss BUILTIN PARSER When a builtin command is executed, the rest of the line is taken by it as arguments, and it's processed by a special parser which is not used for regular Forth commands. .Pp This special parser applies the following rules to the parsed text: .Pp .Bl -enum .It All backslash characters are preprocessed. .Bl -bullet .It \eb , \ef , \er , \en and \et are processed as by C's .fn printf() . .It \es is converted to a space. .It \ev is converted to .Tn ASCII 11. .It \ez is just skipped. .It \eN and \eNN are replaced by the hex N or NN. .It \eNNN is replaced by the octal NNN .Tn ASCII character. .It \e" , \e' and \e$ will escape these characters, preventing them from receiving special semantics on the step 2 described below. .It \e\e will be replaced with a single \e . .It In any other occurance, backslash will just be removed. .El .It Every string between non-escaped quotes or double-quotes will be treated as a single word for the purposes of the remaining steps. .It Replace any .Li $VARIABLE or .Li ${VARIABLE} with the value of the environemnt variable .Va VARIABLE . .It Passes multiple space-delimited arguments to the builtin command called. Spaces can also be escaped through the use of \e\e . .El .Pp An exception to this parsing rule exists, and is described in .Sx BUILTINS AND FORTH . .Ss BUILTINS AND FORTH All builtin words are state-smart, immediate words. If interpreted, they behave exactly as described previously. If they are compiled, though, they extract their arguments from the stack instead of the command line. .Pp If compiled, the builtin words expect to find, at execution time, the following parameters on the stack: .D1 Ar addrN lenN ... addr2 len2 addr1 len1 N where .Ar addrX lenX are strings which will compose the command line that will be parsed into the builtin's arguments. Internally, these strings are concatenated in from 1 to N, with a space put between each one. .Pp If no arguments are passed, a 0 .Em must be passed, even if the builtin accepts no arguments. .Pp While this behavior has benefits, it has it's trade-offs. If the execution token of a builtin is acquired (through .Ic No ' or .Ic No ['] ) , and then passed to .Ic catch or .Ic execute , the builtin behavior will depend on the system state .Bf Em at the time .Ic catch or .Ic execute is processed .Ef \&! This is particular annoying for programs that want or need to treat exceptions. In this case, it is recommended the use of a proxy. For example: .Dl : (boot) boot ; .Sh FICL .Tn FICL is a Forth interpreter written in C, in the form of a forth virtual machine library that can be called by C functions and vice versa. .Pp In .Nm , each line read interactively is then fed to .Tn FICL , which may call .Nm back to execute the builtin words. The builtin .Ic include will also feed .Tn FICL , one line at a time. .Pp The words available to .Tn FICL can be classified in four groups. The .Tn ANS Forth standard words, extra .Tn FICL words, extra .Os words, and the builtin commands. The later were already described. The .Tn ANS Forth standard words are listed in the .Sx STANDARDS section. The words falling in the two other groups are described in the following subsections. .Ss FICL EXTRA WORDS .Bl -tag -width wid-set-super -offset indent .It Ic .env .It Ic .ver .It Ic -roll .It Ic 2constant .It Ic >name .It Ic body> .It Ic compare This the STRING word set's .Ic compare . .It Ic compile-only .It Ic endif .It Ic forget-wid .It Ic parse-word .It Ic sliteral This is the STRING word set's .Ic sliteral . .It Ic wid-set-super .It Ic w@ .It Ic w! .It Ic x. .It Ic empty .It Ic cell- .It Ic -rot .El .Ss FREEBSD EXTRA WORDS .Bl -tag -width XXXXXXX -offset indent .It Ic tib> Pq -- Ar addr len Returns the remainder of the input buffer as a string on the stack. .It Ic \&% Pq -- Evaluates the remainder of the input buffer under a .Ic catch exception guard. .It Ic \&$ Pq -- Evaluates the remainder of the input buffer, after having printed it first. .It Ic fopen Pq Ar addr len -- fd Open a file. Returns a file descriptor, or -1 in case of failure. .It Ic fclose Pq Ar fd -- Closes a file. .It Xo .Ic fread .Pq Ar fd addr len -- len' .Xc Tries to read .Em len bytes from file .Em fd into buffer .Em addr . Returns the actual number of bytes read, or -1 in case of error or end of file. .It Ic fload Pq Ar fd -- Process file .Em fd . .It Ic fkey Pq Ar fd -- char Reads a single character from a file. .It Ic key Pq -- Ar char Reads a single character from the console. .It Ic key? Pq -- Ar flag Returns .Ic true if there is a character available to be read from the console. .It Ic ms Pq Ar u -- Waits .Em u microseconds. .It Ic seconds Pq -- Ar u Returns the number of seconds since midnight. .It Ic trace! Pq Ar flag -- Activates or deactivates tracing. Does not work with .Ic catch . .It Ic outb Pq Ar port char -- Writes a byte to a port. .It Ic inb Pq Ar port -- char Reads a byte from a port. .El .Ss FREEBSD DEFINED ENVIRONMENTAL QUERIES .Bl -tag -width Ds -offset indent .It arch-i386 .Ic TRUE if the architecture is IA32. .It arch-alpha .Ic TRUE if the architecture is AXP. .It FreeBSD_version .Fx version at compile time. .It loader_version .Nm version. .El .Ss SYSTEM DOCUMENTATION .Sh FILES .Bl -tag -width /dev/loader.helpX -compact .It Pa /boot/loader .Nm itself. .It Pa /boot/boot.4th Additional .Tn FICL initialization. .It Pa /boot/boot.conf .Nm bootstrapping script. Deprecated. .It Pa /boot/loader.rc .Nm bootstrapping script. .It Pa /boot/loader.help Loaded by .Ic help . Contains the help messages. .El .Sh EXAMPLES Boot in single user mode: .Pp .Dl boot -s .Pp Loads kernel's user configuration file. Notice that a kernel must be loaded before any other .Ic load command is attempted. .Pp .Bd -literal -offset indent -compact load kernel load -t userconfig_script /boot/kernel.conf .Ed .Pp Loads the kernel, a splash screen, and then autoboots in five seconds. .Pp .Bd -literal -offset indent -compact load kernel load splash_bmp load -t splash_image_data /boot/chuckrulez.bmp autoboot 5 .Ed .Pp Sets the disk unit of the root device to 2, and then boots. This would be needed in the case of a two IDE disks system, with the second IDE hardwired to wd2 instead of wd1. .Pp .Bd -literal -offset indent -compact set root_disk_unit=2 boot /kernel .Ed .Pp See also: .Bl -tag -width /usr/share/examples/bootforth/X .It Pa /boot/loader.4th Extra builtin-like words. .It Pa /boot/support.4th .Pa loader.conf processing words. .It Pa /usr/share/examples/bootforth/ Assorted examples. .El .Sh ERRORS The following values are thrown by .Nm : .Bl -tag -width XXXXX -offset indent .It 100 Any type of error in the processing of a builtin. .It -1 .Ic Abort executed. .It -2 .Ic Abort" executed. .It -56 .Ic Quit executed. .It -256 Out of interpreting text. .It -257 Need more text to succeed -- will finish on next run. .It -258 .Ic Bye executed. .It -259 Unspecified error. .El .Sh SEE ALSO .Xr libstand 3 , .Xr loader.conf 5 , .Xr boot 8 , .Xr btxld 8 .Sh STANDARDS For the purposes of ANS Forth compliance, loader is an .Bf Em ANS Forth System with Environmental Restrictions, Providing .Ef .Bf Li .No .( , .No :noname , .No ?do , parse, pick, roll, refill, to, value, \e, false, true, .No <> , .No 0<> , compile\&, , erase, nip, tuck .Ef .Em and .Li marker .Bf Em from the Core Extensions word set, Providing the Exception Extensions word set, Providing the Locals Extensions word set, Providing the Memory-Allocation Extensions word set, Providing .Ef .Bf Li \&.s , bye, forget, see, words, \&[if] , \&[else] .Ef .Em and .Li No [then] .Bf Em from the Programming-Tools extension word set, Providing the Search-Order extensions word set. .Ef .Sh HISTORY .Nm first appeared in .Fx 3.1 . .Sh AUTHORS .Bl -item .It .Nm was written by .An Michael Smith Aq msmisth@freebsd.org . .It .Tn FICL was written by .An John Sadler Aq john_sadler@alum.mit.edu . .El .Sh BUGS .Tn FICL is case sensitive. Though this is not a standard violation, all Forth words are lower cased, which would result in a standard violation. Do not rely on this bug. .Pp The .Ic expect and .Ic accept words will read from the input buffer instead of the console. The later will be fixed, but the former will not. Index: head/sys/boot/forth/loader.conf =================================================================== --- head/sys/boot/forth/loader.conf (revision 45880) +++ head/sys/boot/forth/loader.conf (revision 45881) @@ -1,156 +1,157 @@ # This is loader.conf - a file full of useful variables that you can # set to change the default load behavior of your system. You should # not edit this file! Put any overrides into one of the # loader_conf_files instead and you will be able to update these # defaults later without spamming your local configuration information. # # All arguments must be in double quotes. # -# $Id: loader.conf,v 1.1 1999/03/09 14:06:55 dcs Exp $ +# $Id: loader.conf,v 1.2 1999/03/14 21:57:49 dcs Exp $ ############################################################## ### Basic configuration options ############################ ############################################################## exec=".( Loading /boot/defaults/loader.conf ) cr" kernel="/kernel" kernel_options="" userconfig_script_load="NO" userconfig_script_name="/boot/kernel.conf" userconfig_script_type="userconfig_script" loader_conf_files="/boot/loader.conf /boot/loader.conf.local" verbose_loading="NO" # Set to YES for verbose loader output ############################################################## ### Splash screen configuration ############################ ############################################################## splash_bmp_load="NO" # Set this to YES if you want splash screen! vesa_load="NO" # Set this to YES to load the vesa module bitmap_load="NO" # Set this to YES if you want splash screen! bitmap_name="/boot/splash.bmp" # Set this to the name of the bmp file bitmap_type="splash_image_data" ############################################################## ### Loader settings ######################################## ############################################################## #autoboot_delay="10" # Delay in seconds before autobooting #bootfile="/kernel,/kernel.old" # Set the default boot file set #console="vidconsole" # Set the current console #currdev="disk1s1a" # Set the current device #module_path="/modules" # Set the module search path #prompt="\\${currdev}" # Set the command prompt #root_disk_unit="0" # Force the root disk unit number #rootdev="disk1s1a" # Set the root filesystem ############################################################## ### Kernel settings ######################################## ############################################################## #boot_askname="NO" # Prompt the user for the name of the root device #boot_ddb="NO" # Instructs the kernel to start in the DDB debugger #boot_gdb="NO" # Selects gdb-remote mode for the kernel debugger #boot_single="NO" # Start system in single-user mode #boot_userconfig="NO" # Run kernel's interactive device configuration program #boot_verbose="NO" # Causes extra debugging information to be printed +#init_path="/sbin/init" # Sets the list of init candidates ############################################################## ### Kernel tunables ######################################## ############################################################## #kern.ipc.nmbclusters="" # Set the number of mbuf clusters #kern.vm.kmem.size="" # Sets the size of kernel memory (bytes) #machdep.pccard.pcic_irq="0" # Assigns PCCARD controller IRQ (0=polled) #net.inet.tcp.tcbhashsize="" # Set the value of TCBHASHSIZE ############################################################## ### Filesystem and related modules ######################### ############################################################## # Filesystems cd9660_load="NO" # ISO 9660 filesystem coda_load="NO" # CODA filesystem fdesc_load="NO" # Filedescriptors filesystem kernfs_load="NO" # Kernel filesystem mfs_load="NO" # Memory filesystem msdos_load="NO" # FAT-12/16/32 nfs_load="NO" # NFS null_load="NO" # Null filesystem portal_load="NO" # Portal filesystem procfs_load="NO" # Process filesystem umap_load="NO" # User-id map filesystem union_load="NO" # Union filesystem # Related stuff atapi_load="NO" # ATAPI-compatible IDE devices ccd_load="NO" # Concatenated disk driver vinum_load="NO" # Concatenated/mirror/raid driver vn_load="NO" # Vnode driver wcd_load="NO" # CD-ROM ############################################################## ### Screen saver modules ################################### ############################################################## # This is best done in rc.conf screensave_load="NO" # Set to YES to load a screensaver module screensave_name="green_saver" # Set to the name of the screensaver module ############################################################## ### Emulation modules ###################################### ############################################################## fpu_load="NO" # Floating point emulation gnufpu_load="NO" # GNU floating point emulation ibcs2_load="NO" # IBCS2 (SCO) emulation ibcs2_coff_load="NO" linux_load="NO" # Linux emulation ############################################################## ### Networking modules ##################################### ############################################################## if_disc_load="NO" # Discard device if_ppp_load="NO" # Kernel ppp if_sl_load="NO" # SLIP if_tun_load="NO" # Tunnel driver (user process ppp) ipfw_load="NO" # Firewall ############################################################## ### Other modules ########################################## ############################################################## joy_load="NO" # Joystick lkm_load="NO" # LKM pcic_load="NO" # PCMCIA ############################################################## ### Module loading syntax example ########################## ############################################################## #module_load="YES" # loads module "module" #module_name="realname" # uses "realname" instead of "module" #module_type="type" # passes "-t type" to load #module_flags="flags" # passes "flags" to the module #module_before="cmd" # executes "cmd" before loading the module #module_after="cmd" # executes "cmd" after loading the module #module_error="cmd" # executes "cmd" if load fails Index: head/sys/boot/i386/loader/loader.8 =================================================================== --- head/sys/boot/i386/loader/loader.8 (revision 45880) +++ head/sys/boot/i386/loader/loader.8 (revision 45881) @@ -1,747 +1,751 @@ .\" Copyright (c) 1999 Daniel C. Sobral .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" .\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE .\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $Id$ +.\" $Id: loader.8,v 1.1 1999/03/15 08:52:23 dcs Exp $ .\" .\" Note: The date here should be updated whenever a non-trivial .\" change is made to the manual page. .Dd March 14, 1999 .Dt LOADER 8 .Os .Sh NAME .Nm loader .Nd system bootstrap stage three .Sh DESCRIPTION The program called .Nm is the third stage of FreeBSD's three stage bootstrap. It is a .Pa BTX client linked statically to libstand(3) and usually located in the directory .Pa /boot . .Pp It provides a scripting language that can be used to automate tasks, do pre-configuration or assist in recovery procedures. This scripting language is roughly divided in two main components. The smaller one is a set of commands designed for direct use by the casual user, called "builtin commands" for historical reasons. The main drive behind these commands is user-friendlyness. The bigger component is an .Tn ANS Forth compatible Forth interpreter based on ficl, by .An John Sadler . .Pp During initialization, .Nm will probe for a console and set the .Va console variable, or set it to serial console .Pq Dq comconsole if the previous boot stage used that. Then, devices are probed, .Va currdev and .Va loaddev are set, and .Va LINES is set to 24 . Next, .Tn FICL is initialized, the builtin words are added to it's vocabulary, and .Pa /boot/boot.4th will be processed if it exists. No disk switching is possible while that file is being read. The inner interpreter .Nm will use with .Tn FICL is then set to .Ic interpret , which is .Tn FICL Ns 's default. After that, .Pa /boot/loader.rc is processed if available, and, failing that, .Pa /boot/boot.conf will be read for historical reasons. These files are processed through the .Ic include command, which read all of them into memory before processing them, making disk changes possible. .Pp At this point, if an .Ic autoboot has not been tried, and if .Va autoboot_delay is not set to .Dq NO (not case sensitive), then an .Ic autoboot will be tried. If the system gets past this point, .Va prompt will be set and .Nm will engage interactive mode. .Sh BUILTIN COMMANDS .Nm Loader Ns No 's builtin commands take it's parameters from the command line. Presently, the only way to call them from a script is by using .Pa evaluate on a string. If an error condition occurs, an exception will be generated, which can be intercepted using .Tn ANS Forth exception handling words. If not intercepted, an error message will be displayed and the interpreter's state will be reset, emptying the stack and restoring interpreting mode. .Pp The builtin commands available are: .Pp .Bl -tag -width Ds -compact -offset indent .It Ic autoboot Op Ar seconds Proceeds to bootstrap the system after a number of seconds, if not interrupted by the user. Displays a countdown prompt warning the user the system is about to be booted, unless interrupted by a key press. The kernel will be loaded first if necessary. Defaults to 10 seconds. .Pp .It Ic bcachestat Displays statistics about disk cache usage. For depuration only. .Pp .It Ic boot .It Ic boot Ar kernelname Op Cm ... .It Ic boot Fl flag Cm ... Immediately proceeds to bootstrap the system, loading the kernel if necessary. Any flags or arguments are passed to the kernel, but they must precede the kernel name, if a kernel name is provided. .Pp .It Ic echo Xo .Op Fl n .Op Aq message .Xc Displays a text on the screen. A new line will be printed unless .Fl n is specified. .Pp .It Ic heap Displays memory usage statistics. For debugging purposes only. .Pp .It Ic help Op topic Op subtopic Shows help messages read from .Pa /boot/loader.help . The special topic .Em index will list the topics available. .Pp .It Ic include Ar file Op Ar Process script files. Each file is, at a turn, completely read into memory, and then have each of it's lines passed to the command line interpreter. If any error is returned by the interpreter, the include commands aborts immediately, without reading any other files, and returns an error itself (see .Sx ERRORS ) . .Pp .It Ic load Xo .Op Fl t Ar type .Ar file Cm ... .Xc Loads a kernel, kernel loadable module (kld), or a file of opaque contents tagged as being of the type .Ar type . Kernel and modules can be either in a.out or elf format. Any arguments passed after the name of the file to be loaded will be passed as arguments to that file. Notice, though, that, at the present, this does not work for the kernel. .Pp .It Ic ls Xo .Op Fl l .Op Ar path .Xc Displays a listing of files in the directory .Ar path , or the root directory if .Ar path is not specified. If .Fl l is specified, file sizes will be shown too. .Pp .It Ic lsdev Op Fl v Lists all of the devices from which it may be possible to load modules. If .Fl v is specified, more details are printed. .Pp .It Ic lsmod Op Fl v Displays loaded modules. If .Fl v is specified, more details are shown. .Pp .It Ic more Ar file Op Ar Display the files specified, with a pause at each .Va LINES displayed. .Pp .It Ic pnpscan Op Fl v Scans for Plug-and-Play devices. This is not functional at the present. .Pp .It Ic read Xo .Op Fl t Ar seconds .Op Fl p Ar prompt .Op Va variable .Xc Reads a line of input from the terminal, storing it in .Va variable if specified. A timeout can be specified with .Fl t , though it will be canceled at the first key pressed. A prompt may also be displayed through the .Fl p flag. .Pp .It Ic reboot Immediately reboots the system. .Pp .It Ic set Ar variable .It Ic set Ar variable Ns = Ns Ar value Set loader's environment variables. .Pp .It Ic show Op Va variable Displays the specified variable's value, or all variables and their values if .Va variable is not specified. .Pp .It Ic unload Remove all modules from memory. .Pp .It Ic unset Va variable Removes .Va variable from the environment. .Pp .It Ic \&? Same as .Dq help index . .Pp .El .Ss BUILTIN ENVIRONMENT VARIABLES The .Nm has actually two different kinds of .Sq environment variables. There are ANS Forth's .Em environmental queries , and a separate space of environment variables used by builtins, which are not directly available to Forth words. It is the later ones that this session covers. .Pp Environment variables can be set and unset through the use of the .Ic set and .Ic unset builtins, and have their value interactively examined through the use of the .Ic show builtin. Their values can also be accessed as described in .Sx BUILTIN PARSER . .Pp Notice that this environment variables are not inherited by any shell after the system has been booted. .Pp A few variables are set automatically by .Nm . Others can affect either .Nm or kernel's behavior at boot. While some of these may require a value, others define behavior just by being set. These are described below. .Bl -tag -width bootfile -offset indent .It Va autoboot_delay Number of seconds .Ic autoboot will wait before booting. If this variable is not defined, .Ic autoboot will default to 10 seconds. .Pp If set to .Dq NO , no .Ic autoboot will be automatically attempted after processing .Pa /boot/loader.rc , though explict .Ic autoboot Ns 's will be processed normally, defaulting to 10 seconds delay. .It Va boot_askname Instructs the kernel to prompt the user for the name of the root device when the kernel is booted. .It Va boot_ddb Instructs the kernel to start in the DDB debugger, rather than proceeding to initialise when booted. .It Va boot_gdb Selects gdb-remote mode for the kernel debugger by default. .It Va boot_single Prevents the kernel from initiating a multi-user startup, single-user mode will be entered when the kernel has finished device probes. .It Va boot_userconfig Requests that the kernel's interactive device configuration program be run when the kernel is booted. .It Va boot_verbose Setting this variable causes extra debugging information to be printed by the kernel during the boot phase. .It Va bootfile List of semicolon-separated search path for bootable kernels. The default is .Li Dq kernel;kernel.old . .It Va console Defines the current console. .It Va currdev Selects the default device. Syntax for devices is odd. +.It Va init_path +Sets the list of binaries which the kernel will try to run as initial +process. The default is +.Li Dq /sbin/init;/sbin/oinit;/sbin/init.bak;/stand/sysinstall . .It Va interpret Has the value .Li Dq ok if the Forth's current state is interpreting. .It Va LINES Define the number of lines on the screen, to be used by the pager. .It Va module_path Sets the list of directories which will be searched in for modules named in a load command or implicitly required by a dependancy. The default value for this variable is .Li Dq /;/boot;/modules . .It Va num_ide_disks Sets the number of IDE disks as a work around for some problems in finding the root disk at boot. This has been deprecated in favour of .Va root_disk_unit . .It Va prompt Value of .Nm Ns No 's prompt. Defaults to .Li Dq "${currdev}>" . .It Va root_disk_unit If the code which detects the disk unit number for the root disk is confused, eg. by a mix of SCSI and IDE disks, or IDE disks with gaps in the sequence (eg. no primary slave), the unit number can be forced by setting this variable. .It Va rootdev By default the value of .Va currdev is used to set the root filesystem when the kernel is booted. This can be overridden by setting .Va rootdev explicitly. .El .Pp Other variables are used to override kernel tunnable parameters. The following tunables are available: .Bl -tag -width Va -offset indent .It Va kern.ipc.nmbclusters Set the number of mbuf clusters to be allocated. The value cannot be set below the default determined when the kernel was compiled. Modifies .Va NMBCLUSTERS . .It Va kern.vm.kmem.size Sets the size of kernel memory (bytes). This overrides completely the value determined when the kernel was compiled. Modifies .Va VM_KMEM_SIZE . .It Va machdep.pccard.pcic_irq Overrides the IRQ normally assigned to a PCCARD controller. Typically the first available interrupt will be allocated, which may conflict with other hardware. If this value is set to 0, an interrupt will not be assigned and the controller will operate in polled mode only. .It Va net.inet.tcp.tcbhashsize Overrides the compile-time set value of .Va TCBHASHSIZE or the preset default of 512. Must be a power of 2. .El .Ss BUILTIN PARSER When a builtin command is executed, the rest of the line is taken by it as arguments, and it's processed by a special parser which is not used for regular Forth commands. .Pp This special parser applies the following rules to the parsed text: .Pp .Bl -enum .It All backslash characters are preprocessed. .Bl -bullet .It \eb , \ef , \er , \en and \et are processed as by C's .fn printf() . .It \es is converted to a space. .It \ev is converted to .Tn ASCII 11. .It \ez is just skipped. .It \eN and \eNN are replaced by the hex N or NN. .It \eNNN is replaced by the octal NNN .Tn ASCII character. .It \e" , \e' and \e$ will escape these characters, preventing them from receiving special semantics on the step 2 described below. .It \e\e will be replaced with a single \e . .It In any other occurance, backslash will just be removed. .El .It Every string between non-escaped quotes or double-quotes will be treated as a single word for the purposes of the remaining steps. .It Replace any .Li $VARIABLE or .Li ${VARIABLE} with the value of the environemnt variable .Va VARIABLE . .It Passes multiple space-delimited arguments to the builtin command called. Spaces can also be escaped through the use of \e\e . .El .Pp An exception to this parsing rule exists, and is described in .Sx BUILTINS AND FORTH . .Ss BUILTINS AND FORTH All builtin words are state-smart, immediate words. If interpreted, they behave exactly as described previously. If they are compiled, though, they extract their arguments from the stack instead of the command line. .Pp If compiled, the builtin words expect to find, at execution time, the following parameters on the stack: .D1 Ar addrN lenN ... addr2 len2 addr1 len1 N where .Ar addrX lenX are strings which will compose the command line that will be parsed into the builtin's arguments. Internally, these strings are concatenated in from 1 to N, with a space put between each one. .Pp If no arguments are passed, a 0 .Em must be passed, even if the builtin accepts no arguments. .Pp While this behavior has benefits, it has it's trade-offs. If the execution token of a builtin is acquired (through .Ic No ' or .Ic No ['] ) , and then passed to .Ic catch or .Ic execute , the builtin behavior will depend on the system state .Bf Em at the time .Ic catch or .Ic execute is processed .Ef \&! This is particular annoying for programs that want or need to treat exceptions. In this case, it is recommended the use of a proxy. For example: .Dl : (boot) boot ; .Sh FICL .Tn FICL is a Forth interpreter written in C, in the form of a forth virtual machine library that can be called by C functions and vice versa. .Pp In .Nm , each line read interactively is then fed to .Tn FICL , which may call .Nm back to execute the builtin words. The builtin .Ic include will also feed .Tn FICL , one line at a time. .Pp The words available to .Tn FICL can be classified in four groups. The .Tn ANS Forth standard words, extra .Tn FICL words, extra .Os words, and the builtin commands. The later were already described. The .Tn ANS Forth standard words are listed in the .Sx STANDARDS section. The words falling in the two other groups are described in the following subsections. .Ss FICL EXTRA WORDS .Bl -tag -width wid-set-super -offset indent .It Ic .env .It Ic .ver .It Ic -roll .It Ic 2constant .It Ic >name .It Ic body> .It Ic compare This the STRING word set's .Ic compare . .It Ic compile-only .It Ic endif .It Ic forget-wid .It Ic parse-word .It Ic sliteral This is the STRING word set's .Ic sliteral . .It Ic wid-set-super .It Ic w@ .It Ic w! .It Ic x. .It Ic empty .It Ic cell- .It Ic -rot .El .Ss FREEBSD EXTRA WORDS .Bl -tag -width XXXXXXX -offset indent .It Ic tib> Pq -- Ar addr len Returns the remainder of the input buffer as a string on the stack. .It Ic \&% Pq -- Evaluates the remainder of the input buffer under a .Ic catch exception guard. .It Ic \&$ Pq -- Evaluates the remainder of the input buffer, after having printed it first. .It Ic fopen Pq Ar addr len -- fd Open a file. Returns a file descriptor, or -1 in case of failure. .It Ic fclose Pq Ar fd -- Closes a file. .It Xo .Ic fread .Pq Ar fd addr len -- len' .Xc Tries to read .Em len bytes from file .Em fd into buffer .Em addr . Returns the actual number of bytes read, or -1 in case of error or end of file. .It Ic fload Pq Ar fd -- Process file .Em fd . .It Ic fkey Pq Ar fd -- char Reads a single character from a file. .It Ic key Pq -- Ar char Reads a single character from the console. .It Ic key? Pq -- Ar flag Returns .Ic true if there is a character available to be read from the console. .It Ic ms Pq Ar u -- Waits .Em u microseconds. .It Ic seconds Pq -- Ar u Returns the number of seconds since midnight. .It Ic trace! Pq Ar flag -- Activates or deactivates tracing. Does not work with .Ic catch . .It Ic outb Pq Ar port char -- Writes a byte to a port. .It Ic inb Pq Ar port -- char Reads a byte from a port. .El .Ss FREEBSD DEFINED ENVIRONMENTAL QUERIES .Bl -tag -width Ds -offset indent .It arch-i386 .Ic TRUE if the architecture is IA32. .It arch-alpha .Ic TRUE if the architecture is AXP. .It FreeBSD_version .Fx version at compile time. .It loader_version .Nm version. .El .Ss SYSTEM DOCUMENTATION .Sh FILES .Bl -tag -width /dev/loader.helpX -compact .It Pa /boot/loader .Nm itself. .It Pa /boot/boot.4th Additional .Tn FICL initialization. .It Pa /boot/boot.conf .Nm bootstrapping script. Deprecated. .It Pa /boot/loader.rc .Nm bootstrapping script. .It Pa /boot/loader.help Loaded by .Ic help . Contains the help messages. .El .Sh EXAMPLES Boot in single user mode: .Pp .Dl boot -s .Pp Loads kernel's user configuration file. Notice that a kernel must be loaded before any other .Ic load command is attempted. .Pp .Bd -literal -offset indent -compact load kernel load -t userconfig_script /boot/kernel.conf .Ed .Pp Loads the kernel, a splash screen, and then autoboots in five seconds. .Pp .Bd -literal -offset indent -compact load kernel load splash_bmp load -t splash_image_data /boot/chuckrulez.bmp autoboot 5 .Ed .Pp Sets the disk unit of the root device to 2, and then boots. This would be needed in the case of a two IDE disks system, with the second IDE hardwired to wd2 instead of wd1. .Pp .Bd -literal -offset indent -compact set root_disk_unit=2 boot /kernel .Ed .Pp See also: .Bl -tag -width /usr/share/examples/bootforth/X .It Pa /boot/loader.4th Extra builtin-like words. .It Pa /boot/support.4th .Pa loader.conf processing words. .It Pa /usr/share/examples/bootforth/ Assorted examples. .El .Sh ERRORS The following values are thrown by .Nm : .Bl -tag -width XXXXX -offset indent .It 100 Any type of error in the processing of a builtin. .It -1 .Ic Abort executed. .It -2 .Ic Abort" executed. .It -56 .Ic Quit executed. .It -256 Out of interpreting text. .It -257 Need more text to succeed -- will finish on next run. .It -258 .Ic Bye executed. .It -259 Unspecified error. .El .Sh SEE ALSO .Xr libstand 3 , .Xr loader.conf 5 , .Xr boot 8 , .Xr btxld 8 .Sh STANDARDS For the purposes of ANS Forth compliance, loader is an .Bf Em ANS Forth System with Environmental Restrictions, Providing .Ef .Bf Li .No .( , .No :noname , .No ?do , parse, pick, roll, refill, to, value, \e, false, true, .No <> , .No 0<> , compile\&, , erase, nip, tuck .Ef .Em and .Li marker .Bf Em from the Core Extensions word set, Providing the Exception Extensions word set, Providing the Locals Extensions word set, Providing the Memory-Allocation Extensions word set, Providing .Ef .Bf Li \&.s , bye, forget, see, words, \&[if] , \&[else] .Ef .Em and .Li No [then] .Bf Em from the Programming-Tools extension word set, Providing the Search-Order extensions word set. .Ef .Sh HISTORY .Nm first appeared in .Fx 3.1 . .Sh AUTHORS .Bl -item .It .Nm was written by .An Michael Smith Aq msmisth@freebsd.org . .It .Tn FICL was written by .An John Sadler Aq john_sadler@alum.mit.edu . .El .Sh BUGS .Tn FICL is case sensitive. Though this is not a standard violation, all Forth words are lower cased, which would result in a standard violation. Do not rely on this bug. .Pp The .Ic expect and .Ic accept words will read from the input buffer instead of the console. The later will be fixed, but the former will not. Index: head/sys/kern/init_main.c =================================================================== --- head/sys/kern/init_main.c (revision 45880) +++ head/sys/kern/init_main.c (revision 45881) @@ -1,689 +1,702 @@ /* * Copyright (c) 1995 Terrence R. Lambert * All rights reserved. * * Copyright (c) 1982, 1986, 1989, 1991, 1992, 1993 * The Regents of the University of California. All rights reserved. * (c) UNIX System Laboratories, Inc. * All or some portions of this file are derived from material licensed * to the University of California by American Telephone and Telegraph * Co. or Unix System Laboratories, Inc. and are reproduced herein with * the permission of UNIX System Laboratories, Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)init_main.c 8.9 (Berkeley) 1/21/94 - * $Id: init_main.c,v 1.110 1999/02/25 11:03:08 bde Exp $ + * $Id: init_main.c,v 1.111 1999/02/28 10:53:29 bde Exp $ */ #include "opt_devfs.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include extern struct linker_set sysinit_set; /* XXX */ extern void __main __P((void)); extern void main __P((void *framep)); /* Components of the first process -- never freed. */ static struct session session0; static struct pgrp pgrp0; struct proc proc0; static struct pcred cred0; static struct procsig procsig0; static struct filedesc0 filedesc0; static struct plimit limit0; static struct vmspace vmspace0; struct proc *initproc; int cmask = CMASK; extern struct user *proc0paddr; struct vnode *rootvp; int boothowto = 0; /* initialized so that it can be patched */ struct timeval boottime; SYSCTL_STRUCT(_kern, KERN_BOOTTIME, boottime, CTLFLAG_RD, &boottime, timeval, ""); /* * Promiscuous argument pass for start_init() * * This is a kludge because we use a return from main() rather than a call * to a new routine in locore.s to kick the kernel alive from locore.s. */ static void *init_framep; #if __GNUC__ >= 2 void __main() {} #endif /* * This ensures that there is at least one entry so that the sysinit_set * symbol is not undefined. A sybsystem ID of SI_SUB_DUMMY is never * executed. */ SYSINIT(placeholder, SI_SUB_DUMMY,SI_ORDER_ANY, NULL, NULL) /* * The sysinit table itself. Items are checked off as the are run. * If we want to register new sysinit types, add them to newsysinit. */ struct sysinit **sysinit = (struct sysinit **)sysinit_set.ls_items; struct sysinit **newsysinit; /* * Merge a new sysinit set into the current set, reallocating it if * necessary. This can only be called after malloc is running. */ void sysinit_add(set) struct sysinit **set; { struct sysinit **newset; struct sysinit **sipp; struct sysinit **xipp; int count = 0; if (newsysinit) for (sipp = newsysinit; *sipp; sipp++) count++; else for (sipp = sysinit; *sipp; sipp++) count++; for (sipp = set; *sipp; sipp++) count++; count++; /* Trailing NULL */ newset = malloc(count * sizeof(*sipp), M_TEMP, M_NOWAIT); if (newset == NULL) panic("cannot malloc for sysinit"); xipp = newset; if (newsysinit) for (sipp = newsysinit; *sipp; sipp++) *xipp++ = *sipp; else for (sipp = sysinit; *sipp; sipp++) *xipp++ = *sipp; for (sipp = set; *sipp; sipp++) *xipp++ = *sipp; *xipp = NULL; if (newsysinit) free(newsysinit, M_TEMP); newsysinit = newset; } /* * System startup; initialize the world, create process 0, mount root * filesystem, and fork to create init and pagedaemon. Most of the * hard work is done in the lower-level initialization routines including * startup(), which does memory initialization and autoconfiguration. * * This allows simple addition of new kernel subsystems that require * boot time initialization. It also allows substitution of subsystem * (for instance, a scheduler, kernel profiler, or VM system) by object * module. Finally, it allows for optional "kernel threads". */ void main(framep) void *framep; { register struct sysinit **sipp; /* system initialization*/ register struct sysinit **xipp; /* interior loop of sort*/ register struct sysinit *save; /* bubble*/ /* * Copy the locore.s frame pointer for proc0, this is forked into * all other processes. */ init_framep = framep; restart: /* * Perform a bubble sort of the system initialization objects by * their subsystem (primary key) and order (secondary key). */ for (sipp = sysinit; *sipp; sipp++) { for (xipp = sipp + 1; *xipp; xipp++) { if ((*sipp)->subsystem < (*xipp)->subsystem || ((*sipp)->subsystem == (*xipp)->subsystem && (*sipp)->order < (*xipp)->order)) continue; /* skip*/ save = *sipp; *sipp = *xipp; *xipp = save; } } /* * Traverse the (now) ordered list of system initialization tasks. * Perform each task, and continue on to the next task. * * The last item on the list is expected to be the scheduler, * which will not return. */ for (sipp = sysinit; *sipp; sipp++) { if ((*sipp)->subsystem == SI_SUB_DUMMY) continue; /* skip dummy task(s)*/ if ((*sipp)->subsystem == SI_SUB_DONE) continue; switch( (*sipp)->type) { case SI_TYPE_DEFAULT: /* no special processing*/ (*((*sipp)->func))((*sipp)->udata); break; case SI_TYPE_KTHREAD: #if !defined(SMP) /* kernel thread*/ if (fork1(&proc0, RFMEM|RFFDG|RFPROC)) panic("fork kernel thread"); cpu_set_fork_handler(pfind(proc0.p_retval[0]), (*sipp)->func, (*sipp)->udata); break; #endif case SI_TYPE_KPROCESS: if (fork1(&proc0, RFFDG|RFPROC)) panic("fork kernel process"); cpu_set_fork_handler(pfind(proc0.p_retval[0]), (*sipp)->func, (*sipp)->udata); break; default: panic("init_main: unrecognized init type"); } /* Check off the one we're just done */ (*sipp)->subsystem = SI_SUB_DONE; /* Check if we've installed more sysinit items via KLD */ if (newsysinit != NULL) { if (sysinit != (struct sysinit **)sysinit_set.ls_items) free(sysinit, M_TEMP); sysinit = newsysinit; newsysinit = NULL; goto restart; } } panic("Shouldn't get here!"); /* NOTREACHED*/ } /* * Start a kernel process. This is called after a fork() call in * main() in the file kern/init_main.c. * * This function is used to start "internal" daemons. */ /* ARGSUSED*/ void kproc_start(udata) const void *udata; { const struct kproc_desc *kp = udata; struct proc *p = curproc; #ifdef DIAGNOSTIC printf("Start pid=%d <%s>\n",p->p_pid, kp->arg0); #endif /* save a global descriptor, if desired*/ if( kp->global_procpp != NULL) *kp->global_procpp = p; /* this is a non-swapped system process*/ p->p_flag |= P_INMEM | P_SYSTEM; /* set up arg0 for 'ps', et al*/ strcpy( p->p_comm, kp->arg0); /* call the processes' main()...*/ (*kp->func)(); /* NOTREACHED */ panic("kproc_start: %s", kp->arg0); } /* *************************************************************************** **** **** The following SYSINIT's belong elsewhere, but have not yet **** been moved. **** *************************************************************************** */ #ifdef OMIT /* * Handled by vfs_mountroot (bad idea) at this time... should be * done the same as 4.4Lite2. */ SYSINIT(swapinit, SI_SUB_SWAP, SI_ORDER_FIRST, swapinit, NULL) #endif /* OMIT*/ static void print_caddr_t __P((void *data)); static void print_caddr_t(data) void *data; { printf("%s", (char *)data); } SYSINIT(announce, SI_SUB_COPYRIGHT, SI_ORDER_FIRST, print_caddr_t, copyright) /* *************************************************************************** **** **** The two following SYSINT's are proc0 specific glue code. I am not **** convinced that they can not be safely combined, but their order of **** operation has been maintained as the same as the original init_main.c **** for right now. **** **** These probably belong in init_proc.c or kern_proc.c, since they **** deal with proc0 (the fork template process). **** *************************************************************************** */ /* ARGSUSED*/ static void proc0_init __P((void *dummy)); static void proc0_init(dummy) void *dummy; { register struct proc *p; register struct filedesc0 *fdp; register unsigned i; /* * Initialize the current process pointer (curproc) before * any possible traps/probes to simplify trap processing. */ p = &proc0; curproc = p; /* XXX redundant*/ /* * Initialize process and pgrp structures. */ procinit(); /* * Initialize sleep queue hash table */ sleepinit(); /* * additional VM structures */ vm_init2(); /* * Create process 0 (the swapper). */ LIST_INSERT_HEAD(&allproc, p, p_list); p->p_pgrp = &pgrp0; LIST_INSERT_HEAD(PGRPHASH(0), &pgrp0, pg_hash); LIST_INIT(&pgrp0.pg_members); LIST_INSERT_HEAD(&pgrp0.pg_members, p, p_pglist); pgrp0.pg_session = &session0; session0.s_count = 1; session0.s_leader = p; p->p_sysent = &aout_sysvec; p->p_flag = P_INMEM | P_SYSTEM; p->p_stat = SRUN; p->p_nice = NZERO; p->p_rtprio.type = RTP_PRIO_NORMAL; p->p_rtprio.prio = 0; /* * Link for kernel based threads */ p->p_peers = 0; p->p_leader = p; bcopy("swapper", p->p_comm, sizeof ("swapper")); /* Create credentials. */ cred0.p_refcnt = 1; p->p_cred = &cred0; p->p_ucred = crget(); p->p_ucred->cr_ngroups = 1; /* group 0 */ /* Create procsig. */ p->p_procsig = &procsig0; p->p_procsig->ps_refcnt = 1; /* Create the file descriptor table. */ fdp = &filedesc0; p->p_fd = &fdp->fd_fd; fdp->fd_fd.fd_refcnt = 1; fdp->fd_fd.fd_cmask = cmask; fdp->fd_fd.fd_ofiles = fdp->fd_dfiles; fdp->fd_fd.fd_ofileflags = fdp->fd_dfileflags; fdp->fd_fd.fd_nfiles = NDFILE; /* Create the limits structures. */ p->p_limit = &limit0; for (i = 0; i < sizeof(p->p_rlimit)/sizeof(p->p_rlimit[0]); i++) limit0.pl_rlimit[i].rlim_cur = limit0.pl_rlimit[i].rlim_max = RLIM_INFINITY; limit0.pl_rlimit[RLIMIT_NOFILE].rlim_cur = limit0.pl_rlimit[RLIMIT_NOFILE].rlim_max = maxfiles; limit0.pl_rlimit[RLIMIT_NPROC].rlim_cur = limit0.pl_rlimit[RLIMIT_NPROC].rlim_max = maxproc; i = ptoa(cnt.v_free_count); limit0.pl_rlimit[RLIMIT_RSS].rlim_max = i; limit0.pl_rlimit[RLIMIT_MEMLOCK].rlim_max = i; limit0.pl_rlimit[RLIMIT_MEMLOCK].rlim_cur = i / 3; limit0.p_cpulimit = RLIM_INFINITY; limit0.p_refcnt = 1; /* Allocate a prototype map so we have something to fork. */ pmap_pinit0(vmspace_pmap(&vmspace0)); p->p_vmspace = &vmspace0; vmspace0.vm_refcnt = 1; vm_map_init(&vmspace0.vm_map, round_page(VM_MIN_ADDRESS), trunc_page(VM_MAXUSER_ADDRESS)); vmspace0.vm_map.pmap = vmspace_pmap(&vmspace0); p->p_addr = proc0paddr; /* XXX */ #ifndef __alpha__ /* XXX what is this? */ #define INCOMPAT_LITES2 #ifdef INCOMPAT_LITES2 /* * proc0 needs to have a coherent frame base in its stack. */ cpu_set_init_frame(p, init_framep); /* XXX! */ #endif /* INCOMPAT_LITES2*/ #endif /* * We continue to place resource usage info and signal * actions in the user struct so they're pageable. */ p->p_stats = &p->p_addr->u_stats; p->p_sigacts = &p->p_addr->u_sigacts; /* * Charge root for one process. */ (void)chgproccnt(0, 1); /* * Initialize the procfs flags (to 0, of course) */ p->p_stops = p->p_stype = p->p_step = 0; } SYSINIT(p0init, SI_SUB_INTRINSIC, SI_ORDER_FIRST, proc0_init, NULL) /* ARGSUSED*/ static void proc0_post __P((void *dummy)); static void proc0_post(dummy) void *dummy; { struct timespec ts; /* * Now we can look at the time, having had a chance to verify the * time from the file system. Pretend that proc0 started now. */ microtime(&proc0.p_stats->p_start); proc0.p_runtime = 0; microuptime(&switchtime); switchticks = ticks; /* * Give the ``random'' number generator a thump. * XXX: Does read_random() contain enough bits to be used here ? */ nanotime(&ts); srandom(ts.tv_sec ^ ts.tv_nsec); /* Initialize signal state for process 0. */ siginit(&proc0); } SYSINIT(p0post, SI_SUB_INTRINSIC_POST, SI_ORDER_FIRST, proc0_post, NULL) /* *************************************************************************** **** **** The following SYSINIT's and glue code should be moved to the **** respective files on a per subsystem basis. **** *************************************************************************** */ /* ARGSUSED */ static void root_conf __P((void *dummy)); static void root_conf(dummy) void *dummy; { cpu_rootconf(); } SYSINIT(root_conf, SI_SUB_ROOT_CONF, SI_ORDER_FIRST, root_conf, NULL) /* ARGSUSED*/ static void xxx_vfs_root_fdtab __P((void *dummy)); static void xxx_vfs_root_fdtab(dummy) void *dummy; { register struct filedesc0 *fdp = &filedesc0; /* Get the vnode for '/'. Set fdp->fd_fd.fd_cdir to reference it. */ if (VFS_ROOT(mountlist.cqh_first, &rootvnode)) panic("cannot find root vnode"); fdp->fd_fd.fd_cdir = rootvnode; VREF(fdp->fd_fd.fd_cdir); VOP_UNLOCK(rootvnode, 0, &proc0); fdp->fd_fd.fd_rdir = rootvnode; } SYSINIT(retrofit, SI_SUB_ROOT_FDTAB, SI_ORDER_FIRST, xxx_vfs_root_fdtab, NULL) /* *************************************************************************** **** **** The following code probably belongs in another file, like **** kern/init_init.c. It is here for two reasons only: **** **** 1) This code returns to startup the system; this is **** abnormal for a kernel thread. **** 2) This code promiscuously uses init_frame **** *************************************************************************** */ static void kthread_init __P((const void *dummy)); SYSINIT_KP(init,SI_SUB_KTHREAD_INIT, SI_ORDER_FIRST, kthread_init, NULL) extern void prepare_usermode __P((void)); static void start_init __P((struct proc *p)); /* ARGSUSED*/ static void kthread_init(dummy) const void *dummy; { /* Create process 1 (init(8)). */ start_init(curproc); prepare_usermode(); /* * This returns to the fork trampoline, then to user mode. */ return; } /* * List of paths to try when searching for "init". */ -static char *initpaths[] = { - "/sbin/init", - "/sbin/oinit", - "/sbin/init.bak", - "/stand/sysinstall", - NULL, -}; +static char init_path[MAXPATHLEN] = + "/sbin/init;/sbin/oinit;/sbin/init.bak;/stand/sysinstall"; +SYSCTL_STRING(_kern, OID_AUTO, init_path, CTLFLAG_RD, init_path, 0, ""); /* - * Start the initial user process; try exec'ing each pathname in "initpaths". + * Start the initial user process; try exec'ing each pathname in init_path. * The program is invoked with one argument containing the boot flags. */ static void start_init(p) struct proc *p; { vm_offset_t addr; struct execve_args args; - int options, i, error; - char **pathp, *path, *ucp, **uap, *arg0, *arg1; + int options, error; + char *var, *path, *next, *s; + char *ucp, **uap, *arg0, *arg1; initproc = p; /* * Need just enough stack to hold the faked-up "execve()" arguments. */ addr = trunc_page(USRSTACK - PAGE_SIZE); - if (vm_map_find(&p->p_vmspace->vm_map, NULL, 0, &addr, PAGE_SIZE, FALSE, VM_PROT_ALL, VM_PROT_ALL, 0) != 0) + if (vm_map_find(&p->p_vmspace->vm_map, NULL, 0, &addr, PAGE_SIZE, + FALSE, VM_PROT_ALL, VM_PROT_ALL, 0) != 0) panic("init: couldn't allocate argument space"); p->p_vmspace->vm_maxsaddr = (caddr_t)addr; p->p_vmspace->vm_ssize = 1; - for (pathp = &initpaths[0]; (path = *pathp) != NULL; pathp++) { + if ((var = getenv("init_path")) != NULL) { + strncpy(init_path, var, MAXPATHLEN); + init_path[sizeof init_path - 1] = 0; + } + + for (path = init_path; path != '\0'; path = next) { + while (*path == ';') + path++; + if (path == '\0') + break; + for (next = path; *next != '\0' && *next != ';'; next++) + /* nothing */ ; + if (bootverbose) + printf("start_init: trying %.*s\n", next-path, path); + /* * Move out the boot flag argument. */ options = 0; ucp = (char *)USRSTACK; (void)subyte(--ucp, 0); /* trailing zero */ if (boothowto & RB_SINGLE) { (void)subyte(--ucp, 's'); options = 1; } #ifdef notyet if (boothowto & RB_FASTBOOT) { (void)subyte(--ucp, 'f'); options = 1; } #endif #ifdef BOOTCDROM (void)subyte(--ucp, 'C'); options = 1; #endif if (options == 0) (void)subyte(--ucp, '-'); (void)subyte(--ucp, '-'); /* leading hyphen */ arg1 = ucp; /* * Move out the file name (also arg 0). */ - for (i = strlen(path) + 1; i >= 0; i--) - (void)subyte(--ucp, path[i]); + (void)subyte(--ucp, 0); + for (s = next - 1; s >= path; s--) + (void)subyte(--ucp, *s); arg0 = ucp; /* * Move out the arg pointers. */ uap = (char **)((intptr_t)ucp & ~(sizeof(intptr_t)-1)); (void)suword((caddr_t)--uap, (long)0); /* terminator */ (void)suword((caddr_t)--uap, (long)(intptr_t)arg1); (void)suword((caddr_t)--uap, (long)(intptr_t)arg0); /* * Point at the arguments. */ args.fname = arg0; args.argv = uap; args.envv = NULL; /* * Now try to exec the program. If can't for any reason * other than it doesn't exist, complain. * * Otherwise return to main() which returns to btext * which completes the system startup. */ if ((error = execve(p, &args)) == 0) return; if (error != ENOENT) - printf("exec %s: error %d\n", path, error); + printf("exec %.*s: error %d\n", next-path, path, error); } printf("init: not found\n"); panic("no init"); }