how to call _start?

how to call _start? What parameters the OS/Loader pass to it? and how to pass?

Reply to
伏虎
Loading thread data ...

sorry my crystal ball is not working. If you can explain a little bit better what do you want to do, where and why, then maybe we can help.

Bye Jack

--
Yoda of Borg am I! Assimilated shall you be! Futile resistance is, hmm?
Reply to
Jack

You would not actually call it, but rather branch to it.

None.

Leo Havmøller.

Reply to
Leo Havmøller

Here's some sample code for ARM7TDMI I found via the web. (Seems as though, no matter what I want to do, this dude named Martin Thomas has wanted to do it first. I find his work frequently.)

In this case, on an embedded processor, _start is entered straight from power-on reset.

Mel.

/* crt0.S for LPC2xxx - based on examples from R O Software - based on examples from newlib-lpc - based on an example from Anglia Designs

collected and modified by Martin Thomas

*/

.global _etext // -> .data initial values in ROM .global _data // -> .data area in RAM .global _edata // end of .data area .global __bss_start // -> .bss area in RAM .global __bss_end__ // end of .bss area .global _stack // top of stack

// Stack Sizes .set UND_STACK_SIZE, 0x00000004 .set ABT_STACK_SIZE, 0x00000004 .set FIQ_STACK_SIZE, 0x00000004 .set IRQ_STACK_SIZE, 0X00000080 .set SVC_STACK_SIZE, 0x00000004

// Standard definitions of Mode bits and Interrupt (I & F) flags in PSRs .set MODE_USR, 0x10 // User Mode .set MODE_FIQ, 0x11 // FIQ Mode .set MODE_IRQ, 0x12 // IRQ Mode .set MODE_SVC, 0x13 // Supervisor Mode .set MODE_ABT, 0x17 // Abort Mode .set MODE_UND, 0x1B // Undefined Mode .set MODE_SYS, 0x1F // System Mode

.equ I_BIT, 0x80 // when I bit is set, IRQ is disabled .equ F_BIT, 0x40 // when F bit is set, FIQ is disabled

.text .arm .section .init, "ax"

.code 32 .align 2

.global _boot .func _boot _boot:

// Runtime Interrupt Vectors // ------------------------- Vectors: b _start // reset - _start ldr pc,_undf // undefined - _undf ldr pc,_swi // SWI - _swi ldr pc,_pabt // program abort - _pabt ldr pc,_dabt // data abort - _dabt nop // reserved ldr pc,[pc,#-0xFF0] // IRQ - read the VIC ldr pc,_fiq // FIQ - _fiq

#if 0 // Use this group for production _undf: .word _reset // undefined - _reset _swi: .word _reset // SWI - _reset _pabt: .word _reset // program abort - _reset _dabt: .word _reset // data abort - _reset _irq: .word _reset // IRQ - _reset _fiq: .word _reset // FIQ - _reset

#else // Use this group for development _undf: .word __undf // undefined _swi: .word __swi // SWI _pabt: .word __pabt // program abort _dabt: .word __dabt // data abort _irq: .word __irq // IRQ _fiq: .word __fiq // FIQ

__undf: b . // undefined __swi: b . // SWI __pabt: b . // program abort __dabt: b . // data abort __irq: b . // IRQ __fiq: b . // FIQ #endif .size _boot, . - _boot .endfunc

// Setup the operating mode & stack. // --------------------------------- .global _start, start, _mainCRTStartup .func _start

_start: start: _mainCRTStartup:

// Initialize Interrupt System // - Set stack location for each mode // - Leave in System Mode with Interrupts Disabled // ----------------------------------------------- ldr r0,=_stack msr CPSR_c,#MODE_UND|I_BIT|F_BIT // Undefined Instruction Mode mov sp,r0 sub r0,r0,#UND_STACK_SIZE msr CPSR_c,#MODE_ABT|I_BIT|F_BIT // Abort Mode mov sp,r0 sub r0,r0,#ABT_STACK_SIZE msr CPSR_c,#MODE_FIQ|I_BIT|F_BIT // FIQ Mode mov sp,r0 sub r0,r0,#FIQ_STACK_SIZE msr CPSR_c,#MODE_IRQ|I_BIT|F_BIT // IRQ Mode mov sp,r0 sub r0,r0,#IRQ_STACK_SIZE msr CPSR_c,#MODE_SVC|I_BIT|F_BIT // Supervisor Mode mov sp,r0 sub r0,r0,#SVC_STACK_SIZE msr CPSR_c,#MODE_SYS|I_BIT|F_BIT // System Mode mov sp,r0

// Copy initialized data to its execution address in RAM // ----------------------------------------------------- #ifdef ROM_RUN ldr r1,=_etext // -> ROM data start ldr r2,=_data // -> data start ldr r3,=_edata // -> end of data

1: cmp r2,r3 // check if data to move ldrlo r0,[r1],#4 // copy it strlo r0,[r2],#4 blo 1b // loop until done #endif // Clear .bss // ---------- mov r0,#0 // get a zero ldr r1,=__bss_start // -> bss start ldr r2,=__bss_end__ // -> bss end 2: cmp r1,r2 // check if data to clear strlo r0,[r1],#4 // clear 4 bytes blo 2b // loop until done /* Call C++ constructors (for objects in "global scope") ctor loop added by Martin Thomas 4/2005 based on a Anglia Design example-application for ST ARM */

