Skip to content

Commit 47db755

Browse files
authored
Merge pull request #101 from Javier-varez/asmInit
Initialize data and bss sections in assembly
2 parents dd266bb + 1693511 commit 47db755

File tree

12 files changed

+315
-33
lines changed

12 files changed

+315
-33
lines changed

ci/main/app-unsound/.cargo

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../memory-layout/.cargo

ci/main/app-unsound/Cargo.toml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
[package]
2+
edition = "2024"
3+
name = "app"
4+
version = "0.1.0"
5+
6+
[dependencies]
7+
rt = { path = "../rt-unsound" }

ci/main/app-unsound/src/main.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#![no_main]
2+
#![no_std]
3+
4+
use core::{arch::asm, ptr};
5+
6+
use rt::entry;
7+
8+
entry!(main);
9+
10+
static mut DATA: i32 = 1;
11+
12+
#[allow(static_mut_refs)]
13+
fn main() -> ! {
14+
unsafe {
15+
// check that DATA is properly initialized
16+
if ptr::read_volatile(&DATA) != 1 {
17+
// this makes QEMU crash
18+
asm!("BKPT");
19+
}
20+
}
21+
22+
loop {}
23+
}

ci/main/rt-unsound/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../rt/Cargo.toml

ci/main/rt-unsound/build.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../rt/build.rs

ci/main/rt-unsound/link.x

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/* Memory layout of the LM3S6965 microcontroller */
2+
/* 1K = 1 KiBi = 1024 bytes */
3+
MEMORY
4+
{
5+
FLASH : ORIGIN = 0x00000000, LENGTH = 256K
6+
RAM : ORIGIN = 0x20000000, LENGTH = 64K
7+
}
8+
9+
/* The entry point is the reset handler */
10+
ENTRY(Reset);
11+
12+
EXTERN(RESET_VECTOR);
13+
14+
SECTIONS
15+
{
16+
.vector_table ORIGIN(FLASH) :
17+
{
18+
/* First entry: initial Stack Pointer value */
19+
LONG(ORIGIN(RAM) + LENGTH(RAM));
20+
21+
/* Second entry: reset vector */
22+
KEEP(*(.vector_table.reset_vector));
23+
} > FLASH
24+
25+
.text :
26+
{
27+
*(.text .text.*);
28+
} > FLASH
29+
30+
/* CHANGED! */
31+
.rodata :
32+
{
33+
*(.rodata .rodata.*);
34+
} > FLASH
35+
36+
.bss :
37+
{
38+
_sbss = .;
39+
*(.bss .bss.*);
40+
_ebss = .;
41+
} > RAM
42+
43+
.data : AT(ADDR(.rodata) + SIZEOF(.rodata))
44+
{
45+
_sdata = .;
46+
*(.data .data.*);
47+
_edata = .;
48+
} > RAM
49+
50+
_sidata = LOADADDR(.data);
51+
52+
/DISCARD/ :
53+
{
54+
*(.ARM.exidx .ARM.exidx.*);
55+
}
56+
}

ci/main/rt-unsound/src/lib.rs

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
#![no_std]
2+
3+
use core::panic::PanicInfo;
4+
use core::ptr;
5+
6+
#[unsafe(no_mangle)]
7+
#[allow(static_mut_refs)]
8+
pub unsafe extern "C" fn Reset() -> ! {
9+
// NEW!
10+
// Initialize RAM
11+
unsafe extern "C" {
12+
static mut _sbss: u8;
13+
static mut _ebss: u8;
14+
15+
static mut _sdata: u8;
16+
static mut _edata: u8;
17+
static _sidata: u8;
18+
}
19+
20+
let count = unsafe { &_ebss as *const u8 as usize - &_sbss as *const u8 as usize };
21+
unsafe { ptr::write_bytes(&mut _sbss as *mut u8, 0, count) };
22+
23+
let count = unsafe { &_edata as *const u8 as usize - &_sdata as *const u8 as usize };
24+
unsafe { ptr::copy_nonoverlapping(&_sidata as *const u8, &mut _sdata as *mut u8, count) };
25+
26+
// Call user entry point
27+
unsafe extern "Rust" {
28+
safe fn main() -> !;
29+
}
30+
31+
main()
32+
}
33+
34+
// The reset vector, a pointer into the reset handler
35+
#[unsafe(link_section = ".vector_table.reset_vector")]
36+
#[unsafe(no_mangle)]
37+
pub static RESET_VECTOR: unsafe extern "C" fn() -> ! = Reset;
38+
39+
#[panic_handler]
40+
fn panic(_panic: &PanicInfo<'_>) -> ! {
41+
loop {}
42+
}
43+
44+
#[macro_export]
45+
macro_rules! entry {
46+
($path:path) => {
47+
#[unsafe(export_name = "main")]
48+
pub unsafe fn __main() -> ! {
49+
// type check the given path
50+
let f: fn() -> ! = $path;
51+
52+
f()
53+
}
54+
};
55+
}

