Skip to content

Commit

Permalink
Add support for RISC-V 64bit architecture
Browse files Browse the repository at this point in the history
Basic support of riscv64 architecture. Shim is not
supported yet, will be added later.

Signed-off-by: Loic Devulder <[email protected]>
  • Loading branch information
ldevulder committed Nov 9, 2023
1 parent e732621 commit 5f44860
Show file tree
Hide file tree
Showing 11 changed files with 228 additions and 38 deletions.
14 changes: 8 additions & 6 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
ARG GO_VERSION=1.20
ARG LEAP_VERSION=15.5
ARG GOLANG_IMAGE
ARG BUILD_OS_DISTRI
ARG BUILD_OS_VERSION

FROM golang:${GO_VERSION}-alpine as elemental-bin
FROM $GOLANG_IMAGE as elemental-bin

ENV CGO_ENABLED=0
WORKDIR /src/
Expand All @@ -27,15 +28,16 @@ RUN go build \
-X github.com/rancher/elemental-toolkit/internal/version.gitCommit=$ELEMENTAL_COMMIT" \
-o /usr/bin/elemental

FROM opensuse/leap:$LEAP_VERSION AS elemental
FROM $BUILD_OS_DISTRI:$BUILD_OS_VERSION AS elemental
# This helps invalidate the cache on each build so the following steps are really run again getting the latest packages
# versions, as long as the elemental commit has changed
ARG ELEMENTAL_COMMIT=""
ENV ELEMENTAL_COMMIT=${ELEMENTAL_COMMIT}

RUN ARCH=$(uname -m); \
if [[ $ARCH == "aarch64" ]]; then ARCH="arm64"; fi; \
zypper install -y --no-recommends xfsprogs \
[[ "${ARCH}" == "aarch64" ]] && ARCH="arm64"; \
zypper --non-interactive install --no-recommends \
xfsprogs \
parted \
util-linux-systemd \
e2fsprogs \
Expand Down
14 changes: 13 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ REPO?=local/elemental-$(FLAVOR)
TOOLKIT_REPO?=local/elemental-toolkit
DOCKER?=docker

# Used for docker build
BUILD_OS_DISTRI?=opensuse/leap
BUILD_OS_VERSION?=15.5
GO_VERSION?=1.20
GOLANG_IMAGE?=golang:$(GO_VERSION)-alpine

GIT_COMMIT ?= $(shell git rev-parse HEAD)
GIT_COMMIT_SHORT ?= $(shell git rev-parse --short HEAD)
GIT_TAG ?= $(shell git describe --candidates=50 --abbrev=0 --tags 2>/dev/null || echo "v0.0.1" )
Expand All @@ -35,7 +41,13 @@ include make/Makefile.test

.PHONY: build
build:
$(DOCKER) build --platform ${PLATFORM} ${DOCKER_ARGS} --build-arg ELEMENTAL_VERSION=${GIT_TAG} --build-arg ELEMENTAL_COMMIT=${GIT_COMMIT} --target elemental -t ${TOOLKIT_REPO}:${VERSION} .
$(DOCKER) build --platform ${PLATFORM} ${DOCKER_ARGS} \
--build-arg ELEMENTAL_VERSION=${GIT_TAG} \
--build-arg ELEMENTAL_COMMIT=${GIT_COMMIT} \
--build-arg BUILD_OS_DISTRI=${BUILD_OS_DISTRI} \
--build-arg BUILD_OS_VERSION=${BUILD_OS_VERSION} \
--build-arg GOLANG_IMAGE=${GOLANG_IMAGE} \
--target elemental -t ${TOOLKIT_REPO}:${VERSION} .

.PHONY: push-toolkit
push-toolkit:
Expand Down
7 changes: 3 additions & 4 deletions examples/green/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ ENV VERSION=${VERSION}

# install kernel, systemd, dracut, grub2 and other required tools
RUN ARCH=$(uname -m); \
if [[ $ARCH == "aarch64" ]]; then ARCH="arm64"; fi; \
[[ "${ARCH}" == "aarch64" ]] && ARCH="arm64"; \
zypper --non-interactive install --no-recommends -- \
kernel-default \
device-mapper \
Expand Down Expand Up @@ -42,6 +42,7 @@ RUN ARCH=$(uname -m); \
less \
sudo \
curl \
iproute2 \
sed

# Just add the elemental cli
Expand All @@ -55,7 +56,7 @@ RUN cp /usr/share/systemd/tmp.mount /etc/systemd/system

# Generate initrd with required elemental services
RUN elemental init -f && \
kernel=$(ls /boot/Image-* | head -n1) && \
kernel=$(ls /boot/Image-* 2>/dev/null | head -n1) && \
if [ -e "$kernel" ]; then ln -sf "${kernel#/boot/}" /boot/vmlinuz; fi && \
rm -rf /var/log/update* && \
>/var/log/lastlog && \
Expand All @@ -70,5 +71,3 @@ RUN echo IMAGE_REPO=\"${REPO}\" >> /etc/os-release && \

