Skip to content
This repository was archived by the owner on Jul 2, 2021. It is now read-only.

Commit a10731c

Browse files
authored
Try #11:
2 parents ddaa95b + 96a0569 commit a10731c

File tree

5 files changed

+57
-125
lines changed

5 files changed

+57
-125
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@ This project adheres to [Semantic Versioning](http://semver.org/).
55

66
## [Unreleased]
77

8+
### Breaking Changes
9+
10+
- Remove the init array APIs as they are not pulling their weight.
11+
- Bound `zero_bss` and `init_data` by a new `Word` trait.
12+
813
## [v0.2.2] - 2017-07-21
914

1015
### Changed

Cargo.toml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
[package]
2+
name = "r0"
23
authors = ["Jorge Aparicio <[email protected]>"]
34
description = "Initialization code ('crt0') written in Rust"
45
documentation = "https://docs.rs/r0"
5-
keywords = ["initialization", "start", "crt0", "c0"]
6-
license = "MIT OR Apache-2.0"
7-
name = "r0"
86
repository = "https://github.com/rust-embedded/r0"
7+
keywords = ["initialization", "init", "start", "crt0", "c0"]
8+
categories = ["embedded", "no-std"]
9+
license = "MIT OR Apache-2.0"
10+
edition = "2018"
911
version = "0.2.2"

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
[![Build status](https://travis-ci.org/japaric/r0.svg?branch=master)](https://travis-ci.org/japaric/r0)
1+
[![Build status](https://travis-ci.org/rust-embedded/r0.svg?branch=master)](https://travis-ci.org/rust-embedded/r0)
22
[![crates.io](https://img.shields.io/crates/d/r0.svg)](https://crates.io/crates/r0)
33
[![crates.io](https://img.shields.io/crates/v/r0.svg)](https://crates.io/crates/r0)
44

src/lib.rs

Lines changed: 45 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
//! Initialization code ("crt0") written in Rust
1+
//! Initialization code ("crt0") written in Rust.
22
//!
33
//! This is for bare metal systems where there is no ELF loader or OS to take
44
//! care of initializing RAM for the program.
55
//!
66
//! # Initializing RAM
77
//!
88
//! On the linker script side, we must assign names (symbols) to the boundaries
9-
//! of the `.bss` and `.data` sections.
9+
//! of the `.bss` and `.data` sections:
1010
//!
1111
//! ```text
1212
//! .bss : ALIGN(4)
@@ -26,9 +26,10 @@
2626
//! _sidata = LOADADDR(.data);
2727
//! ```
2828
//!
29-
//! On the Rust side, we must bind to those symbols using an `extern` block.
29+
//! On the Rust side, we must bind to those symbols using an `extern` block:
3030
//!
31-
//! ```rust,ignore
31+
//! ```no_run
32+
//! # use r0::{zero_bss, init_data};
3233
//! unsafe fn before_main() {
3334
//! // The type, `u32`, indicates that the memory is 4-byte aligned
3435
//! extern "C" {
@@ -45,69 +46,46 @@
4546
//! init_data(&mut _sdata, &mut _edata, &_sidata);
4647
//! }
4748
//! ```
48-
//!
49-
//! # `.init_array` & `.pre_init_array`
50-
//!
51-
//! This crate also provides an API to add "life before main" functionality to
52-
//! bare metal systems.
53-
//!
54-
//! On the linker script side, instruct the linker to keep the `.init_array`
55-
//! sections from input object files. Store the start and end address of the
56-
//! merged `.init_array` section.
57-
//!
58-
//! ```text
59-
//! .text :
60-
//! {
61-
//! /* .. */
62-
//! _init_array_start = ALIGN(4);
63-
//! KEEP(*(.init_array));
64-
//! _init_array_end = ALIGN(4);
65-
//! /* .. */
66-
//! }
67-
//! ```
68-
//!
69-
//! On the startup code, invoke the `run_init_array` function *before* you call
70-
//! the user `main`.
71-
//!
72-
//! ```rust,ignore
73-
//! unsafe fn start() {
74-
//! extern "C" {
75-
//! static _init_array_start: extern "C" fn();
76-
//! static _init_array_end: extern "C" fn();
77-
//! }
78-
//!
79-
//! ::r0::run_init_array(&_init_array_start, &_init_array_end);
80-
//!
81-
//! extern "C" {
82-
//! fn main(argc: isize, argv: *const *const u8) -> isize;
83-
//! }
84-
//!
85-
//! main();
86-
//! }
87-
//! ```
88-
//!
89-
//! Then the user application can use this crate `init_array!` macro to run code
90-
//! before `main`.
91-
//!
92-
//! ```rust,ignore
93-
//! init_array!(before_main, {
94-
//! println!("Hello");
95-
//! });
96-
//!
97-
//! fn main() {
98-
//! println!("World");
99-
//! }
100-
//! ```
10149
10250
#![deny(warnings)]
10351
#![no_std]
10452

10553
#[cfg(test)]
10654
mod test;
10755

108-
use core::{mem, ptr, slice};
56+
use core::{mem, ptr};
57+
58+
mod sealed {
59+
pub trait Sealed {}
60+
}
61+
62+
/// Trait for machine word types.
63+
///
64+
/// This trait is implemented by unsigned integers representing common machine
65+
/// word sizes. It can not be implemented by the user.
66+
///
67+
/// Types implementing this trait can be used by the [`init_data`] and
68+
/// [`zero_bss`] functions. For that to be sound, all bit patterns need to be
69+
/// valid for the type, the type must implement `Copy`, and the type must not
70+
/// be zero-sized.
71+
///
72+
/// [`init_data`]: fn.init_data.html
73+
/// [`zero_bss`]: fn.zero_bss.html
74+
pub unsafe trait Word: sealed::Sealed + Copy {}
75+
76+
impl sealed::Sealed for u8 {}
77+
impl sealed::Sealed for u16 {}
78+
impl sealed::Sealed for u32 {}
79+
impl sealed::Sealed for u64 {}
80+
impl sealed::Sealed for u128 {}
81+
82+
unsafe impl Word for u8 {}
83+
unsafe impl Word for u16 {}
84+
unsafe impl Word for u32 {}
85+
unsafe impl Word for u64 {}
86+
unsafe impl Word for u128 {}
10987

110-
/// Initializes the `.data` section
88+
/// Initializes the `.data` section.
11189
///
11290
/// # Arguments
11391
///
@@ -119,18 +97,17 @@ use core::{mem, ptr, slice};
11997
///
12098
/// # Safety
12199
///
122-
/// - Must be called exactly once
123-
/// - `mem::size_of::<T>()` must be non-zero
124-
/// - `edata >= sdata`
100+
/// - Must be called exactly once, before the application has started.
101+
/// - `edata >= sdata`.
125102
/// - The `sdata -> edata` region must not overlap with the `sidata -> ...`
126-
/// region
103+
/// region.
127104
/// - `sdata`, `edata` and `sidata` must be `T` aligned.
128105
pub unsafe fn init_data<T>(
129106
mut sdata: *mut T,
130107
edata: *mut T,
131108
mut sidata: *const T,
132109
) where
133-
T: Copy,
110+
T: Word,
134111
{
135112
while sdata < edata {
136113
ptr::write(sdata, ptr::read(sidata));
@@ -139,20 +116,7 @@ pub unsafe fn init_data<T>(
139116
}
140117
}
141118

142-
pub unsafe fn run_init_array(
143-
init_array_start: &extern "C" fn(),
144-
init_array_end: &extern "C" fn(),
145-
) {
146-
let n = (init_array_end as *const _ as usize -
147-
init_array_start as *const _ as usize) /
148-
mem::size_of::<extern "C" fn()>();
149-
150-
for f in slice::from_raw_parts(init_array_start, n) {
151-
f();
152-
}
153-
}
154-
155-
/// Zeroes the `.bss` section
119+
/// Zeroes the `.bss` section.
156120
///
157121
/// # Arguments
158122
///
@@ -163,55 +127,16 @@ pub unsafe fn run_init_array(
163127
///
164128
/// # Safety
165129
///
166-
/// - Must be called exactly once
167-
/// - `mem::size_of::<T>()` must be non-zero
168-
/// - `ebss >= sbss`
130+
/// - Must be called exactly once, before the application has started.
131+
/// - `ebss >= sbss`.
169132
/// - `sbss` and `ebss` must be `T` aligned.
170133
pub unsafe fn zero_bss<T>(mut sbss: *mut T, ebss: *mut T)
171134
where
172-
T: Copy,
135+
T: Word,
173136
{
174137
while sbss < ebss {
175138
// NOTE(volatile) to prevent this from being transformed into `memclr`
176139
ptr::write_volatile(sbss, mem::zeroed());
177140
sbss = sbss.offset(1);
178141
}
179142
}
180-
181-
#[macro_export]
182-
macro_rules! pre_init_array {
183-
($name:ident, $body:expr) => {
184-
#[allow(dead_code)]
185-
unsafe extern "C" fn $name() {
186-
#[link_section = ".pre_init_array"]
187-
#[used]
188-
static PRE_INIT_ARRAY_ELEMENT: unsafe extern "C" fn() = $name;
189-
190-
#[inline(always)]
191-
fn inner() {
192-
$body
193-
}
194-
195-
inner()
196-
}
197-
}
198-
}
199-
200-
#[macro_export]
201-
macro_rules! init_array {
202-
($name:ident, $body:expr) => {
203-
#[allow(dead_code)]
204-
unsafe extern "C" fn $name() {
205-
#[link_section = ".init_array"]
206-
#[used]
207-
static INIT_ARRAY_ELEMENT: unsafe extern "C" fn() = $name;
208-
209-
#[inline(always)]
210-
fn inner() {
211-
$body
212-
}
213-
214-
inner()
215-
}
216-
}
217-
}

src/test.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use ::{init_data, zero_bss};
1+
use crate::{init_data, zero_bss};
22

33
#[test]
44
fn test_init_data() {

0 commit comments

Comments
 (0)