Complete the kernel bootstrap by adding kexec of Linux from Fiwix.

A tiny bootloader bootstrap has been added to compile the builder-hex0 kernel from hex0 source.
The boot compiler is builder-hex0-x86-stage1.hex0 and builder-hex0-x86-stage1.bin.
The builder-hex0 kernel is now named builder-hex0-x86-stage2.hex0.
The inclusion of a binary seed resolves the problem with the previous strategy which used an
architecture-specific hex0 compiler.

If sysb detects a full disk (i.e. DISK=sda) it now partitions the disk unconditionally because
previously fdisk was reporting existing but empty partitions which resulted in no
parititions being created.

e2fsprogs is now built with --disable-tls because musl was built on Fiwix without full threading
support and mkfs.ext4 was crashing without disabling thread local storage.

kexec-linux writes the linux kernel and initramfs to a RAM drive on Fiwix which ensure
a pre-allocated contiguous memory block. The following is written to the ram drive:
a 32-bit number which is the size of the kernel in bytes, a 32-bit number which is the size
of the initramfs in bytes, followed by the Linux kernel image, followed by the initramfs.

kexec-fiwix invokes a sync syscall to ensure all writes are flushed to
the ram drive and then initiates the kexec by shutting down Fiwix with a reboot syscall.
Fiwix knows whether and how to perform the kexec based on kernel parameters passed to it.
This commit is contained in:
rick-masters 2023-05-10 14:33:42 +00:00
parent e86db47b6e
commit a2fcf1ced9
23 changed files with 633 additions and 277 deletions

Binary file not shown.

View File

@ -0,0 +1,209 @@
# SPDX-FileCopyrightText: 2023 Richard Masters <grick23@gmail.com>
# SPDX-License-Identifier: MIT
#
# Builder-Hex0 is a small bootable machine image which acts as
# a bootloader using a hex0 compiler. It compiles hex0 code starting
# at sector 2, placing the compiled code at address 0x7E00 and then
# and then jumps to the resulting binary.
#
# hex0 is a "language" for binary encoding in hexadecimal
# with support for comments.
# Functions:
# _start
# read_sector
# read
# compile
#------------------------------------------------------------
# Memory:
# 9FC00 - FFFFF BIOS
# 7C00 - 7E00 MBR/code
# 7A00 - 7BFF sector read buffer
# < 7700 real mode stack
#------------------------------------------------------------
# ------------------------------------------------------------
# Stub Entry Point
#
# boot drive is in dl
#
#[7C00][15]
#:_start
# We cannot be sure the registers are initialized to zero so we
# do that first. We far jump to mbr_main in order to set CS.
31 C0 # xor ax, ax
8E D8 # mov ds, ax
8E C0 # mov es, ax
8E D0 # mov ss, ax
BC 00 77 # mov sp, 0x7700
FC # cld ; clear direction flag
#----------------------------------------
# Compile hex0 to binary
# compile(dl=boot_drive):
#[7C0C]
BF 00 7E # mov di, 0x7E00
# this flag is set after the first digit is seen
31 DB # xor bx,bx
#:read_loop
9A 91 7C 00 00 # call read
84 C0 # test al, al
74 4D # jz finish
3C 23 # cmp al, '#'
74 28 # jz skip_comment
3C 3B # cmp ';'
74 24 # jz skip_comment
3C 66 # cmp al, 'f'
7F EB # jg read_loop
3C 61 # cmp al, 'a'
7C 04 # jl maybe_upper
# Handle a to f
2C 57 # sub al, 'a'-10 == 87 = 0x57
EB 23 # jmp maybe_store
#:maybe_upper
3C 46 # cmp al, 'F'
7F DF # jg read_loop
3C 41 # cmp al, 'A'
7C 04 # jl maybe_digit
# Handle A to F
2C 37 # sub al, 'A'-10 == 55 = x37
EB 17 # jmp maybe_store
#:maybe_digit
3C 39 # cmp al, '9'
7F D3 # jg read_loop
3C 30 # cmp al, '0'
7C CF # jl read_loop
# Handle 0 to 9
2C 30 # sub al, '0' == x30
EB 0B # jmp maybe_store
#:skip_comment
9A 91 7C 00 00 # call read
3C 0A # cmp al, '\n'
75 F7 # jnz skip_comment
EB C0 # jmp read_loop
# only store on second digit
#:maybe_store
84 DB # test bl, bl
75 09 # jnz second_digit
# If on first digit, record and keep going
#:first_digit
C0 E0 04 # shl al, 4
88 C7 # mov bh, al
FE C3 # inc bl
EB B3 # jmp read_loop
# If on second digit, store and clear state
#:second_digit
08 C7 # or bh, al
88 F8 # mov al, bh
AA # stosb
31 DB # xor bx, bx
EB AA # jmp read_loop
#:finish
EA 00 7E 00 00 # ljmp $0000:7E00 ; jump to stage2
#[7C6C][ ]
#:read_sector(di = *dest_addr, cx=cylinder/sector, dh = head, dl=drive)
#
# returns: di - next byte to write to
# cx,dh - next disk sector to read from
#
50 # push ax
53 # push bx
89 FB # mov bx, di ; int 13 writes to bx
#:read_one_loop
B4 02 # mov ah, 2 ; rw mode = 02 (read)
B0 01 # mov al, 1 ; num_sectors
CD 13 # int 0x13
72 F8 # jnc read_one_loop
3C 01 # cmp al, 1
75 F4 # jnz read_one_loop
80 F9 3F # cmp cl, 0x3f ; if sector_num == max_sector
74 04 # jz next_head ; goto next_head
FE C1 # inc cl ; else sector_num++;
EB 04 # jmp cleanup
#next_head:
FE C6 # inc dh ; else head_num++
B1 01 # mov cl, 1 ; sector = 1
5B # pop bx
58 # pop ax
CB # retf
#----------------------------------------
# last_read_location
#[7C8C]
02 00 ; last_cylinder/sector
00 ; last_head
FF 01 ; last_byte
#[7C91]
#:read()
53 # push bx
51 # push cx
52 # push dx
56 # push si
57 # push di
# get current position
BB 8C 7C # mov bx, last_read_location
8B 0F # mov cx, [bx]
8A 77 02 # mov dh, [bx+2]
8B 47 03 # mov ax, [bx+3]
#end of sector?
3D FF 01 # cmp ax, 0x01ff
74 03 # je next sector
#nextchar:
40 # inc ax
EB 0F # jmp getchar
#read next sector
BF 00 78 # mov di, 0x7800
9A 6C 7C 00 00 # call read_sector
# save new location and offset
89 0F # mov [bx], cx
88 77 02 # mov [bx+2], dh
31 C0 # xor ax, ax
#getchar:
89 47 03 # mov [bx+3], ax
BE 00 78 # mov si, 0x7800
89 C3 # mov bx, ax
8A 00 # mov al, [si+bx]
#finish:
5F # pop di
5E # pop si
5A # pop dx
59 # pop cx
5B # pop bx
CB # ret

