Skip to content

Commit c863f44

Browse files
committed
support riscv64
Allows update EFI bootloader on riscv64 similar to aarch64 and x86_64. xref: coreos/fedora-coreos-tracker#1931
1 parent d12e330 commit c863f44

File tree

7 files changed

+141
-31
lines changed

7 files changed

+141
-31
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ that's for tools like `grubby` and `ostree`.
3232
## Status
3333

3434
bootupd supports updating GRUB and shim for UEFI firmware on
35-
x86_64 and aarch64, and GRUB for BIOS firmware on x86_64.
35+
x86_64, aarch64, and riscv64, and GRUB for BIOS firmware on x86_64
36+
and ppc64le.
3637
The project is [deployed in Fedora CoreOS](https://docs.fedoraproject.org/en-US/fedora-coreos/bootloader-updates/) and derivatives,
3738
and is also used by the new [`bootc install`](https://github.com/containers/bootc/#using-bootc-install)
3839
functionality. The bootupd CLI should be considered stable.

src/bootupd.rs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,11 @@ use crate::bios;
33
use crate::component;
44
use crate::component::{Component, ValidationResult};
55
use crate::coreos;
6-
#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))]
6+
#[cfg(any(
7+
target_arch = "x86_64",
8+
target_arch = "aarch64",
9+
target_arch = "riscv64"
10+
))]
711
use crate::efi;
812
use crate::model::{ComponentStatus, ComponentUpdatable, ContentMetadata, SavedState, Status};
913
use crate::util;
@@ -113,7 +117,8 @@ pub(crate) fn install(
113117
#[cfg(any(
114118
target_arch = "x86_64",
115119
target_arch = "aarch64",
116-
target_arch = "powerpc64"
120+
target_arch = "powerpc64",
121+
target_arch = "riscv64"
117122
))]
118123
crate::grubconfigs::install(sysroot, installed_efi_vendor.as_deref(), uuid)?;
119124
// On other architectures, assume that there's nothing to do.
@@ -163,7 +168,7 @@ pub(crate) fn get_components_impl(auto: bool) -> Components {
163168
insert_component(&mut components, Box::new(efi::Efi::default()));
164169
}
165170
}
166-
#[cfg(target_arch = "aarch64")]
171+
#[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))]
167172
insert_component(&mut components, Box::new(efi::Efi::default()));
168173

169174
#[cfg(target_arch = "powerpc64")]
@@ -390,7 +395,11 @@ pub(crate) fn print_status(status: &Status) -> Result<()> {
390395
println!("CoreOS aleph version: {}", coreos_aleph.aleph.version);
391396
}
392397

393-
#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))]
398+
#[cfg(any(
399+
target_arch = "x86_64",
400+
target_arch = "aarch64",
401+
target_arch = "riscv64"
402+
))]
394403
{
395404
let boot_method = if efi::is_efi_booted()? { "EFI" } else { "BIOS" };
396405
println!("Boot method: {}", boot_method);

src/component.rs

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,11 @@ pub(crate) trait Component {
8080
/// Given a component name, create an implementation.
8181
pub(crate) fn new_from_name(name: &str) -> Result<Box<dyn Component>> {
8282
let r: Box<dyn Component> = match name {
83-
#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))]
83+
#[cfg(any(
84+
target_arch = "x86_64",
85+
target_arch = "aarch64",
86+
target_arch = "riscv64"
87+
))]
8488
#[allow(clippy::box_default)]
8589
"EFI" => Box::new(crate::efi::Efi::default()),
8690
#[cfg(any(target_arch = "x86_64", target_arch = "powerpc64"))]
@@ -93,14 +97,22 @@ pub(crate) fn new_from_name(name: &str) -> Result<Box<dyn Component>> {
9397

9498
/// Returns the path to the payload directory for an available update for
9599
/// a component.
96-
#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))]
100+
#[cfg(any(
101+
target_arch = "x86_64",
102+
target_arch = "aarch64",
103+
target_arch = "riscv64"
104+
))]
97105
pub(crate) fn component_updatedirname(component: &dyn Component) -> PathBuf {
98106
Path::new(BOOTUPD_UPDATES_DIR).join(component.name())
99107
}
100108