ci/main/rt2/src/lib.rs

Lines changed: 52 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,59 @@
11
#![no_std]
22

33
use core::panic::PanicInfo;
4-
use core::ptr;
54

6-
#[unsafe(no_mangle)]
7-
#[allow(static_mut_refs)]
8-
pub unsafe extern "C" fn Reset() -> ! {
9-
// NEW!
10-
// Initialize RAM
11-
unsafe extern "C" {
12-
static mut _sbss: u8;
13-
static mut _ebss: u8;
14-
15-
static mut _sdata: u8;
16-
static mut _edata: u8;
17-
static _sidata: u8;
18-
}
19-
20-
let count = unsafe { &_ebss as *const u8 as usize - &_sbss as *const u8 as usize };
21-
unsafe { ptr::write_bytes(&mut _sbss as *mut u8, 0, count) };
22-
23-
let count = unsafe { &_edata as *const u8 as usize - &_sdata as *const u8 as usize };
24-
unsafe { ptr::copy_nonoverlapping(&_sidata as *const u8, &mut _sdata as *mut u8, count) };
25-
26-
// Call user entry point
27-
unsafe extern "Rust" {
28-
safe fn main() -> !;
29-
}
30-
31-
main()
5+
use core::arch::global_asm;
6+
7+
global_asm!(
8+
".text
9+
10+
.syntax unified
11+
.global _sbss
12+
.global _ebss
13+
14+
.global _sdata
15+
.global _edata
16+
.global _sidata
17+
18+
.global main
19+
.global Reset
20+
21+
.type Reset,%function
22+
.thumb_func
23+
Reset:
24+
25+
_init_bss:
26+
movs r2, #0
27+
ldr r0, =_sbss
28+
ldr r1, =_ebss
29+
30+
1:
31+
cmp r1, r0
32+
beq _init_data
33+
strb r2, [r0]
34+
add r0, #1
35+
b 1b
36+
37+
_init_data:
38+
ldr r0, =_sdata
39+
ldr r1, =_edata
40+
ldr r2, =_sidata
41+
42+
1:
43+
cmp r0, r1
44+
beq _main_trampoline
45+
ldrb r3, [r2]
46+
strb r3, [r0]
47+
add r0, #1
48+
add r2, #1
49+
b 1b
50+
_main_trampoline:
51+
ldr r0, =main
52+
bx r0"
53+
);
54+
55+
unsafe extern "C" {
56+
pub safe fn Reset() -> !;
3257
}
3358

3459
// The reset vector, a pointer into the reset handler

ci/script.sh

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,12 @@ main() {
9292
edition_check
9393
popd
9494

95+
pushd app-unsound
96+
cargo build
97+
qemu_check target/thumbv7m-none-eabi/debug/app
98+
edition_check
99+
popd
100+
95101
popd
96102

97103

src/SUMMARY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
- [The smallest `#![no_std]` program](./smallest-no-std.md)
55
- [Memory layout](./memory-layout.md)
66
- [A `main` interface](./main.md)
7+
- [Why don't we initialize `.data` and `.bss` using Rust](./sections-in-rust.md)
78
- [Exception handling](./exceptions.md)
89
- [Assembly on stable](./asm.md)
910
- [Logging with symbols](./logging.md)

0 commit comments

Comments
 (0)