Giter Site home page Giter Site logo

oreboot / oreboot Goto Github PK

View Code? Open in Web Editor NEW
1.5K 37.0 100.0 83.46 MB

oreboot is a fork of coreboot, with C removed, written in Rust.

License: GNU General Public License v2.0

Assembly 2.17% Go 0.41% Rust 95.17% Makefile 1.05% ASL 0.98% Shell 0.04% BitBake 0.17%
oreboot rust hacktoberfest bootloader firmware linux os riscv

oreboot's Introduction

oreboot README

Build Status

oreboot logo

oreboot is a downstream fork of coreboot, i.e. oreboot is coreboot without 'c'.

oreboot is mostly written in Rust, with assembly where needed.

oreboot currently only plans to support LinuxBoot payloads.

Demos

Output sample from oreboot on Allwinner D1
oreboot 🦀
v 13
cpu_pll fa001000
cpu_axi 5000100
cpu_axi 5000100
peri0_ctrl was: f8216300
peri0_ctrl lock en
peri0_ctrl PLLs
peri0_ctrl set: f8216300
DDR3@792MHz
test OK
512M 🐏
NOR flash: c2/2018
load 00018000 bytes to 40000000: ➡️.
load 00fc0000 bytes to 44000000: ➡️➡️➡️➡️➡️➡️➡️➡️➡️➡️➡️➡️➡️➡️➡️➡️.
load 00010000 bytes to 41a00000: ➡️.
{ɕ serial uart0 initialized
RISC-V vendor 5b7 arch 0 imp 0
==== platform CSRs ====
   MXSTATUS  c0408000
   MHCR      00000109
   MCOR      00000002
   MHINT     00004000
see C906 manual p581 ff
=======================
Set up extension CSRs
==== platform CSRs ====
   MXSTATUS  c0638000
   MHCR      0000017f
   MCOR      00000003
   MHINT     0000610c
see C906 manual p581 ff
=======================
timer init
reset init
ipi init
RustSBI version 0.3.1
.______       __    __      _______.___________.  _______..______   __
|   _  \     |  |  |  |    /       |           | /       ||   _  \ |  |
|  |_)  |    |  |  |  |   |   (----`---|  |----`|   (----`|  |_)  ||  |
|      /     |  |  |  |    \   \       |  |      \   \    |   _  < |  |
|  |\  \----.|  `--'  |.----)   |      |  |  .----)   |   |  |_)  ||  |
| _| `._____| \______/ |_______/       |__|  |_______/    |______/ |__|
Platform Name: T-HEAD Xuantie Platform
Implementation: oreboot version 0.1.0
[rustsbi] misa: RV64ACDFIMSUVX
[rustsbi] mideleg: ssoftstimersext (0x222)
[rustsbi] medeleg: imaialmalasmasauecallipagelpagespage(0xb1f3)
[rustsbi] mie: msoft ssoft mtimer stimer mext sext (00000aaa)
PMP0     0x0 - 0x40000000 (A,R,W,X)
PMP1     0x40000000 - 0x40200000 (A,R)
PMP2     0x40200000 - 0x80000000 (A,R,W,X)
PMP3     0x80000000 - 0x80200000 (A,R)
PMP4     0x80200000 - 0xfffff800 (A,R,W,X)
PMP8     0x0 - 0x0 (A,R,W,X)
DTB looks fine, yay!
Decompress 12375521 bytes from 0x44000004 to 0x40200000, reserved 25165824 bytes
Success, decompressed 21910144 bytes :)
Payload looks like Linux Image, yay!
DTB still fine, yay!
Handing over to SBI, will continue at 0x40200000
enter supervisor at 40200000 with DTB from 41a00000
...
[    0.000000] OF: fdt: Ignoring memory range 0x40000000 - 0x40200000
[    0.000000] Machine model: Sipeed Lichee RV Dock
[    0.000000] earlycon: sbi0 at I/O port 0x0 (options '')
[    0.000000] printk: bootconsole [sbi0] enabled
[    0.000000] Zone ranges:
[    0.000000]   DMA32    [mem 0x0000000040200000-0x000000005fffffff]
[    0.000000]   Normal   empty
[    0.000000] Movable zone start for each node
[    0.000000] Early memory node ranges
[    0.000000]   node   0: [mem 0x0000000040200000-0x000000005fffffff]
[    0.000000] Initmem setup node 0 [mem 0x0000000040200000-0x000000005fffffff]
[    0.000000] riscv: SBI specification v1.0 detected
[    0.000000] riscv: SBI implementation ID=0x4 Version=0x301
[    0.000000] riscv: SBI TIME extension detected
[    0.000000] riscv: SBI IPI extension detected
[    0.000000] riscv: SBI SRST extension detected
[    0.000000] riscv: base ISA extensions acdfim
[    0.000000] riscv: ELF capabilities acdfim
[    0.000000] percpu: Embedded 17 pages/cpu s31912 r8192 d29528 u69632
[    0.000000] Built 1 zonelists, mobility grouping on.  Total pages: 128520
[    0.000000] Kernel command line: console=tty0 console=ttyS0,115200 loglevel=7 earlycon=sbi

Rust Embedded

Rust Embedded Working Group Logo

We build on top of the abstractions from the Rust Embedded Working Group's model with its crates and traits, detailed in their book.

In a nutshell: Rust Embedded Model

Vendor support

SoC vendors are expected to provide documentation to their cores, peripherals and other blocks and/or their SVD files, so that we can generate the PAC and HAL crates, or ideally, the vendor should provide and maintain those as well.

The Rust Embedded book offers design patterns and implementation guidelines as well as a glossary to gain an understanding of the structure.

Boot Flow and Setup

To get a general understanding of how oreboot and firmware in general works, have a look at the boot flow documentation. It describes how firmware is stored and boots up on a platform / SoC.

Getting oreboot

Clone this repo and enter its directory, i.e.:

git clone git://github.com/oreboot/oreboot
cd oreboot

Prerequisites

In general, you will need the following packages installed:

  • device-tree-compiler
  • pkg-config
  • libssl
  • rustup

For Debian based systems, there is a make target to install those, which pulls rustup through curl from https://sh.rustup.rs:

make debiansysprepare

Otherwise, install the package through your system package manager.

Setting up the toolchain

Regardless of your OS, you will need to install the toolchain for oreboot. This command only needs to be done once but it is safe to do it repeatedly.

make firsttime

Keeping build tools up to date

Each time you start to work with oreboot, or even daily:

cd oreboot
make update

You should definitely do this before reporting any issues.

Developing oreboot

There are two different things in the project:

  1. src/mainboards/* the actual targets; those depend on and share crates, which can be drivers, SoC init code, and similar. For mainboards, Cargo.lock must be tracked.
  2. src/* everything else; these are the aforementioned crates, for which, we do not track the Cargo.lock files.

Checking in a mainboard's Cargo.lock file records the state of its dependencies at the time of a successful build, enabling reproducibility. Ideally, a lock file is updated follwoing successful boot on hardware.

For more, see: https://doc.rust-lang.org/cargo/faq.html#why-do-binaries-have-cargolock-in-version-control-but-not-libraries

When creating a new mainboard, looking at how others are set up for the same architecture is a good start. Be aware that oreboot is targeting bare metal, so there is no standard library available.

Building oreboot

To build oreboot for a specific platform, do this:

# Go to the mainboard's directory
cd src/mainboard/sunxi/nezha
# Build the mainboard target
make mainboard
# View disassembly
make objdump
# Run from RAM without flashing
make run
# Flash to the board
make flash

The root Makefile allows you to quickly build all platforms:

# build all mainboards
make mainboards
# build everything in parallel
make -j mainboards

QEMU

# Install QEMU for your target platform, e.g. x86
sudo apt install qemu-system-x86

# Build release build and start with QEMU
cd src/mainboard/emulation/qemu-q35 && make run
# Quit qemu with CTRL-A X

To build QEMU from source for RISC-V:

git clone https://github.com/qemu/qemu && cd qemu
mkdir build-riscv64 && cd build-riscv64
../configure --target-list=riscv64-softmmu
make -j$(nproc)
# QEMU binary is at riscv64-softmmu/qemu-system-riscv64

To build QEMU from source for aarch64:

git clone https://github.com/qemu/qemu && cd qemu
mkdir build-aarch64 && cd build-aarch64
../configure --target-list=aarch64-softmmu
make -j$(nproc)
# QEMU binary is at aarch64-softmmu/qemu-system-aarch64

Mainboards

Similar to coreboot, the structure in oreboot is per vendor and mainboard. Multiple architectures and SoCs are supported respectively, and their common code is shared between the boards. Boards may have variants if minor deviations would otherwise cause too much code duplication.

Emulation

  • qemu-riscv

Hardware

RISC-V

Allwinner D1 SoC
  • Sipeed Lichee RV Dock / Dock Pro
  • MangoPi MQ-Pro
  • DongshanPi Nezha STU
  • Allwinner Nezha

Previous Implementations

For reference, earlier approaches are documented. Have a look at those for x86 and Arm platforms and mainboards.

Parked for Revival

Earlier emulation targets have been parked in src.broken/mainboard/emulation/. They are supposed to provide a general understanding of each architecture that oreboot seeks to support:

  • qemu-armv7
  • qemu-aarch64
  • qemu-q35

Ground Rules

  • Makefiles must be simple. Use xtask instead for control flow, e.g., adding headers or checksums to the binaries, sitchting images, etc..
  • Cargo.toml in the respective src/mainboard/$VENDOR/$BOARD (sub)directories allow for board-specific dependencies and building all stages in parallel.
  • All code and markup is auto-formatted with make format with no exceptions. A CI check will tell if a change does not adhere to the formatting rules.
  • There will be no code written in C. We write all code in Rust.
  • We will not run our own Gerrit. We are using GitHub for now, and the GitHub Pull Request review mechanism.
  • We will not run our own Jenkins. We will use the most appropriate CI; for now, that is GitHub, but we will be flexible.

Copyright and License

The copyright on oreboot is owned by quite a large number of individual developers and companies. Please check the individual source files for details.

oreboot is licensed under the terms of the GNU General Public License (GPL). Some files are licensed under the "GPL (version 2, or any later version)", and some files are licensed under the "GPL, version 2". For some parts, which were derived from other projects, other (GPL-compatible) licenses may apply. Please check the individual source files for details.

This makes the resulting oreboot images licensed under the GPL, version 2.

oreboot's People

Contributors

arthurheymans avatar ebiederm avatar elyesh avatar fishbaoz avatar furquan-goog avatar gabemblack avatar hailfinger avatar i-c-o-n avatar jwerner-chromium avatar kmalkki avatar leeleahy avatar lijianzhao2017 avatar madscientist159 avatar marcj303 avatar marshall-dawson avatar mrchromebox avatar mrnuke avatar myleswatson avatar n-huber avatar neuschaefer avatar orangecms avatar paulepanter avatar pgeorgi avatar phcoder avatar reinauer avatar rminnich avatar siro20 avatar subrata-b avatar svenschnelle avatar uwehermann avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

oreboot's Issues

powernv/pseries ppc64[le] support

The Talos II, Talos II Lite and Blackbird motherboards with IBM POWER9 and later CPUs require no binary blobs to run

Judging from the README, this target should qualify for inclusion in this projet.

Opening this issue to track progress! 💫

Add function to perform debug prints

Currently, it's difficult to perform "printf() debugging". If you want to place a debug print into an arbitrary function, you must pass the uart0 driver or w through the entire call stack which can be a fair bit of work.

It would be much more convenient if there were some global debug print function.

However, it seems Rust is averse to having global mutable state like this. From my current understanding, there would need to be an unsafe somewhere in there (which I think is okay if there's no other way).

Adapt oreboot runtime based on DT

As mentioned in #144 oreboot could look at the device tree that has been passed to it and use that to decide what to initialise. The DT could also be used to make the Rust code more generic as we could obtain addresses and other information from the DT instead of hard coding it.

This would probably increase the complexity of oreboot, but as we already had FDT logic it shouldn't be too bad.

Thoughts?

We are overusing trait objects

We need to rethink our use of trait objects

sphinxc0re [1:21 AM]
I see that there are a lot of trait objects in the current codebase.

I don't think that's good. We should use generics whenever we can.
For lists of abstract objects, there is no other way though.
We couldn't do Vec<T> where T: Driver
because that would mean we had a list of all the same driver

rminnich [8:10 AM]
if we used &Driver more could we then use generics instead of traits? I did get to the writeups on why generics are frequently better than traits and your point is well taken, esp. in the romstage. How can we reduce trait usage?

sphinxc0re [8:36 AM]
We would still use traits but not necessarily trait objects anymore.
We can look for places in the code, where trait objects are used in a field or parameter situation. In those cases you can usually swap them out for generics that implement that trait
or in some rare cases just do impl Trait

Make it less painful to switch between link.ld and link_hw.ld

Right now there are two pain points:

  • You have to copy back-and-forth between link.ld and link_hw.ld when switching back-and-forth between qemu and hardware.
  • cargo-make is oblivious to changes in linker files, so you must remember to manually delete the target directory. "rm -rf target"

Alternatively, we can have a single linker script if we find the right setting to enable position independent code.

cargo objcopy invocation incompatible with cargo-binutils 0.2.0

My build failed at the cargo obj-copy step with the message:

RUST_TARGET_PATH=/usr/local/google/home/foton/src/oreboot/src/custom_targets cargo objcopy -- -O binary -R .bss target/riscv64imac-unknown-none-elf/release/hifive target/riscv64imac-unknown-none-elf/release/bootblob.bin
    Finished dev [unoptimized + debuginfo] target(s) in 0.02s
/usr/local/google/home/foton/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/bin/llvm-objcopy: error: too many positional arguments
make: *** [../../../../Makefile.inc:45: target/riscv64imac-unknown-none-elf/release/bootblob.bin] Error 1

After reading the docs and noting a discrepancy with what @rjoleary saw in cargo objcopy --help, we determined that the argument structure changed between cargo-binutils 0.1.6 and 0.2.0. The new syntax moves the source argument to --bin _executable_name_. This appears to be a backwards-and forwards-compatible change.

Turn on CI

  • Use azure pipelines
  • Run tests in qemu

Setup system to allow end-users to configure the build

Coreboot has kconfig and "make menuconfig". This provides UI to discover and change build settings.

Right now for oreboot, we use conditional compilation to select which drivers to include. This does not seem to extend far beyond turning features on/off.

For example, we need a mechanism for the end-user to specify a path to the kernel they want to include.

Build is broken

oreboot is unable to link. I see this error:

error: linking with `rust-lld` failed: exit code: 1
  |
  = note: "rust-lld" "-flavor" "gnu" "-L" "/home/vsts/work/1/s/src/mainboard/sifive/hifive/target/sysroot/lib/rustlib/riscv64imac-unknown-none-elf/lib" "/home/vsts/work/1/s/src/mainboard/sifive/hifive/target/riscv64imac-unknown-none-elf/release/deps/hifive-5d67b9f37960cb79.hifive.eefz7yfk-cgu.5.rcgu.o" "-o" "/home/vsts/work/1/s/src/mainboard/sifive/hifive/target/riscv64imac-unknown-none-elf/release/deps/hifive-5d67b9f37960cb79" "--gc-sections" "-L" "/home/vsts/work/1/s/src/mainboard/sifive/hifive/target/riscv64imac-unknown-none-elf/release/deps" "-L" "/home/vsts/work/1/s/src/mainboard/sifive/hifive/target/release/deps" "-L" "/home/vsts/work/1/s/src/mainboard/sifive/hifive/target/sysroot/lib/rustlib/riscv64imac-unknown-none-elf/lib" "-Bstatic" "/home/vsts/work/1/s/src/mainboard/sifive/hifive/target/sysroot/lib/rustlib/riscv64imac-unknown-none-elf/lib/libcompiler_builtins-94979fc64732be66.rlib" "-Tlink.ld" "-Bdynamic"
  = note: rust-lld: error: undefined symbol: __atomic_load_16
          >>> referenced by compiler_builtins.4xlgpysu-cgu.3
          >>>               compiler_builtins-94979fc64732be66.compiler_builtins.4xlgpysu-cgu.3.rcgu.o:(__llvm_memcpy_element_unordered_atomic_16) in archive /home/vsts/work/1/s/src/mainboard/sifive/hifive/target/sysroot/lib/rustlib/riscv64imac-unknown-none-elf/lib/libcompiler_builtins-94979fc64732be66.rlib
          >>> referenced by compiler_builtins.4xlgpysu-cgu.3
          >>>               compiler_builtins-94979fc64732be66.compiler_builtins.4xlgpysu-cgu.3.rcgu.o:(__llvm_memmove_element_unordered_atomic_16) in archive /home/vsts/work/1/s/src/mainboard/sifive/hifive/target/sysroot/lib/rustlib/riscv64imac-unknown-none-elf/lib/libcompiler_builtins-94979fc64732be66.rlib
          >>> referenced by compiler_builtins.4xlgpysu-cgu.3
          >>>               compiler_builtins-94979fc64732be66.compiler_builtins.4xlgpysu-cgu.3.rcgu.o:(__llvm_memmove_element_unordered_atomic_16) in archive /home/vsts/work/1/s/src/mainboard/sifive/hifive/target/sysroot/lib/rustlib/riscv64imac-unknown-none-elf/lib/libcompiler_builtins-94979fc64732be66.rlib
          
          rust-lld: error: undefined symbol: __atomic_store_16
          >>> referenced by compiler_builtins.4xlgpysu-cgu.3
          >>>               compiler_builtins-94979fc64732be66.compiler_builtins.4xlgpysu-cgu.3.rcgu.o:(__llvm_memcpy_element_unordered_atomic_16) in archive /home/vsts/work/1/s/src/mainboard/sifive/hifive/target/sysroot/lib/rustlib/riscv64imac-unknown-none-elf/lib/libcompiler_builtins-94979fc64732be66.rlib
          >>> referenced by compiler_builtins.4xlgpysu-cgu.3
          >>>               compiler_builtins-94979fc64732be66.compiler_builtins.4xlgpysu-cgu.3.rcgu.o:(__llvm_memmove_element_unordered_atomic_16) in archive /home/vsts/work/1/s/src/mainboard/sifive/hifive/target/sysroot/lib/rustlib/riscv64imac-unknown-none-elf/lib/libcompiler_builtins-94979fc64732be66.rlib
          >>> referenced by compiler_builtins.4xlgpysu-cgu.3
          >>>               compiler_builtins-94979fc64732be66.compiler_builtins.4xlgpysu-cgu.3.rcgu.o:(__llvm_memmove_element_unordered_atomic_16) in archive /home/vsts/work/1/s/src/mainboard/sifive/hifive/target/sysroot/lib/rustlib/riscv64imac-unknown-none-elf/lib/libcompiler_builtins-94979fc64732be66.rlib
          >>> referenced by compiler_builtins.4xlgpysu-cgu.3
          >>>               compiler_builtins-94979fc64732be66.compiler_builtins.4xlgpysu-cgu.3.rcgu.o:(__llvm_memset_element_unordered_atomic_16) in archive /home/vsts/work/1/s/src/mainboard/sifive/hifive/target/sysroot/lib/rustlib/riscv64imac-unknown-none-elf/lib/libcompiler_builtins-94979fc64732be66.rlib

It happens locally and on Azure: https://dev.azure.com/azure0427/Oreboot%20Pipeline/_build/results?buildId=338

Cargo-make issues

cargo-make is deficient in the following areas:

  1. Config variables: Ideally, the end user can customize compile-time constants such as the baudrate. Something like, but not necessarily, kconfig is desired.
  2. Duplication: Each mainboard has a Makefile.toml which is nearly identical. Ideally, some of the logic here can be shared across mainboards.
  3. Incremental builds: Changes to some files do not trigger a rebuild. A few times, I have accidentally used an older build.

Hello from the embedded WG!

Hi,

I am from Rust's embedded devices working group and by chance I stumbled over your interesting project here.
We're glad you find our (and Tock's) registers crate useful.
I just wanted to drop you a note that in the WG, for drivers we often use a pattern that leverages the Deref trait that gives the code a nicer look and eases access to registers.

Example from here:

#[allow(non_snake_case)]
#[repr(C)]
pub struct RegisterBlock {
    DR: ReadWrite<u32>,                   // 0x00
}

pub struct PL011Uart {
    base_addr: usize,
}

impl ops::Deref for PL011Uart {
    type Target = RegisterBlock;

    fn deref(&self) -> &Self::Target {
        unsafe { &*self.ptr() }
    }
}

impl PL011Uart {
    pub fn new(base_addr: usize) -> PL011Uart {
        PL011Uart { base_addr }
    }

    /// Returns a pointer to the register block
    fn ptr(&self) -> *const RegisterBlock {
        self.base_addr as *const _
}

This enables you to access the registers like in the following, not needing manual dereference on each access and the unsafe keyword is already encapsulated as well:

self.DR.set(c)

Maybe you'll find it useful.

In case that during your project, you encounter any place where you find a lack of generic embedded infrastructure crates, feel free to drop us a note.
We're always interested in what the real world needs.

Enable DCO

Check that the commit message has a signed-off-by line.

Checksum payloads

The checksum would check the integrity of the payload and print an error if it doesn't match. This isn't for security.

Reduce size of compiled Rust code

We're noticing the size of the bootblob is already around 10x larger than the boot block in coreboot.

For this issue:

  • Measure the size of the generated Rust code
  • Find out why it is larger
  • Try to reduce it (compiler flags, removing symbols, ...)

Improve usability of layoutflash tool

  • "No such file or directory" error message should also print the file which could not be found.
  • If a file is too big to fit into the flash area, an error message should be printed. Currently, the tool silently does something bizarre.
  • If two or more areas overlap, print an appropriate error message.
  • Automatically calculate the offset of the area based on the sizes of the previous areas.

Run "cargo make" without RUST_TARGET_PATH

Currently, our use of cargo make requires you to set the RUST_TARGET_PATH environment variable as seen in the main README. Find a setting to make this automatic.

OpenTitan: oreboot needs flash header to load properly

In Tock on OpenTitan, we discovered that Tock was broken by lowRISC/opentitan@4425b28, as described in tock/tock#1460 (comment). It appears that oreboot has the same problem: its layout will need to be updated to reflect the flash header that the OpenTitan boot ROM is looking for. To get oreboot working after lowRISC/opentitan@4425b28, the flash header will need to be at 0x20000000; this fix gets oreboot working again:

diff --git a/src/mainboard/opentitan/crb/link.ld b/src/mainboard/opentitan/crb/link.ld
index 712cec6cc3..691e922eef 100644
--- a/src/mainboard/opentitan/crb/link.ld
+++ b/src/mainboard/opentitan/crb/link.ld
@@ -28,6 +28,10 @@ SECTIONS
 {
 
     . = 0x20000000;
+    .flash_header :
+    {
+        LONG(_boot);
+    }
     .bootblock :
     {
         KEEP(*(.bootblock.boot));

Happy to open a pull request on this, if desired. Though do note that integrating this fix will mean that oreboot will now fail to function on any OpenTitan that pre-dates lowRISC/opentitan@4425b28. That there is no versioning in the flash header makes it too easy for OpenTitan payloads to break; an OpenTitan issue will be raised on that.

Add compile-time check to guarantee a driver have exclusive access to its MMIO block

If you initialize two drivers using the same MMIO register block, oreboot will still compile, but the drivers will conflict at runtime. For example:

// Notice these two drivers incorrectly reference the same MMIO register block.
let driver1 = &mut NS16550::new(0x1E78_3000, 115200);
let driver2 = &mut NS16550::new(0x1E78_3000, 9600);
driver1.init();
driver2.init(); // Second driver messes up the first driver's memory block.

Ideally, there should be some sort of compile-time check to ensure drivers have exclusive access to register blocks.

Fix debug mode

Currently, oreboot only builds when you include the "-p release" option. Either we should fix debug mode or remove it entirely to avoid confusion.

Use position-independent-code

Currently, we have separate linker scripts for RISCV because the firmware is run from different base addresses in QEMU (link.ld) vs hardware (link_hw.ld). This can be simplified the oreboot is position independent.

Static stack size check

For example on the ast2500, the stack size should not exceed 36KiB during the romstage because the SRAM is 36KiB. All memory is stack-allocated, so this should guarantee no stack overflow.

Tools such as cargo-call-stack can tell you the maximum stack size a function will use. It would be useful to have a build-time check ensure the stack size is less or equal to the maximum stack size for the mainboard.

Coroutines

  • Polling I/O is very slow
    • A few UART prints = 0.01s
    • Read from SPI and verify loop
  • Interrupt-based I/O is difficult to do well
    • Puts us on slippery slope to becoming a kernel
    • Non-preemptive threading has been shown to be “good enough” in firmware
  • Implementation details
    • Save state
    • Long jump
    • (simple) Scheduler -- round robin has been shown to be good enough

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.