Rewrite init(8).
This commit is contained in:
parent
70687ac610
commit
9fe234d4d8
11
Makefile
11
Makefile
|
@ -88,12 +88,15 @@ endif
|
||||||
rm -rf "$(INSTALL_ROOTFS)/boot/sortix.initrd.d"
|
rm -rf "$(INSTALL_ROOTFS)/boot/sortix.initrd.d"
|
||||||
mkdir -p "$(INSTALL_ROOTFS)/boot/sortix.initrd.d"
|
mkdir -p "$(INSTALL_ROOTFS)/boot/sortix.initrd.d"
|
||||||
mkdir -p "$(INSTALL_ROOTFS)/boot/sortix.initrd.d/bin"
|
mkdir -p "$(INSTALL_ROOTFS)/boot/sortix.initrd.d/bin"
|
||||||
for PROGRAM in init mbrfs extfs; do \
|
mkdir -p "$(INSTALL_ROOTFS)/boot/sortix.initrd.d/sbin"
|
||||||
cp "$(INSTALL_ROOTFS)/bin/$$PROGRAM" "$(INSTALL_ROOTFS)/boot/sortix.initrd.d/bin/$$PROGRAM"; \
|
test ! -e "$(INSTALL_ROOTFS)/bin/fsck.ext2" || \
|
||||||
done
|
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"
|
||||||
mkdir -p "$(INSTALL_ROOTFS)/boot/sortix.initrd.d/etc/init"
|
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"
|
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"
|
rm -rf "$(INSTALL_ROOTFS)/boot/sortix.initrd.d"
|
||||||
|
|
||||||
|
|
|
@ -24,8 +24,8 @@ all: $(BINARIES)
|
||||||
.PHONY: all install clean
|
.PHONY: all install clean
|
||||||
|
|
||||||
install: all
|
install: all
|
||||||
mkdir -p $(DESTDIR)$(BINDIR)
|
mkdir -p $(DESTDIR)$(SBINDIR)
|
||||||
install $(BINARIES) $(DESTDIR)$(BINDIR)
|
install $(BINARIES) $(DESTDIR)$(SBINDIR)
|
||||||
|
|
||||||
extfs: *.cpp *.h
|
extfs: *.cpp *.h
|
||||||
$(CXX) $(PTHREAD_OPTION) -std=gnu++11 $(CPPFLAGS) $(CXXFLAGS) *.cpp -o $@ $(LIBS)
|
$(CXX) $(PTHREAD_OPTION) -std=gnu++11 $(CPPFLAGS) $(CXXFLAGS) *.cpp -o $@ $(LIBS)
|
||||||
|
|
139
ext/extfs.cpp
139
ext/extfs.cpp
|
@ -128,66 +128,6 @@ void StatInode(Inode* inode, struct stat* st)
|
||||||
st->st_blocks = inode->data->i_blocks;
|
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)
|
static void compact_arguments(int* argc, char*** argv)
|
||||||
{
|
{
|
||||||
for ( int i = 0; i < *argc; i++ )
|
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[])
|
int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
const char* argv0 = argv[0];
|
const char* argv0 = argv[0];
|
||||||
const char* test_uuid = NULL;
|
const char* pretend_mount_path = NULL;
|
||||||
bool foreground = false;
|
bool foreground = false;
|
||||||
bool probe = false;
|
|
||||||
bool read = false;
|
bool read = false;
|
||||||
bool write = false;
|
bool write = false;
|
||||||
for ( int i = 1; i < argc; i++ )
|
for ( int i = 1; i < argc; i++ )
|
||||||
|
@ -250,20 +189,21 @@ int main(int argc, char* argv[])
|
||||||
foreground = false;
|
foreground = false;
|
||||||
else if ( !strcmp(arg, "--foreground") )
|
else if ( !strcmp(arg, "--foreground") )
|
||||||
foreground = true;
|
foreground = true;
|
||||||
else if ( !strcmp(arg, "--probe") )
|
|
||||||
probe = true;
|
|
||||||
else if ( !strcmp(arg, "--read") )
|
else if ( !strcmp(arg, "--read") )
|
||||||
read = true;
|
read = true;
|
||||||
else if ( !strcmp(arg, "--write") )
|
else if ( !strcmp(arg, "--write") )
|
||||||
write = true;
|
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 )
|
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);
|
exit(1);
|
||||||
}
|
}
|
||||||
test_uuid = argv[++i], argv[i] = NULL;
|
pretend_mount_path = argv[++i];
|
||||||
|
argv[i] = NULL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -296,6 +236,9 @@ int main(int argc, char* argv[])
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( !pretend_mount_path )
|
||||||
|
pretend_mount_path = mount_path;
|
||||||
|
|
||||||
int fd = open(device_path, write ? O_RDWR : O_RDONLY);
|
int fd = open(device_path, write ? O_RDWR : O_RDONLY);
|
||||||
if ( fd < 0 )
|
if ( fd < 0 )
|
||||||
error(1, errno, "`%s'", device_path);
|
error(1, errno, "`%s'", device_path);
|
||||||
|
@ -304,98 +247,50 @@ int main(int argc, char* argv[])
|
||||||
struct ext_superblock sb;
|
struct ext_superblock sb;
|
||||||
if ( preadall(fd, &sb, sizeof(sb), 1024) != sizeof(sb) )
|
if ( preadall(fd, &sb, sizeof(sb), 1024) != sizeof(sb) )
|
||||||
{
|
{
|
||||||
if ( probe )
|
if ( errno == EEOF )
|
||||||
exit(1);
|
|
||||||
else if ( errno == EEOF )
|
|
||||||
error(1, 0, "`%s' isn't a valid extended filesystem", device_path);
|
error(1, 0, "`%s' isn't a valid extended filesystem", device_path);
|
||||||
else
|
else
|
||||||
error(1, errno, "read: `%s'", device_path);
|
error(1, errno, "read: `%s'", device_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify the magic value to detect a compatible filesystem.
|
// 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);
|
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.
|
// Test whether this revision of the extended filesystem is supported.
|
||||||
if ( sb.s_rev_level == EXT2_GOOD_OLD_REV )
|
if ( sb.s_rev_level == EXT2_GOOD_OLD_REV )
|
||||||
{
|
|
||||||
if ( probe )
|
|
||||||
exit(1);
|
|
||||||
error(1, 0, "`%s' is formatted with an obsolete filesystem revision",
|
error(1, 0, "`%s' is formatted with an obsolete filesystem revision",
|
||||||
device_path);
|
device_path);
|
||||||
}
|
|
||||||
|
|
||||||
// Verify that no incompatible features are in use.
|
// Verify that no incompatible features are in use.
|
||||||
if ( sb.s_feature_compat & ~EXT2_FEATURE_INCOMPAT_SUPPORTED )
|
if ( sb.s_feature_compat & ~EXT2_FEATURE_INCOMPAT_SUPPORTED )
|
||||||
{
|
|
||||||
if ( probe )
|
|
||||||
exit(1);
|
|
||||||
error(1, 0, "`%s' uses unsupported and incompatible features",
|
error(1, 0, "`%s' uses unsupported and incompatible features",
|
||||||
device_path);
|
device_path);
|
||||||
}
|
|
||||||
|
|
||||||
// Verify that no incompatible features are in use if opening for write.
|
// Verify that no incompatible features are in use if opening for write.
|
||||||
if ( !default_access && write &&
|
if ( !default_access && write &&
|
||||||
sb.s_feature_ro_compat & ~EXT2_FEATURE_RO_COMPAT_SUPPORTED )
|
sb.s_feature_ro_compat & ~EXT2_FEATURE_RO_COMPAT_SUPPORTED )
|
||||||
{
|
|
||||||
if ( probe )
|
|
||||||
exit(1);
|
|
||||||
error(1, 0, "`%s' uses unsupported and incompatible features, "
|
error(1, 0, "`%s' uses unsupported and incompatible features, "
|
||||||
"read-only access is possible, but write-access was "
|
"read-only access is possible, but write-access was "
|
||||||
"requested", device_path);
|
"requested", device_path);
|
||||||
}
|
|
||||||
|
|
||||||
if ( write && sb.s_feature_ro_compat & ~EXT2_FEATURE_RO_COMPAT_SUPPORTED )
|
if ( write && sb.s_feature_ro_compat & ~EXT2_FEATURE_RO_COMPAT_SUPPORTED )
|
||||||
{
|
{
|
||||||
if ( !probe )
|
fprintf(stderr, "Warning: `%s' uses unsupported and incompatible "
|
||||||
fprintf(stderr, "Warning: `%s' uses unsupported and incompatible "
|
"features, falling back to read-only access\n",
|
||||||
"features, falling back to read-only access\n",
|
device_path);
|
||||||
device_path);
|
|
||||||
// TODO: Modify the file descriptor such that writing fails!
|
// TODO: Modify the file descriptor such that writing fails!
|
||||||
read = true;
|
read = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check whether any features are in use that we can safely disregard.
|
// 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 "
|
fprintf(stderr, "Note: filesystem uses unsupported but compatible "
|
||||||
"features\n");
|
"features\n");
|
||||||
|
|
||||||
// Check the block size is sane. 64 KiB may have issues, 32 KiB then.
|
// 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 ( sb.s_log_block_size > (15-10) /* 32 KiB blocks */ )
|
||||||
{
|
|
||||||
if ( probe )
|
|
||||||
exit(1);
|
|
||||||
error(1, 0, "`%s': excess block size", device_path);
|
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.
|
// Check whether the filesystem was unmounted cleanly.
|
||||||
if ( sb.s_state != EXT2_VALID_FS )
|
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);
|
Device* dev = new Device(fd, device_path, block_size, write);
|
||||||
if ( !dev ) // TODO: Use operator new nothrow!
|
if ( !dev ) // TODO: Use operator new nothrow!
|
||||||
error(1, errno, "malloc");
|
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!
|
if ( !fs ) // TODO: Use operator new nothrow!
|
||||||
error(1, errno, "malloc");
|
error(1, errno, "malloc");
|
||||||
|
|
||||||
|
|
|
@ -19,14 +19,16 @@ all: $(BINARY)
|
||||||
.PHONY: all install clean
|
.PHONY: all install clean
|
||||||
|
|
||||||
$(BINARY): $(OBJS)
|
$(BINARY): $(OBJS)
|
||||||
$(CXX) $(OBJS) -o $(BINARY) $(CXXFLAGS) $(LIBS)
|
$(CXX) $(OBJS) -o $(BINARY) $(CXXFLAGS) -lmount $(LIBS)
|
||||||
|
|
||||||
%.o: %.c++
|
%.o: %.c++
|
||||||
$(CXX) -std=gnu++11 $(CPPFLAGS) $(CXXFLAGS) -c $< -o $@
|
$(CXX) -std=gnu++11 $(CPPFLAGS) $(CXXFLAGS) -c $< -o $@
|
||||||
|
|
||||||
install: all
|
install: all
|
||||||
mkdir -p $(DESTDIR)$(BINDIR)
|
mkdir -p $(DESTDIR)$(SBINDIR)
|
||||||
install $(BINARY) $(DESTDIR)$(BINDIR)
|
install $(BINARY) $(DESTDIR)$(SBINDIR)
|
||||||
|
mkdir -p $(DESTDIR)$(MANDIR)/man8
|
||||||
|
cp init.8 $(DESTDIR)$(MANDIR)/man8/init.8
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f $(BINARY) $(OBJS) *.o
|
rm -f $(BINARY) $(OBJS) *.o
|
||||||
|
|
|
@ -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
|
1216
init/init.c++
1216
init/init.c++
File diff suppressed because it is too large
Load Diff
|
@ -586,8 +586,14 @@ static void BootThread(void* /*user*/)
|
||||||
|
|
||||||
switch ( status )
|
switch ( status )
|
||||||
{
|
{
|
||||||
case 0: CPU::ShutDown();
|
case 0:
|
||||||
case 1: CPU::Reboot();
|
CPU::ShutDown();
|
||||||
|
case 1:
|
||||||
|
CPU::Reboot();
|
||||||
|
case 2:
|
||||||
|
Log::Print("kernel: fatal: Halting system due to init fatality\n");
|
||||||
|
Log::Sync();
|
||||||
|
HaltKernel();
|
||||||
default:
|
default:
|
||||||
PanicF("Init returned with unexpected return code %i", status);
|
PanicF("Init returned with unexpected return code %i", status);
|
||||||
}
|
}
|
||||||
|
@ -618,7 +624,7 @@ static void InitThread(void* /*user*/)
|
||||||
|
|
||||||
dtable.Reset();
|
dtable.Reset();
|
||||||
|
|
||||||
static char default_init_cmdline[] = "/bin/init";
|
static char default_init_cmdline[] = "/sbin/init";
|
||||||
if ( !init_cmdline )
|
if ( !init_cmdline )
|
||||||
init_cmdline = default_init_cmdline;
|
init_cmdline = default_init_cmdline;
|
||||||
|
|
||||||
|
|
|
@ -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
|
invokes the
|
||||||
.Xr init 8
|
.Xr init 8
|
||||||
extracted from the initrd as
|
extracted from the initrd as
|
||||||
.Pa /bin/init .
|
.Pa /sbin/init .
|
||||||
.Pp
|
.Pp
|
||||||
The initrd is in the custom format made by
|
The initrd is in the custom format made by
|
||||||
.Xr mkinitrd 8
|
.Xr mkinitrd 8
|
||||||
|
|
|
@ -22,7 +22,7 @@ The kernel extracts the initrd into the initial kernel memory root filesystem
|
||||||
and executes
|
and executes
|
||||||
.Xr init 8
|
.Xr init 8
|
||||||
as
|
as
|
||||||
.Pa /bin/init .
|
.Pa /sbin/init .
|
||||||
The computer is powered off if this process exits 0, rebooted if it exits 1,
|
The computer is powered off if this process exits 0, rebooted if it exits 1,
|
||||||
halted if it exits 2, and paniced otherwise.
|
halted if it exits 2, and paniced otherwise.
|
||||||
.Pp
|
.Pp
|
||||||
|
|
Loading…
Reference in New Issue