mirror of
https://gitlab.com/sortix/sortix.git
synced 2023-02-13 20:55:38 -05:00
Rewrite init(8).
This commit is contained in:
parent
70687ac610
commit
9fe234d4d8
10 changed files with 1053 additions and 569 deletions
11
Makefile
11
Makefile
|
@ -88,12 +88,15 @@ endif
|
|||
rm -rf "$(INSTALL_ROOTFS)/boot/sortix.initrd.d"
|
||||
mkdir -p "$(INSTALL_ROOTFS)/boot/sortix.initrd.d"
|
||||
mkdir -p "$(INSTALL_ROOTFS)/boot/sortix.initrd.d/bin"
|
||||
for PROGRAM in init mbrfs extfs; do \
|
||||
cp "$(INSTALL_ROOTFS)/bin/$$PROGRAM" "$(INSTALL_ROOTFS)/boot/sortix.initrd.d/bin/$$PROGRAM"; \
|
||||
done
|
||||
mkdir -p "$(INSTALL_ROOTFS)/boot/sortix.initrd.d/sbin"
|
||||
test ! -e "$(INSTALL_ROOTFS)/bin/fsck.ext2" || \
|
||||
cp "$(INSTALL_ROOTFS)/bin/fsck.ext2" "$(INSTALL_ROOTFS)/boot/sortix.initrd.d/bin/fsck.ext2"
|
||||
cp "$(INSTALL_ROOTFS)/sbin/extfs" "$(INSTALL_ROOTFS)/boot/sortix.initrd.d/sbin/extfs"
|
||||
cp "$(INSTALL_ROOTFS)/sbin/init" "$(INSTALL_ROOTFS)/boot/sortix.initrd.d/sbin/init"
|
||||
mkdir -p "$(INSTALL_ROOTFS)/boot/sortix.initrd.d/etc"
|
||||
mkdir -p "$(INSTALL_ROOTFS)/boot/sortix.initrd.d/etc/init"
|
||||
cp "$(INSTALL_ROOTFS)/etc/rootfs.uuid" "$(INSTALL_ROOTFS)/boot/sortix.initrd.d/etc/init/rootfs.uuid"
|
||||
cp "$(INSTALL_ROOTFS)/etc/fstab" "$(INSTALL_ROOTFS)/boot/sortix.initrd.d/etc/fstab"
|
||||
echo chain > "$(INSTALL_ROOTFS)/boot/sortix.initrd.d/etc/init/target"
|
||||
mkinitrd --format=sortix-initrd-2 "$(INSTALL_ROOTFS)/boot/sortix.initrd.d" -o "$(INSTALL_ROOTFS)/boot/sortix.initrd"
|
||||
rm -rf "$(INSTALL_ROOTFS)/boot/sortix.initrd.d"
|
||||
|
||||
|
|
|
@ -24,8 +24,8 @@ all: $(BINARIES)
|
|||
.PHONY: all install clean
|
||||
|
||||
install: all
|
||||
mkdir -p $(DESTDIR)$(BINDIR)
|
||||
install $(BINARIES) $(DESTDIR)$(BINDIR)
|
||||
mkdir -p $(DESTDIR)$(SBINDIR)
|
||||
install $(BINARIES) $(DESTDIR)$(SBINDIR)
|
||||
|
||||
extfs: *.cpp *.h
|
||||
$(CXX) $(PTHREAD_OPTION) -std=gnu++11 $(CPPFLAGS) $(CXXFLAGS) *.cpp -o $@ $(LIBS)
|
||||
|
|
133
ext/extfs.cpp
133
ext/extfs.cpp
|
@ -128,66 +128,6 @@ void StatInode(Inode* inode, struct stat* st)
|
|||
st->st_blocks = inode->data->i_blocks;
|
||||
}
|
||||
|
||||
static bool is_hex_digit(char c)
|
||||
{
|
||||
return ('0' <= c && c <= '9') ||
|
||||
('a' <= c && c <= 'f') ||
|
||||
('A' <= c && c <= 'F');
|
||||
}
|
||||
|
||||
static bool is_valid_uuid(const char* uuid)
|
||||
{
|
||||
if ( strlen(uuid) != 36 )
|
||||
return false;
|
||||
// Format: 01234567-0123-0123-0123-0123456789AB
|
||||
for ( size_t i = 0; i < 36; i++ )
|
||||
{
|
||||
if ( i == 8 || i == 13 || i == 18 || i == 23 )
|
||||
{
|
||||
if ( uuid[i] != '-' )
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !is_hex_digit(uuid[i]) )
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static unsigned char debase(char c)
|
||||
{
|
||||
if ( '0' <= c && c <= '9' )
|
||||
return (unsigned char) (c - '0');
|
||||
if ( 'a' <= c && c <= 'f' )
|
||||
return (unsigned char) (c - 'a' + 10);
|
||||
if ( 'A' <= c && c <= 'F' )
|
||||
return (unsigned char) (c - 'A' + 10);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void uuid_from_string(uint8_t uuid[16], const char* string)
|
||||
{
|
||||
assert(is_valid_uuid(string));
|
||||
size_t output_index = 0;
|
||||
size_t i = 0;
|
||||
while ( i < 36 )
|
||||
{
|
||||
assert(string[i + 0] != '\0');
|
||||
if ( i == 8 || i == 13 || i == 18 || i == 23 )
|
||||
{
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
assert(string[i + 1] != '\0');
|
||||
uuid[output_index++] = debase(string[i + 0]) << 4 |
|
||||
debase(string[i + 1]) << 0;
|
||||
i += 2;
|
||||
}
|
||||
assert(string[i] == '\0');
|
||||
}
|
||||
|
||||
static void compact_arguments(int* argc, char*** argv)
|
||||
{
|
||||
for ( int i = 0; i < *argc; i++ )
|
||||
|
@ -217,9 +157,8 @@ static void version(FILE* fp, const char* argv0)
|
|||
int main(int argc, char* argv[])
|
||||
{
|
||||
const char* argv0 = argv[0];
|
||||
const char* test_uuid = NULL;
|
||||
const char* pretend_mount_path = NULL;
|
||||
bool foreground = false;
|
||||
bool probe = false;
|
||||
bool read = false;
|
||||
bool write = false;
|
||||
for ( int i = 1; i < argc; i++ )
|
||||
|
@ -250,20 +189,21 @@ int main(int argc, char* argv[])
|
|||
foreground = false;
|
||||
else if ( !strcmp(arg, "--foreground") )
|
||||
foreground = true;
|
||||
else if ( !strcmp(arg, "--probe") )
|
||||
probe = true;
|
||||
else if ( !strcmp(arg, "--read") )
|
||||
read = true;
|
||||
else if ( !strcmp(arg, "--write") )
|
||||
write = true;
|
||||
else if ( !strcmp(arg, "--test-uuid") )
|
||||
else if ( !strncmp(arg, "--pretend-mount-path=", strlen("--pretend-mount-path=")) )
|
||||
pretend_mount_path = arg + strlen("--pretend-mount-path=");
|
||||
else if ( !strcmp(arg, "--pretend-mount-path") )
|
||||
{
|
||||
if ( i+1 == argc )
|
||||
{
|
||||
fprintf(stderr, "%s: --test-uuid: Missing operand\n", argv0);
|
||||
fprintf(stderr, "%s: --pretend-mount-path: Missing operand\n", argv0);
|
||||
exit(1);
|
||||
}
|
||||
test_uuid = argv[++i], argv[i] = NULL;
|
||||
pretend_mount_path = argv[++i];
|
||||
argv[i] = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -296,6 +236,9 @@ int main(int argc, char* argv[])
|
|||
exit(1);
|
||||
}
|
||||
|
||||
if ( !pretend_mount_path )
|
||||
pretend_mount_path = mount_path;
|
||||
|
||||
int fd = open(device_path, write ? O_RDWR : O_RDONLY);
|
||||
if ( fd < 0 )
|
||||
error(1, errno, "`%s'", device_path);
|
||||
|
@ -304,74 +247,35 @@ int main(int argc, char* argv[])
|
|||
struct ext_superblock sb;
|
||||
if ( preadall(fd, &sb, sizeof(sb), 1024) != sizeof(sb) )
|
||||
{
|
||||
if ( probe )
|
||||
exit(1);
|
||||
else if ( errno == EEOF )
|
||||
if ( errno == EEOF )
|
||||
error(1, 0, "`%s' isn't a valid extended filesystem", device_path);
|
||||
else
|
||||
error(1, errno, "read: `%s'", device_path);
|
||||
}
|
||||
|
||||
// Verify the magic value to detect a compatible filesystem.
|
||||
if ( !probe && sb.s_magic != EXT2_SUPER_MAGIC )
|
||||
if ( sb.s_magic != EXT2_SUPER_MAGIC )
|
||||
error(1, 0, "`%s' isn't a valid extended filesystem", device_path);
|
||||
|
||||
if ( probe && sb.s_magic != EXT2_SUPER_MAGIC )
|
||||
exit(1);
|
||||
|
||||
// Test whether this was the filesystem the user was looking for.
|
||||
if ( test_uuid )
|
||||
{
|
||||
if ( !is_valid_uuid(test_uuid) )
|
||||
{
|
||||
if ( !probe )
|
||||
error(1, 0, "`%s' isn't a valid uuid", test_uuid);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
uint8_t uuid[16];
|
||||
uuid_from_string(uuid, test_uuid);
|
||||
|
||||
if ( memcmp(sb.s_uuid, uuid, 16) != 0 )
|
||||
{
|
||||
if ( !probe )
|
||||
error(1, 0, "uuid `%s' did not match the ext2 filesystem at `%s'", test_uuid, device_path);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
// Test whether this revision of the extended filesystem is supported.
|
||||
if ( sb.s_rev_level == EXT2_GOOD_OLD_REV )
|
||||
{
|
||||
if ( probe )
|
||||
exit(1);
|
||||
error(1, 0, "`%s' is formatted with an obsolete filesystem revision",
|
||||
device_path);
|
||||
}
|
||||
|
||||
// Verify that no incompatible features are in use.
|
||||
if ( sb.s_feature_compat & ~EXT2_FEATURE_INCOMPAT_SUPPORTED )
|
||||
{
|
||||
if ( probe )
|
||||
exit(1);
|
||||
error(1, 0, "`%s' uses unsupported and incompatible features",
|
||||
device_path);
|
||||
}
|
||||
|
||||
// Verify that no incompatible features are in use if opening for write.
|
||||
if ( !default_access && write &&
|
||||
sb.s_feature_ro_compat & ~EXT2_FEATURE_RO_COMPAT_SUPPORTED )
|
||||
{
|
||||
if ( probe )
|
||||
exit(1);
|
||||
error(1, 0, "`%s' uses unsupported and incompatible features, "
|
||||
"read-only access is possible, but write-access was "
|
||||
"requested", device_path);
|
||||
}
|
||||
|
||||
if ( write && sb.s_feature_ro_compat & ~EXT2_FEATURE_RO_COMPAT_SUPPORTED )
|
||||
{
|
||||
if ( !probe )
|
||||
fprintf(stderr, "Warning: `%s' uses unsupported and incompatible "
|
||||
"features, falling back to read-only access\n",
|
||||
device_path);
|
||||
|
@ -380,22 +284,13 @@ int main(int argc, char* argv[])
|
|||
}
|
||||
|
||||
// Check whether any features are in use that we can safely disregard.
|
||||
if ( !probe && sb.s_feature_compat & ~EXT2_FEATURE_COMPAT_SUPPORTED )
|
||||
if ( sb.s_feature_compat & ~EXT2_FEATURE_COMPAT_SUPPORTED )
|
||||
fprintf(stderr, "Note: filesystem uses unsupported but compatible "
|
||||
"features\n");
|
||||
|
||||
// Check the block size is sane. 64 KiB may have issues, 32 KiB then.
|
||||
if ( sb.s_log_block_size > (15-10) /* 32 KiB blocks */ )
|
||||
{
|
||||
if ( probe )
|
||||
exit(1);
|
||||
error(1, 0, "`%s': excess block size", device_path);
|
||||
}
|
||||
|
||||
// We have found no critical problems, so let the caller know that this
|
||||
// filesystem satisfies the probe request.
|
||||
if ( probe )
|
||||
exit(0);
|
||||
|
||||
// Check whether the filesystem was unmounted cleanly.
|
||||
if ( sb.s_state != EXT2_VALID_FS )
|
||||
|
@ -407,7 +302,7 @@ int main(int argc, char* argv[])
|
|||
Device* dev = new Device(fd, device_path, block_size, write);
|
||||
if ( !dev ) // TODO: Use operator new nothrow!
|
||||
error(1, errno, "malloc");
|
||||
Filesystem* fs = new Filesystem(dev, mount_path);
|
||||
Filesystem* fs = new Filesystem(dev, pretend_mount_path);
|
||||
if ( !fs ) // TODO: Use operator new nothrow!
|
||||
error(1, errno, "malloc");
|
||||
|
||||
|
|
|
@ -19,14 +19,16 @@ all: $(BINARY)
|
|||
.PHONY: all install clean
|
||||
|
||||
$(BINARY): $(OBJS)
|
||||
$(CXX) $(OBJS) -o $(BINARY) $(CXXFLAGS) $(LIBS)
|
||||
$(CXX) $(OBJS) -o $(BINARY) $(CXXFLAGS) -lmount $(LIBS)
|
||||
|
||||
%.o: %.c++
|
||||
$(CXX) -std=gnu++11 $(CPPFLAGS) $(CXXFLAGS) -c $< -o $@
|
||||
|
||||
install: all
|
||||
mkdir -p $(DESTDIR)$(BINDIR)
|
||||
install $(BINARY) $(DESTDIR)$(BINDIR)
|
||||
mkdir -p $(DESTDIR)$(SBINDIR)
|
||||
install $(BINARY) $(DESTDIR)$(SBINDIR)
|
||||
mkdir -p $(DESTDIR)$(MANDIR)/man8
|
||||
cp init.8 $(DESTDIR)$(MANDIR)/man8/init.8
|
||||
|
||||
clean:
|
||||
rm -f $(BINARY) $(OBJS) *.o
|
||||
|
|
182
init/init.8
Normal file
182
init/init.8
Normal file
|
@ -0,0 +1,182 @@
|
|||
.Dd $Mdocdate: October 5 2015 $
|
||||
.Dt INIT 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm init
|
||||
.Nd system initialization
|
||||
.Sh SYNOPSIS
|
||||
.Nm init
|
||||
.Op Fl \-target Ns "=" Ns Ar init-target
|
||||
.Op Fl \-chain Ns "=" Ns Ar path-or-uuid
|
||||
.Sh DESCRIPTION
|
||||
.Nm
|
||||
is the first program run after system startup and is responsible for
|
||||
initializing the operating system and starting the specified
|
||||
.Ar init-target .
|
||||
This is normally a login screen, a root shell, or a dedicated special purpose
|
||||
program.
|
||||
.Pp
|
||||
The
|
||||
.Xr kernel 7
|
||||
starts the system in a temporary environment with a root filesystem
|
||||
backed by system memory and extracts the
|
||||
.Xr initrd 7
|
||||
into it. The kernel runs the
|
||||
.Pa /sbin/init
|
||||
program of the system memory root filesystem as the first process. If the
|
||||
system is bootable cdrom, then the initrd will be a fully functional system and
|
||||
.Nm
|
||||
will start a live environment or an operating system installer. If the
|
||||
system is installed on a harddisk, then the initrd is a minimal system made with
|
||||
.Xr update-initrd 8
|
||||
that will search for the actual root filesystem and chain init it. The next
|
||||
stage init will recognize it as the intended system and complete the system
|
||||
startup.
|
||||
.Ss Initialization Target
|
||||
.Nm
|
||||
first determines its target from the
|
||||
.Fl \-target
|
||||
option if specified or
|
||||
.Pa /etc/init/target
|
||||
otherwise. Supported targets are:
|
||||
.Pp
|
||||
.Bl -tag -width "single-user" -compact -offset indent
|
||||
.It chain
|
||||
mount real root filesystem and run its
|
||||
.Nm
|
||||
.It multi-user
|
||||
boot to
|
||||
.Xr login 8
|
||||
.It single-user
|
||||
boot to root shell without password (not secure)
|
||||
.It sysinstall
|
||||
boot to operating system installer (not secure)
|
||||
.It sysupgrade
|
||||
boot to operating system upgrader (not secure)
|
||||
.El
|
||||
.Pp
|
||||
It is a full system compromise if unauthenticated users are able to boot the
|
||||
wrong target. The kernel command line can specify the path to
|
||||
.Nm
|
||||
and its arguments. Unprivileged users can change the kernel command line from
|
||||
the bootloader command line if it hasn't been password protected. Likewise
|
||||
unprivileged users can use their own replacement bootloader by booting a
|
||||
portable device under their control if the firmware configuration has not been
|
||||
password protected.
|
||||
.Ss Partition Creation
|
||||
.Nm
|
||||
will scan every block device for valid partition tables and create the
|
||||
corresponding partition devices in
|
||||
.Pa /dev .
|
||||
.Ss Chain Initialization
|
||||
The chain target triggers a search for the root filesystem. The
|
||||
.Fl \-chain Ns "=" Ns Ar path-or-uuid
|
||||
option implies
|
||||
.Fl \-target Ns "=" Ns chain
|
||||
if it is not set and specifies the method to locate the root filesystem. The
|
||||
.Ar path-or-uuid
|
||||
value is either a path to a directory, in which case it is used as the root
|
||||
filesystem, or a file that contains a uuid of the root filesystem, or it can be
|
||||
a valid uuid of the intended root filesystem. If the
|
||||
.Fl \-chain
|
||||
option is not specified, the root filesystem of
|
||||
.Pa /etc/fstab
|
||||
is used as described in
|
||||
.Xr fstab 5 .
|
||||
.Pp
|
||||
Every block device and partition is scanned to determine if it is the filesystem
|
||||
by matching the desired uuid. The root filesystem is checked for consistency
|
||||
and mounted at
|
||||
.Pa /tmp/fs.XXXXXX
|
||||
and the
|
||||
.Pa /dev
|
||||
filesystem directory is bound at
|
||||
.Pa /tmp/fs.XXXXXX/dev .
|
||||
.Pp
|
||||
Finally the
|
||||
.Pa /sbin/init
|
||||
program of the target root filesystem is run inside a chroot.
|
||||
.Ss Configuration
|
||||
Once the
|
||||
.Nm
|
||||
of the real root filesystem runs, it will process basic configuration files and
|
||||
apply them:
|
||||
.Pp
|
||||
.Bl -tag -width "/etc/videomode" -compact -offset indent
|
||||
.It Pa /etc/hostname
|
||||
set hostname (see
|
||||
.Xr hostname 5 )
|
||||
.It Pa /etc/kblayout
|
||||
set keyboard layout (see
|
||||
.Xr kblayout 5 )
|
||||
.It Pa /etc/videomode
|
||||
set graphics resolution (see
|
||||
.Xr videomode 5 )
|
||||
.El
|
||||
.Ss Session
|
||||
Finally
|
||||
.Nm
|
||||
will start the target program according to its initialization target. This will
|
||||
be a login screen, a root shell, or something else. If the process exits
|
||||
abnormally
|
||||
.Nm
|
||||
will automatically restart it.
|
||||
.Nm
|
||||
will exit with the same exit status as the process if it exits
|
||||
normally. The kernel decides whether to power off, reboot or halt based on this
|
||||
exit status.
|
||||
.Sh ENVIRONMENT
|
||||
.Nm
|
||||
sets the following environment variables.
|
||||
.Bl -tag -width "INIT_PID"
|
||||
.It Ev HOME
|
||||
root's home directory
|
||||
.It Ev INIT_PID
|
||||
.Nm Ns 's
|
||||
process id
|
||||
.It Ev LOGNAME
|
||||
root
|
||||
.It Ev PATH
|
||||
.Pa /bin:/sbin
|
||||
.It Ev SHELL
|
||||
root's shell
|
||||
.It Ev TERM
|
||||
sortix
|
||||
.It Ev USER
|
||||
root
|
||||
.El
|
||||
.Sh FILES
|
||||
.Bl -tag -width "/etc/init/target" -compact
|
||||
.It Pa /etc/init/target
|
||||
default initialization target
|
||||
.It Pa /etc/fstab
|
||||
filesystem table (see
|
||||
.Xr fstab 5 )
|
||||
.It Pa /etc/hostname
|
||||
hostname (see
|
||||
.Xr hostname 5 )
|
||||
.It Pa /etc/kblayout
|
||||
keyboard layout (see
|
||||
.Xr kblayout 5 )
|
||||
.It Pa /etc/videomode
|
||||
graphics resolution (see
|
||||
.Xr videomode 5 )
|
||||
.El
|
||||
.Sh EXIT STATUS
|
||||
.Nm
|
||||
exits 0 if the kernel should power off, exits 1 if the kernel should reboot, or
|
||||
exits 2 if the boot failed and the kernel should halt. Any other exit by the
|
||||
initial
|
||||
.Nm
|
||||
will trigger a kernel panic.
|
||||
.Nm
|
||||
exits with the same exit status as its target session if it terminates normally.
|
||||
.Sh SEE ALSO
|
||||
.Xr fstab 5 ,
|
||||
.Xr hostname 5 ,
|
||||
.Xr kblayout 5 ,
|
||||
.Xr videomode 5 ,
|
||||
.Xr initrd 7 ,
|
||||
.Xr kernel 7 ,
|
||||
.Xr login 8 ,
|
||||
.Xr update-initrd 8
|
1224
init/init.c++
1224
init/init.c++
File diff suppressed because it is too large
Load diff
|
@ -586,8 +586,14 @@ static void BootThread(void* /*user*/)
|
|||
|
||||
switch ( status )
|
||||
{
|
||||
case 0: CPU::ShutDown();
|
||||
case 1: CPU::Reboot();
|
||||
case 0:
|
||||
CPU::ShutDown();
|
||||
case 1:
|
||||
CPU::Reboot();
|
||||
case 2:
|
||||
Log::Print("kernel: fatal: Halting system due to init fatality\n");
|
||||
Log::Sync();
|
||||
HaltKernel();
|
||||
default:
|
||||
PanicF("Init returned with unexpected return code %i", status);
|
||||
}
|
||||
|
@ -618,7 +624,7 @@ static void InitThread(void* /*user*/)
|
|||
|
||||
dtable.Reset();
|
||||
|
||||
static char default_init_cmdline[] = "/bin/init";
|
||||
static char default_init_cmdline[] = "/sbin/init";
|
||||
if ( !init_cmdline )
|
||||
init_cmdline = default_init_cmdline;
|
||||
|
||||
|
|
46
share/man/man5/videomode.5
Normal file
46
share/man/man5/videomode.5
Normal file
|
@ -0,0 +1,46 @@
|
|||
.Dd $Mdocdate: October 5 2015 $
|
||||
.Dt VIDEOMODE 5
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm videomode
|
||||
.Nd initial graphics resolution
|
||||
.Sh SYNOPSIS
|
||||
.Nm /etc/videomode
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm videomode
|
||||
file is read on boot by
|
||||
.Xr init 8
|
||||
and is used as the initial graphics resolution on the primary monitor. The
|
||||
resolution provided by the bootloader remains in effect if the file is missing.
|
||||
The resolution is usable only if the graphics card has a driver and the
|
||||
resolution is supported.
|
||||
.Sh FORMAT
|
||||
.Ar width Ns x Ns Ar height Ns x Ns Ar bits-per-pixel
|
||||
.Pp
|
||||
The file specifies a graphics resolution as a single line with three numeric
|
||||
fields separated by x characters and no whitespace whatsoever. The first field
|
||||
is used as the
|
||||
.Ar width
|
||||
in pixels, the second field is used as the
|
||||
.Ar height
|
||||
in pixels, and the third field is used as the
|
||||
.Ar bits-per-pixel .
|
||||
.Sh FILES
|
||||
.Bl -tag -width "/etc/videomode" -compact
|
||||
.It Pa /etc/videomode
|
||||
primary monitor graphics resolution.
|
||||
.El
|
||||
.Sh EXAMPLES
|
||||
.Bd -literal
|
||||
1920x1080x32
|
||||
.Ed
|
||||
.Sh SEE ALSO
|
||||
.Xr chvideomode 1 ,
|
||||
.Xr dispmsg_issue 2 ,
|
||||
.Xr init 8
|
||||
.Sh BUGS
|
||||
This scheme only supports a single monitor. The kernel console doesn't handle
|
||||
resolution changes gracefully, the console will be cleared and the console
|
||||
cursor might be out of the screen upon resolution shrink. Early boot messages
|
||||
will be unavailable.
|
|
@ -14,7 +14,7 @@ that extracts it into the initial kernel memory root filesystem. The kernel
|
|||
invokes the
|
||||
.Xr init 8
|
||||
extracted from the initrd as
|
||||
.Pa /bin/init .
|
||||
.Pa /sbin/init .
|
||||
.Pp
|
||||
The initrd is in the custom format made by
|
||||
.Xr mkinitrd 8
|
||||
|
|
|
@ -22,7 +22,7 @@ The kernel extracts the initrd into the initial kernel memory root filesystem
|
|||
and executes
|
||||
.Xr init 8
|
||||
as
|
||||
.Pa /bin/init .
|
||||
.Pa /sbin/init .
|
||||
The computer is powered off if this process exits 0, rebooted if it exits 1,
|
||||
halted if it exits 2, and paniced otherwise.
|
||||
.Pp
|
||||
|
|
Loading…
Reference in a new issue