当前位置: 首页 > article >正文

根文件系统(二):busybox

        本文主要探讨210的busybox相关知识。

busybox初移植

        修改Makefile

ARCH = arm
CROSS_COMPILE = /root/arm-2009q3/bin//arm-none-linux-gnueabi-

        配置修改

make menuconfigBusybox Settings--->Build Options--->[*]Build BusyBox as a static binary(no shared libs)Busybox Library Tuning--->[*]vi-style line editing commands[*]Fancy shell promptsLinux Module Utilities--->[ ]Simplified modutils[*]insmod[*]rmmod[*]lsmod[*]modprobe[*]depmodLinux System Utilities--->[*]mdev[*]Support /etc/mdev.conf[*]Support subdirs/symlinks[*]Support regular expressions substitutions when renaming dev[*]Support command execution at device addition/removal[*]Support loading of firmwaresCoreutils  --->[ ] sync 

        编译安装 

make -j 8 && make install -j 8

        结果显示      

        挂载根文件系统/linuxrc成功,找不到/etc/init.d/rcS和/dev/tty2等文件

busybox再移植

        inittab
                inittab是etc下的配置文件,linuxrc运行时调用并且按格式解析文件。
                inittab格式:

id:runlevels:action:process

                    #注释
                    :分隔符
                    unlevels:程序运行级别(15)
                    process为可执行程序(shell)
                    action是process的执行条件

        添加inittab

cd rootfsmkdir etccd etcvim inittab#first:run the system script file
::sysinit:/etc/init.d/rcS
::askfirst:-/bin/sh
::ctrlaltdel:-/sbin/reboot
#umount all filesystem
::shutdown:/bin/umount -a -r
#restart init process
::restart:/sbin/init


        busybox(C)
                busybox入口是libbb/appletlib.c的main
                其余xxx_main函数为shell命令数主函数

 

#if ENABLE_BUILD_LIBBUSYBOX
int lbb_main(char **argv)
#else
int main(int argc UNUSED_PARAM, char **argv)
#endif
{/* Tweak malloc for reduced memory consumption */
#ifdef M_TRIM_THRESHOLD/* M_TRIM_THRESHOLD is the maximum amount of freed top-most memory* to keep before releasing to the OS* Default is way too big: 256k*/mallopt(M_TRIM_THRESHOLD, 8 * 1024);
#endif
#ifdef M_MMAP_THRESHOLD/* M_MMAP_THRESHOLD is the request size threshold for using mmap()* Default is too big: 256k*/mallopt(M_MMAP_THRESHOLD, 32 * 1024 - 256);
#endif#if !BB_MMU/* NOMMU re-exec trick sets high-order bit in first byte of name */if (argv[0][0] & 0x80) {re_execed = 1;argv[0][0] &= 0x7f;}
#endif#if defined(SINGLE_APPLET_MAIN)/* Only one applet is selected in .config */if (argv[1] && is_prefixed_with(argv[0], "busybox")) {/* "busybox <applet> <params>" should still work as expected */argv++;}/* applet_names in this case is just "applet\0\0" */lbb_prepare(applet_names IF_FEATURE_INDIVIDUAL(, argv));return SINGLE_APPLET_MAIN(argc, argv);
#elselbb_prepare("busybox" IF_FEATURE_INDIVIDUAL(, argv));applet_name = argv[0];if (applet_name[0] == '-')applet_name++;applet_name = bb_basename(applet_name);parse_config_file(); /* ...maybe, if FEATURE_SUID_CONFIG */run_applet_and_exit(applet_name, argv);/*bb_error_msg_and_die("applet not found"); - sucks in printf */full_write2_str(applet_name);full_write2_str(": applet not found\n");/* POSIX: "If a command is not found, the exit status shall be 127" */exit(127);
#endif
}

                 busybox执行main函数判断argv[0]再调用相应的xxx_main实现命令

lbb_prepare("busybox" IF_FEATURE_INDIVIDUAL(, argv));applet_name = argv[0];if (applet_name[0] == '-')applet_name++;applet_name = bb_basename(applet_name);parse_config_file(); /* ...maybe, if FEATURE_SUID_CONFIG */run_applet_and_exit(applet_name, argv);/*bb_error_msg_and_die("applet not found"); - sucks in printf */full_write2_str(applet_name);full_write2_str(": applet not found\n");/* POSIX: "If a command is not found, the exit status shall be 127" */exit(127);

                parse_inittab(init.c)函数解析/etc/inittab再执行sysinit,wait,once后死循环执行respwan和askfirst

