谷动谷力

 找回密码
 立即注册
查看: 510|回复: 0
打印 上一主题 下一主题
收起左侧

OpenWrt 启动过程分析

[复制链接]
跳转到指定楼层
楼主
发表于 2023-7-8 21:41:46 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 sunsili 于 2023-7-8 21:59 编辑

OpenWrt 启动过程分析


简介
目前最新的 (integrated 2010-01-25) preinit / firstboot boot sequence 是为了Ⅹ启动系统 更容易扩展(通过增加程序包),比如usb上的根文件系统,或者增强的failsafe模式。
其中包括了一部分'init' (多用户)被执行前,OpenWrt 的启动序列,同时也负责烧写OpenWrt后, 第一次运行时建立并初始化文件系统。


基本的OpenWrt启动顺序
  • boot loader loads kernel  bootloader->加载内核
  • kernel loads  内核启动,同时扫描mtd文件系统分区
  • kernel calls /etc/preinit (the kernel considers this to be the init (or root) process 内核执行/etc/preinit脚本(内核包涵调用系统初始化进程nit或root)
  • /etc/preinit prepares system for multiuser mode 内核执行/etc/preinit脚本为多用户系统准备
  • /etc/preinit execs /sbin/init which becomes the init (or root) process and launches multiuser /etc/preinit执行/sbin/init系统初始进程
  • /sbin/init launches processes according to /etc/inittab.  /sbin/init根据/etc/inittab定义执行启动过程
  • Typically the first process launched is /etc/init.d/rcS which causes the scripts in /etc/rc.d which begin with 'S' to be launched (in glob sort order). The /etc/rc.d directory is populated with symlinks to the scripts in /etc/init.d. Each script/etc/inittab首先执行/etc/init.d/rcS,此脚本将顺序启动/etc/rc.d/目录以S开关的脚本
  • in /etc/init.d accepts enable and disable arguments for creating and removing the symlinks.   在/etc/init.d 配置要启动或卸载的模块
  • These script initialize the system and also initialize daemons that wait for input, so that when all the scripts have executed the normal system is active. On first boot this initializing includes the process of preparing the root filesystem for use. 初始化脚本输入输出控制台, 所有初始化脚本执行后激活进入文件系统的默认用户终端。

各启动函数(进程分析)
/sbin/init
early()
mount /proc /sys /tmp /dev /dev/pts目录(early_mount)

创建设备节点和/dev/null文件结点(early_dev)

设置PATH环境变量(early_env)

初始化/dev/console

cmdline()
根据/proc/cmdline内容init_debug=([0-9]+)判断debug级别

watchdog_init()
初始化内核watchdog(/dev/watchdog)

加载内核模块
创建子进程/sbin/kmodloader加载/etc/modules-boot.d/目录中的内核模块

preinit()
创建子进程执行/etc/preinit脚本,此时PREINIT环境变量被设置为1,主进程同时使用uloop_process_add()把/etc/preinit子进程加入uloop进行监控,当/etc/preinit执行结束时回调plugd_proc_cb()函数把监控/etc/preinit进程对应对象中pid属性设置为0,表示/etc/preinit已执行完成

创建子进程执行/sbin/procd -h
/etc/hotplug-preinit.json,主进程同时使用uloop_process_add()把/sbin/procd子进程加入uloop进行监控,当/sbin/procd进程结束时回调spawn_procd()函数

spawn_procd()函数繁衍后继真正使用的/sbin/procd进程,从/tmp/debuglevel读出debug级别并设置到环境变量DBGLVL中,把watchdog fd设置到环境变量WDTFD中,最后调用execvp()繁衍/sbin/procd进程

watchdog
如果存在/dev/watchdog设备,设置watchdog timeout等于30秒,如果内核在30秒内没有收到任何数据将重启系统。用户状进程使用uloop定时器设置5秒周期向/dev/wathdog设备写一些数据通知内核,表示此用户进程在正常工作

/**
* 初始化watchdog
*/
void watchdog_init(int preinit)

/**
* 设备通知内核/dev/watchdog频率(缺省为5秒)
* 返回老频率值
*/
int watchdog_frequency(int frequency)

/**
* 设备内核/dev/watchdog超时时间
* 当参数timeout<=0时,表示从返回值获取当前超时时间
*/
int watchdog_timeout(int timeout)

/**
* val为true时停止用户状通知定时器,意味着30秒内系统将重启
*/
void watchdog_set_stopped(bool val)
ignal
信息处理,下面为procd对不同信息的处理方法

SIGBUS、SIGSEGV信号将调用do_reboot() RB_AUTOBOOT重启系统

SIGHUP、SIGKILL、SIGSTOP信号将被忽略

SIGTERM信号使用RB_AUTOBOOT事件重启系统

SIGUSR1、SIGUSR2信号使用RB_POWER_OFF事件关闭系统

procd
procd有5个状态,分别为STATE_EARLY、STATE_INIT、STATE_RUNNING、STATE_SHUTDOWN、STATE_HALT,这5个状态将按顺序变化,当前状态保存在全局变量state中,可通过procd_state_next()函数使用状态发生变化

STATE_EARLY状态 - init前准备工作
初始化watchdog

根据"/etc/hotplug.json"规则监听hotplug

procd_coldplug()函数处理,把/dev挂载到tmpfs中,fork udevtrigger进程产生冷插拔事件,以便让hotplug监听进行处理

udevstrigger进程处理完成后回调procd_state_next()函数把状态从STATE_EARLY转变为STATE_INIT

STATE_INIT状态 - 初始化工作
连接ubusd,此时实际上ubusd并不存在,所以procd_connect_ubus函数使用了定时器进行重连,而uloop_run()需在初始化工作完成后才真正运行。当成功连接上ubusd后,将注册service main_object对象,system_object对象、watch_event对象(procd_connect_ubus()函数),

初始化services(服务)和validators(服务验证器)全局AVL tree

把ubusd服务加入services管理对象中(service_start_early)

根据/etc/inittab内容把cmd、handler对应关系加入全局链表actions中

顺序加载respawn、askconsole、askfirst、sysinit命令

sysinit命令把/etc/rc.d/目录下所有启动脚本执行完成后将回调rcdone()函数把状态从STATE_INITl转变为STATE_RUNNING

STATE_RUNNING状态
进入STATE_RUNNING状态后procd运行uloop_run()主循环

trigger任务队列
数据结构
struct trigger {
    struct list_head list;

    char *type;

    int pending;
    int remove;
    int timeout;

    void *id;

    struct blob_attr *rule;
    struct blob_attr *data;
    struct uloop_timeout delay;

    struct json_script_ctx jctx;
};

struct cmd {
    char *name;
    void (*handler)(struct job *job, struct blob_attr *exec, struct blob_attr *env);
};

struct job {
    struct runqueue_process proc;
    struct cmd *cmd;
    struct trigger *trigger;
    struct blob_attr *exec;
    struct blob_attr *env;
};
接口说明
/**
* 初始化trigger任务队列
*/
void trigger_init(void)

/**
* 把服务和服务对应的规则加入trigger任务队列
*/
void trigger_add(struct blob_attr *rule, void *id)

/**
* 把服务从trigger任务队列中删除
*/
void trigger_del(void *id)

/**
*
*/
void trigger_event(const char *type, struct blob_attr *data)
service
Name        Handler        Blob_msg policy
set        service_handle_set        service_set_attrs
add        service_handle_set        service_set_attrs
list        service_handle_list        service_attrs
delete        service_handle_delete        service_del_attrs
update_start        service_handle_update        service_attrs
update_complete        service_handle_update        service_attrs
event        service_handle_event        event_policy
validate        service_handle_validate        validate_policy
system
Name        Handler        Blob_msg policy
board        system_board        
info        system_info        
upgrade        system_upgrade        
watchdog        watchdog_set        watchdog_policy
signal        proc_signal        signal_policy
nandupgrade        nand_set        nand_policy
shell调用接口
代码库路径: package/system/procd/files/procd.sh
设备上路径: /lib/functions/procd.sh

/etc/init.d/daemon

#!/bin/sh /etc/rc.common

START=80
STOP=20

USE_PROCD=1

start_service()
{
    procd_open_instance
    procd_set_param command /sbin/daemon
    procd_set_param respawn
    procd_close_instance
}



Preinit
Preinit brings the system from raw kernel to ready for multiuser. To do so it performs the following tasks:
  • Sources “/etc/functions.sh” and /lib/functions/boot.sh for common functions for boot/mount
  • Mounts essential kernel filesystems like procfs
  • Initializes device tree (/dev)
  • Initializes console (serial console if present, otherwise dummy so that the script interpreter works properly)
  • Presents opportunity for the user to enter a special operating mode called 'failsafe' (Failsafe mode is presented in a separate section. Once failsafe mode is entered it doesn't exit. A reboot is necessary to enter normal operating mode).
  • Mounts the root filesystem (this involves a number steps, presented in a separate section)
  • If it's the first time booting after flashing the firmware, and a previous configuration was saved during the flashing process, that configuration is restored.
  • Becomes (though exec) 'init' which goes to multiuser mode


Failsafe
  • Prepares network interface (optional) and notifies that failsafe mode is being entered
  • Launches daemon to allow network logins
  • Allows login via serial console, if there is one.
  • When the serial console login process exits, failsafe doesn't exit, instead it continues to wait for network logins (whether or not they are actually possible).


Mount Root Filesystem
all_jffs2 refers to a 'jffs2' target in menuconfig; e.g. firmware has no squashfs, but is purely a rw filesystem (jffs2), while, jffs2 in the following text refers to the jffs2 portion of a squashfs/jffs2 system.
  • If there is no mtd device with label rootfs_data, then mounts /dev/root (e.g. squashfs or all_jffs2 with no squashfs) as root filesystem, and indicates that further steps should be skipped
  • If mtd device rootfs_data has not already been formatted, mounts a tmpfs (ramdisk) as root filesystem, and indicates that further steps should be skipped.
  • Mounts previously formatted jjfs2 partition on /jffs2 and indicates successful mount.
  • Makes successfully mounted /jffs (if it exists) the new root filesystem and moves the new root filesystem to /rom, and indicates to skip further steps.
  • This is only reached on an error condition; attempts to mount a tmpfs (ramdisk) as root filesystem
  • This is only reached if no other step succeeds; attempt to mount /dev/root (e.g. squashfs/all_jffs2) as root filesystem.


First Boot
/sbin/firstboot may be referenced in three ways.
  • It may be called as part of the system startup, in which cased it is called as /sbin/firstboot switch2jffs.
  • It may be used as a standalone command with no parameters (.e.g. /sbin/firstboot)
  • It may be sourced from another script


Common
  • Source /lib/functions/boot.sh for common functions (e.g. also used by preinit)
  • Source files used by hooks
  • Determine how called, and branch to appropriate commands.


Sourced rather than executed
  • Determine (and set variable for) MTD rootfs_data partition
  • Determine (and set variable for) rom partition
  • Determine (and set variable for) jffs2 partition


Executed with no parameters
  • Resets jffs2 to original settings, if possible.
  • If jffs2 is not mounted, erases mtd and attempts format, mount, and pivot jffs2 as root.

If jffs2 is mounted, firstboot runs hook jffs2reset
  • Determine (and set variable for) MTD rootfs_data partition
  • Determine (and set variable for) rom partition
  • Determine (and set variable for) jffs2 partition
  • Determine (and set variable to indicate) whether the mini overlay filesystem type is supported.
  • If overlay is supported, remove all files on jffs2 and remount it.
  • If overlay not supported, create directories and symlinks, copying only certain critical files


Executed with parameter 'switch2jffs'
  • Determine (and set variable for) MTD rootfs_data partition
  • Determine (and set variable for) rom partition
  • Determine (and set variable for) jffs2 partition
  • Determine if mini overlay is supported. If not run hook no_fo
  • Otherwise, if mounted, skip the rest, otherwise mount under squashfs (/rom/jffs)
  • Copy ramdisk to jffs2
  • Move /jffs to / (root) and move / (root) to /rom
  • Cleanup


hook no_fo
  • Switch to kernel fs, get rid of union overlay and bind from /tmp/root
  • Mount jffs (and make it safe for union)
  • If not mounted, mount; copy from squashfs, and pivot so that /jffs is now / (root)
  • Copy files from ramdisk
  • Get rid of unnecessary mounts (cleanup)


Preinit Operation
Preinit consists of a number of the scripts. The main script is /etc/preinit which reads in the scripts. The scripts define functions which they attach to hooks. These hooks are, when processed, launch the functions in the order they were added to the hooks.
Currently there are five hooks used by the preinit system:
  • preinit_essential
  • preinit_main
  • failsafe
  • initramfs
  • preinit_mount_root

These hooks are actually just string variables with the name of each function to be executed, separated by spaces. The hook variables have _hook appended to the hook name. Thus the name of the variable for the preinit_essential hook is preinit_essential_hook.

Main Preinit Script
The main preinit script is actually quite empty. It:
  • Initializes some variables (including the hook variables)
  • Defines the function pi_hook_add, which is used to add functions to a hook
  • Defines the function pi_run_hook, which executes the functions that were added to a hook
  • Sources (reads) the shell scripts under folder /lib/preinit/, in glob sort order
  • Processes the hook preinit_essential
  • Initializes variables used by preinit_main
  • Processes the hook preinit_main

That's it.

Variables
There are a number of variables that control options of preinit. Defaults are defined in the main script /etc/preinit defined by the base-files package. However the variables are customizable via make menuconfig, in section “Preinit configuration options”. The OpenWrt build process will then create the file /lib/preinit/00_preinit.conf which will be sourced by the main script.
The variables defined at present are:
Variable
Description

pi_ifname
The device name of the network interface used to emit network messages during preinit (except failsafe)

pi_ip
The IP address of the preinit network (see above)

pi_broadcast
The broadcast address of the preinit network (see above)
pi_netmask
The netmask for the preinit network (see above)

fs_failsafe_wait_timeout
How long to pause while allowing the user to choose to enter failsafe mode. Default is two (2) seconds.

pi_suppress_stderr
If this is “y”, then output on standard error (stderr, file descriptor 2), is ignored during preinit. This is the default in previous versions of OpenWrt (which did not have this option)

pi_init_suppress_stderr
If pi_suppress_stderr is not “y” (i.e. stderr is not suppressed for preinit), then this option controls whether init, and process run by init, except those associated with a terminal device (e.g. tts/0, ttyS0, tty1, pts/0, or other similar devices) will have stderr suppressed (not that network terminals such as those from SSH are associated with a pseudo-terminal device such as pty0/pty1 and are thus unaffected). As with pi_suppress_stderr, the default, and behaviour from previous versions of OpenWrt is “y”.

pi_init_path
The default search PATH for binaries for commands run by init. Default is /bin:/sbin:/usr/bin:/usr/sbin

pi_init_cmd
The command to run as init. Default is /sbin/init
pi_preinit_no_failsafe_netmsgsuppress netmsg to say that one can enter failsafe mode
pi_preinit_net_messagesIf enabled, show more network messages than just the message that one can enter failsafe mode
There are also variables used in the operation of preinit. They are:
Variable
Description

preinit_essential_hookVariable containing hook names to execute, in order, for hook preinit_essential
preinit_main_hook
Ditto, for preinit_main

failsafe_hook
Ditto, for failsafe

initramfs_hook
Ditto, for initramfs

preinit_mount_root_hook
Ditto, for preinit_mount_root

pi_mount_skip_next
During hook preinit_mount_root, skips most steps; usually set by a preceeding step
pi_jffs2_mount_successDuring hook preinit_mount_root, used by steps following mount attempt to determine which action they should take

Hooks
The following sections describe the files and functions used by the various hooks.
NB: The files, even though divided by hook here are all in the single /lib/preinit directory, and are thus combined in the directory lists, and are processed in glob sort order, not by hook (when sourcing them, the hooks specify the order of the execution of functions, which is as listed below)

Development
For the purposes of development, you will locate the files under $ROOTDIR/package/base-files/files/lib/preinit, for the existing files, and you can add new files anywhere that ultimately ends up in /lib/preinit on the router (while in preinit, e.g. not by user edits after read-write is mounted).

preinit_essentials
The preinit_essentials hook takes care of mounting essential kernel filesystems such as proc, and initializing the console.
Files containing the functions executed by this hook
File
Functions

10_essential_fs
do_mount_procfs, do_mount_sysfs, do_mount_tmpfs

20_device_fs_mount
do_mount_devfs, do_mount_hotplug, do_mount_udev, choose_device_fs

30_device_daemons
init_hotplug, init_udev, init_device_fs

40_init_shm
init_shm

40_pts_mount
do_mount_pts

50_choose_console
choose_console

60_init_console
init_console

Functions, in order, executed by this hook (doesn't list the functions only called by other functions)
Function
Description

do_mount_procfs
mounts /proc

do_mount_sysfs
mounts /sys

do_mount_tmpfs
mounts /tmp

choose_device_fs
determines type of device daemon and the appropriate filesystem to mount on /dev for that device daemon

init_device_fs
launches daemons (if any) responsible for population /dev, and/or creating hotplug events when devices are added/removed (and for initial coldplug events)

init_shm
makes sure /dev/shm exists

init_pts
makes sure /dev/pts exists

do_mount_pts
mounts devpts on /dev/pts (pseudo-terminals)

choose_console
determines devices for stdin, stdout, and stderr

init_console
activates stdin, stdout, and stderr of preinit (and subsequent init) (prior to this they are not present in the environment)

Functions which are called by other functions, rather than directly as part of a hook
Function
Description

do_mount_devfs
mount devfs on /dev

do_mount_hotplug
mount tmpfs on /dev (for hotplug)

do_mount_udev
mount tmpfs on /dev (for udev)

init_hotplug
set hotplug handler (actually initiated after console init)
init_udev
start udev


preinit_main
The preinit_main hook performs all the functions required of preinit, except those functions, like console, that are essential even for preinit tasks.
File
Description

10_indicate_preinit
preinit_ip, preinit_ip_deconfig, preinit_net_echo, preinit_echo, pi_indicate_led, pi_indicate_preinit

30_failsafe_wait
fs_wait_for_key, failsafe_wait

40_run_failsafe_hook
run_failsafe_hook

50_indicate_regular_preinit
indicate_regular_preinit_boot

60_init_hotplug
init_hotplug

70_initramfs_test
initramfs_test

80_mount_root
do_mount_root

90_restore_config
restore_config

99_10_run_init
run_init

Functions, in order, executed by this hook (doesn't list the functions only called by other functions)
Function
Description

init_hotplug
Initialize hotplug, if needed (that is for devfs). Hotplug or a device daemon is needed so that devices are available for use for preinit

preinit_ip
Initialize network interface (if one has been defined for as available for preinit)

pi_indicate_preinit
Send messages to console, network, and/or led, depending on which, if any, of these is present which say that we are in preinit mode

failsafe_wait
Emits messages (to network and console) that indicate the user has the option to enter failsafe mode and wait for the configured period of time (default two seconds) for the user to select failsafe mode

run_failsafe_hook
If user chooses to enter failsafe mode, run the *failsafe* hook (which at present doesn't return, which means no more functions from preinit_main get run on this boot)

indicate_regular_preinit_boot
Emits messages to network, console, and/or LED depending on which (if any) is present, indicating that it's a regular boot not a failsafe boot

initramfs_test
If initramfs is present run the *initramfs* hook and exit
do_mount_root
Executes hook *preinit_mount_root*
restore_config
If a previous configuration was stored by sysupgrade, restore it to the rootfs

run_init
Exec the command defined by `pi_init_cmd` with the environment variables defined by `pi_init_env`, plus PATH `pi_init_path`

Functions which are called by other functions, rather than directly as part of a hook.
Function
Description

preinit_ip_deconfigdeconfigure interface used for preinit network messages etc
preinit_net_echo
emit a message on the preinit network interface

preinit_echo
emit a message on the (serial) console

pi_indicate_led
set LED status to indicate preinit mode

fs_wait_for_key
wait for reset button press, CTRL-C, or <some_key><ENTER>, with timeout

failsafe
Do what needs to done to prepare failsafe mode and enter it.
File
Description

10_indicate_failsafe
indicate_failsafe_led, indicate_failsafe

99_10_failsafe_login
failsafe_netlogin, failsafe_shell

Functions, in order, executed by this hook (doesn't list the functions only called by other functions)
Function
Description

indicate_failsafe
Emit message/status to network, console, and/or LED (depending on which, if any, are present) indicating that the device is now in failsafe mode

failsafe_netlogin
Launch telnet daemon to allow telnet login on the defined network interface (if any)

failsafe_shell
Launch a shell for access via serial console (if present)

Functions which are called by other functions, rather than directly as part of a hook
Function
Description

indicate_failsafe_led
set LED status to indicate preinit mode


preinit_mount_root
Mount the root filesystem
File
Description

05_mount_skip
check_skip

10_check_for_mtd
mount_no_mtd, check_for_mtd

Functions, in order, executed by this hook (doesn't list the functions only called by other functions)
Function
Description

check_for_mtd
Check for a mtd partition named rootfs_data. If not present mount kernel fs as root (e.g. all_jjfs2 or squashfs only) and skip rest.
check_for_jffs2
Check if jffs2 formatted yet. If not, mount ramoverlay and skip rest
do_mount_jffs2
find jffs2 partition and mount it, indicating result
rootfs_pivot
if jffs2 mounted, make it root (/) and old root (squashfs) /rom , skipping rest on success
do_mount_no_jffs2
If nothing was mounted so far, mount ramdisk (ram overlay), skipping rest on success
do_mount_no_mtd
If there was nothing mounted , mount /dev/root as root (/)
Functions which are called by other functions, rather than directly as part of a hook
Function
Description

mount_no_mtd
if there is not mtd partition named rootfs_data, mount /dev/root as / (root). E.g. this can occur if the firmware filesystem is entirely a jffs2 partition, with no squashfs)
mount_no_jffs2
mount ramdisk (ram overlay) if there is rootfs_data, but it has not been formatted yet)
find_mount_jffs2
find and mount rootfs_data jffs2 partition on /jffs

jffs2_not_mounted
returns true (0) if jffs2 is not mounted


initramfs
No files or functions at this time.

Firstboot Operation
Main Firstboot Script
  • Source common functions
  • Source functions for hooks
  • if block:

if invoked as executable
       if called with `switch2jffs` parameter (i.e. from rcS)           run hook `switch2jffs`       if called standalone (e.g. from commandline)           if there is a jffs2 partition mounted                run hook `jffs2reset`           else                erase rootfs_data mtd partition                format                and remount it           end       end if sourced (that is not executed)      set some variables end
Hooks
switch2jffs
Make the filesystem that we want to be the rootfs, to be the rootfs
File
Description

10_determine_parts
deterimine_mtd_part, determine_rom_part, determine_jffs2_part, set_mtd_part, set_rom_part, set_jffs2_part
20_has_mini_fo
check_for_mini_fo

30_is_rootfs_mounted
skip_if_rootfs_mounted

40_copy_ramoverlay
copy_ramoverlay

50_pivot
with_fo_pivot

99_10_with_fo_cleanup
with_fo_cleanup

Functions, in order, executed by this hook (doesn't list the functions only called by other functions)
Function
Description

determine_mtd_part
exit if no mtd partition at all

determine_rom_partexit if not squashfs partition (firstboot not for all_jffs2)
determine_jffs2_partfigure out the jffs2 partition (assuming we have an mtd part
check_for_mini_fodetermine if we have mini_fo overlay in kernel. If not run *no_fo* hook
skip_if_rootfs_mountedattempt mount jffs2 on /rom/jffs2. If partition already mounted exit
copy_ramoverlay
copy the data from the temporary rootfs (on the ramdisk overlay over the squashfs) to the new jffs2 partition
with_fo_pivot
make current jffs2 partition the root partition and the current root /rom
with_fo_cleanup
clean up unneeded mount of ramdisk, if possible

Functions which are called by other functions, rather than directly as part of a hook
Function
Description

set_mtd_part
set variables for mtd partition

set_rom_part
set variable for squashfs (rom) partition

set_jffs_part
set variable for jffs2 partition


no_fo
Make the filesystem that we want to be the rootfs, to be the rootfs, given that we have no mini\_fo overlay filesystem
File
Description

10_no_fo_clear_overlay
no_fo_clear_overlay

20_no_fo_mount_jffs
no_fo_mount_jffs

30_no_fo_pivot
no_fo_pivot

40_no_fo_copy_ram_overlay
no_fo_copy_ram_overlay

99_10_no_fo_cleanup
no_fo_cleanup

Functions, in order, executed by this hook (doesn't list the functions only called by other functions)
Function
Description

no_fo_clear_overlay
stop ramdisk overlaying the squashfs

no_fo_mount_jffs
attempt to mount jffs (work around problem with union). If already mounted exit
no_fo_pivot
make jffs root and old root /rom

no_fo_copy_ram_overlaycopy data from ram overlay to jffs2 overlay of squashfs
no_fo_cleanup
get rid of extra binds and mounts


jffs2reset
Reset jffs2 to defaults
File
Description

10_rest_has_mini_fo
reset_check_for_mini_fo

20_reset_clear_jffs
reset_clear_jffs

30_reset_copy_rom
reset_copy_rom

Functions, in order, executed by this hook (doesn't list the functions only called by other functions)
Function
Description

reset_check_for_mini_foDetermine if the kernel supports mini_fo overlay
reset_clear_jffs
if mini_fo is supported, erase all data in overlay and remount (resets back to 'pure' squashfs versions
reset_copy_rom
if mini_fo is not supported, make symlinks and copy critical files from squashfs to jffs

Customizing the system
NB: These files must be added to the *squashfs* (or if using a all_jffs2 system, to the jffs2). That means, for instance adding it to the image's rootfs. This can be done, for instace, by creating `${ROOTDIR}/files/filename` (with appropriate substitutions of course).

Overriding Example
Warning!
This section describes actions that might damage your device or firmware. Proceed with care!



Customizing the system is quite simple. We give an example of changing the message for preinit from '- preinit -' to '- setting the table for dinner -'
Create a file that replaces the function `indicate_regular_preinit_boot`. `pi_indicate_preinit` is defined in `20_indicate_preinit`, so we define our replace functions in `25_dinner_not_router`.
`/lib/preinit/25_dinner_not_router`
   pi_indicate_preinit() {          echo "- setting the table for dinner -"         preinit_net_echo "Dinner is just about ready!"         pi_indicate_led   }   
This results in the following boot log:
NET: Registered protocol family 17802.1Q VLAN Support v1.8 Ben Greear <greearb@candelatech.com>All bugs added by David S. Miller <davem@redhat.com>VFS: Mounted root (squashfs filesystem) readonly on device 31:2.Freeing unused kernel memory: 132k freedPlease be patient, while OpenWrt loads ...eth1: link forced UP - 100/full - flow control off/off- setting the table for dinner -Press CTRL-C or Press f<ENTER> to enter failsafe modeswitching to jffs2mini_fo: using base directory: /mini_fo: using storage directory: /jffs- init -
The default boot log is
NET: Registered protocol family 17802.1Q VLAN Support v1.8 Ben Greear <greearb@candelatech.com>All bugs added by David S. Miller <davem@redhat.com>VFS: Mounted root (squashfs filesystem) readonly on device 31:2.Freeing unused kernel memory: 132k freedPlease be patient, while OpenWrt loads ...eth1: link forced UP - 100/full - flow control off/off- preinit -Press CTRL-C or Press f<ENTER> to enter failsafe modeswitching to jffs2mini_fo: using base directory: /mini_fo: using storage directory: /jffs- init -   
Adding Example
As another example we will add a message to failsafe, between the notice that we're in failsafe mode in the shell. You could use this, for example, to create a text menu system, or to launch a simple web server (with cgi scripts) to permit the user to do failsafe things.
We want to add the message, 'Remember, at this point there are no writable filesystems'
We create the file `50_failsafe_remember_no_rw`, in `/lib/preinit`
  remember_no_rw() {      echo "Remember, at this point there are no writable filesystems"  }    boot_hook_add failsafe remember_no_rw  
This creates the function `remember_no_rw` and adds it to the failsafe hook, in between `10_indicate_failsafe` and `99_10_failsafe_login` which define the other functions in the `failsafe` hook. This wasn't necessary for the previous example because the function was already in a hook.
The boot log for this, when entering failsafe, is:
VFS: Mounted root (squashfs filesystem) readonly on device 31:2.Freeing unused kernel memory: 132k freedPlease be patient, while OpenWrt loads ...eth1: link forced UP - 100/full - flow control off/off- preinit -Press CTRL-C or Press f<ENTER> to enter failsafe modef- failsafe -Remember, at this point there are no writable filesystemsBusyBox v1.15.3 (2010-01-20 19:26:26 EST) built-in shell (ash)Enter 'help' for a list of built-in commands.ash: can't access tty; job control turned off  _______                     ________        __ |       |.-----.-----.-----.|  |  |  |.----.|  |_ |   -   ||  _  |  -__|     ||  |  |  ||   _||   _| |_______||   __|_____|__|__||________||__|  |____|                |__| W I R E L E S S   F R E E D O M KAMIKAZE (bleeding edge, r19235) ------------------  * 10 oz Vodka       Shake well with ice and strain  * 10 oz Triple sec  mixture into 10 shot glasses.  * 10 oz lime juice  Salute! ---------------------------------------------------
Architecture-specific notes
Some architectures have additional files and functions (or overrides of the above functions) in order to accommodate specific needs of that hardware. In that case the files are located in the source tree under $ROOTDIR/target/linux/<architecture[/subarch]/base-files/lib/preinit. During build they are merged and appear under /lib/preinit along with the rest.


+10
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|深圳市光明谷科技有限公司|光明谷商城|Sunshine Silicon Corpporation ( 粤ICP备14060730号|Sitemap

GMT+8, 2024-12-28 01:21 , Processed in 0.097253 second(s), 39 queries .

Powered by Discuz! X3.2 Licensed

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表