1.\" 2.\" SPDX-License-Identifier: BSD-2-Clause 3.\" 4.\" Copyright (c) 1999 Daniel C. Sobral 5.\" All rights reserved. 6.\" 7.\" Redistribution and use in source and binary forms, with or without 8.\" modification, are permitted provided that the following conditions 9.\" are met: 10.\" 1. Redistributions of source code must retain the above copyright 11.\" notice, this list of conditions and the following disclaimer. 12.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" notice, this list of conditions and the following disclaimer in the 14.\" documentation and/or other materials provided with the distribution. 15.\" 16.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26.\" SUCH DAMAGE. 27.\" 28.Dd September 29, 2021 29.Dt LOADER_4TH 8 30.Os 31.Sh NAME 32.Nm loader_4th 33.Nd kernel bootstrapping final stage 34.Sh DESCRIPTION 35The program called 36.Nm 37is the final stage of 38.Fx Ns 's 39kernel bootstrapping process. 40On IA32 (i386) architectures, it is a 41.Pa BTX 42client. 43It is linked statically to 44.Xr libsa 3 45and usually located in the directory 46.Pa /boot . 47.Pp 48It provides a scripting language that can be used to 49automate tasks, do pre-configuration or assist in recovery 50procedures. 51This scripting language is roughly divided in 52two main components. 53The smaller one is a set of commands 54designed for direct use by the casual user, called "builtin 55commands" for historical reasons. 56The main drive behind these commands is user-friendliness. 57The bigger component is an 58.Tn ANS 59Forth compatible Forth interpreter based on FICL, by 60.An John Sadler . 61.Pp 62During initialization, 63.Nm 64will probe for a console and set the 65.Va console 66variable, or set it to serial console 67.Pq Dq Li comconsole 68if the previous boot stage used that. 69If multiple consoles are selected, they will be listed separated by spaces. 70Then, devices are probed, 71.Va currdev 72and 73.Va loaddev 74are set, and 75.Va LINES 76is set to 24. 77Next, 78.Tn FICL 79is initialized, the builtin words are added to its vocabulary, and 80.Pa /boot/boot.4th 81is processed if it exists. 82No disk switching is possible while that file is being read. 83The inner interpreter 84.Nm 85will use with 86.Tn FICL 87is then set to 88.Ic interpret , 89which is 90.Tn FICL Ns 's 91default. 92After that, 93.Pa /boot/loader.rc 94is processed if available. 95These files are processed through the 96.Ic include 97command, which reads all of them into memory before processing them, 98making disk changes possible. 99.Pp 100At this point, if an 101.Ic autoboot 102has not been tried, and if 103.Va autoboot_delay 104is not set to 105.Dq Li NO 106(not case sensitive), then an 107.Ic autoboot 108will be tried. 109If the system gets past this point, 110.Va prompt 111will be set and 112.Nm 113will engage interactive mode. 114Please note that historically even when 115.Va autoboot_delay 116is set to 117.Dq Li 0 118user will be able to interrupt autoboot process by pressing some key 119on the console while kernel and modules are being loaded. 120In some 121cases such behaviour may be undesirable, to prevent it set 122.Va autoboot_delay 123to 124.Dq Li -1 , 125in this case 126.Nm 127will engage interactive mode only if 128.Ic autoboot 129has failed. 130.Sh BUILTIN COMMANDS 131In 132.Nm , 133builtin commands take parameters from the command line. 134Presently, 135the only way to call them from a script is by using 136.Pa evaluate 137on a string. 138If an error condition occurs, an exception will be generated, 139which can be intercepted using 140.Tn ANS 141Forth exception handling 142words. 143If not intercepted, an error message will be displayed and 144the interpreter's state will be reset, emptying the stack and restoring 145interpreting mode. 146The commands are described in the 147.Xr loader_simp 8 148.Dq BUILTIN COMMANDS 149section. 150.Ss BUILTIN ENVIRONMENT VARIABLES 151The environment variables common to all interpreters are described in the 152.Xr loader_simp 8 153.Dq BUILTIN ENVIRONMENT VARIABLES 154section. 155.Ss BUILTIN PARSER 156When a builtin command is executed, the rest of the line is taken 157by it as arguments, and it is processed by a special parser which 158is not used for regular Forth commands. 159.Pp 160This special parser applies the following rules to the parsed text: 161.Bl -enum 162.It 163All backslash characters are preprocessed. 164.Bl -bullet 165.It 166\eb , \ef , \er , \en and \et are processed as in C. 167.It 168\es is converted to a space. 169.It 170\ev is converted to 171.Tn ASCII 17211. 173.It 174\ez is just skipped. 175Useful for things like 176.Dq \e0xf\ez\e0xf . 177.It 178\e0xN and \e0xNN are replaced by the hex N or NN. 179.It 180\eNNN is replaced by the octal NNN 181.Tn ASCII 182character. 183.It 184\e" , \e' and \e$ will escape these characters, preventing them from 185receiving special treatment in Step 2, described below. 186.It 187\e\e will be replaced with a single \e . 188.It 189In any other occurrence, backslash will just be removed. 190.El 191.It 192Every string between non-escaped quotes or double-quotes will be treated 193as a single word for the purposes of the remaining steps. 194.It 195Replace any 196.Li $VARIABLE 197or 198.Li ${VARIABLE} 199with the value of the environment variable 200.Va VARIABLE . 201.It 202Space-delimited arguments are passed to the called builtin command. 203Spaces can also be escaped through the use of \e\e . 204.El 205.Pp 206An exception to this parsing rule exists, and is described in 207.Sx BUILTINS AND FORTH . 208.Ss BUILTINS AND FORTH 209All builtin words are state-smart, immediate words. 210If interpreted, they behave exactly as described previously. 211If they are compiled, though, 212they extract their arguments from the stack instead of the command line. 213.Pp 214If compiled, the builtin words expect to find, at execution time, the 215following parameters on the stack: 216.D1 Ar addrN lenN ... addr2 len2 addr1 len1 N 217where 218.Ar addrX lenX 219are strings which will compose the command line that will be parsed 220into the builtin's arguments. 221Internally, these strings are concatenated in from 1 to N, 222with a space put between each one. 223.Pp 224If no arguments are passed, a 0 225.Em must 226be passed, even if the builtin accepts no arguments. 227.Pp 228While this behavior has benefits, it has its trade-offs. 229If the execution token of a builtin is acquired (through 230.Ic ' 231or 232.Ic ['] ) , 233and then passed to 234.Ic catch 235or 236.Ic execute , 237the builtin behavior will depend on the system state 238.Bf Em 239at the time 240.Ic catch 241or 242.Ic execute 243is processed! 244.Ef 245This is particularly annoying for programs that want or need to 246handle exceptions. 247In this case, the use of a proxy is recommended. 248For example: 249.Dl : (boot) boot ; 250.Sh FICL 251.Tn FICL 252is a Forth interpreter written in C, in the form of a forth 253virtual machine library that can be called by C functions and vice 254versa. 255.Pp 256In 257.Nm , 258each line read interactively is then fed to 259.Tn FICL , 260which may call 261.Nm 262back to execute the builtin words. 263The builtin 264.Ic include 265will also feed 266.Tn FICL , 267one line at a time. 268.Pp 269The words available to 270.Tn FICL 271can be classified into four groups. 272The 273.Tn ANS 274Forth standard words, extra 275.Tn FICL 276words, extra 277.Fx 278words, and the builtin commands; 279the latter were already described. 280The 281.Tn ANS 282Forth standard words are listed in the 283.Sx STANDARDS 284section. 285The words falling in the two other groups are described in the 286following subsections. 287.Ss FICL EXTRA WORDS 288.Bl -tag -width wid-set-super 289.It Ic .env 290.It Ic .ver 291.It Ic -roll 292.It Ic 2constant 293.It Ic >name 294.It Ic body> 295.It Ic compare 296This is the STRING word set's 297.Ic compare . 298.It Ic compile-only 299.It Ic endif 300.It Ic forget-wid 301.It Ic parse-word 302.It Ic sliteral 303This is the STRING word set's 304.Ic sliteral . 305.It Ic wid-set-super 306.It Ic w@ 307.It Ic w! 308.It Ic x. 309.It Ic empty 310.It Ic cell- 311.It Ic -rot 312.El 313.Ss FREEBSD EXTRA WORDS 314.Bl -tag -width XXXXXXXX 315.It Ic \&$ Pq -- 316Evaluates the remainder of the input buffer, after having printed it first. 317.It Ic \&% Pq -- 318Evaluates the remainder of the input buffer under a 319.Ic catch 320exception guard. 321.It Ic .# 322Works like 323.Ic "." 324but without outputting a trailing space. 325.It Ic fclose Pq Ar fd -- 326Closes a file. 327.It Ic fkey Pq Ar fd -- char 328Reads a single character from a file. 329.It Ic fload Pq Ar fd -- 330Processes a file 331.Em fd . 332.It Ic fopen Pq Ar addr len mode Li -- Ar fd 333Opens a file. 334Returns a file descriptor, or \-1 in case of failure. 335The 336.Ar mode 337parameter selects whether the file is to be opened for read access, write 338access, or both. 339The constants 340.Dv O_RDONLY , O_WRONLY , 341and 342.Dv O_RDWR 343are defined in 344.Pa /boot/support.4th , 345indicating read only, write only, and read-write access, respectively. 346.It Xo 347.Ic fread 348.Pq Ar fd addr len -- len' 349.Xc 350Tries to read 351.Em len 352bytes from file 353.Em fd 354into buffer 355.Em addr . 356Returns the actual number of bytes read, or -1 in case of error or end of 357file. 358.It Ic heap? Pq -- Ar cells 359Return the space remaining in the dictionary heap, in cells. 360This is not related to the heap used by dynamic memory allocation words. 361.It Ic inb Pq Ar port -- char 362Reads a byte from a port. 363.It Ic key Pq -- Ar char 364Reads a single character from the console. 365.It Ic key? Pq -- Ar flag 366Returns 367.Ic true 368if there is a character available to be read from the console. 369.It Ic ms Pq Ar u -- 370Waits 371.Em u 372microseconds. 373.It Ic outb Pq Ar port char -- 374Writes a byte to a port. 375.It Ic seconds Pq -- Ar u 376Returns the number of seconds since midnight. 377.It Ic tib> Pq -- Ar addr len 378Returns the remainder of the input buffer as a string on the stack. 379.It Ic trace! Pq Ar flag -- 380Activates or deactivates tracing. 381Does not work with 382.Ic catch . 383.El 384.Ss FREEBSD DEFINED ENVIRONMENTAL QUERIES 385.Bl -tag -width Ds 386.It arch-i386 387.Ic TRUE 388if the architecture is IA32. 389.It FreeBSD_version 390.Fx 391version at compile time. 392.It loader_version 393.Nm 394version. 395.El 396.Sh SECURITY 397Access to the 398.Nm 399command line provides several ways of compromising system security, 400including, but not limited to: 401.Pp 402.Bl -bullet 403.It 404Booting from removable storage, by setting the 405.Va currdev 406or 407.Va loaddev 408variables 409.It 410Executing binary of choice, by setting the 411.Va init_path 412or 413.Va init_script 414variables 415.It 416Overriding ACPI DSDT to inject arbitrary code into the ACPI subsystem 417.El 418.Pp 419One can prevent unauthorized access 420to the 421.Nm 422command line by setting the 423.Va password , 424or setting 425.Va autoboot_delay 426to -1. 427See 428.Xr loader.conf 5 429for details. 430In order for this to be effective, one should also configure the firmware 431(BIOS or UEFI) to prevent booting from unauthorized devices. 432.Sh MD 433Memory disk (MD) can be used when the 434.Nm 435was compiled with 436.Va MD_IMAGE_SIZE . 437The size of the memory disk is determined by 438.Va MD_IMAGE_SIZE . 439If MD available, a file system can be embedded into the 440.Nm 441with 442.Pa /sys/tools/embed_mfs.sh . 443Then, MD will be probed and be set to 444.Va currdev 445during initialization. 446.Pp 447Currently, MD is only supported in 448.Xr loader.efi 8 . 449.Sh FILES 450.Bl -tag -width /usr/share/examples/bootforth/ -compact 451.It Pa /boot/loader 452.Nm 453itself. 454.It Pa /boot/boot.4th 455Additional 456.Tn FICL 457initialization. 458.It Pa /boot/defaults/loader.conf 459.It Pa /boot/loader.4th 460Extra builtin-like words. 461.It Pa /boot/loader.conf 462.It Pa /boot/loader.conf.local 463.Nm 464configuration files, as described in 465.Xr loader.conf 5 . 466.It Pa /boot/loader.rc 467.Nm 468bootstrapping script. 469.It Pa /boot/loader.help 470Loaded by 471.Ic help . 472Contains the help messages. 473.It Pa /boot/support.4th 474.Pa loader.conf 475processing words. 476.It Pa /usr/share/examples/bootforth/ 477Assorted examples. 478.El 479.Sh EXAMPLES 480Boot in single user mode: 481.Pp 482.Dl boot -s 483.Pp 484Load the kernel, a splash screen, and then autoboot in five seconds. 485Notice that a kernel must be loaded before any other 486.Ic load 487command is attempted. 488.Bd -literal -offset indent 489load kernel 490load splash_bmp 491load -t splash_image_data /boot/chuckrulez.bmp 492autoboot 5 493.Ed 494.Pp 495Set the disk unit of the root device to 2, and then boot. 496This would be needed in a system with two IDE disks, 497with the second IDE disk hardwired to ada2 instead of ada1. 498.Bd -literal -offset indent 499set root_disk_unit=2 500boot /boot/kernel/kernel 501.Ed 502.Pp 503Set the default device used for loading a kernel from a ZFS filesystem: 504.Bd -literal -offset indent 505set currdev=zfs:tank/ROOT/knowngood: 506.Ed 507.Pp 508.Sh ERRORS 509The following values are thrown by 510.Nm : 511.Bl -tag -width XXXXX -offset indent 512.It 100 513Any type of error in the processing of a builtin. 514.It -1 515.Ic Abort 516executed. 517.It -2 518.Ic Abort" 519executed. 520.It -56 521.Ic Quit 522executed. 523.It -256 524Out of interpreting text. 525.It -257 526Need more text to succeed -- will finish on next run. 527.It -258 528.Ic Bye 529executed. 530.It -259 531Unspecified error. 532.El 533.Sh SEE ALSO 534.Xr libsa 3 , 535.Xr loader.conf 5 , 536.Xr tuning 7 , 537.Xr boot 8 , 538.Xr btxld 8 539.Sh STANDARDS 540For the purposes of ANS Forth compliance, loader is an 541.Bf Em 542ANS Forth System with Environmental Restrictions, Providing 543.Ef 544.Bf Li 545.No .( , 546.No :noname , 547.No ?do , 548parse, pick, roll, refill, to, value, \e, false, true, 549.No <> , 550.No 0<> , 551compile\&, , erase, nip, tuck 552.Ef 553.Em and 554.Li marker 555.Bf Em 556from the Core Extensions word set, Providing the Exception Extensions 557word set, Providing the Locals Extensions word set, Providing the 558Memory-Allocation Extensions word set, Providing 559.Ef 560.Bf Li 561\&.s, 562bye, forget, see, words, 563\&[if], 564\&[else] 565.Ef 566.Em and 567.Li [then] 568.Bf Em 569from the Programming-Tools extension word set, Providing the 570Search-Order extensions word set. 571.Ef 572.Sh HISTORY 573The 574.Nm 575first appeared in 576.Fx 3.1 . 577.Sh AUTHORS 578.An -nosplit 579The 580.Nm 581was written by 582.An Michael Smith Aq Mt msmith@FreeBSD.org . 583.Pp 584.Tn FICL 585was written by 586.An John Sadler Aq Mt john_sadler@alum.mit.edu . 587