static void parse_inittab(void)
{
#if ENABLE_FEATURE_USE_INITTABchar *token[4];parser_t *parser = config_open2("/etc/inittab", fopen_for_read);if (parser == NULL)
#endif{/* No inittab file - set up some default behavior *//* Sysinit */new_init_action(SYSINIT, INIT_SCRIPT, "");/* Askfirst shell on tty1-4 */new_init_action(ASKFIRST, bb_default_login_shell, "");
//TODO: VC_1 instead of ""? "" is console -> ctty problems -> angry usersnew_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);/* 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 */new_init_action(SHUTDOWN, "swapoff -a", "");/* Restart init when a QUIT is received */new_init_action(RESTART, "init", "");return;}#if ENABLE_FEATURE_USE_INITTAB/* optional_tty:ignored_runlevel:action:command* Delims are not to be collapsed and need exactly 4 tokens*/while (config_read(parser, token, 4, 0, "#:",PARSE_NORMAL & ~(PARSE_TRIM | PARSE_COLLAPSE))) {/* order must correspond to SYSINIT..RESTART constants */static const char actions[] ALIGN1 ="sysinit\0""wait\0""once\0""respawn\0""askfirst\0""ctrlaltdel\0""shutdown\0""restart\0";int action;char *tty = token[0];if (!token[3]) /* less than 4 tokens */goto bad_entry;action = index_in_strings(actions, token[2]);if (action < 0 || !token[3][0]) /* token[3]: command */goto bad_entry;/* turn .*TTY -> /dev/TTY */if (tty[0]) {tty = concat_path_file("/dev/", skip_dev_pfx(tty));}new_init_action(1 << action, token[3], tty);if (tty[0])free(tty);continue;bad_entry:message(L_LOG | L_CONSOLE, "Bad inittab entry at line %d",parser->lineno);}config_close(parser);
#endif
}int init_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
int init_main(int argc UNUSED_PARAM, char **argv)
{if (argv[1] && strcmp(argv[1], "-q") == 0) {return kill(1, SIGHUP);}#if DEBUG_SEGV_HANDLER{struct sigaction sa;memset(&sa, 0, sizeof(sa));sa.sa_sigaction = handle_sigsegv;sa.sa_flags = SA_SIGINFO;sigaction(SIGSEGV, &sa, NULL);sigaction(SIGILL, &sa, NULL);sigaction(SIGFPE, &sa, NULL);sigaction(SIGBUS, &sa, NULL);}
#endifif (!DEBUG_INIT) {/* Expect to be invoked as init with PID=1 or be invoked as linuxrc */if (getpid() != 1&& (!ENABLE_FEATURE_INITRD || applet_name[0] != 'l') /* not linuxrc? */) {bb_error_msg_and_die("must be run as PID 1");}
#ifdef RB_DISABLE_CAD/* Turn off rebooting via CTL-ALT-DEL - we get a* SIGINT on CAD so we can shut things down gracefully... */reboot(RB_DISABLE_CAD); /* misnomer */
#endif}/* If, say, xmalloc would ever die, we don't want to oops kernel* by exiting.* NB: we set die_func *after* PID 1 check and bb_show_usage.* Otherwise, for example, "init u" ("please rexec yourself"* command for sysvinit) will show help text (which isn't too bad),* *and sleep forever* (which is bad!)*/die_func = sleep_much;/* Figure out where the default console should be */console_init();set_sane_term();xchdir("/");setsid();/* Make sure environs is set to something sane */putenv((char *) "HOME=/");putenv((char *) bb_PATH_root_path);putenv((char *) "SHELL=/bin/sh");putenv((char *) "USER=root"); /* needed? why? */if (argv[1])xsetenv("RUNLEVEL", argv[1]);#if !ENABLE_FEATURE_EXTRA_QUIET/* Hello world */message(L_CONSOLE | L_LOG, "init started: %s", bb_banner);
#endif#endif/* Check if we are supposed to be in single user mode */if (argv[1]&& (strcmp(argv[1], "single") == 0 || strcmp(argv[1], "-s") == 0 || LONE_CHAR(argv[1], '1'))) {/* ??? shouldn't we set RUNLEVEL="b" here? *//* 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., INIT_SCRIPT and a pair* of "askfirst" shells) */parse_inittab();}#if ENABLE_SELINUXif (getenv("SELINUX_INIT") == NULL) {int enforce = 0;putenv((char*)"SELINUX_INIT=YES");if (selinux_init_load_policy(&enforce) == 0) {BB_EXECVP(argv[0], argv);} else if (enforce > 0) {/* SELinux in enforcing mode but load_policy failed */message(L_CONSOLE, "can't load SELinux Policy. ""Machine is in enforcing mode. Halting now.");return EXIT_FAILURE;}}
#endif/* Make the command line just say "init"  - thats all, nothing else */strncpy(argv[0], "init", strlen(argv[0]));/* Wipe argv[1]-argv[N] so they don't clutter the ps listing */while (*++argv)nuke_str(*argv);/* Set up signal handlers */if (!DEBUG_INIT) {struct sigaction sa;/* Stop handler must allow only SIGCONT inside itself */memset(&sa, 0, sizeof(sa));sigfillset(&sa.sa_mask);sigdelset(&sa.sa_mask, SIGCONT);sa.sa_handler = stop_handler;/* NB: sa_flags doesn't have SA_RESTART.* It must be able to interrupt wait().*/sigaction_set(SIGTSTP, &sa); /* pause *//* Does not work as intended, at least in 2.6.20.* SIGSTOP is simply ignored by init:*/sigaction_set(SIGSTOP, &sa); /* pause *//* These signals must interrupt wait(),* setting handler without SA_RESTART flag.*/bb_signals_recursive_norestart(0+ (1 << SIGINT)  /* Ctrl-Alt-Del */+ (1 << SIGQUIT) /* re-exec another init */
#ifdef SIGPWR+ (1 << SIGPWR)  /* halt */
#endif+ (1 << SIGUSR1) /* halt */+ (1 << SIGTERM) /* reboot */+ (1 << SIGUSR2) /* poweroff */
#if ENABLE_FEATURE_USE_INITTAB+ (1 << SIGHUP)  /* reread /etc/inittab */
#endif, record_signo);}/* Now run everything that needs to be run *//* First run the sysinit command */run_actions(SYSINIT);check_delayed_sigs();/* Next run anything that wants to block */run_actions(WAIT);check_delayed_sigs();/* Next run anything to be run only once */run_actions(ONCE);/* Now run the looping stuff for the rest of forever.*/while (1) {int maybe_WNOHANG;maybe_WNOHANG = check_delayed_sigs();/* (Re)run the respawn/askfirst stuff */run_actions(RESPAWN | ASKFIRST);maybe_WNOHANG |= check_delayed_sigs();/* Don't consume all CPU time - sleep a bit */sleep(1);maybe_WNOHANG |= check_delayed_sigs();/* Wait for any child process(es) to exit.** If check_delayed_sigs above reported that a signal* was caught, wait will be nonblocking. This ensures* that if SIGHUP has reloaded inittab, respawn and askfirst* actions will not be delayed until next child death.*/if (maybe_WNOHANG)maybe_WNOHANG = WNOHANG;while (1) {pid_t wpid;struct init_action *a;/* If signals happen _in_ the wait, they interrupt it,* bb_signals_recursive_norestart set them up that way*/wpid = waitpid(-1, NULL, maybe_WNOHANG);if (wpid <= 0)break;a = mark_terminated(wpid);if (a) {message(L_LOG, "process '%s' (pid %d) exited. ""Scheduling for restart.",a->command, wpid);}/* See if anyone else is waiting to be reaped */maybe_WNOHANG = WNOHANG;}} /* while (1) */
}

        /etc/init.d/rcS

                PATH定义程序路径,export导出为环境变量,默认为/bin /sbin /usr/bin /usr/sbin 
                runleve运行模式,S为单用户模式
                umask是用户在创建文件时的默认权限,umask值与文件权限互补
                mount -a是挂载/etc/fstab文件中的所有挂载
                mdev(udev/mdev)是linux启动时配合驱动生成/dev下的设备文件
                hostname指定主机名
                ifconfig指定ip地址

        添加rcs