View File

@ -35,11 +35,12 @@ def create_configuration_file(args):
config.write(f"CHROOT_ONLY_SYSA={args.bwrap}\n")
config.write(f"UPDATE_CHECKSUMS={args.update_checksums}\n")
config.write(f"JOBS={args.cores}\n")
config.write("DISK=sda1\n")
config.write(f"INTERNAL_CI={args.internal_ci}\n")
if (args.bare_metal or args.qemu) and not args.kernel:
config.write("DISK=sda\n")
config.write("KERNEL_BOOTSTRAP=True\n")
else:
config.write("DISK=sda1\n")
config.write("KERNEL_BOOTSTRAP=False\n")
config.write(f"BUILD_KERNELS={args.update_checksums or args.build_kernels}\n")

22
sysa.py
View File

@ -193,12 +193,24 @@ class SysA(SysGeneral):
def create_builder_hex0_disk_image(self, image_file_name):
"""Create builder-hex0 disk image"""
run(os.path.join('sysa', 'stage0-posix', 'src',
'bootstrap-seeds', 'POSIX', 'x86', 'hex0-seed'),
os.path.join('kernel-bootstrap', 'builder-hex0-x86.hex0'),
image_file_name)
shutil.copyfile(os.path.join('kernel-bootstrap', 'builder-hex0-x86-stage1.bin'), image_file_name)
with open(image_file_name, 'ab') as image_file:
current_size = os.stat(image_file_name).st_size
while current_size != 510:
image_file.write(b'\0')
current_size += 1
image_file.write(b'\x55')
image_file.write(b'\xAA')
# Append stage2 hex0 source
with open(os.path.join('kernel-bootstrap', 'builder-hex0-x86-stage2.hex0')) as infile:
image_file.write(infile.read().encode())
# Pad to next sector
current_size = os.stat(image_file_name).st_size
while current_size % 512 != 0:
image_file.write(b'\0')
current_size += 1
self.append_srcfs(image_file)
current_size = os.stat(image_file_name).st_size
@ -213,6 +225,6 @@ class SysA(SysGeneral):
# fill file with zeros up to desired size, one megabyte at a time
with open(image_file_name, 'ab') as image_file:
while current_size < 1008 * megabyte:
while current_size < 16384 * megabyte:
image_file.write(b'\0' * megabyte)
current_size += megabyte

