根文件系统(二):busybox
? ? ? ? 本文主要探讨210的busybox相关知识。
busybox初移植
????????修改Makefile
ARCH = arm
CROSS_COMPILE = /root/arm-2009q3/bin//arm-none-linux-gnueabi-
????????配置修改
make menuconfig
Busybox Settings--->
?? ?Build Options--->
?? ??? ?[*]Build BusyBox as a static binary(no shared libs)
?? ??? ?
Busybox Library Tuning--->
?? ?[*]vi-style line editing commands
?? ?[*]Fancy shell prompts
?? ?
?? ?
Linux Module Utilities--->
?? ?[ ]Simplified modutils
?? ?[*]insmod
?? ?[*]rmmod
?? ?[*]lsmod
?? ?[*]modprobe
?? ?[*]depmod
?? ?
Linux 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 firmwares
Coreutils ?--->
?? ?[ ] 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 rootfs
mkdir etc
cd etc
vim 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);
#else
?? ?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);
#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_INITTAB
?? ?char *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 users
?? ??? ?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);
?? ??? ?/* 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);
?? ?}
#endif
?? ?if (!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_SELINUX
?? ?if (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/etc
mkdir init.d
cd init.d
vim rcS
#!/bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin
runlevel=S
prevlevel=N
umask 022
export PATH runlevel prevlevel
mount -a
echo /sbin/mdev > /proc/sys/kernel/hotplug
mdev -s
/bin/hostname -F /etc/sysconfig/hostname
ifconfig eth0 192.168.100.27
chmod +x rcS
????????添加fastab
cd etc
vim 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 ?? ??? ?0
?? ?sysfs ?? ??? ??? ?/sys ?? ??? ??? ?sysfs ?? ?defaults ?? ?0 ?? ??? ?0
?? ?tmpfs ?? ??? ??? ?/var ?? ??? ??? ?tmpfs ?? ?defaults ?? ?0 ?? ??? ?0
?? ?tmpfs ?? ??? ??? ?/tmp ?? ??? ??? ?tmpfs ?? ?defaults ?? ?0 ?? ??? ?0
?? ?tmpfs ?? ??? ??? ?/dev ?? ??? ??? ?tmpfs ?? ?defaults ?? ?0 ?? ??? ?0
cd rootfs
mkdir proc sys var tmp dev root
????????添加主机名
cd rootfs/etc
mkdir sysconfig
cd sysconfig
vim hostname
cxb210
????????添加用户登录????????
????????用户登录在inittab执行/bin/sh生成shell界面,故添加/bin/login或/sbin/gettty登录功能
vim etc/inittab
#::askfirst:-/bin/sh
s3c2410_serial2::sysinit:/bin/login
添加passwd和shadow文件
vim etc/passwd
root:x:0:0:root:/root:/bin/sh
vim 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>&1
USER="`id -un`"
LOGNAME=$USER
PS1='[\u@\h \W]\# '
PATH=$PATH
HOSTNAME=`/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/c
cd c
vim hello.c
#include <stdio.h>
int main()
{
? ? ? ? printf("hello word\n");
? ? ? ? return 0;
}
arm-linux-gcc hello.c -o hello_dynamic
arm-linux-gcc hello.c -o hello_satic -static
cp ./* rootfs/root
????????添加开机自启动(末尾添加)
vim etc/init.d/rcS
./root/hello_satic
./root/hello_dynamic
????????制作镜像
mkdir /root/make_image
cd /root/make_image
dd if=/dev/zero of=rootfs.ext2 bs=1024 count=10240
losetup ?/dev/loop1 rootfs.ext2
mke2fs -m 0 /dev/loop1 10240
mount -t ext2 /dev/loop1 /mnt
cp /root/rootfs/* /mnt -rf
umount /dev/loop1
losetup -d /dev/loop1
????????烧录并启动
?
uboot:
set bootargs console=ttySAC2,115200 root=/dev/mmcblk0p2 rw init=/linuxrc rootfstype=ext2
save
fastboot
windows:
fastboot flash system rootfs.ext2
fastboot reboot
结果显示?
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!