101109
/// Returns the path to the payload directory for an available update for
102110
/// a component.
103-
#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))]
111+
#[cfg(any(
112+
target_arch = "x86_64",
113+
target_arch = "aarch64",
114+
target_arch = "riscv64"
115+
))]
104116
pub(crate) fn component_updatedir(sysroot: &str, component: &dyn Component) -> PathBuf {
105117
Path::new(sysroot).join(component_updatedirname(component))
106118
}

src/efi.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ pub(crate) const SHIM: &str = "shimaa64.efi";
3636
#[cfg(target_arch = "x86_64")]
3737
pub(crate) const SHIM: &str = "shimx64.efi";
3838

39+
#[cfg(target_arch = "riscv64")]
40+
pub(crate) const SHIM: &str = "shimriscv64.efi";
41+
3942
/// The ESP partition label on Fedora CoreOS derivatives
4043
pub(crate) const COREOS_ESP_PART_LABEL: &str = "EFI-SYSTEM";
4144
pub(crate) const ANACONDA_ESP_PART_LABEL: &str = "EFI\\x20System\\x20Partition";

src/filetree.rs

Lines changed: 95 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,33 +4,61 @@
44
* SPDX-License-Identifier: Apache-2.0
55
*/
66

7-
#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))]
7+
#[cfg(any(
8+
target_arch = "x86_64",
9+
target_arch = "aarch64",
10+
target_arch = "riscv64"
11+
))]
812
use anyhow::{bail, Context, Result};
9-
#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))]
13+
#[cfg(any(
14+
target_arch = "x86_64",
15+
target_arch = "aarch64",
16+
target_arch = "riscv64"
17+
))]
1018
use camino::{Utf8Path, Utf8PathBuf};
11-
#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))]
19+
#[cfg(any(
20+
target_arch = "x86_64",
21+
target_arch = "aarch64",
22+
target_arch = "riscv64"
23+
))]
1224
use openat_ext::OpenatDirExt;
13-
#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))]
25+
#[cfg(any(
26+
target_arch = "x86_64",
27+
target_arch = "aarch64",
28+
target_arch = "riscv64"
29+
))]
1430
use openssl::hash::{Hasher, MessageDigest};
1531
use rustix::fd::BorrowedFd;
1632
use serde::{Deserialize, Serialize};
1733
#[allow(unused_imports)]
1834
use std::collections::{BTreeMap, HashMap, HashSet};
1935
use std::fmt::Display;
20-
#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))]
36+
#[cfg(any(
37+
target_arch = "x86_64",
38+
target_arch = "aarch64",
39+
target_arch = "riscv64"
40+
))]
2141
use std::os::unix::io::AsRawFd;
2242
use std::os::unix::process::CommandExt;
2343
use std::process::Command;
2444

2545
/// The prefix we apply to our temporary files.
26-
#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))]
46+
#[cfg(any(
47+
target_arch = "x86_64",
48+
target_arch = "aarch64",
49+
target_arch = "riscv64"
50+
))]
2751
pub(crate) const TMP_PREFIX: &str = ".btmp.";
2852
// This module doesn't handle modes right now, because
2953
// we're only targeting FAT filesystems for UEFI.
3054
// In FAT there are no unix permission bits, usually
3155
// they're set by mount options.
3256
// See also https://github.com/coreos/fedora-coreos-config/commit/8863c2b34095a2ae5eae6fbbd121768a5f592091
33-
#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))]
57+
#[cfg(any(
58+
target_arch = "x86_64",
59+
target_arch = "aarch64",
60+
target_arch = "riscv64"
61+
))]
3462
const DEFAULT_FILE_MODE: u32 = 0o700;
3563

3664
use crate::sha512string::SHA512String;
@@ -79,7 +107,11 @@ impl FileTreeDiff {
79107
}
80108

