日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > windows >内容正文

windows

构建根文件系统之busybox(一)浅析

發(fā)布時(shí)間:2025/4/5 windows 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 构建根文件系统之busybox(一)浅析 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

目錄

  • busybox(一)淺析
  • 引入
  • 讀取inittab
  • 創(chuàng)建執(zhí)行腳本鏈表
  • 執(zhí)行腳本
  • 小結(jié)

busybox(一)淺析

源碼包在busybox-1.7.0.tar.bz2,一個(gè)命令對應(yīng)著一個(gè)c文件,執(zhí)行init命令,則是有init.c,有函數(shù)init_main

int init_main(int argc, char **argv);

最終的目的是啟動(dòng)客戶的應(yīng)用程序,需要指定具體的環(huán)境

1. 配置文件讀取 2. 解析配置文件 3. 執(zhí)行用戶程序

help

相關(guān)的幫助可以搜索下/examples下的文件,比如搜索inittab,里面有相關(guān)說明

#define SYSINIT 0x001 //執(zhí)行一次等待結(jié)束后從鏈表刪除 #define RESPAWN 0x002 //while循環(huán)執(zhí)行 #define ASKFIRST 0x004 //while循環(huán)執(zhí)行,會(huì)打印信息,等待回車 #define WAIT 0x008 //執(zhí)行一次等待結(jié)束后從鏈表刪除,在SYSINIT后 #define ONCE 0x010 //與SYSINIT 區(qū)別在于不等待其執(zhí)行結(jié)束 #define CTRLALTDEL 0x020 //輸入信號(hào)后執(zhí)行 #define SHUTDOWN 0x040 //輸入信號(hào)后執(zhí)行 #define RESTART 0x080 //輸入信號(hào)后執(zhí)行

流程圖

引入

從init_main函數(shù)入口分析,Linux 是按照run_init_process("/sbin/init");形式調(diào)用,沒有傳遞參數(shù),所以執(zhí)行else分支,解析配置表

if (argc > 1&& (!strcmp(argv[1], "single") || !strcmp(argv[1], "-s") || LONE_CHAR(argv[1], '1')) ) {/* Start a shell on console */new_init_action(RESPAWN, bb_default_login_shell, ""); } else {/* Not in single user mode -- see what inittab says *//* NOTE that if CONFIG_FEATURE_USE_INITTAB is NOT defined,* then parse_inittab() simply adds in some default* actions(i.e., runs INIT_SCRIPT and then starts a pair* of "askfirst" shells */parse_inittab(); }

讀取inittab

parse_inittab();讀取inittab配置表,可以搜索下example下查看例子幫助,查閱如下格式

Format for each entry: <id>:<runlevels>:<action>:<process> <id>: WARNING: This field has a non-traditional meaning for BusyBox init! <runlevels>: The runlevels field is completely ignored. <action>: Valid actions include: sysinit, respawn, askfirst, wait, once,restart, ctrlaltdel, and shutdown. <process>: Specifies the process to be executed and it's command line. 標(biāo)識(shí)作用
id自動(dòng)加上/dev/的前綴,用作終端,stdin,stdout,stderr:printf,scanf,err 可以省略
runlevels可以忽略
action指示何止執(zhí)行
process應(yīng)用程序或者可執(zhí)行腳本

最終執(zhí)行new_init_action運(yùn)行腳本程序

默認(rèn)的配置表讀取

#define INITTAB "/etc/inittab" /* inittab file location */ static void parse_inittab(void) {file = fopen(INITTAB, "r"); }

創(chuàng)建執(zhí)行腳本鏈表

