I checked the startup code of eCos a few days ago, made some notes, and published them here to increase the popularity of space. Since the target board I used is MIPS, I only analyzed the startup code of for MIPS.Start code analysis (for MIPS ): Packages/hal/MIPS/ARCH/v2_0/src/vector. s Func_start (reset_vector) // Reset vector. The address is 0xbfc00000. the kernel is started from this address. # Ifndef cyg_hal_startup_ram # If defined (cygpkg_hal_reset_vector_first_code) Hal_reset_vector_first_code # Endif # If defined (cygpkg_hal_early_init) Hal_early_init # Endif # Decide whether this is an NMI, cold or warm boot. Mfc0 K0, status # Get status Reg // process NMI bits. NMI operations are not involved in MIPS r3000. Lui K1, 0x0008 # isolate NMI bit And K1, K1, K0 Beqz K1, 1f # Skip if zero NOP Lar K1 ,__ nmi_entry # Jump to Rom NMI code Jalr K1 NOP 1: Lui K1, 0x0010 # isolate soft reset bit And K1, K1, K0 Beqz K1, 2f # Skip if zero NOP Lar K1 ,__ warm_start # Jump to Rom warm_start code // _ Warm_start code is used for debugging. Optional. JR K1 NOP 2: La K0, initial_config0 # Set up config0 register // Initialize the config0 register. The MIPs r3000 does not have this register. Mtc0 K0, config0 # To disable cache // disable Cache # Endif Lar v0, _ start # Jump to start // load the _ start address (the LAR command MIPS r3000 is not supported here) # Ifdef cygarc_start_func_uncached Cygarc_address_reg_uncached (v0) # Endif JR V0 // jump to _ start NOP # (delay slot) Func_end (reset_vector) Func_start (_ start) // _ start function, which performs most initialization work. The code is analyzed after _ start. # Initialize hardware Hal_cpu_init // packages/hal/MIPS/ARCH/v2_0/include/arch. inc initializes the watchdog register, and the cause register clears the initialization Status Register to initialize the config0 register (MIPs r3000 does not have the config0 register) Hal_diag_init // diagnosis supports initialization. If cygpkg_hal_mips_diag_defined is not defined, then in packages/hal/MIPS/ARCH/v2_0/include/arch. INC defines an empty macro. If it is defined, the implementation depends on a specific platform, such as packages/hal/MIPS/tx39/v2_0/src/hal_duag.c. Hal_mmu_init // initialize MMU. If cygpkg_hal_mips_mmu_defined is not defined, the variant does not support MMU. In packages/hal/MIPS/ARCH/v2_0/include/arch. INC defines an empty macro. If it is defined, the implementation depends on a specific platform, such as packages/hal/MIPS/vrc437x/v2_0/include/platform. INC Hal_fpu_init // packages/hal/MIPS/ARCH/v2_0/include/arch. Inc, initialize FPU Hal_memc_init // initialize the memory controller. If cygpkg_hal_mips_memc_defined is not defined, it indicates that the platform does not have a memory controller. Then, in packages/hal/MIPS/ARCH/v2_0/include/arch. INC defines an empty macro. If it is defined, the implementation depends on a specific platform, such as packages/hal/MIPS/tx39/v2_0/include/variant. inc. The macro may also be in platform. implementation in Inc Hal_intc_init // initialize the interrupt controller. If cygpkg_hal_mips_intc_init_defined is not defined, it indicates that the platform has no interrupt controller, and then in packages/hal/MIPS/ARCH/v2_0/include/arch. INC defines the macro and disables all interrupts in the Status Register. If defined, the implementation depends on a specific platform, such as packages/hal/MIPS/tx39/v2_0/include/variant. inc. The macro may also be in platform. implementation in Inc Hal_cache_init // initialize the cache. If cygpkg_hal_mips_cache_defined is not defined, the variable cache is a standard cache, and the variable cache is in packages/hal/MIPS/ARCH/v2_0/include/arch. INC defines the macro and uses the config register to initialize the cache. If it is defined, the implementation depends on specific variant, such as packages/hal/MIPS/tx49/v2_0/include/variant. INC Hal_timer_init // initialize timer. If cygpkg_hal_mips_timer_defined is not defined, it indicates that the platform does not have Timer. In packages/hal/MIPS/ARCH/v2_0/include/arch. INC defines an empty macro. If it is defined, the implementation depends on a specific platform.
# Ifdef cygarc_start_func_uncached # Switch to cached execution address if necessary # Assumption is that hal_cache_init makes this safe Lar v0, 1f JR V0 NOP 1: # Endif
# Load global pointer register. La GP, _ GP // load the GP register # Load initial Stack pointer // set the stack pointer for C code. Generally, interrupt stack is used for this purpose. La A0 ,__ interrupt_stack // defined in vector. s and defined as follows: . Balign 16 . Global cyg_interrupt_stack Cyg_interrupt_stack: _ Interrupt_stack: . Long Move sp, a0 // load the stack pointer Hal_mon_init // initialize the monitor, which is used to install the interrupt vector. If cygpkg_hal_mips_mon_defined is not defined, it indicates that the platform does not implement the monitor. Then, in packages/hal/MIPS/ARCH/v2_0/include/arch. INC defines an empty macro. If it is defined, the implementation depends on a specific platform, such as packages/hal/MIPS/rm7000/v2_0/include/platform. INC, which generally calls hal_vectors_init () # Ifdef cyg_hal_startup_rom // If ECOs is started from Rom, copy the data segment to ram. # Copy data from Rom to ram . Extern hal_copy_data Jal hal_copy_data // packages/hal/MIPS/ARCH/v2_0/src/hal_misc.c NOP # Endif # Zero BSS // clear BSS segments . Extern hal_zero_bss Jal hal_zero_bss // packages/hal/MIPS/ARCH/v2_0/src/vectors. s NOP # Call variant and platform hal # Initialization routines. . Extern hal_variant_init Jal hal_variant_init // variant initialization, packages/hal/MIPS/tx39/v2_0/src/var_misc.c. Most of them are empty functions. You can further initialize the interrupt controller, PCI bridge, IO Device, cache enabled, etc. NOP . Extern hal_platform_init Jal hal_platform_init // platform initialization, packages/hal/MIPS/vrc437x/v2_0/src/plf_misc.c, which can not be implemented, or further initialize the interrupt controller, PCI bridge, Io device, enable cache, etc. NOP # Call Constructors . Extern cyg_hal_invoke_constructors Jal cyg_hal_invoke_constructors // create a constructor table and run static Constructor (packages/hal/MIPS/ARCH/v2_0/src/hal_misc.c) NOP # If defined (cygdbg_hal_debug_gdb_include_stubs) // If GDB stub is implemented, initialize . Extern initialize_stub Jal initialize_stub // initialize GDB stub, packages/hal/common/v2_0/src/generic-stub.c NOP # Endif # If defined (cygdbg_hal_mips_debug_gdb_ctrlc_support) // If GDB requires Ctrl-C Support, initialize . Extern hal_ctrlc_isr_init Jal hal_ctrlc_isr_init // initialize the support of GDB Ctrl-C, which depends on platform, such as packages/hal/MIPS/vrc437x/v2_0/src/plf_misc.c NOP # Endif # Call cyg_start . Extern cyg_start J cyg_start // call cyg_start () to enter the main loop. The kernel starts to run and never returns. cyg_start () is implemented by the application itself. You can call _ bsp_init () here to initialize the device driver, the general implementation is as follows: Void Cyg_start (void) { Cyg_thread_create (10, // priority-just a number (Cyg_thread_entry_t *) console_test, // entry 0 ,//
"Lele_thread", // name & Stack [0], // Stack Stack_size, // size & Thread_handle, // handle & Thread_data // thread Data Structure ); Cyg_thread_resume (thread_handle ); Cyg_scheduler_start (); } Lui Ra, 0
Func_end (_ start) |