81109
impl FileMetadata {
82-
#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))]
110+
#[cfg(any(
111+
target_arch = "x86_64",
112+
target_arch = "aarch64",
113+
target_arch = "riscv64"
114+
))]
83115
pub(crate) fn new_from_path<P: openat::AsPath>(
84116
dir: &openat::Dir,
85117
name: P,
@@ -99,7 +131,11 @@ impl FileMetadata {
99131

100132
impl FileTree {
101133
// Internal helper to generate a sub-tree
102-
#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))]
134+
#[cfg(any(
135+
target_arch = "x86_64",
136+
target_arch = "aarch64",
137+
target_arch = "riscv64"
138+
))]
103139
fn unsorted_from_dir(dir: &openat::Dir) -> Result<HashMap<String, FileMetadata>> {
104140
let mut ret = HashMap::new();
105141
for entry in dir.list_dir(".")? {
@@ -136,7 +172,11 @@ impl FileTree {
136172
}
137173

138174
/// Create a FileTree from the target directory.
139-
#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))]
175+
#[cfg(any(
176+
target_arch = "x86_64",
177+
target_arch = "aarch64",
178+
target_arch = "riscv64"
179+
))]
140180
pub(crate) fn new_from_dir(dir: &openat::Dir) -> Result<Self> {
141181
let mut children = BTreeMap::new();
142182
for (k, v) in Self::unsorted_from_dir(dir)?.drain() {
@@ -147,7 +187,11 @@ impl FileTree {
147187
}
148188

149189
/// Determine the changes *from* self to the updated tree
150-
#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))]
190+
#[cfg(any(
191+
target_arch = "x86_64",
192+
target_arch = "aarch64",
193+
target_arch = "riscv64"
194+
))]
151195
pub(crate) fn diff(&self, updated: &Self) -> Result<FileTreeDiff> {
152196
self.diff_impl(updated, true)
153197
}
@@ -167,7 +211,11 @@ impl FileTree {
167211
current.diff_impl(self, false)
168212
}
169213

