redboot的启动流程

如下述:

以下是从ecos的官网文档中抄录下来的。但在浩瀚的文档中找到这些信息也非易事,在此记录下来,以备查用。

 

其中reset vector定义在packages/hal/arm/arch/v3_0/src/vector.S中。

 

PLATFORM_SETUP1定义在packages/hal/arm/arch/v3_0/include/hal_platform_setup.h中。

 

cyg_start定义在packages/redboot/v3_0/src/main.c中。

 

 

 

Getting RedBoot Going
=====================

Startup
=======

1. Reset entry point. At location 0.
   Transfer control to ROM entry point: reset_vector.

2. Here we call invoke PLATFORM_SETUP1 macro. This does the following:
   - disable interrupts
   - disable and clear caches
   - Init memory controllers. may involve discovery of what RAM is
     present.
   - Set up clock frequencies.
   - Init MMU table
     - sets up TTBR and DACR to default values
     - fills in MMU table to map
       - DRAM at 0x00000000 cacheable/buffered
       - Device registers elsewhere uncacheable/unbuffered usually 1-1
       - DRAM at 0xF0000000 uncacheable/unbuffered (1-1 in aaed2000)
       - remap ROM at 0 elsewhere
   - Enable MMU
   - Relocate image to RAM for ROMRAM startup
   - Any other CPU setup required
     
3. Jump to HAL startup.
   - Plant vector intructions at 0+
   - copy .data section to RAM
   - Init CPSR and SPSR
   - Set SP
   - Clear .bss
   - Call hal_hardware_init()
   - call initialize_stub() if GDB stubs included
   - call hal_ctrlc_isr_init()
   - call cyg_hal_invoke_constructors()
   - call cyg_start()


HAL Serial support
==================

Set up CDL in platform CDL file.
    CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS
    number of channels usually 0, 1 or 2
    CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL
    channel to use for GDB
    CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL_BAUD
    initial baud rate
    CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL
    channel to use for console
    CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD
    initial baud rate
    CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_DEFAULT
    default console channel

The code in hal_diag.c need to be converted to the new serial device.
If this the same as a device already supported, copy that.

Things that need to be written:

struct channel_data_t;
       Structure containing base address, timeout and ISR vector
       number for each serial device.

xxxx_ser_channels[];
    Array of channel_data_t, initialized with parameters of each
    channel.

void cyg_hal_plf_serial_init_channel(void *__ch_data)
    Initialize the serial device. parameter is a pointer to a
    channel_data_t.

void cyg_hal_plf_serial_putc(void * __ch_data, char *c)
        Send a character to the serial device.
    Poll for ready, write the char.
    Maybe poll for char sent.

bool cyg_hal_plf_serial_getc_nonblock(void* __ch_data, cyg_uint8* ch)
        Look for a character and return it if available.
    If none available, return false.

int cyg_hal_plf_serial_control(void *__ch_data, __comm_control_cmd_t
__func, ...)
    An IOCTL-like function for controlling various aspects of the
    serial device.
    May need to do some work in __COMMCTL_IRQ_ENABLE and
    __COMMCTL_IRQ_DISABLE cases to enable/disable interrupts.

int cyg_hal_plf_serial_isr(void *__ch_data, int* __ctrlc,
                       CYG_ADDRWORD __vector, CYG_ADDRWORD __data)
        Interrupt handler, specifically for dealing with Ctrl-C.
    - Check for an incoming character.
    - Read the character and call cyg_hal_is_break().
    - If result is true, set *__ctrlc to 1.
    - return CYG_ISR_HANDLED;

void cyg_hal_plf_serial_init()
        Initialize each of the serial channels.
    - call cyg_hal_plf_serial_init_channel() for each channel.
    - call CYGACC_COMM_IF_* macros for each channel -
          cut/paste/edit these.

       
Interrupt Controller
====================

ARM platforms have interrupt controller access in functions in variant
or platform source file.

void hal_interrupt_mask(int vector)
        Manipulate interrupt controller to mask the interrupt.

void hal_interrupt_unmask(int vector)
        Manipulate interrupt controller to unmask the interrupt.

void hal_interrupt_acknowledge(int vector)
        Manipulate interrupt controller to acknowledge the interrupt.
    May not be needed in some platforms.

