---
title: Documentation for setroot()
---
# conventions used in this document
- `sourcefile:functionname()`
sourcefile paths will be relative to `src/sys/`, e.g. `kern/kern_subr.c:setroot()`
- we use links to [NXR](https://nxr.netbsd.org/) to point to source code.
E.g. \[setroot()](https://nxr.netbsd.org/xref/src/sys/kern/kern_subr.c#193)
NB: these links reference absolute line numbers. the actual line number might be slightly off, if the corresponding source file has been changed since creating the link.
# device configuration
during boot the kernel needs to configure a lot of hardware devices in the system to bring them into a known state and to probe for the presence of optional hardware like disks, network cards etc. to facilitate this a description of all the devices that the kernel needs to know about is created and processed by `config(8)`which is then compiled into the kernel image.
Not all the devices desribed in the config files are exposed as Unix device drivers, accessible through `/dev/` or as network interfaces.
Note that conflicting terminology is used here. There are devices and device drivers that are exposed to user land through special device files (commonly in `/dev`) and as network interfaces. But there are also devices and device drivers used by the (auto) configuration system. They use different programming interfaces and data structures to describe them.
The best documentation for how the kernel detects and configures devices is [Device Configuration in 4.4 BSD](https://www.netbsd.org/~mrg/config-torek-fixed.pdf). Page 10 of that document describes the `config sysname system-paramters` syntax, that is relevant to setroot() (`rootspec` and `dumpspec`).
# the boot process (or how the kernel comes to know from where it was loaded)
this is a somewhat simplified description to get the general idea. the actual boot process varies widely between the different NetBSD architectures. we will only concern ourselves with *amd64* for the time being.
## booting on amd64
the computer firmware (BIOS or UEFI) determines which device to boot the operating system from. E.g. a DVD/CDROM or from a specific disk and partition. (or even from the network.)
the firmware next loads and operating system specific *bootloader programm* from the device that was selected for booting from. this can be a multi-stage process, e.g. when using the old BIOS method. the firmware then executes the bootloader passing it the location where the bootloader was loaded from (DVD/CDROM, disk and partition, network device).
the NetBSD bootloader loads /boot.cfg and determine which kernel to load and what options and arguments to pass to the kernel and what device the kernel was loaded from.
these options and arguments (and other information) is passed to the kernel in a variable called `bootinfo`.
this variable and its structure is defined in the file `machine/bootinfo.h`. `machine` isn't an actual directory. it is a symbolic link that is created when the kernel compile directory is created by `config(8)` and points to the architecture directory.
See [arch/amd64/include/bootinfo.h](https://nxr.netbsd.org/xref/src/sys/arch/amd64/include/bootinfo.h) and [arch/x86/include/bootinfo.h](https://nxr.netbsd.org/xref/src/sys/arch/x86/include/bootinfo.h)
we are mainly interested in
- [btinfo_bootpath](https://nxr.netbsd.org/xref/src/sys/arch/x86/include/bootinfo.h#59)
- [btinfo_rootdevice](https://nxr.netbsd.org/xref/src/sys/arch/x86/include/bootinfo.h#64)
- [btinfo_bootdisk](https://nxr.netbsd.org/xref/src/sys/arch/x86/include/bootinfo.h#69)
- [btinfo_bootwedge](https://nxr.netbsd.org/xref/src/sys/arch/x86/include/bootinfo.h#80)
- [btinfo_netif](https://nxr.netbsd.org/xref/src/sys/arch/x86/include/bootinfo.h#90)
these variables are processed in [findroot()](https://nxr.netbsd.org/xref/src/sys/arch/x86/x86/x86_autoconf.c#findroot) on `x86` (`amd64` and `i386`).
# kernel initialization
when the kernel start it initializes all the subsystems in [intit_main.c:main()](https://nxr.netbsd.org/xref/src/sys/kern/init_main.c#263). It probes all the hardware devices it knows about and configures the device drivers for them.
all devices that are accessible from user land are entered into the `cdevsw` and `bdevsw` tables, so that they can be accessed through device special files in `/dev/`.
when all subsystems are initialized and all devices are configured it calls [cpu_rootconf()](https://nxr.netbsd.org/xref/src/sys/kern/init_main.c#678) to find out what the (Unix) device for the root file system should be. then it calls [cpu_dumpconf()](https://nxr.netbsd.org/xref/src/sys/kern/init_main.c#679) to configure the initial device for swap and kernel crash dumps.
then it tries to mount the root file system by first running the root mount hooks [domountroothook()](https://nxr.netbsd.org/xref/src/sys/kern/init_main.c#683), then calls [vfs_mountroot()](https://nxr.netbsd.org/xref/src/sys/kern/init_main.c#684) to actually mount the file system.
If mounting the root file system fails, it sets the `RB_ASKNAME` flag in `boothowto` and calls `setroot()` again, causing `setroot()` to prompt for a root device on the console. this repeats until a valid root file system can be mounted.
it is possible to abort this loop in `setroot_ask()` by entering `halt` or `reboot` or do start the in-kernel debugger with `ddb` when `setroot_ask()` prompts for the file system type.
`cpu_rootconf()` is defined per architecture.
on [x86](https://nxr.netbsd.org/xref/src/sys/arch/x86/x86/x86_autoconf.c#553) `cpu_rootconf()` calls `cpu_bootconf()` which calls `findroot()` and then `matchbiosdisks()`
`findroot()` processes the information passed in the bootinfo area, setting: `booted_device`, `booted_method`, `booted_partition`, `booted_nblks`, possibly `bootspec`.
after `cpu_rootconf()` returns the kernel calls `cpu_dumpconf` to setup the device where kernel crash dumps are written to. [cpu_dumpconf()](https://nxr.netbsd.org/xref/src/sys/arch/amd64/amd64/machdep.c#1300)
[arch/x86/x86/x86_autoconf.c:findroot](https://nxr.netbsd.org/xref/src/sys/arch/x86/x86/x86_autoconf.c#333)
[arch/x86/x86/x86_autoconf.c: call to findroot()](https://nxr.netbsd.org/xref/src/sys/arch/x86/x86/x86_autoconf.c#548)
# kernel initalization (alternate version)
XXX is this version better? I tried to visualize the call tree with nested lists.
- [init_main.c:main()](https://nxr.netbsd.org/xref/src/sys/kern/init_main.c#263)
the kernel starts to initializes all the subsystems.
it probes all the hardware devices it knows about and configures the device drivers for them.
all devices that are accessible from user land are entered into the `cdevsw` and `bdevsw` tables, so that they can be accessed through device special files in `/dev/`.
- [cpu_rootconf()](https://nxr.netbsd.org/xref/src/sys/kern/init_main.c#678)
is called when all subsystems are initialized and all devices are configured.
`cpu_rootconf` finds out what the (Unix) device for the root file system should be.
`cpu_rootconf()` is defined per architecture.
see [arch/x86/x86/x86_autoconf.c:cpu_rootconf()](https://nxr.netbsd.org/xref/src/sys/arch/x86/x86/x86_autoconf.c#553)
- `cpu_bootconf()`
is called next which calls
- `findroot()`
it processes the information passed in `bootinfo`, setting: `booted_device`, `booted_method`, `booted_partition`, `booted_nblks`, and possibly `bootspec`.
`findroot()` first checks if `booted_device` already set and return immediately in that case.
next, if there is a BTINFO_NETIF record in the bootinfo area, `findroot()` returns. XXX where and how is BTINFO_NETIF handled? what does it mean for `setroot`? the code comment in the BTINFO_NETIF case suggests that `booted_device` should already be set.
- `matchbiosdisks()`
[arch/x86/x86/x86_autoconf.c:findroot](https://nxr.netbsd.org/xref/src/sys/arch/x86/x86/x86_autoconf.c#333)
[arch/x86/x86/x86_autoconf.c: call to findroot()](https://nxr.netbsd.org/xref/src/sys/arch/x86/x86/x86_autoconf.c#548)
after `cpu_rootconf()` returns the kernel calls `cpu_dumpconf` to setup the device where kernel crash dumps are written to. [cpu_dumpconf()](https://nxr.netbsd.org/xref/src/sys/arch/amd64/amd64/machdep.c#1300)
- [cpu_dumpconf()](https://nxr.netbsd.org/xref/src/sys/kern/init_main.c#679)
is called next. it sets up the dump device for kernel crash dumps.
- [init_main.c:domountroothook(device_t therootdev)](https://nxr.netbsd.org/xref/src/sys/kern/init_main.c#683)
next it runs `domountroothook()` XXX to do what?
from rudimentary understanding `domountroothook` takes root device as argument and loops through every item on `mountroothook_list` to find hook matching with root device and after finding it calls hook function with root device as argument. where is `mountroothook_list` populated with all functions and parameters ?
`domountroothook` is currently used when booting from floppy disks to prompt to insert the root file system floppy.
- [init_main.c:vfs_mountroot()](https://nxr.netbsd.org/xref/src/sys/kern/init_main.c#684)
is called to actually mount the file system.
If mounting the root file system fails, it sets the flag `RB_ASKNAME` in `boothowto` and calls `setroot()` again, causing `setroot()` to prompt for a root device on the console. this repeats until a valid root file system can be mounted.
it is possible to abort this loop in `setroot_ask()` by entering `halt` or `reboot` or to start the in-kernel debugger with `ddb` when `setroot_ask()` prompts for the file system type.
# input variables
```clike=
/*
* The device and partition that we booted from.
*
* This data might be initialized by MD code, but is defined here.
*/
device_t booted_device;
const char *booted_method;
int booted_partition;
daddr_t booted_startblk;
uint64_t booted_nblks;
char *bootspec;
const char *rootspec; /* how root device was specified */
const char *dumpspec; /* how dump device was specified */
boothowto;
```
# Input Variable Description
1. **device_t booted_device**
This variable tells about device,it can be a wedge or a disk, system has booted from. It is used by setroot() function to specify root device. there are conditional in findroot() through which above variables are set together.
- If boot entry in boot info with `BTINFO_ROOTDEVICE` is present
then booted_device is assigned to device(`DV_DISK`) which has matching name with devname of boot entry and (something I do n)
# output variables
```clike=
device_t rootdv; /* maybe? */
dev_t rootdev; /* root device */
device_t root_device; /* device equivalent to above */
dev_t dumpdev; /* dump device */
dev_t dumpcdev; /* dump device (character equivalent) */
long dumplo; /* offset into dumpdev */
int dumpsize; /* size of dump in pages */
```
# files and function
- kern/kern_subr.c: definition of setroot() and related functions
- called from kern/init_main.c:
- main()
- rootconf()
## related functions
- cpu_rootconf() arch/x86/x86/x86_autoconf.c
- cpu_bootconf()
- findroot()
> iterates through all devices in system ,finds dev which matches info passed by bios to kernel, that device info is set to input variables of setroot functions.
- matchbiosdisks()
> matchbiosdisk counts, number of disk with which it can interact natively ,from bios entries.
- rootconf()
- cpu_dumpconf()
## setroot()
if config file does not define any device then it defaults to bootspec set during findroot() execution. if rootfs is on memmory then macro`MEMORY_DISK_IS_ROOT` should be defined.
setroot also has support for nfs to be used as root inthat case it first interface is used.
it then checks for device passed to be NULL, if it is then asks for user rootdevice. it will loop it a root device has been found. once there is a root device it passes control over to setroot_root which sets root_device.