170-
#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))]
214+
#[cfg(any(
215+
target_arch = "x86_64",
216+
target_arch = "aarch64",
217+
target_arch = "riscv64"
218+
))]
171219
fn diff_impl(&self, updated: &Self, check_additions: bool) -> Result<FileTreeDiff> {
172220
let mut additions = HashSet::new();
173221
let mut removals = HashSet::new();
@@ -199,7 +247,11 @@ impl FileTree {
199247

200248
/// Create a diff from a target directory. This will ignore
201249
/// any files or directories that are not part of the original tree.
202-
#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))]
250+
#[cfg(any(
251+
target_arch = "x86_64",
252+
target_arch = "aarch64",
253+
target_arch = "riscv64"
254+
))]
203255
pub(crate) fn relative_diff_to(&self, dir: &openat::Dir) -> Result<FileTreeDiff> {
204256
let mut removals = HashSet::new();
205257
let mut changes = HashSet::new();
@@ -233,7 +285,11 @@ impl FileTree {
233285
}
234286

235287
// Recursively remove all files/dirs in the directory that start with our TMP_PREFIX
236-
#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))]
288+
#[cfg(any(
289+
target_arch = "x86_64",
290+
target_arch = "aarch64",
291+
target_arch = "riscv64"
292+
))]
237293
fn cleanup_tmp(dir: &openat::Dir) -> Result<()> {
238294
for entry in dir.list_dir(".")? {
239295
let entry = entry?;
@@ -264,7 +320,11 @@ fn cleanup_tmp(dir: &openat::Dir) -> Result<()> {
264320
}
265321

266322
#[derive(Default, Clone)]
267-
#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))]
323+
#[cfg(any(
324+
target_arch = "x86_64",
325+
target_arch = "aarch64",
326+
target_arch = "riscv64"
327+
))]
268328
pub(crate) struct ApplyUpdateOptions {
269329
pub(crate) skip_removals: bool,
270330
pub(crate) skip_sync: bool,
@@ -274,7 +334,11 @@ pub(crate) struct ApplyUpdateOptions {
274334
// to be bound in nix today. I found https://github.com/XuShaohua/nc
275335
// but that's a nontrivial dependency with not a lot of code review.
276336
// Let's just fork off a helper process for now.
277-
#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))]
337+
#[cfg(any(
338+
target_arch = "x86_64",
339+
target_arch = "aarch64",
340+
target_arch = "riscv64"
341+
))]
278342
pub(crate) fn syncfs(d: &openat::Dir) -> Result<()> {
279343
use rustix::fs::{Mode, OFlags};
280344
let d = unsafe { BorrowedFd::borrow_raw(d.as_raw_fd()) };
@@ -284,7 +348,11 @@ pub(crate) fn syncfs(d: &openat::Dir) -> Result<()> {
284348
}
285349

286350
/// Copy from src to dst at root dir
287-
#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))]
351+
#[cfg(any(
352+
target_arch = "x86_64",
353+
target_arch = "aarch64",
354+
target_arch = "riscv64"
355+
))]
288356
fn copy_dir(root: &openat::Dir, src: &str, dst: &str) -> Result<()> {
289357
use bootc_utils::CommandRunExt;
290358

@@ -304,7 +372,11 @@ fn copy_dir(root: &openat::Dir, src: &str, dst: &str) -> Result<()> {
304372
/// Get first sub dir and tmp sub dir for the path
305373
/// "fedora/foo/bar" -> ("fedora", ".btmp.fedora")
306374
/// "foo" -> ("foo", ".btmp.foo")
307-
#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))]
375+
#[cfg(any(
376+
target_arch = "x86_64",
377+
target_arch = "aarch64",
378+
target_arch = "riscv64"
379+
))]
308380
fn get_first_dir(path: &Utf8Path) -> Result<(&Utf8Path, String)> {
309381
let first = path
310382
.iter()
@@ -316,7 +388,11 @@ fn get_first_dir(path: &Utf8Path) -> Result<(&Utf8Path, String)> {
316388
}
317389

318390
/// Given two directories, apply a diff generated from srcdir to destdir
319-
#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))]
391+
#[cfg(any(
392+
target_arch = "x86_64",
393+
target_arch = "aarch64",
394+
target_arch = "riscv64"
395+
))]
320396
pub(crate) fn apply_diff(
321397
srcdir: &openat::Dir,
322398
destdir: &openat::Dir,

src/main.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
**Boot**loader **upd**ater.
33
44
This is an early prototype hidden/not-yet-standardized mechanism
5-
which just updates EFI for now (x86_64/aarch64 only).
5+
which just updates EFI for now (x86_64/aarch64/riscv64 only).
66
77
But in the future will hopefully gain some independence from
88
ostree and also support e.g. updating the MBR etc.
@@ -24,15 +24,20 @@ mod bootupd;
2424
mod cli;
2525
mod component;
2626
mod coreos;
27-
#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))]
27+
#[cfg(any(
28+
target_arch = "x86_64",
29+
target_arch = "aarch64",
30+
target_arch = "riscv64"
31+
))]
2832
mod efi;
2933
mod failpoints;
3034
mod filesystem;
3135
mod filetree;
3236
#[cfg(any(
3337
target_arch = "x86_64",
3438
target_arch = "aarch64",
35-
target_arch = "powerpc64"
39+
target_arch = "powerpc64",
40+
target_arch = "riscv64"
3641
))]
3742
mod grubconfigs;
3843
mod model;

src/ostreeutil.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,11 @@ use anyhow::Result;
1010
use log::debug;
1111

1212
/// https://github.com/coreos/rpm-ostree/pull/969/commits/dc0e8db5bd92e1f478a0763d1a02b48e57022b59
13-
#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))]
13+
#[cfg(any(
14+
target_arch = "x86_64",
15+
target_arch = "aarch64",
16+
target_arch = "riscv64"
17+
))]
1418
pub(crate) const BOOT_PREFIX: &str = "usr/lib/ostree-boot";
1519
const LEGACY_RPMOSTREE_DBPATH: &str = "usr/share/rpm";
1620
const SYSIMAGE_RPM_DBPATH: &str = "usr/lib/sysimage/rpm";

0 commit comments

Comments
 (0)