can run entrypoint on user elf
syscalls via call_abi are still not working
This commit is contained in:
87
Cargo.lock
generated
87
Cargo.lock
generated
@@ -422,17 +422,6 @@ dependencies = [
|
|||||||
"defmt 0.3.100",
|
"defmt 0.3.100",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "delegate"
|
|
||||||
version = "0.13.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "6178a82cf56c836a3ba61a7935cdb1c49bfaa6fa4327cd5bf554a503087de26b"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn 2.0.104",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "diff"
|
name = "diff"
|
||||||
version = "0.1.13"
|
version = "0.1.13"
|
||||||
@@ -485,26 +474,6 @@ version = "1.15.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
|
checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "elf"
|
|
||||||
version = "0.7.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "4445909572dbd556c457c849c4ca58623d84b27c8fff1e74b0b4227d8b90d17b"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "elf_loader"
|
|
||||||
version = "0.12.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "30a0da8db95cff71e500b3d7015c2441a4eb628e0df788b23d1b8d1243314342"
|
|
||||||
dependencies = [
|
|
||||||
"bitflags 2.9.1",
|
|
||||||
"cfg-if",
|
|
||||||
"delegate",
|
|
||||||
"elf",
|
|
||||||
"portable-atomic",
|
|
||||||
"portable-atomic-util",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "embassy-embedded-hal"
|
name = "embassy-embedded-hal"
|
||||||
version = "0.3.1"
|
version = "0.3.1"
|
||||||
@@ -662,7 +631,6 @@ dependencies = [
|
|||||||
"nb 1.1.0",
|
"nb 1.1.0",
|
||||||
"pio 0.3.0",
|
"pio 0.3.0",
|
||||||
"rand_core",
|
"rand_core",
|
||||||
"rp-binary-info",
|
|
||||||
"rp-pac",
|
"rp-pac",
|
||||||
"rp2040-boot2",
|
"rp2040-boot2",
|
||||||
"sha2-const-stable",
|
"sha2-const-stable",
|
||||||
@@ -1065,6 +1033,17 @@ dependencies = [
|
|||||||
"wasi",
|
"wasi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "goblin"
|
||||||
|
version = "0.10.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0e961b33649994dcf69303af6b3a332c1228549e604d455d61ec5d2ab5e68d3a"
|
||||||
|
dependencies = [
|
||||||
|
"log",
|
||||||
|
"plain",
|
||||||
|
"scroll",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "half"
|
name = "half"
|
||||||
version = "2.6.0"
|
version = "2.6.0"
|
||||||
@@ -1456,13 +1435,13 @@ dependencies = [
|
|||||||
"abi",
|
"abi",
|
||||||
"bitflags 2.9.1",
|
"bitflags 2.9.1",
|
||||||
"bt-hci",
|
"bt-hci",
|
||||||
|
"bumpalo",
|
||||||
"cortex-m",
|
"cortex-m",
|
||||||
"cortex-m-rt",
|
"cortex-m-rt",
|
||||||
"cyw43",
|
"cyw43",
|
||||||
"cyw43-pio",
|
"cyw43-pio",
|
||||||
"defmt 0.3.100",
|
"defmt 0.3.100",
|
||||||
"defmt-rtt",
|
"defmt-rtt",
|
||||||
"elf_loader",
|
|
||||||
"embassy-embedded-hal",
|
"embassy-embedded-hal",
|
||||||
"embassy-executor",
|
"embassy-executor",
|
||||||
"embassy-futures",
|
"embassy-futures",
|
||||||
@@ -1476,6 +1455,7 @@ dependencies = [
|
|||||||
"embedded-hal-bus",
|
"embedded-hal-bus",
|
||||||
"embedded-layout",
|
"embedded-layout",
|
||||||
"embedded-sdmmc",
|
"embedded-sdmmc",
|
||||||
|
"goblin",
|
||||||
"heapless",
|
"heapless",
|
||||||
"num_enum 0.7.4",
|
"num_enum 0.7.4",
|
||||||
"panic-probe",
|
"panic-probe",
|
||||||
@@ -1588,6 +1568,12 @@ dependencies = [
|
|||||||
"syn 2.0.104",
|
"syn 2.0.104",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "plain"
|
||||||
|
version = "0.2.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "portable-atomic"
|
name = "portable-atomic"
|
||||||
version = "1.11.1"
|
version = "1.11.1"
|
||||||
@@ -1597,15 +1583,6 @@ dependencies = [
|
|||||||
"critical-section",
|
"critical-section",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "portable-atomic-util"
|
|
||||||
version = "0.2.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d8a2f0d8d040d7848a709caf78912debcc3f33ee4b3cac47d73d1e1069e83507"
|
|
||||||
dependencies = [
|
|
||||||
"portable-atomic",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "precomputed-hash"
|
name = "precomputed-hash"
|
||||||
version = "0.1.1"
|
version = "0.1.1"
|
||||||
@@ -1752,12 +1729,6 @@ dependencies = [
|
|||||||
"bytemuck",
|
"bytemuck",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rp-binary-info"
|
|
||||||
version = "0.1.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "88ed2051a0bf2c726df01cfce378ed8a367be2a6e402fc183857f429a346d429"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rp-pac"
|
name = "rp-pac"
|
||||||
version = "7.0.0"
|
version = "7.0.0"
|
||||||
@@ -1807,6 +1778,26 @@ version = "1.2.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "scroll"
|
||||||
|
version = "0.13.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c1257cd4248b4132760d6524d6dda4e053bc648c9070b960929bf50cfb1e7add"
|
||||||
|
dependencies = [
|
||||||
|
"scroll_derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "scroll_derive"
|
||||||
|
version = "0.13.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "22fc4f90c27b57691bbaf11d8ecc7cfbfe98a4da6dbe60226115d322aa80c06e"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.104",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "semver"
|
name = "semver"
|
||||||
version = "0.9.0"
|
version = "0.9.0"
|
||||||
|
|||||||
@@ -3,9 +3,8 @@
|
|||||||
use core::ffi::c_void;
|
use core::ffi::c_void;
|
||||||
use shared::keyboard::{KeyCode, KeyEvent, KeyState, Modifiers};
|
use shared::keyboard::{KeyCode, KeyEvent, KeyState, Modifiers};
|
||||||
|
|
||||||
unsafe extern "C" {
|
#[unsafe(no_mangle)]
|
||||||
fn call_abi(call: *const Syscall);
|
pub unsafe fn call_abi(_call: *const Syscall) {}
|
||||||
}
|
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub enum Syscall {
|
pub enum Syscall {
|
||||||
|
|||||||
@@ -41,7 +41,6 @@ embassy-rp = { version = "0.4.0", features = [
|
|||||||
"critical-section-impl",
|
"critical-section-impl",
|
||||||
"unstable-pac",
|
"unstable-pac",
|
||||||
"time-driver",
|
"time-driver",
|
||||||
"binary-info",
|
|
||||||
] }
|
] }
|
||||||
embassy-usb = "0.4.0"
|
embassy-usb = "0.4.0"
|
||||||
embassy-futures = "0.1.1"
|
embassy-futures = "0.1.1"
|
||||||
@@ -77,11 +76,12 @@ embedded-layout = "0.4.2"
|
|||||||
|
|
||||||
static_cell = "2.1.1"
|
static_cell = "2.1.1"
|
||||||
bitflags = "2.9.1"
|
bitflags = "2.9.1"
|
||||||
talc = "4.4.3"
|
|
||||||
spin = "0.10.0"
|
|
||||||
heapless = "0.8.0"
|
heapless = "0.8.0"
|
||||||
num_enum = { version = "0.7.4", default-features = false }
|
num_enum = { version = "0.7.4", default-features = false }
|
||||||
elf_loader = {version ="0.12.0", default-features = false, features = ["portable-atomic"]}
|
goblin = { version = "0.10.0", default-features = false, features = ["elf32", "elf64", "alloc", "endian_fd"] }
|
||||||
|
bumpalo = "3.19.0"
|
||||||
|
talc = "4.4.3"
|
||||||
|
spin = "0.10.0"
|
||||||
|
|
||||||
shared = { path = "../shared" }
|
shared = { path = "../shared" }
|
||||||
abi = { path = "../abi" }
|
abi = { path = "../abi" }
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ fn main() {
|
|||||||
let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
|
let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
|
||||||
File::create(out.join("memory.x"))
|
File::create(out.join("memory.x"))
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.write_all(include_bytes!("../memory.x"))
|
.write_all(include_bytes!("memory.x"))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
println!("cargo:rustc-link-search={}", out.display());
|
println!("cargo:rustc-link-search={}", out.display());
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
use abi::Syscall;
|
use abi::Syscall;
|
||||||
|
use defmt::info;
|
||||||
use embassy_futures::block_on;
|
use embassy_futures::block_on;
|
||||||
use embedded_graphics::{
|
use embedded_graphics::{
|
||||||
Drawable,
|
Drawable,
|
||||||
@@ -9,8 +10,9 @@ use embedded_graphics::{
|
|||||||
|
|
||||||
use crate::display::FRAMEBUFFER;
|
use crate::display::FRAMEBUFFER;
|
||||||
|
|
||||||
#[unsafe(no_mangle)]
|
#[allow(unused)]
|
||||||
pub extern "C" fn call_abi(call: *const Syscall) {
|
pub fn call_abi(call: *const Syscall) {
|
||||||
|
info!("called abi");
|
||||||
let call = unsafe { &*call };
|
let call = unsafe { &*call };
|
||||||
match call {
|
match call {
|
||||||
Syscall::DrawPixel { x, y, color } => {
|
Syscall::DrawPixel { x, y, color } => {
|
||||||
@@ -20,6 +22,7 @@ pub extern "C" fn call_abi(call: *const Syscall) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn draw_pixel(x: u32, y: u32, color: u16) {
|
fn draw_pixel(x: u32, y: u32, color: u16) {
|
||||||
|
info!("draw pixel abi called");
|
||||||
let framebuffer = block_on(FRAMEBUFFER.lock());
|
let framebuffer = block_on(FRAMEBUFFER.lock());
|
||||||
Rectangle::new(Point::new(x as i32, y as i32), Size::new(1, 1))
|
Rectangle::new(Point::new(x as i32, y as i32), Size::new(1, 1))
|
||||||
.draw_styled(
|
.draw_styled(
|
||||||
|
|||||||
85
kernel/src/elf.rs
Normal file
85
kernel/src/elf.rs
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
#![allow(static_mut_refs)]
|
||||||
|
use abi::Syscall;
|
||||||
|
use bumpalo::Bump;
|
||||||
|
use core::{alloc::Layout, ffi::c_void, ptr::NonNull, slice::from_raw_parts_mut};
|
||||||
|
use goblin::{
|
||||||
|
elf::{Elf, header::ET_DYN, program_header::PT_LOAD, sym},
|
||||||
|
elf32,
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::abi::call_abi;
|
||||||
|
|
||||||
|
pub fn load_elf(elf_bytes: &[u8], bump: &mut Bump) -> Result<extern "C" fn() -> !, ()> {
|
||||||
|
let elf = Elf::parse(elf_bytes).map_err(|_| ())?;
|
||||||
|
|
||||||
|
if elf.is_64
|
||||||
|
|| elf.is_lib
|
||||||
|
|| elf.is_object_file()
|
||||||
|
|| !elf.little_endian
|
||||||
|
|| elf.header.e_type != ET_DYN
|
||||||
|
|| elf.interpreter.is_some()
|
||||||
|
{
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find base address (lowest virtual address of PT_LOAD segments)
|
||||||
|
let base_vaddr = elf
|
||||||
|
.program_headers
|
||||||
|
.iter()
|
||||||
|
.filter(|ph| ph.p_type == PT_LOAD)
|
||||||
|
.map(|ph| ph.p_vaddr)
|
||||||
|
.min()
|
||||||
|
.ok_or(())?;
|
||||||
|
|
||||||
|
// Determine total memory needed for all PT_LOAD segments
|
||||||
|
let total_size = elf
|
||||||
|
.program_headers
|
||||||
|
.iter()
|
||||||
|
.filter(|ph| ph.p_type == PT_LOAD)
|
||||||
|
.map(|ph| {
|
||||||
|
let start = ph.p_vaddr;
|
||||||
|
let end = ph.p_vaddr + ph.p_memsz;
|
||||||
|
end - base_vaddr
|
||||||
|
})
|
||||||
|
.max()
|
||||||
|
.unwrap_or(0) as usize;
|
||||||
|
|
||||||
|
// Allocate one big block from the bump heap
|
||||||
|
let layout = Layout::from_size_align(total_size, 0x1000).map_err(|_| ())?;
|
||||||
|
let base_ptr = bump.alloc_layout(layout).as_ptr();
|
||||||
|
|
||||||
|
for ph in &elf.program_headers {
|
||||||
|
if ph.p_type != PT_LOAD {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let file_offset = ph.p_offset as usize;
|
||||||
|
let file_size = ph.p_filesz as usize;
|
||||||
|
let mem_size = ph.p_memsz as usize;
|
||||||
|
let virt_offset = (ph.p_vaddr - base_vaddr) as usize;
|
||||||
|
|
||||||
|
let src = &elf_bytes[file_offset..file_offset + file_size];
|
||||||
|
let dst = unsafe { base_ptr.add(virt_offset) };
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
core::ptr::copy_nonoverlapping(src.as_ptr(), dst, file_size);
|
||||||
|
if mem_size > file_size {
|
||||||
|
core::ptr::write_bytes(dst.add(file_size), 0, mem_size - file_size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Patch `call_abi` symbol
|
||||||
|
for sym in elf.syms.iter() {
|
||||||
|
let name = elf.strtab.get_at(sym.st_name).ok_or(())?;
|
||||||
|
if name == "call_abi" && sym.st_bind() == sym::STB_GLOBAL {
|
||||||
|
let offset = (sym.st_value - base_vaddr) as usize;
|
||||||
|
let ptr = unsafe { base_ptr.add(offset) as *mut usize };
|
||||||
|
unsafe { *ptr = call_abi as usize };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compute relocated entry point
|
||||||
|
let relocated_entry = unsafe { base_ptr.add((elf.entry - base_vaddr) as usize) };
|
||||||
|
Ok(unsafe { core::mem::transmute(relocated_entry) })
|
||||||
|
}
|
||||||
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
mod abi;
|
mod abi;
|
||||||
mod display;
|
mod display;
|
||||||
|
mod elf;
|
||||||
mod peripherals;
|
mod peripherals;
|
||||||
mod scsi;
|
mod scsi;
|
||||||
mod storage;
|
mod storage;
|
||||||
@@ -14,6 +15,7 @@ mod utils;
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
display::{display_handler, init_display},
|
display::{display_handler, init_display},
|
||||||
|
elf::load_elf,
|
||||||
peripherals::{
|
peripherals::{
|
||||||
conf_peripherals,
|
conf_peripherals,
|
||||||
keyboard::{KeyCode, KeyState, read_keyboard_fifo},
|
keyboard::{KeyCode, KeyState, read_keyboard_fifo},
|
||||||
@@ -22,24 +24,10 @@ use crate::{
|
|||||||
usb::{ENABLE_SCSI, usb_handler},
|
usb::{ENABLE_SCSI, usb_handler},
|
||||||
};
|
};
|
||||||
|
|
||||||
use defmt::unwrap;
|
|
||||||
use elf_loader::{
|
|
||||||
Loader, load_exec,
|
|
||||||
mmap::MmapImpl,
|
|
||||||
object::{ElfBinary, ElfObject},
|
|
||||||
};
|
|
||||||
use static_cell::StaticCell;
|
|
||||||
use talc::*;
|
|
||||||
|
|
||||||
static mut ARENA: [u8; 10000] = [0; 10000];
|
|
||||||
|
|
||||||
#[global_allocator]
|
|
||||||
static ALLOCATOR: Talck<spin::Mutex<()>, ClaimOnOom> =
|
|
||||||
Talc::new(unsafe { ClaimOnOom::new(Span::from_array(core::ptr::addr_of!(ARENA).cast_mut())) })
|
|
||||||
.lock();
|
|
||||||
|
|
||||||
use {defmt_rtt as _, panic_probe as _};
|
use {defmt_rtt as _, panic_probe as _};
|
||||||
|
|
||||||
|
use bumpalo::Bump;
|
||||||
|
use defmt::unwrap;
|
||||||
use embassy_executor::{Executor, Spawner};
|
use embassy_executor::{Executor, Spawner};
|
||||||
use embassy_futures::join::join;
|
use embassy_futures::join::join;
|
||||||
use embassy_rp::{
|
use embassy_rp::{
|
||||||
@@ -56,16 +44,25 @@ use embassy_rp::{
|
|||||||
use embassy_time::{Delay, Timer};
|
use embassy_time::{Delay, Timer};
|
||||||
use embedded_hal_bus::spi::ExclusiveDevice;
|
use embedded_hal_bus::spi::ExclusiveDevice;
|
||||||
use embedded_sdmmc::SdCard as SdmmcSdCard;
|
use embedded_sdmmc::SdCard as SdmmcSdCard;
|
||||||
|
use static_cell::StaticCell;
|
||||||
|
use talc::*;
|
||||||
|
|
||||||
embassy_rp::bind_interrupts!(struct Irqs {
|
embassy_rp::bind_interrupts!(struct Irqs {
|
||||||
I2C1_IRQ => i2c::InterruptHandler<I2C1>;
|
I2C1_IRQ => i2c::InterruptHandler<I2C1>;
|
||||||
USBCTRL_IRQ => embassy_rp_usb::InterruptHandler<USB>;
|
USBCTRL_IRQ => embassy_rp_usb::InterruptHandler<USB>;
|
||||||
});
|
});
|
||||||
|
|
||||||
static mut CORE1_STACK: Stack<4096> = Stack::new();
|
static mut CORE1_STACK: Stack<16384> = Stack::new();
|
||||||
static EXECUTOR0: StaticCell<Executor> = StaticCell::new();
|
static EXECUTOR0: StaticCell<Executor> = StaticCell::new();
|
||||||
static EXECUTOR1: StaticCell<Executor> = StaticCell::new();
|
static EXECUTOR1: StaticCell<Executor> = StaticCell::new();
|
||||||
|
|
||||||
|
static mut ARENA: [u8; 50_000] = [0; 50_000];
|
||||||
|
|
||||||
|
#[global_allocator]
|
||||||
|
static ALLOCATOR: Talck<spin::Mutex<()>, ClaimOnOom> =
|
||||||
|
Talc::new(unsafe { ClaimOnOom::new(Span::from_array(core::ptr::addr_of!(ARENA).cast_mut())) })
|
||||||
|
.lock();
|
||||||
|
|
||||||
#[embassy_executor::main]
|
#[embassy_executor::main]
|
||||||
async fn main(_spawner: Spawner) {
|
async fn main(_spawner: Spawner) {
|
||||||
let p = embassy_rp::init(Default::default());
|
let p = embassy_rp::init(Default::default());
|
||||||
@@ -110,12 +107,14 @@ async fn main(_spawner: Spawner) {
|
|||||||
// runs dynamically loaded elf files
|
// runs dynamically loaded elf files
|
||||||
#[embassy_executor::task]
|
#[embassy_executor::task]
|
||||||
async fn userland_task() {
|
async fn userland_task() {
|
||||||
let binary_data: &[u8] = include_bytes!("../../example.bin");
|
let mut bump = Bump::with_capacity(25_000);
|
||||||
let bin = load_exec!("example", binary_data).unwrap();
|
|
||||||
let entry = bin.entry();
|
|
||||||
|
|
||||||
let entry_fn: extern "C" fn() = unsafe { core::mem::transmute(entry) };
|
let binary_data: &[u8] =
|
||||||
entry_fn(); // jump into user code
|
include_bytes!("../../target/thumbv8m.main-none-eabihf/debug/calculator");
|
||||||
|
let entry = load_elf(binary_data, &mut bump).unwrap();
|
||||||
|
|
||||||
|
entry();
|
||||||
|
bump.reset(); // clear heap arena
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Display {
|
struct Display {
|
||||||
|
|||||||
@@ -1,14 +1,26 @@
|
|||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_main]
|
#![no_main]
|
||||||
|
|
||||||
|
use abi::{Syscall, call_abi};
|
||||||
use core::panic::PanicInfo;
|
use core::panic::PanicInfo;
|
||||||
|
|
||||||
#[panic_handler]
|
#[panic_handler]
|
||||||
fn panic(_info: &PanicInfo) -> ! {
|
fn panic(_info: &PanicInfo) -> ! {
|
||||||
loop {} // or call your ABI trap, or `abort()`
|
loop {}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unsafe(no_mangle)]
|
#[unsafe(no_mangle)]
|
||||||
fn main() {
|
pub extern "C" fn _start() -> ! {
|
||||||
loop {}
|
loop {
|
||||||
|
for i in 0..300 {
|
||||||
|
for o in 0..300 {
|
||||||
|
let call = Syscall::DrawPixel {
|
||||||
|
x: i,
|
||||||
|
y: o,
|
||||||
|
color: 0,
|
||||||
|
};
|
||||||
|
unsafe { call_abi(&call) };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
21
user-apps/link.x
Normal file
21
user-apps/link.x
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
RAM : ORIGIN = 0x00000000, LENGTH = 256K
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
.text : {
|
||||||
|
*(.text .text.*);
|
||||||
|
*(.rodata .rodata.*);
|
||||||
|
} > RAM
|
||||||
|
|
||||||
|
.data : {
|
||||||
|
*(.data .data.*);
|
||||||
|
} > RAM
|
||||||
|
|
||||||
|
.bss : {
|
||||||
|
*(.bss .bss.*);
|
||||||
|
*(COMMON);
|
||||||
|
} > RAM
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user