cd rootfs/etcmkdir init.dcd init.dvim rcS#!/bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/binrunlevel=S
prevlevel=Numask 022export PATH runlevel prevlevelmount -aecho /sbin/mdev > /proc/sys/kernel/hotplug
mdev -s/bin/hostname -F /etc/sysconfig/hostnameifconfig eth0 192.168.100.27chmod +x rcS

        添加fastab

cd etcvim fastab# /etc/fstab: static file system information.
#
# Use 'vol_id --uuid' to print the universally unique identifier for a
# device; this may be used with UUID= as a more robust way to name devices
# that works even if disks are added and removed. See fstab(5).
#
#     <file system>     <mount point>     <type>     <options>     <dump>     <pass>proc             /proc             proc     defaults     0         0sysfs             /sys             sysfs     defaults     0         0tmpfs             /var             tmpfs     defaults     0         0tmpfs             /tmp             tmpfs     defaults     0         0tmpfs             /dev             tmpfs     defaults     0         0cd rootfsmkdir proc sys var tmp dev root


        添加主机名

cd rootfs/etcmkdir sysconfigcd sysconfigvim hostnamecxb210


        添加用户登录        

        用户登录在inittab执行/bin/sh生成shell界面,故添加/bin/login或/sbin/gettty登录功能

vim etc/inittab#::askfirst:-/bin/sh
s3c2410_serial2::sysinit:/bin/login
添加passwd和shadow文件vim etc/passwdroot:x:0:0:root:/root:/bin/shvim etc/shadow(123456)root:$6$xHD0aja9$Bxg0rl3jJCq7RXnUuCaBNZGXC5aZrKWUHCiE0Lgp3vh6.S.4gsMhfPLVSwOwIDVZDNVhjksB0VdcvI7MDTKaz0:19612:0:99999:7:::

         profile文件(/etc/)修改提示符号,导出环境变量