View File

@ -40,7 +40,7 @@ d7d0a5fc9117f9b3ebd287851a48716c96a3c11991365edb8890f0e203d3b810 curl-7.88.1_1.
ed1581d1ef5d42c809a7db1c27614e0a900076e7ce08349ea4797944d41c7bc7 dhcpcd-10.0.1_0.tar.bz2
c4008ae6b168aee4120b0f3624a1875f9e413d8f0c637708b8b04a1fb5be173c diffutils-2.7_0.tar.bz2
bda6afcd3a390a34a57443269a4857ccc470129f7a557981778c145fd841cbd1 dist-3.5-236_0.tar.bz2
c0514138e251062c9ac2ff1e432e01a541777bfd61480c77479ea55f5b75cdd1 e2fsprogs-1.45.7_0.tar.bz2
5a5923e9dcbec079b032a349471627460f553a430c82bc9b4b6c0bd34ae97547 e2fsprogs-1.45.7_0.tar.bz2
d7b7453ad400eac1ba39f99971afdc392cb8a92c557ef5d6fd9fa2625124de4a ed-1.4_0.tar.bz2
258282c136145d8fba4d66f7e150800e7ca33e024483083a15d0dba3aeb5e86b file-5.44_0.tar.bz2
5984d3f2d5513dd04dc97619e2809d634fc7e3692f36f770e0202a61b6b2921d findutils-4.2.33_0.tar.bz2

View File

