@@ -802,29 +802,70 @@ macro_rules! sys_log {
802
802
#[ doc( hidden) ]
803
803
#[ no_mangle]
804
804
#[ link_section = ".text.start" ]
805
+ #[ naked]
805
806
pub unsafe extern "C" fn _start ( ) -> ! {
806
- // Symbols from the linker script:
807
- extern "C" {
808
- static mut __sbss: u32 ;
809
- static mut __ebss: u32 ;
810
- static mut __sdata: u32 ;
811
- static mut __edata: u32 ;
812
- static __sidata: u32 ;
813
- }
814
-
815
807
// Provided by the user program:
816
808
extern "Rust" {
817
809
fn main ( ) -> !;
818
810
}
819
811
820
- // Initialize RAM
821
- r0:: zero_bss ( & mut __sbss, & mut __ebss) ;
822
- r0:: init_data ( & mut __sdata, & mut __edata, & __sidata) ;
812
+ asm ! ( "
813
+ @ Copy data initialization image into data section.
814
+ @ Note: this assumes that both source and destination are 32-bit
815
+ @ aligned and padded to 4-byte boundary.
816
+
817
+ movw r0, #:lower16:__edata @ upper bound in r0
818
+ movt r0, #:upper16:__edata
819
+
820
+ movw r1, #:lower16:__sidata @ source in r1
821
+ movt r1, #:upper16:__sidata
822
+
823
+ movw r2, #:lower16:__sdata @ dest in r2
824
+ movt r2, #:upper16:__sdata
825
+
826
+ b 1f @ check for zero-sized data
827
+
828
+ 2: ldr r3, [r1], #4 @ read and advance source
829
+ str r3, [r2], #4 @ write and advance dest
830
+
831
+ 1: cmp r2, r0 @ has dest reached the upper bound?
832
+ bne 2b @ if not, repeat
833
+
834
+ @ Zero BSS section.
823
835
824
- // Do *not* reorder any instructions from main above this point.
825
- core :: sync :: atomic :: compiler_fence ( core :: sync :: atomic :: Ordering :: SeqCst ) ;
836
+ movw r0, #:lower16:__ebss @ upper bound in r0
837
+ movt r0, #:upper16:__ebss
826
838
827
- main ( )
839
+ movw r1, #:lower16:__sbss @ base in r1
840
+ movt r1, #:upper16:__sbss
841
+
842
+ movs r2, #0 @ materialize a zero
843
+
844
+ b 1f @ check for zero-sized BSS
845
+
846
+ 2: str r2, [r1], #4 @ zero one word and advance
847
+
848
+ 1: cmp r1, r0 @ has base reached bound?
849
+ bne 2b @ if not, repeat
850
+
851
+ @ Be extra careful to ensure that those side effects are
852
+ @ visible to the user program.
853
+
854
+ dsb @ complete all writes
855
+ isb @ and flush the pipeline
856
+
857
+ @ Now, to the user entry point. We call it in case it
858
+ @ returns. (It's not supposed to.) We reference it through
859
+ @ a sym operand because it's a Rust func and may be mangled.
860
+ bl {main}
861
+
862
+ @ The noreturn option below will automatically generate an
863
+ @ undefined instruction trap past this point, should main
864
+ @ return.
865
+ " ,
866
+ main = sym main,
867
+ options( noreturn) ,
868
+ )
828
869
}
829
870
830
871
#[ cfg( feature = "panic-messages" ) ]
0 commit comments