vim etc/profile# Ash profile
# vim: syntax=sh# No core files by default
ulimit -S -c 0 > /dev/null 2>&1USER="`id -un`"
LOGNAME=$USER
PS1='[\u@\h \W]\# '
PATH=$PATHHOSTNAME=`/bin/hostname`export USER LOGNAME PS1 PATH

        

        添加库文件
        未添加库文件210可执静态链接行程序,添加库文件可执行动态链接程序

mkdir /root/rootfs/lib/cp /root/arm-2009q3/arm-none-linux-gnueabi/libc/lib/*so* /root/rootfs/lib/ -rdf


        库文件添加测试

mkdir /root/ccd cvim hello.c#include <stdio.h>int main()
{printf("hello word\n");return 0;
}arm-linux-gcc hello.c -o hello_dynamicarm-linux-gcc hello.c -o hello_satic -staticcp ./* rootfs/root

        添加开机自启动(末尾添加)

vim etc/init.d/rcS./root/hello_satic./root/hello_dynamic


        制作镜像

mkdir /root/make_imagecd /root/make_imagedd if=/dev/zero of=rootfs.ext2 bs=1024 count=10240losetup  /dev/loop1 rootfs.ext2mke2fs -m 0 /dev/loop1 10240mount -t ext2 /dev/loop1 /mntcp /root/rootfs/* /mnt -rfumount /dev/loop1losetup -d /dev/loop1


        烧录并启动

 

uboot:set bootargs console=ttySAC2,115200 root=/dev/mmcblk0p2 rw init=/linuxrc rootfstype=ext2savefastbootwindows:fastboot flash system rootfs.ext2fastboot reboot

结果显示 

http://www.lryc.cn/news/2417775.html

相关文章:

  • 浅谈NBIOT
  • 全网最全python教程,从零到精通(学python有它就够必收藏)_python学习相关博客
  • 如何使用好google学术?
  • js刷新当前页面的5种方式
  • LNMP架构环境搭建(Linux+Nginx+Mysql+PHP)
  • 数组详细讲解
  • loki介绍
  • 正确配置安装和卸载Cygwin
  • Windows server 2016——SQL server 简介与安装
  • 都2023年了,Servlet还有必要学习吗?一文带你快速了解Servlet
  • Activiti入门及案例
  • window硬盘管理
  • 什么是UTF-8编码
  • spice新手学习手册
  • 我的docker随笔38:用 registry 搭建私有仓库
  • 常用概率分布的矩母函数、特征函数以及期望、方差的推导
  • ActiveMQ:消息的优先级与抢占机制
  • Tomcat下载及配置(IDEA)
  • Linux服务器JDK安装环境变量配置详细步骤
  • 【Java技术专题】「Guava技术系列」Guava-Collections实战使用相关Guava不一般的集合框架
  • CountDownLatch 和 CyclicBarrier 使用场景详解
  • 2024年安卓最全理解Android虚拟机体系结构,2024年最新Android高级工程师进阶学习
  • U盘启动盘怎么制作?
  • Regression算法之通俗讲解
  • UTF-8基础
  • 算法刷题笔记——动态规划篇
  • 损失函数MSE和MAE的区别以及如何选择
  • c语言md5函数头文件,【C】md5函数实现代码
  • 【Java】lambda表达式的3种写法
  • MyCat 管理及监控