# Good for validation after the build
CMD /bin/bash


39 changes: 30 additions & 9 deletions examples/tumbleweed/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,34 @@ ARG VERSION
FROM ${TOOLKIT_REPO}:${VERSION} as TOOLKIT

# OS base image of our choice
FROM opensuse/tumbleweed:latest as OS
ARG BASE_OS_IMAGE=opensuse/tumbleweed
ARG BASE_OS_VERSION=latest
FROM ${BASE_OS_IMAGE}:${BASE_OS_VERSION} as OS
ARG REPO
ARG VERSION
ENV REPO=${REPO}
ENV VERSION=${VERSION}

# install kernel, systemd, dracut, grub2 and other required tools
# Workaround for RISC-V, specific kernel might be needed for some boards
ARG ADD_REPO
ENV ADD_REPO=${ADD_REPO}

# Install kernel, systemd, dracut, grub2 and other required tools
RUN ARCH=$(uname -m); \
if [[ $ARCH == "aarch64" ]]; then ARCH="arm64"; fi; \
zypper --non-interactive install --no-recommends -- \
zypper --non-interactive removerepo repo-update || true; \
if [[ -n "${ADD_REPO}" ]]; then \
zypper --non-interactive addrepo --enable --refresh ${RISCV_REPO} added-repo; \
fi; \
if [[ "${ARCH}" != "riscv64" ]]; then \
ADD_PKGS+=" shim"; \
[[ "${ARCH}" == "aarch64" ]] && ARCH="arm64"; \
fi; \
zypper --non-interactive --gpg-auto-import-keys install --no-recommends -- \
kernel-default \
device-mapper \
dracut \
grub2 \
grub2-${ARCH}-efi \
shim \
haveged \
systemd \
NetworkManager \
Expand All @@ -42,7 +55,10 @@ RUN ARCH=$(uname -m); \
less \
sudo \
curl \
sed
sed \
patch \
iproute2 \
${ADD_PKGS}

# Just add the elemental cli
COPY --from=TOOLKIT /usr/bin/elemental /usr/bin/elemental
Expand All @@ -53,9 +69,16 @@ RUN systemctl enable NetworkManager.service
# This is for automatic testing purposes, do not do this in production.
RUN echo "PermitRootLogin yes" > /etc/ssh/sshd_config.d/rootlogin.conf

