Loader.elf, the main build artifact, besides kernel code also contains small
bootfs filesystem. The purpose of bootfs is to provide mkfs.so, zpool.so and
other binaries intended to help create ZFS filesystem on he main drive which
is then populated by upload_manifest.py tool during build process. Once usr.img
is created, the bootfs filesystem, which is still part of the original loader.elf
and therefore usr.img, is no longer necessary to boot OSv image as the ZFS file system
is already created. On average bootfs adds 800K to loader-stripped.elf
which causes unnecessary memory waste and slightly slows down kernel loading.
It is worth pointing out the loader.elf created for ROFS filesystem has empty bootfs.
This patch changes main makefile to produce new artifact - kernel.elf -
that in effect is loader.elf with empty bootfs. The kernel.elf is intended
for direct-kernel boot with firecracker and qemu '-kernel' mode and can be used
to boot with either ZFS or ROFS disk.
This patch alse changes firecracker.elf and run.py with '-k' option to use kernel.elf
instead of loader.elf to boot OSv from.
Signed-off-by: Waldemar Kozaczuk <
jwkoz...@gmail.com>
---
Makefile | 17 ++++++++++++++++-
empty_bootfs.S | 4 ++++
scripts/firecracker.py | 4 ++--
scripts/run.py | 4 +++-
4 files changed, 25 insertions(+), 4 deletions(-)
create mode 100644 empty_bootfs.S
diff --git a/Makefile b/Makefile
index 9401e809..db3c68cf 100644
--- a/Makefile
+++ b/Makefile
@@ -125,7 +125,7 @@ endif
quiet = $(if $V, $1, @echo " $2"; $1)
very-quiet = $(if $V, $1, @$1)
-all: $(out)/loader.img links
+all: $(out)/loader.img links $(out)/kernel.elf
ifeq ($(arch),x64)
all: $(out)/vmlinuz.bin
endif
@@ -1868,6 +1868,19 @@ $(out)/loader.elf: $(stage1_targets) arch/$(arch)/loader.ld $(out)/bootfs.o $(lo
@scripts/libosv.py $(out)/osv.syms $(out)/libosv.ld `scripts/osv-version.sh` | $(CC) -c -o $(out)/osv.o -x assembler -
$(call quiet, $(CC) $(out)/osv.o -nostdlib -shared -o $(out)/libosv.so -T $(out)/libosv.ld, LIBOSV.SO)
+$(out)/kernel.elf: $(stage1_targets) arch/$(arch)/loader.ld $(out)/empty_bootfs.o $(loader_options_dep)
+ $(call quiet, $(LD) -o $@ --defsym=OSV_KERNEL_BASE=$(kernel_base) \
+ --defsym=OSV_KERNEL_VM_BASE=$(kernel_vm_base) --defsym=OSV_KERNEL_VM_SHIFT=$(kernel_vm_shift) \
+ -Bdynamic --export-dynamic --eh-frame-hdr --enable-new-dtags -L$(out)/arch/$(arch) \
+ $(^:%.ld=-T %.ld) \
+ --whole-archive \
+ $(libstdc++.a) $(libgcc_eh.a) \
+ $(boost-libs) \
+ --no-whole-archive $(libgcc.a), \
+ LINK kernel.elf)
+ $(call quiet, $(STRIP) $(out)/kernel.elf -o $(out)/kernel-stripped.elf, STRIP kernel.elf -> kernel-stripped.elf )
+ $(call very-quiet, cp $(out)/kernel-stripped.elf $(out)/kernel.elf)
+
$(out)/bsd/%.o: COMMON += -DSMP -D'__FBSDID(__str__)=extern int __bogus__'
environ_sources = $(addprefix libc/, $(environ_libc))
@@ -1907,6 +1920,8 @@ $(out)/bootfs.bin: scripts/mkbootfs.py $(bootfs_manifest) $(bootfs_manifest_dep)
$(out)/bootfs.o: $(out)/bootfs.bin
$(out)/bootfs.o: ASFLAGS += -I$(out)
+$(out)/empty_bootfs.o: ASFLAGS += -I$(out)
+
$(out)/tools/mkfs/mkfs.so: $(out)/tools/mkfs/mkfs.o $(out)/libzfs.so
$(makedir)
$(call quiet, $(CC) $(CFLAGS) -o $@ $(out)/tools/mkfs/mkfs.o -L$(out) -lzfs, LINK mkfs.so)
diff --git a/empty_bootfs.S b/empty_bootfs.S
new file mode 100644
index 00000000..c72b9d94
--- /dev/null
+++ b/empty_bootfs.S
@@ -0,0 +1,4 @@
+.pushsection .data
+.global bootfs_start
+bootfs_start:
+.popsection
diff --git a/scripts/firecracker.py b/scripts/firecracker.py
index 8656ae79..3cf47c58 100755
--- a/scripts/firecracker.py
+++ b/scripts/firecracker.py
@@ -266,7 +266,7 @@ def main(options):
# Prepare arguments we are going to pass when creating VM instance
kernel_path = options.kernel
if not kernel_path:
- kernel_path = os.path.join(dirname, '../build/release/loader-stripped.elf')
+ kernel_path = os.path.join(dirname, '../build/release/kernel.elf')
qemu_disk_path = options.image
if not qemu_disk_path:
@@ -364,7 +364,7 @@ if __name__ == "__main__":
parser.add_argument("-i", "--image", action="store", default=None, metavar="CMD",
help="path to disk image file. defaults to ../build/release/usr.img")
parser.add_argument("-k", "--kernel", action="store", default=None, metavar="CMD",
- help="path to kernel loader file. defaults to ../build/release/loader-stripped.elf")
+ help="path to kernel loader file. defaults to ../build/release/kernel.elf")
parser.add_argument("-n", "--networking", action="store_true",
help="needs root to setup tap networking first time")
parser.add_argument("-b", "--bridge", action="store", default=None,
diff --git a/scripts/run.py b/scripts/run.py
index 26177d57..76cecb56 100755
--- a/scripts/run.py
+++ b/scripts/run.py
@@ -548,6 +548,8 @@ if __name__ == "__main__":
help="Path to the optional cloud-init image that should be attached to the instance")
parser.add_argument("-k", "--kernel", action="store_true",
help="Run OSv in QEMU kernel mode as PVH.")
+ parser.add_argument("--kernel-path", action="store",
+ help="path to kernel.elf. defaults to build/$mode/kernel.elf")
parser.add_argument("--virtio", action="store", choices=["legacy","transitional","modern"], default="transitional",
help="specify virtio version: legacy, transitional or modern")
parser.add_argument("--arch", action="store", choices=["x86_64","aarch64"], default="x86_64",
@@ -558,7 +560,7 @@ if __name__ == "__main__":
if cmdargs.arch == 'aarch64':
cmdargs.kernel_file = os.path.join(osv_base, "build/%s/loader.img" % cmdargs.opt_path)
else:
- cmdargs.kernel_file = os.path.join(osv_base, "build/%s/loader-stripped.elf" % cmdargs.opt_path)
+ cmdargs.kernel_file = os.path.abspath(cmdargs.kernel_path or os.path.join(osv_base, "build/%s/kernel.elf" % cmdargs.opt_path))
if not os.path.exists(cmdargs.image_file):
raise Exception('Image file %s does not exist.' % cmdargs.image_file)
if cmdargs.cloud_init_image:
--
2.20.1