LDR r0, =__ctors_start__ LDR r1, =__ctors_end__ ctor_loop: CMP r0, r1 BEQ ctor_end LDR r2, [r0], #4 STMFD sp!, {r0-r1} MOV lr, pc MOV pc, r2 LDMFD sp!, {r0-r1} B ctor_loop ctor_end:

// Call main program: main(0) // -------------------------- mov r0,#0 // no arguments (argc = 0) mov r1,r0 mov r2,r0 mov fp,r0 // null frame pointer mov r7,r0 // null frame pointer for thumb ldr r10,=main mov lr,pc

/* Enter the C code, use BX instruction so as to never return */ /* use BLX (?) main if you want to use c++ destructors below */

bx r10 // enter main()

/* "global object"-dtors are never called and it should not be needed since there is no OS to exit to. */ /* Call destructors */ # LDR r0, =__dtors_start__ # LDR r1, =__dtors_end__ dtor_loop: # CMP r0, r1 # BEQ dtor_end # LDR r2, [r0], #4 # STMFD sp!, {r0-r1} # MOV lr, pc # MOV pc, r2 # LDMFD sp!, {r0-r1} # B dtor_loop dtor_end: .size _start, . - _start .endfunc

.global _reset, reset, exit, abort .func _reset _reset: reset: exit: abort: #if 0 // Disable interrupts, then force a hardware reset by driving P23 low // ------------------------------------------------------------------- mrs r0,cpsr // get PSR orr r0,r0,#I_BIT|F_BIT // disable IRQ and FIQ msr cpsr,r0 // set up status register

ldr r1,=(PS_BASE) // PS Base Address ldr r0,=(PS_PIO) // PIO Module str r0,[r1,#PS_PCER_OFF] // enable its clock ldr r1,=(PIO_BASE) // PIO Base Address ldr r0,=(1

Reply to
mwilson

Careful with disabling global dtors, which may be used to do good things like flush IO to your SD card during power-down...

Hope that helps, Best Regards, Dave

Reply to
Dave Nadler

Your question makes no sense. The places where I've seen a _start label in code have been in microcontroller code bases where _start is the reset vector. Thus, there are no parameters to pass, an entire universe to build before the OS can start, and because there is no OS, no loader to work either.

Further, if I'm not mistaken this question has already been answered in the last thread that you started -- perhaps you should read the responses?

This is a question about bringing up an embedded system from reset (maybe), and should be covered in Ganssle's book on embedded systems programming -- do you have a copy? Can you look in the table of contents and see? If not, try looking on Amazon's list of books on embedded systems programming and see. I'd suggest you start with Barr and Ganssle first, and go from there.

--
Tim Wescott
Control system and signal processing consulting
www.wescottdesign.com
Reply to
Tim Wescott

In others, _start is the entry point of a program which assumes to have been loaded by a boot loader, into external RAM initialized by that boot loader, running at a clock frequency configured by that boot loader. And if it were me who wrote that boot loader, I would also pass some parameters to the application by initializing some fixed memory cells.

Definitely a good idea.

Stefan

Reply to
Stefan Reuther

There are plenty of systems where the actual entry point of the executable is called (rather than branched to - this allows a program to exit by returning to the OS), and plenty of OSs that pass parameters to that entry point (command lines, environment blocks, stuff like that).

Of course they don't all do that either.

Reply to
Robert Wessel

Interesting. Now that you mention it I dimly recall the one WindRiver BSP that I had the ill fortune to work on had such a system, where there was a layer of assembly code that brought up a minimal C run-time environment, then some C language that brought up some more stuff, and then finally 'main' was called.

Mostly because all of the stuff that I've worked on has been deeply embedded boards OS needs no more sophisticated than an RTOS kernel, that were doing jobs that twenty or thirty years ago would have been performed with 7400 series logic and analog*. Using VxWorks for that was vast overkill, and only made sense because we (a) piggy-backed on a project that was using it for a very similar processor, and (b) were unable to find a decent RTOS kernel that cost less (Micro-C/OS-II having either not come along yet, or not having been made popular, or just having been not mainstream enough at the time -- I can't remember which).

  • Mind you, we were doing those jobs far better, and with user interfaces in human languages, but still...
--
My liberal friends think I'm a conservative kook.
My conservative friends think I'm a liberal kook.
Why am I not happy that they have found common ground?

Tim Wescott, Communications, Control, Circuits & Software
http://www.wescottdesign.com
Reply to
Tim Wescott

sysinit in sysALib.s

That's not the end of the story,

usrInit( ) usrKernelInit( ) kernelInit( ) usrRoot( )

and the main().

That was also the scheme used by VRTX.

>
Reply to
Lanarcam

Fasten your seatbelt: Chips like TI's OMAP4 can boot from an SD card. They have an SD card initialisation sequence and a FAT filesystem interpreter built in. There is a lot which happens before it executes the first instruction written by the software guy.

So, '_start' definitely is not the reset vector of *that* system.

Likewise, if you're working with an operating system with loadable modules, '_start' usually is the entry point of the loadable module, performing C library initialisation before calling main. That'll be closer to "PC programming" than to "embedded programming", still I'd expect embedded programmers to mess with library initialisation more often than PC programmers.

Stefan

Reply to
Stefan Reuther

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.