void hal_interrupt_configure(int vector, int level, int up)
        Set interrupt detection: level vs. edge; high/low
        rising/falling.
    Leave empty where not implemented.   

void hal_interrupt_set_level(int vector, int level)
        Set interrupt priority level.
    Leave empty where not implemented.   


Redboot Configuration
=====================

Having done all of the above, you should be in a position to get
RedBoot running.

If the platform you copied has redboot, there should be some .ecm
files in the misc directory. Named redboot_<startup>.ecm.

Choose a startup and edit the .ecm file.
       - remove any options that are not relevant
       - comment out FLASH, ETH and COMPRESS packages

Configure for redboot:

% setenv ECOS_REPOSITORY <path to source repository>
% ecosconfig new xxxxxxxx redboot
% ecosconfig import $ECOS_REPOSITORY/hal/arm/arm9/xxxxxxxx/current/misc/redboot_ROM.ecm
% ecosconfig tree
% make

Repeat until successful.

<think>嗯,用户想了解OpenWRT系统中reboot命令的完整执行流程。我需要先回忆一下OpenWRT的基本结构,尤其是procd的作用。记得procd是OpenWRT的进程管理守护进程,负责系统初始化和服务管理。当执行reboot命令时,应该会触发procd的状态转换。 根据引用[1],reboot命令会让procd进入STATE_SHUTDOWN状态,然后执行/etc/rc.d/K*的关机脚本。这和sysinit流程类似,但参数是shutdown。完成之后,状态转为STATE_HALT,接着系统重启。那具体步骤可能包括用户输入命令、触发procd、执行关机脚本、卸载文件系统、最后调用内核重启。 需要确认各个阶段的具体操作,比如服务停止的顺序,如何调用内核的reboot函数。另外,用户可能还想知道这些脚本的位置和如何自定义,比如引用[2]提到的wireless配置,可能关机脚本里也有类似的配置处理。还有引用[3]提到恢复出厂设置,可能和某些关机脚本有关联,比如清除配置。 可能用户的问题不仅仅是流程,还想了解如何调试或修改这个流程,比如添加自定义的关机步骤。需要分步骤详细说明流程,并引用正确的资料。同时,生成的相关问题要考虑用户可能的后续疑问,比如优化启动时间、自定义脚本、日志分析等。</think>### OpenWRT reboot命令执行流程分析 根据OpenWRT的进程管理机制和引用资料,reboot命令的执行流程可分为以下六个阶段: 1. **用户命令触发** 用户通过终端输入`reboot`命令,系统调用`/sbin/reboot`可执行文件,该文件通过busybox实现基础命令功能 2. **procd状态转换** reboot命令会触发procd(OpenWRT进程管理守护进程)从当前状态转变为`STATE_SHUTDOWN`状态[^1]。此时procd会: - 发送SIGTERM信号给所有托管进程 - 等待预设超时时间(默认5秒) - 强制发送SIGKILL信号终止未响应进程 3. **执行关机脚本** ```bash # 执行顺序示例 /etc/rc.common /etc/rc.d/K90network stop /etc/rc.d/K60odhcpd stop ``` 系统按照反向序号顺序执行`/etc/rc.d/K*`开头的shutdown脚本,具体步骤包括: - 关闭网络服务 - 停止系统守护进程 - 卸载非必要文件系统 4. **文件系统同步** 执行`sync`操作确保所有缓存数据写入存储设备,关键代码路径: ```c // procd源码片段 system("/sbin/sysctl -w vm.drop_caches=3"); sync(); ``` 5. **内核级操作** 通过reboot系统调用触发内核操作: ```c reboot(LINUX_REBOOT_CMD_RESTART); ``` 内核依次执行: - 设备驱动shutdown回调 - CPU架构相关重置操作 - 看门狗定时器触发(如启用) 6. **硬件重启阶段** 根据引用[1]描述,最终状态会从`STATE_SHUTDOWN`转变为`STATE_HALT`,不同硬件平台的表现: - x86平台:通过ACPI发送重置命令 - ARM平台:写寄存器触发SoC复位 - 嵌入式设备:可能触发看门狗复位
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值