flowchart TD
A[setroot Start] --> B{md_is_root?}
B -->|Yes| C[setroot_md]
B -->|No| D{TFTPROOT defined?}
D -->|Yes| E[tftproot_dhcpboot]
E -->|Success| C[setroot_md]
C --> G
D -->|No| G[setroot_nfs]
E -->|Failure| G
G --> H{rootspec == NULL & bootdv == NULL?}
H -->|Yes| I[Set RB_ASKNAME]
H -->|No| J
I --> J{Root Device Loop}
J -->|RB_ASKNAME set| K[setroot_ask]
K --> |root_device==NULL| J
J -->|RB_ASKNAME not set| L[setroot_root]
L --> N[Sleep 1 sec]
L -->|root_device == NULL| M{Wait timeout?}
%%M -->|No| N[Sleep 1 sec]
N --> M
M -->|No| J
M -->|Yes| I
%%N --> L
%%setroot_root -> sleep 1 sec -> if no timeout -> root device loop else -> set rb_askname
%%[Tuesday, November 5, 2024] [11:37:43 PM IST] <good> and setroot_ask if root_device == NULL -> root device loop
K --> P[Configure root_device]
L -->|root_device found| P
P --> Q[setroot_dump]
Q --> R[End]
During a system boot up, based on kernel Config file, system mounts root filesystem. This is handled by setroot function in kern_subr.c. device and partition are defined with syntax
config netbsd root on XXX_device type XXX
device name with partition is loaded onto rootspec variable which is used by setroot and associated functions to select a device. device can also be a network device in that case a valid interface name should be specified. if instead of a device ‘ ? ‘ is specified, setroot uses boot device(from bootspec) as root device. Boot device is set by findroot function. Findroot is machine dependent. x86/x86_autoconf.c contains function which interact with BIOS entries to configure boot spec variable. it also has different cases for different device type Christoph badura’s documentation.
setroot()
: Main entry point that orchestrates root device selectionsetroot_nfs()
: Handles NFS root configurationsetroot_md()
: Sets up memory disk as root devicesetroot_ask()
: Interactive root device configurationsetroot_root()
: core root device configurationsetroot_dump()
: Configures dump deviceb) Device Selection:
c) Interactive Configuration (setroot_ask
):
b) Filesystem Support:
c) Dump Device Configuration:
rootdev
: Device number for root devicedumpdev
: Device number for dump devicedumpcdev
: Character device for dumpsroot_device
: Device structure for root devicebooted_device
: Device through which system booted. Obtained through BIOS entriesrootspec
: Specification for root device from config filebootspec
: Boot device specificationb) Memory Disk:
md_is_root
is set.md0
device if needed.c) Dump Device Selection:
sets parameter device to md device of name “md0” , after reading the block device.
The tftproot_dhcpboot
is to set up a root filesystem for the device using TFTP (Trivial File Transfer Protocol) over NFS (Network File System) based on DHCP (Dynamic Host Configuration Protocol) information.
tftproot_dhcpboot
takes a device_t
type argument bootdv
(a device pointer to the boot device).nd
(NFS diskless information), ifp
(network interface), trh
(a TFTP root handle), and error
(initially set to -1, which indicates failure if nothing is done).rootspec
is non-NULL (indicating a specific network interface was given for booting), the function iterates through all available network interfaces (IFNET_READER_FOREACH
) to find one matching rootspec
.ifp
and exits the loop.ifp
is still NULL) and bootdv
is non-NULL, the function checks if bootdv
is a network interface (using device_class
).bootdv
’s name (device_xname(bootdv)
) with the names of available network interfaces, setting ifp
if a match is found.ifp
is still NULL, the function outputs a debug message indicating failure to locate the interface, then jumps to the cleanup and exit section (out
label).device_find_by_xname
to locate the device object for ifp
using its if_xname
.dv
) is not found or is not of the network interface type (DV_IFNET
), it logs a debug message and exits.root_device
to dv
(the found network device).curlwp
(current lightweight process, l
) and allocates memory for nd
(an nfs_diskless
structure), zero-initializing it. This structure will contain essential NFS boot information.nd->nd_ifp
to ifp
and marks nd->nd_nomount
to 1, indicating no mounting is performed during this phase.nfs_boot_init
, which initializes network-based boot information for NFS using nd
and l
. If this function fails, it logs a debug message and exits.nd->nd_bootfile
, which represents the boot file path. If the boot file starts with “tftp:”, it removes this prefix for easier handling in subsequent steps.trh
to zero and assigns nd
to trh.trh_nd
, setting the trh_block
to 1.tftproot_getfile
, which retrieves the boot file via TFTP. If this function fails, it logs a debug message and exits.error
to 0, indicating success.out
label section, it frees the allocated nd
memory if it was allocated.error
, which will be 0 on success or an error code if any part of the function failed.The tftproot_dhcpboot
function:
ifp
) using either rootspec
or bootdv
.flowchart TD
A[Start]
A --> B{Input loop}
B --> C{bootdv!= NULL}
C -->|Yes| D[Show default bootdv]
C -->|No| E[Prompt user for root device]
D --> E
E --> F{User input for root device}
F -->|No input| G[Set to bootdv]
F -->|Wildcard input| H[Search matching devices]
F -->|Valid input| I[Set rootdv and exit loop]
H --> I
I --> ZA{Breaks input loop}
G --> ZA
ZA --> |No| B
ZA -->|Yes| J[Set rootdev to nrootdev]
J --> K[Default Dump Device Setup]
K --> L{Root device supports partitions?}
L -->|Yes| M[Set defdumpdv to rootdv]
L -->|No| N[Set defdumpdv to NULL]
M --> O[Dump Device Selection]
N --> O
O --> P{User input for dump device}
P -->|empty input| Q{Is defdumpdv available?}
Q -->|Yes| R[Set dumpdv to second partition of rootdv]
R --> S[Set dumpdev to ndumpdev identifier]
Q -->|No| T[Skip setting dump device]
P -->|Input none| T
P -->|Valid input| S
T --> S
S --> U[Filesystem Type Selection]
U --> V{User input for filesystem}
V -->|empty input| W[Set rootfstype to default deffsname]
V -->|Command input halt reboot ddb| X[Execute command]
V -->|Filesystem not valid| Y[List available filesystems]
Y --> V
W --> Z[Set rootfstype based on input or default]
X --> Z
Z --> AA[Root Device Validation and Final Setup]
AA --> AB{Is rootdv class network or disk?}
AB -->|Yes| AC[Print root device details]
AB -->|No| AD[Display error message]
AC --> AE[Set root_device and call setroot_dump]
AD --> AE
AE --> AF[End]
The setroot_root
function is responsible for configuring the root device of the system during the boot process if root device was specified and boot device was found. It selects the appropriate root device based on a specified configuration (rootspec
) or falls back to the boot device if rootspec
is not defined. This function also determines the major device number and partition of the root device, ensuring that the system can mount the root filesystem correctly.
device_t bootdv
: Represents the device from which the system was booted. It serves as the default root device if no specific root device is provided by rootspec
.int bootpartition
: Specifies the partition number of the boot device. Used when the root device is a disk with partitions.device_t rootdv
: The selected root device, determined either from rootspec
or defaulted to the boot device (bootdv
).int majdev
: Holds the major device number of the root device, which is used to identify the device type in the system.const char *rootdevname
: Name of the root device based on the major number, used in error messages or device identification.char buf[128]
: Buffer to store the root device name, used for formatted messages.dev_t nrootdev
: Represents the device number parsed from rootspec
.rootspec
):
rootspec
is NULL
, the function defaults to using bootdv
as the root device.bootdv
is defined, majdev
is assigned the major number of bootdv
.rootdev
) using MAKEDISKDEV
if the device uses partitions, or makedev
otherwise.rootspec
:
rootspec
is defined, parsedisk
attempts to parse it and assign the resulting device to rootdv
.rootdev
and rootdv
are computed from the major device name (rootdevname
) and device unit.finddevice
to locate rootdv
based on the constructed device name in buf
.majdev
is invalid or rootdv
is NULL
, error messages are printed, and the function exits early.rootdv
, the function checks the device class of rootdv
to ensure it is either a network interface (DV_IFNET
) or a disk (DV_DISK
).root_device
is assigned to rootdv
, and setroot_dump
is called to complete the root device setup.rootspec
, making it adaptable to various boot configurations.#