@ -30,6 +30,7 @@ src_prepare() {
src_configure() {
./configure --prefix="${PREFIX}" \
--sbindir="${PREFIX}/bin" \
--disable-tls \
with_udev_rules_dir=no \
with_systemd_unit_dir=no
}

View File

@ -1 +0,0 @@
dd9e799311b3c505fa8efe045b969b851c60499ab41db546e5c8b545b3e19ec8 /boot/fiwix

View File

@ -1 +0,0 @@
https://github.com/rick-masters/Fiwix/releases/download/v1.4.0-lb1/fiwix-1.4.0-lb1.tar.gz ff57d1fbf0547a27dec4d7146eb9c17d01158ca5886de54e5b9bac2bec473ef3

View File

@ -0,0 +1 @@
0de298be5c0b00654ddb226c2e657d4fdd2fa0c613ffb3bb32c23c65d2257bf0 /boot/fiwix

View File

@ -18,9 +18,9 @@ cd build
untar --file ../src/${pkg}.tar
cd ${pkg}
alias as="tcc -m32 -march=i386 -std=c89 -D__KERNEL__ -DMAX_PID_VALUE=64000000 -DCONFIG_MMAP2 -DCONFIG_64BIT_SYSCALLS -DNR_PROCS=4096 -DCHILD_MAX=4096 -DOPEN_MAX=1536 -DNR_OPENS=1536 -DINIT_PROGRAM=\"/init\" -DUTS_SYSNAME=\"Linux\" -D__VERSION__=\"tcc\" -traditional -I/sysa/fiwix-1.4.0-lb1/build/fiwix-1.4.0-lb1/include"
alias as="tcc -m32 -march=i386 -std=c89 -D__KERNEL__ -DMAX_PID_VALUE=64000000 -DCONFIG_MMAP2 -DCONFIG_64BIT_SYSCALLS -DCONFIG_KEXEC -DNR_PROCS=4096 -DCHILD_MAX=4096 -DOPEN_MAX=1536 -DNR_OPENS=1536 -DINIT_PROGRAM=\"/init\" -DUTS_SYSNAME=\"Linux\" -D__VERSION__=\"tcc\" -traditional -I/sysa/fiwix-1.4.0-lb2/build/fiwix-1.4.0-lb2/include"
alias cc="tcc -m32 -march=i386 -std=c89 -D__KERNEL__ -DMAX_PID_VALUE=64000000 -DCONFIG_MMAP2 -DCONFIG_64BIT_SYSCALLS -DNR_PROCS=4096 -DCHILD_MAX=4096 -DOPEN_MAX=1536 -DNR_OPENS=1536 -DINIT_PROGRAM=\"/init\" -DUTS_SYSNAME=\"Linux\" -D__VERSION__=\"tcc\" -I/sysa/fiwix-1.4.0-lb1/build/fiwix-1.4.0-lb1/include -O2 -fno-pie -fno-common -ffreestanding -Wall -Wstrict-prototypes"
alias cc="tcc -m32 -march=i386 -std=c89 -D__KERNEL__ -DMAX_PID_VALUE=64000000 -DCONFIG_MMAP2 -DCONFIG_64BIT_SYSCALLS -DCONFIG_KEXEC -DNR_PROCS=4096 -DCHILD_MAX=4096 -DOPEN_MAX=1536 -DNR_OPENS=1536 -DINIT_PROGRAM=\"/init\" -DUTS_SYSNAME=\"Linux\" -D__VERSION__=\"tcc\" -I/sysa/fiwix-1.4.0-lb2/build/fiwix-1.4.0-lb2/include -O2 -fno-pie -fno-common -ffreestanding -Wall -Wstrict-prototypes"
cd kernel
as -c -o boot.o boot.S
@ -42,6 +42,7 @@ cc -c -o sleep.o sleep.c
cc -c -o signal.o signal.c
cc -c -o process.o process.c
cc -c -o multiboot.o multiboot.c
cc -c -o kexec.o kexec.c
cd syscalls
cc -c -o umount.o umount.c
@ -278,6 +279,7 @@ cc -c -o floppy.o floppy.c
cc -c -o part.o part.c
cc -c -o ata.o ata.c
cc -c -o ata_hd.o ata_hd.c
cc -c -o ata_pci.o ata_pci.c
cc -c -o atapi.o atapi.c
cc -c -o atapi_cd.o atapi_cd.c
cc -c -o ramdisk.o ramdisk.c
@ -321,6 +323,7 @@ tcc -m32 -Wl,-Ttext=0xC0100000 -static -nostdlib -nostdinc \
kernel/signal.o \
kernel/process.o \
kernel/multiboot.o \
kernel/kexec.o \
kernel/syscalls/umount.o \
kernel/syscalls/getgid.o \
kernel/syscalls/getppid.o \
@ -529,6 +532,7 @@ tcc -m32 -Wl,-Ttext=0xC0100000 -static -nostdlib -nostdinc \
drivers/block/part.o \
drivers/block/ata.o \
drivers/block/ata_hd.o \
drivers/block/ata_pci.o \
drivers/block/atapi.o \
drivers/block/atapi_cd.o \
drivers/block/ramdisk.o \

View File

@ -0,0 +1 @@
https://github.com/rick-masters/Fiwix/releases/download/v1.4.0-lb2/fiwix-1.4.0-lb2.tar.gz 44fb14fb666dcf4f5abf7f49eb3f1d92436b9d7353daa23138ff21e9ec78e30f

View File

@ -1 +1 @@
afb30f2e80adefc979bdffdb525cf2862897f0beefbb0740fbd05ab3246a32c9 /usr/bin/kexec-fiwix
4f78914aef30b569a531102998e52a0514d8836204d57ff42bf0a3324968f247 /usr/bin/kexec-fiwix

View File

@ -77,10 +77,10 @@ int main() {
puts("Preparing multiboot info for kernel...");
char cmdline[256];
sprintf(cmdline, "fiwix console=/dev/ttyS0 root=/dev/ram0 ramdisksize=%d initrd=sysa.ext2", INITRD_MB * 1024);
sprintf(cmdline, "fiwix console=/dev/ttyS0 root=/dev/ram0 ramdisksize=%d initrd=sysa.ext2 kexec_proto=linux kexec_size=67000 kexec_cmdline=\"init=/init console=ttyS0\"", INITRD_MB * 1024);
char * boot_loader_name = "kexec-fiwix";
unsigned int next_avail_mem = 0x8000;
unsigned int next_avail_mem = 0x9800;
multiboot_info_t * pmultiboot_info = (multiboot_info_t *) next_avail_mem;
memset(pmultiboot_info, 0, sizeof(multiboot_info_t));

View File

@ -0,0 +1 @@
c0993adf00bd2c110539a310246f0e50d727e09701ed187827c71c64021431f4 /usr/bin/kexec-linux

View File

@ -0,0 +1,16 @@
# SPDX-FileCopyrightText: 2023 Richard Masters <grick23@gmail.com>
# SPDX-License-Identifier: MIT
cd src
tcc -static -m32 -march=i386 -std=c89 -I../../tcc/tcc-0.9.27/include -o ${bindir}/kexec-linux kexec-linux.c
cd ..
# Checksums
if match x${UPDATE_CHECKSUMS} xTrue; then
sha256sum /usr/bin/kexec-linux
sha256sum -o ${pkg}.checksums \
/usr/bin/kexec-linux
cp ${pkg}.checksums ${srcdir}
else
sha256sum -c ${pkg}.checksums
fi

View File

@ -0,0 +1,91 @@
/* SPDX-FileCopyrightText: 2023 Richard Masters <grick23@gmail.com> */
/* SPDX-License-Identifier: MIT */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <time.h>
int append_file(FILE *dst_file, char *src_file_name);
int main(int argc, char **argv) {
char *ramdrive_file_name, *kernel_file_name, *initramfs_file_name;
FILE *ramdrive_file;
struct stat stats;
if (argc < 3) {
puts("Usage: fiwix-kexec-linux <ram-drive-name> <kernel-file-name> <initramfs-file-name>");
exit(1);
}
ramdrive_file_name = argv[1];
kernel_file_name = argv[2];
initramfs_file_name = argv[3];
ramdrive_file = fopen(ramdrive_file_name, "wb");
/* Write length of kernel */
if (stat(kernel_file_name, &stats) == 0) {
fwrite(&stats.st_size, sizeof(stats.st_size), 1, ramdrive_file);
} else {
fprintf(stderr, "Cannot stat kernel file '%s'\n", kernel_file_name);
exit(1);
}
/* Write length of initramfs */
if (stat(initramfs_file_name, &stats) == 0) {
fwrite(&stats.st_size, sizeof(stats.st_size), 1, ramdrive_file);
} else {
fprintf(stderr, "Cannot stat initramfs file '%s'\n", initramfs_file_name);
exit(1);
}
if (append_file(ramdrive_file, kernel_file_name)) {
fprintf(stderr, "Cannot append kernel '%s'\n", kernel_file_name);
exit(1);
}
if (append_file(ramdrive_file, initramfs_file_name)) {
fprintf(stderr, "Cannot append initramfs '%s'\n", initramfs_file_name);
exit(1);
}
fclose(ramdrive_file);
/* Perform syscall sync */
__asm__ __volatile__(
"movl $0x00000024, %%eax\n\t"
"int $0x80\n\t"
: /* no output */
: /* no input */
);
/* Perform syscall reboot to initiate kexec */
__asm__ __volatile__(
"movl $0x58, %%eax\n\t"
"movl $0xfee1dead, %%ebx\n\t"
"movl $0x28121969, %%ecx\n\t"
"movl $0xcdef0123, %%edx\n\t"
"movl $0x00, %%esi\n\t"
"int $0x80\n\t"
: /* no output */
: /* no input */
);
}
int append_file(FILE *dst_file, char *src_file_name) {
FILE *src_file;
char buff[BUFSIZ];
size_t n;
if (src_file = fopen(src_file_name, "rb")) {
while ((n = fread(buff, 1, BUFSIZ, src_file)) != 0) {
fwrite(buff, 1, n, dst_file );
}
fclose(src_file);
return 0;
} else {
printf("Cannot open file '%s'\n", src_file_name);
return 1;
}
}

View File

@ -21,6 +21,7 @@
/usr/bin/checksum-transcriber
/usr/bin/tcc
/usr/bin/tcc-0.9.26
/usr/bin/kexec-linux
/usr/lib/mes/libc.a
/usr/lib/mes/libgetopt.a
/usr/lib/mes/crt1.o

View File

@ -267,6 +267,18 @@ int main(int argc, char **argv)
printf("ext4_mknod error: %d \n", err);
return EXIT_FAILURE;
}
printf("ext4_mknod /mp/dev/ram0\n");
err = ext4_mknod("/mp/dev/ram0", EXT4_DE_BLKDEV, MKDEV(1, 0));
if (err != EOK) {
printf("ext4_mknod error: %d \n", err);
return EXIT_FAILURE;
}
printf("ext4_mknod /mp/dev/ram1\n");
err = ext4_mknod("/mp/dev/ram1", EXT4_DE_BLKDEV, MKDEV(1, 1));
if (err != EOK) {
printf("ext4_mknod error: %d \n", err);
return EXIT_FAILURE;
}
copy_file("/usr/bin/kaem", "/mp/init");
copy_file("/sysa/after2.kaem", "/mp/kaem.run");

View File

@ -1 +1 @@
0a3f0012c01cb5aee0643f1674f265e68b5eeadb37596bcc4fe60aad55c9d3d7 /usr/bin/make_fiwix_initrd
4135d55c65ba001b98804425de67907ba92d281a0582dfd8861d728d19da9e7d /usr/bin/make_fiwix_initrd

View File

@ -57,7 +57,7 @@ fi
if match x${BUILD_FIWIX} xTrue; then
# The Fiwix kernel
pkg="fiwix-1.4.0-lb1"
pkg="fiwix-1.4.0-lb2"
cd ${pkg}
kaem --verbose --file ${pkg}.kaem
cd ..
@ -73,6 +73,12 @@ if match x${BUILD_FIWIX} xTrue; then
cd ${pkg}
kaem --verbose --file ${pkg}.kaem
cd ..
# Live boot loader for Fiwix to Linux
pkg="kexec-linux"
cd ${pkg}
kaem --verbose --file ${pkg}.kaem
cd ..
fi
if match x${KERNEL_BOOTSTRAP} xTrue; then

View File

@ -25,16 +25,20 @@ create_sysb() {
}
go_sysb() {
# Mount proc for kexec
mkdir /proc /etc
mount -t proc proc /proc
# kexec time
echo "Loading kernel + sysb initramfs using kexec"
kexec -l "/boot/linux-4.9.10" --console-serial \
--initrd="/boot/initramfs-sysb.cpio.gz" \
--append="init=/init console=ttyS0"
echo "kexecing into sysb"
kexec -e
if [ "${KERNEL_BOOTSTRAP}" = True ]; then
kexec-linux "/dev/ram1" "/boot/linux-4.9.10" "/boot/initramfs-sysb.cpio.gz"
else
# Mount proc for kexec
mkdir /proc /etc
mount -t proc proc /proc
# kexec time
echo "Loading kernel + sysb initramfs using kexec"
kexec -l "/boot/linux-4.9.10" --console-serial \
--initrd="/boot/initramfs-sysb.cpio.gz" \
--append="init=/init console=ttyS0"
echo "kexecing into sysb"
kexec -e
fi
}
build automake-1.15.1
@ -96,12 +100,7 @@ build musl-1.2.3 '' no-patches
if [ "${CHROOT}" = False ]; then
create_sysb
if [ "${KERNEL_BOOTSTRAP}" = True ]; then
echo "Kernel bootstrapping successful."
echo "NOTE: Transition to Linux and building remaining packages is under development."
else
go_sysb
fi
go_sysb
else
# In chroot mode transition directly into System C.
SYSC=/sysc_image

View File

@ -65,15 +65,15 @@ if [ -z "${DISK}" ] || ! [ -e "/dev/${DISK}" ]; then
echo "DISK=${DISK}" >> /usr/src/bootstrap.cfg
fi
# Is it a full disk, and not a partition
# Is it a full disk, and not a partition?
# shellcheck disable=SC2012
if [ $(($(ls -l "/dev/${DISK}" | sed "s/.*, *//" | sed "s/ .*//") % 8)) -eq 0 ]; then
if ! fdisk -l "/dev/${DISK}" | grep -qE "${DISK}p?[0-9]" ; then
echo "Creating partition table and partition"
echo ";" | sfdisk "/dev/${DISK}"
mkfs.ext4 "/dev/${DISK}1"
DISK="${DISK}1"
fi
echo "Creating partition table..."
echo ";" | sfdisk "/dev/${DISK}"
fdisk -l "/dev/${DISK}"
echo "Creating ext4 partition..."
mkfs.ext4 "/dev/${DISK}1"
DISK="${DISK}1"
fi
echo "export DISK=${DISK}" >> /usr/src/bootstrap.cfg