# This is patches are fix upstream dracut, see https://github.com/dracutdevs/dracut/pull/2525
ADD patches /
RUN cd /usr/lib/dracut && \
patch -p 1 -f -i /0001-fix-dmsquash-live-restore-compatibility-with-earlier.patch && \
patch -p 1 -f -i /0001-fix-overlayfs-split-overlayfs-mount-in-two-steps.patch && \
rm /*.patch

# Generate initrd with required elemental services
RUN elemental init -f && \
kernel=$(ls /boot/Image-* | head -n1) && \
kernel=$(ls /boot/Image-* 2>/dev/null | head -n1) && \
if [ -e "$kernel" ]; then ln -sf "${kernel#/boot/}" /boot/vmlinuz; fi && \
rm -rf /var/log/update* && \
>/var/log/lastlog && \
Expand All @@ -70,5 +93,3 @@ RUN echo IMAGE_REPO=\"${REPO}\" >> /etc/os-release && \

# Good for validation after the build
CMD /bin/bash


Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
From 0e780720efe6488c4e07af39926575ee12f40339 Mon Sep 17 00:00:00 2001
From: Laszlo Gombos <[email protected]>
Date: Fri, 24 Feb 2023 01:57:19 +0000
Subject: [PATCH] fix(dmsquash-live): restore compatibility with earlier
releases

Follow-up to 40dd5c90e0efcb9ebaa9abb42a38c7316e9706bd .
---
modules.d/90dmsquash-live/dmsquash-live-root.sh | 4 ++++
1 file changed, 4 insertions(+)

diff --git a/modules.d/90dmsquash-live/dmsquash-live-root.sh b/modules.d/90dmsquash-live/dmsquash-live-root.sh
index 62d1b5e7..a98e258c 100755
--- a/modules.d/90dmsquash-live/dmsquash-live-root.sh
+++ b/modules.d/90dmsquash-live/dmsquash-live-root.sh
@@ -403,6 +403,10 @@ fi

ROOTFLAGS="$(getarg rootflags)"

+if [ "$overlayfs" = required ]; then
+ echo "rd.live.overlay.overlayfs=1" > /etc/cmdline.d/dmsquash-need-overlay.conf
+fi
+
if [ -n "$overlayfs" ]; then
if [ -n "$FSIMG" ]; then
mkdir -m 0755 -p /run/rootfsbase
--
2.35.3
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
From bddffedae038ceca263a904e40513a6e92f1b558 Mon Sep 17 00:00:00 2001
From: David Cassany <[email protected]>
Date: Fri, 22 Sep 2023 16:28:48 +0200
Subject: [PATCH] fix(overlayfs): split overlayfs mount in two steps

This commit splits the creation of required overlayfs underlaying
directories and the actual overlayfs mount. This way it is still
possible to mount the overlayfs with the generated sysroot.mount that
dmsquash-live creates.

The overlayfs tree is created in a pre-mount hook so it is executed
before sysroot.mount is started. Otherwise sysroot.mount starts and
fails before mount hooks are executed.

Signed-off-by: David Cassany <[email protected]>
---
modules.d/90overlayfs/module-setup.sh | 1 +
modules.d/90overlayfs/mount-overlayfs.sh | 13 -------------
modules.d/90overlayfs/prepare-overlayfs.sh | 21 +++++++++++++++++++++
3 files changed, 22 insertions(+), 13 deletions(-)
create mode 100755 modules.d/90overlayfs/prepare-overlayfs.sh

diff --git a/modules.d/90overlayfs/module-setup.sh b/modules.d/90overlayfs/module-setup.sh
index 27aa7cfa..893e2dc3 100755
--- a/modules.d/90overlayfs/module-setup.sh
+++ b/modules.d/90overlayfs/module-setup.sh
@@ -15,4 +15,5 @@ installkernel() {

install() {
inst_hook mount 01 "$moddir/mount-overlayfs.sh"
+ inst_hook pre-mount 01 "$moddir/prepare-overlayfs.sh"
}
diff --git a/modules.d/90overlayfs/mount-overlayfs.sh b/modules.d/90overlayfs/mount-overlayfs.sh
index 7e2da1a8..e1d23fb4 100755
--- a/modules.d/90overlayfs/mount-overlayfs.sh
+++ b/modules.d/90overlayfs/mount-overlayfs.sh
@@ -3,24 +3,11 @@
type getarg > /dev/null 2>&1 || . /lib/dracut-lib.sh

getargbool 0 rd.live.overlay.overlayfs && overlayfs="yes"
-getargbool 0 rd.live.overlay.reset -d -y reset_overlay && reset_overlay="yes"
getargbool 0 rd.live.overlay.readonly -d -y readonly_overlay && readonly_overlay="--readonly" || readonly_overlay=""

ROOTFLAGS="$(getarg rootflags)"

if [ -n "$overlayfs" ]; then
- if ! [ -e /run/rootfsbase ]; then
- mkdir -m 0755 -p /run/rootfsbase
- mount --bind "$NEWROOT" /run/rootfsbase
- fi
-
- mkdir -m 0755 -p /run/overlayfs
- mkdir -m 0755 -p /run/ovlwork
- if [ -n "$reset_overlay" ] && [ -h /run/overlayfs ]; then
- ovlfsdir=$(readlink /run/overlayfs)
- info "Resetting the OverlayFS overlay directory."
- rm -r -- "${ovlfsdir:?}"/* "${ovlfsdir:?}"/.* > /dev/null 2>&1
- fi
if [ -n "$readonly_overlay" ] && [ -h /run/overlayfs-r ]; then
ovlfs=lowerdir=/run/overlayfs-r:/run/rootfsbase
else
diff --git a/modules.d/90overlayfs/prepare-overlayfs.sh b/modules.d/90overlayfs/prepare-overlayfs.sh
new file mode 100755
index 00000000..87bcc196
--- /dev/null
+++ b/modules.d/90overlayfs/prepare-overlayfs.sh
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+type getarg > /dev/null 2>&1 || . /lib/dracut-lib.sh
+
+getargbool 0 rd.live.overlay.overlayfs && overlayfs="yes"
+getargbool 0 rd.live.overlay.reset -d -y reset_overlay && reset_overlay="yes"
+
+if [ -n "$overlayfs" ]; then
+ if ! [ -e /run/rootfsbase ]; then
+ mkdir -m 0755 -p /run/rootfsbase
+ mount --bind "$NEWROOT" /run/rootfsbase
+ fi
+
+ mkdir -m 0755 -p /run/overlayfs
+ mkdir -m 0755 -p /run/ovlwork
+ if [ -n "$reset_overlay" ] && [ -h /run/overlayfs ]; then
+ ovlfsdir=$(readlink /run/overlayfs)
+ info "Resetting the OverlayFS overlay directory."
+ rm -r -- "${ovlfsdir:?}"/* "${ovlfsdir:?}"/.* > /dev/null 2>&1
+ fi
+fi
--
2.35.3
1 change: 1 addition & 0 deletions pkg/constants/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ const (
Archx86 = "x86_64"
ArchArm64 = "arm64"
ArchAarch64 = "aarch64"
ArchRiscV64 = "riscv64"

Fedora = "fedora"
Ubuntu = "ubuntu"
Expand Down
1 change: 1 addition & 0 deletions pkg/live/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ const (
efiBootPath = "/EFI/BOOT"
efiImgX86 = "bootx64.efi"
efiImgArm64 = "bootaa64.efi"
efiImgRiscV64 = "bootriscv64.efi"
grubCfg = "grub.cfg"
grubPrefixDir = "/boot/grub2"
isoBootCatalog = "/boot/boot.catalog"
Expand Down
47 changes: 34 additions & 13 deletions pkg/live/green.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,14 @@ func NewGreenLiveBootLoader(cfg *v1.BuildConfig, spec *v1.LiveISO) *GreenLiveBoo

func (g *GreenLiveBootLoader) PrepareEFI(rootDir, uefiDir string) error {
const (
grubEfiImageX86 = "/usr/share/grub2/x86_64-efi/grub.efi"
grubEfiImageArm64 = "/usr/share/grub2/arm64-efi/grub.efi"
shimBasePathX86 = "/usr/share/efi/x86_64"
shimBasePathArm64 = "/usr/share/efi/aarch64"
shimImg = "shim.efi"
mokManager = "MokManager.efi"
grubEfiImageX86 = "/usr/share/grub2/x86_64-efi/grub.efi"
grubEfiImageArm64 = "/usr/share/grub2/arm64-efi/grub.efi"
grubEfiImageRiscV64 = "/usr/share/grub2/riscv64-efi/grub.efi"
shimBasePathX86 = "/usr/share/efi/x86_64"
shimBasePathArm64 = "/usr/share/efi/aarch64"
shimBasePathRiscV64 = "/usr/share/efi/riscv64"
shimImg = "shim.efi"
mokManager = "MokManager.efi"
)

err := utils.MkdirAll(g.buildCfg.Fs, filepath.Join(uefiDir, efiBootPath), constants.DirPerm)
Expand All @@ -68,6 +70,15 @@ func (g *GreenLiveBootLoader) PrepareEFI(rootDir, uefiDir string) error {
filepath.Join(rootDir, grubEfiImageArm64),
efiImgArm64,
)
case constants.ArchRiscV64:
// No shim/MOK in RISC-V
err = g.copyEfiFiles(
uefiDir,
filepath.Join(rootDir, grubEfiImageRiscV64),
"",
filepath.Join(rootDir, grubEfiImageRiscV64),
efiImgRiscV64,
)
default:
err = fmt.Errorf("Not supported architecture: %v", g.buildCfg.Platform.Arch)
}
Expand All @@ -79,15 +90,25 @@ func (g *GreenLiveBootLoader) PrepareEFI(rootDir, uefiDir string) error {
}

func (g *GreenLiveBootLoader) copyEfiFiles(uefiDir, shimImg, mokManager, grubImg, efiImg string) error {
err := utils.CopyFile(g.buildCfg.Fs, shimImg, filepath.Join(uefiDir, efiBootPath, efiImg))
if err != nil {
return err
var err error

// No shim in some architecture
if shimImg != "" {
err = utils.CopyFile(g.buildCfg.Fs, shimImg, filepath.Join(uefiDir, efiBootPath, efiImg))
if err != nil {
return err
}
}
err = utils.CopyFile(g.buildCfg.Fs, grubImg, filepath.Join(uefiDir, efiBootPath))
if err != nil {
return err

// No MOK in some architecture
if mokManager != "" {
err = utils.CopyFile(g.buildCfg.Fs, mokManager, filepath.Join(uefiDir, efiBootPath))
if err != nil {
return err
}
}
return utils.CopyFile(g.buildCfg.Fs, mokManager, filepath.Join(uefiDir, efiBootPath))

return utils.CopyFile(g.buildCfg.Fs, grubImg, filepath.Join(uefiDir, efiBootPath))
}

func (g *GreenLiveBootLoader) PrepareISO(rootDir, imageDir string) error {
Expand Down
4 changes: 4 additions & 0 deletions pkg/types/v1/platform.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,8 @@ func archToGolangArch(arch string) (string, error) {
return constants.ArchArm64, nil
case constants.ArchAarch64:
return constants.ArchArm64, nil
case constants.ArchRiscV64:
return constants.ArchRiscV64, nil
default:
return "", errInvalidArch
}
Expand All @@ -132,6 +134,8 @@ func golangArchToArch(arch string) (string, error) {
return constants.ArchArm64, nil
case constants.ArchAarch64:
return constants.ArchArm64, nil
case constants.ArchRiscV64:
return constants.ArchRiscV64, nil
default:
return "", errInvalidArch
}
Expand Down
Loading

0 comments on commit 5f44860

Please sign in to comment.