for (a = actions; a->name != 0; a++) {if (strcmp(a->name, action) == 0) {if (*id != '\0') {if (strncmp(id, "/dev/", 5) == 0) //這里為id加上/dev/的前綴id += 5;strcpy(tmpConsole, "/dev/");safe_strncpy(tmpConsole + 5, id,sizeof(tmpConsole) - 5);id = tmpConsole;}new_init_action(a->action, command, id);break;} }

當(dāng)不存在這個(gè)配置表的時(shí)候也會(huì)有一個(gè)默認(rèn)配置文件,這里以默認(rèn)的其中一個(gè)腳本解析

new_init_action(ASKFIRST, bb_default_login_shell, VC_2);# define VC_2 "/dev/tty2" #define ASKFIRST 0x004 const char bb_default_login_shell[] ALIGN1 = LIBBB_DEFAULT_LOGIN_SHELL; #define LIBBB_DEFAULT_LOGIN_SHELL "-/bin/sh"

也就是最終執(zhí)行

new_init_action(ASKFIRST, "-/bin/sh", "/dev/tty2"); ASKFIRST 執(zhí)行的時(shí)機(jī) -/bin/sh 腳本程序 /dev/tty2 id終端,加上了/dev/,符合上述描述

分析下new_init_action函數(shù)內(nèi)部,

  • 創(chuàng)建?init_action結(jié)構(gòu),包含inittab中的信息
  • 加入到init_action_list鏈表中
  • for (a = last = init_action_list; a; a = a->next) {/* don't enter action if it's already in the list,* but do overwrite existing actions */if ((strcmp(a->command, command) == 0)&& (strcmp(a->terminal, cons) == 0)) {a->action = action;return;}last = a; }struct init_action {struct init_action *next;int action; pid_t pid; //對應(yīng)進(jìn)程id, process idchar command[INIT_BUFFS_SIZE]; //對應(yīng)應(yīng)用程序 char terminal[CONSOLE_NAME_SIZE]; //對應(yīng)終端 };

    由此,可以理解當(dāng)配置文件不存在的時(shí)候,會(huì)去創(chuàng)建配置表

    #define INITTAB "/etc/inittab" /* inittab file location */file = fopen(INITTAB, "r");if (file == NULL) {/* No inittab file -- set up some default behavior *//* Reboot on Ctrl-Alt-Del */new_init_action(CTRLALTDEL, "reboot", "");/* Umount all filesystems on halt/reboot */new_init_action(SHUTDOWN, "umount -a -r", "");/* Swapoff on halt/reboot */if (ENABLE_SWAPONOFF) new_init_action(SHUTDOWN, "swapoff -a", "");/* Prepare to restart init when a HUP is received */new_init_action(RESTART, "init", "");/* Askfirst shell on tty1-4 */new_init_action(ASKFIRST, bb_default_login_shell, "");new_init_action(ASKFIRST, bb_default_login_shell, VC_2);new_init_action(ASKFIRST, bb_default_login_shell, VC_3);new_init_action(ASKFIRST, bb_default_login_shell, VC_4);/* sysinit */new_init_action(SYSINIT, INIT_SCRIPT, "");return;} >>>>>>>>>>>>>>>>>>>>>>>>>>>>>↓ 創(chuàng)建類似的inittatb ↓ >>>>>>>>>>>>>>>>>>>>>>>>>>>>>↓ ::CTRLALTDEL:reboot ::SHUTDOWN:umount -a -r ::RESTART:init ::ASKFIRST:-/bin/sh: tty2::ASKFIRST:-/bin/sh tty3::ASKFIRST:-/bin/sh tty4::ASKFIRST:-/bin/sh ::SYSINIT:/etc/init.d/rcS

    執(zhí)行腳本

    腳本有多種類型,不同類型執(zhí)行方式與時(shí)機(jī)不同

    #define SYSINIT 0x001 //執(zhí)行一次等待結(jié)束后從鏈表刪除 #define RESPAWN 0x002 //while循環(huán)執(zhí)行 #define ASKFIRST 0x004 //while循環(huán)執(zhí)行,會(huì)打印信息,等待回車 #define WAIT 0x008 //執(zhí)行一次等待結(jié)束后從鏈表刪除,在SYSINIT后 #define ONCE 0x010 //與SYSINIT 區(qū)別在于不等待其執(zhí)行結(jié)束 #define CTRLALTDEL 0x020 //輸入信號(hào)后執(zhí)行 #define SHUTDOWN 0x040 //輸入信號(hào)后執(zhí)行 #define RESTART 0x080 //輸入信號(hào)后執(zhí)行 run_actions(SYSINIT);waitfor(a, 0);//執(zhí)行a,等待執(zhí)行結(jié)束run(a);//執(zhí)行創(chuàng)建process子進(jìn)程waitpid(runpid, &status, 0);delete_init_action(a);//刪除鏈表/* Next run anything that wants to block */run_actions(WAIT);waitfor(a, 0);//執(zhí)行a,等待執(zhí)行結(jié)束run(a);//執(zhí)行創(chuàng)建process子進(jìn)程waitpid(runpid, &status, 0);delete_init_action(a);//刪除鏈表/* Next run anything to be run only once */run_actions(ONCE);run(a);delete_init_action(a);/* Now run the looping stuff for the rest of forever */while (1) {//重新運(yùn)行pid已經(jīng)退出的子進(jìn)程run_actions(RESPAWN);if (a->pid == 0) { //默認(rèn)pid為0a->pid = run(a);}run_actions(ASKFIRST);if (a->pid == 0) {a->pid = run(a);}//打印"\nPlease press Enter to activate this console. ";,//等待輸入回車//創(chuàng)建子進(jìn)程wpid = wait(NULL);//等待子進(jìn)程退出while (wpid > 0) {a->pid--;//推出后pid=0}}}

    小結(jié)

  • 打開終端?dev/console
  • 打開dev/null,用作不設(shè)置終端id的時(shí)候的定位
  • 讀取配置文件etc/inittab,需要存在配置文件的可執(zhí)行程序或者腳本
  • 執(zhí)行腳本
  • 所以一個(gè)最小的根文件系統(tǒng)必備的一些資源

    dev/console dev/null sbin/init-------------busybox提供,至少需要這個(gè)應(yīng)用程序,這是linux啟動(dòng)的第一個(gè)應(yīng)用程序 etc/inittab-----------配置文件,定義了一些應(yīng)用程序 配置文件制定的應(yīng)用程序----配置文件指定的應(yīng)用程序 C庫--------------------應(yīng)用程序的C庫

    總結(jié)

    以上是生活随笔為你收集整理的构建根文件系统之busybox(一)浅析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。