1. busybox简介

busybox是一个集成了一百多个最常用linux命令和工具的软件,它将许多常用的LINUX命令和工具结合到了一个单独的可执行程序中。虽然与相应的GNU工具比较起来,busybox所提供的功能和参数略少,但在比较小的系统(例如启动盘)或者嵌入式系统中,已经足够了。

busybox在设计上就充分考虑了硬件资源受限的特殊工作环境。它采用一种很巧妙的办法减少自己的体积:所有的命令都通过“插件”的方式集中到一个可执行文件中,在实际应用过程中通过不同的符号链接来确定到底要执行哪个操作。例如最终生成的可执行文件为busybox,当为它建立一个符号链接ls的时候,就可以通过执行这个新命令实现列目录的功能。采用单一执行文件的方式最大限度地共享了程序代码,甚至连文件头、内存中的程序控制块等其他操作系统资源都共享了,对于资源比较紧张的系统来说,是最合适不过了。

Busybox配置如下:

Build Options--->

[*] Build BusyBox as a static binary (no shared libs)

Installation Options --->
Login/Password Management Utilities --->

Do you want to build BusyBox with a Cross Compiler。如果要对其他平台进行编译就要选择它并设置相应的编译程序前缀。我们选择armv5l-linux-,前面加上绝对路径。

Login/Password Management Utilities--->

[*]Use internal password and group functions rather than system
functions。这里设置使用busybox自己的password和shadow文件的功能。

如果需要一个交互的登录界面,则选择getty、login和passwd

编译make TARGET_ARCH=arm,生成的目标代码位于_install目录下。

2. 文件系统启动过程

Linux的启动过程主要分成两个阶段:

1.启动内核。在这个阶段,内核装入内存并在初始化每个设备驱动器时打印信息。
2.执行程序init。装入内核并初始化设备后,运行init程序。init程序处理所有程序的启动,包括重要系统程序和其它指定在启动时装入的软件。

现在主要详细介绍一下文件系统的启动过程,即linux启动过程的第二阶段,大概分为以下几个过程:

(1)运行init

init的进程号是1,从这一点就能看出,init进程是系统所有进程的起点,linux在完成核内引导以后,就开始运行init程序。init程序需要读取配置文件/etc/inittab,以查看下一步做什么。inittab是一个不可执行的文本文件,它有若干行指令所组成,告诉 init 要进入什么运行级别,以及在哪里可以找到该运行级别的配置文件。以下是qsan的inittab文件(部分注释省略):

# The default runlevel.

id:4:initdefault:

# Boot-time system configuration/initialization
script.

# This is run first except when booting in emergency
(-b) mode.

si::sysinit:/etc/init.d/rcS

# /etc/init.d executes the S and K scripts upon change
of runlevel.

l0:0:wait:/etc/init.d/rc 0

l1:1:wait:/etc/init.d/rc 1

l2:2:wait:/etc/init.d/rc 2

l3:3:wait:/etc/init.d/rc 3

l4:4:wait:/etc/init.d/rc 4

l6:6:wait:/etc/init.d/rc 6

# Trap CTRL-ALT-DELETE

ca::ctrlaltdel:/sbin/shutdown -t3 -h now

# /sbin/getty invocations for the runlevels.

# Example how to put a getty on a serial line (for a
terminal)

T0:134:respawn:/sbin/getty -L ttyS0
115200 vt100

T1:1:respawn:/sbin/getty -L ttyS1 115200
vt100

以上面的inittab文件为例,来说明一下inittab的格式。其中以#开始的行是注释行,除了注释行之外,每一行都有以下格式:

id:runlevel:action:process

id入口标识符,用于标识文件/etc/inittab中的每一个登记项。它是一个1-4位的字符串,对于getty或mingetty等其他login程序项,要求id与tty的编号相同,否则getty程序将不能正常工作。

runlevel – 运行级。说明该登记项适用于哪一个运行级。为空表示适用于所有级别.它是init所处于的运行级别标识,一般使用0-6以及S或s。0、1、6运行级别被系统保留。0作为halt动作,1作为重启至单用户模式,6为重启。S和s意义相同,表示单用户模式,且无需inittab文件,因此也不在inittab中出现,实际上,进入单用户模式时,init直接在控制台(/dev/console)上运行/sbin/sulogin。runlevel可以是并列的多个值,以匹配多个运行级别,对大多数action来说,仅当runlevel与当前运行级别匹配成功才会执行。

action – 定义init命令应该向进程实施什么动作。包括以下:

respawn-无论何时它终止,均重新启动命令

wait-运行命令一次。在继续之前,init等待它终止

once-运行命令一次

boot-命令在启动过程中运行。忽略运行等级字段

bootwait-命令在启动过程中运行,忽略运行等级字段。在继续之前,init等待该进程终止

initdefault-定义Linux系统的默认运行等级

powerwait-停电时命令运行。在继续之前,init等待该进程终止

powerfail-停电时命令运行。在继续之前,init不等待该进程终止

powerokwait-恢复电力时命令运行。在继续之前,init等待该进程终止

powerfailnow-UPS发出电池即将耗尽的信号时,运行该命令

process - 是具体的执行程序。程序后面可以带参数。

(2)系统初始化

sysinit、boot、bootwait等action将在系统启动时无条件运行,而忽略其中的runlevel。因此init进程首先会执行etc/init.d/rcS脚本,rcS内容如下:

#首先,定义PATH、runlevel、prevlevel然后导出到环境中

PATH=/sbin:/bin:/usr/sbin:/usr/bin

runlevel=S

prevlevel=N

umask 022

export PATH runlevel prevlevel

#然后,判断是不是第一次安装系统,如果是,则检查并且执行安装程序留下的脚本

if [ -x /sbin/unconfigured.sh ]

then

/sbin/unconfigured.sh

fi

. /etc/default/rcS

export VERBOSE

#捕捉INT、QUIT、TSTP信号,

trap":"INT QUIT TSTP

#检查/etc/rcS.d/目录,看是否有以S开头并且紧跟两个字符(实际上

#一般是两个数字0-99)命名的非普通(! -f"$i")文件,如果有则根据

#文件的类型作出两个选择

# 1,是.sh结尾的脚本时执行

# 2,如果不是.sh结尾的脚本,则传递给start参数执行这个文件

for i in /etc/rcS.d/S??*

do

#
Ignore dangling symlinks for now.

[ !
-f"$i"]&& continue

case"$i"in

*.sh)

#
Source shell script for speed.

(

trap - INT QUIT TSTP

set start

. $i

)

;;

*)

#
No sh extension, so fork subprocess.

$i start

;;

esac

done

#这是为了兼容其他系统的/etc/rc.boot脚本

[ -d /etc/rc.boot ]&& run-parts
/etc/rc.boot

#这也是用于第一次安装系统后需要执行的脚本,安装成功后,系统上

#一般没有这个脚本

if [ -x /sbin/setup.sh ]

then

/sbin/setup.sh

fi

#/etc/rc.S/rcS脚本执行结束.返回/inittab

(3)启动对应运行级别的守护进程

返回/inittab,接下来根据系统进入的运行级别,启动对应运行级别的守护进程,这里为4,init将执行配置文件inittab中的以下这行:

l4:4:wait:/etc/init.d/rc 4

这一行表示以4为参数运行/etc/rc.d/rc,/etc/rc.d/rc是一个Shell脚本,它接受4作为参数,去执行/etc/rc.d/rc4.d/目录下的所有的rc启动脚本,/etc/rc.d/rc4.d/目录中的这些启动脚本实际上都是一些链接文件,而不是真正的rc启动脚本,真正的rc启动脚本实际上都是放在/etc/rc.d/init.d/目录下。而这些rc启动脚本有着类似的用法,它们一般能接受start、stop、restart、status等参数。

/etc/rc.d/rc4.d/中的rc启动脚本通常是K或S开头的链接文件,对于以S开头的启动脚本,将以start参数来运行。而如果发现存在相应的脚本也存在K打头的链接,而且已经处于运行态了(以/var/lock/subsys/下的文件作为标志),则将首先以stop为参数停止这些已经启动了的守护进程,然后再重新运行。这样做是为了保证是当init改变运行级别时,所有相关的守护进程都将重启。

(4)建立终端

rc执行完毕后,返回init。这时基本系统环境已经设置好了,各种守护进程也已经启动了。init接下来会打开终端,以便用户登录系统,如以下2行:

T0:134:respawn:/sbin/getty -L ttyS0
115200 vt100

T1:1:respawn:/sbin/getty -L ttyS1 115200
vt100

从上面可以看出在1、3、4的运行级别中将以respawn方式运行getty程序,它会显示一个文本登录界面,这个界面就是我们经常看到的登录界面,在这个登录界面中会提示用户输入用户名,而用户输入的用户名将作为参数传给login程序来验证用户的身份。

注意:如果想绕过登录验证过程,想直接进入shell界面的话,则把以上两行注释掉,改为:T0:134:respawn:/bin/sh

(5)登录系统,启动完成

getty进程接收到用户名后,启动login进程.

login进程要求用户输入口令.

用户输入口令.

login进程对username和password进行检查.

login启动shell进程.

shell进程根据/etc/password中的shell类型,启动相应的shell.并启动/etc/profile文件和$HOME/.bash_profile文件.最后出现shell提示符,等待用户输入命令.

至此,启动过程结束。

3. login验证过程

Linux的帐号验证程序是login,login会接收getty传来的用户名作为用户名参数。然后login会对用户名进行分析:如果用户名不是root,且存在/etc/nologin文件,login将输出nologin文件的内容,然后退出。这通常用来系统维护时防止非root用户登录。只有/etc/securetty中登记了的终端才允许root用户登录,如果不存在这个文件,则root可以在任何终端上登录。/etc/usertty文件用于对用户作出附加访问限制,如果不存在这个文件,则没有其他限制。

在分析完用户名后,login将搜索/etc/passwd以及/etc/shadow来验证密码以及设置帐户的其它信息,比如:主目录是什么、使用何种shell。如果没有指定主目录,将默认为根目录;如果没有指定shell,将默认为/bin/bash。

login程序成功后,会向对应的终端在输出最近一次登录的信息(在/var/log/lastlog中有记录),并检查用户是否有新邮件(在/usr/spool/mail/的对应用户名目录下)。然后开始设置各种环境变量:对于bash来说,系统首先寻找/etc/profile脚本文件,并执行它;然后如果用户的主目录中存在.bash_profile文件,就执行它,在这些文件中又可能调用了其它配置文件,所有的配置文件执行后,各种环境变量也设好了,这时会出现大家熟悉的命令行提示符,到此整个启动过程就结束了。

以下是passwd,shadow和group脚本的格式说明:

/etc/passwd密码文件的格式如下所示:

用户名:口令:用户标识号:组标识号:注释性描述:主目录:登录Shell

user_name:password:uid:gid:comment:home:shell

每行有很多项组成,项与项之间用":"隔开.每项的说明如下:

user_name 用户名

password 登录密码,初始设置时为空

uid 用户识别号(User ID),是一数值,每个用户的识别号不同

gid 用户组识别号,参见/etc/group文件

comment 注释,可以任意字符,一般用来说明用户的身份特征

home 家目录名

shell 该用户缺省shell,一般取值为:/bin/sh,/bin/ksh,/bin/csh

/etc/shadow文件格式如下

登录名:加密口令:最后一次修改时间:最小时间间隔:最大时间间隔:警告时间:不活动时间:失效时间:标志

username:passwd:last:may:must:warn:expire:disable:reserved

username 使用者名称

passwd 编码密码

last 密码上次更动日期,以从1970年1月1日算起的天数代表

may 密码改变前天数

must 密码最常使用天数

warn 代表期限前几天就事先警告使用者

expire 超过密码过期天数后,就关闭该帐号

disable 帐号关闭,以从1970年1月1日算起的天数代表

reserved 预备栏位

/etc/group文件格式如下:

group_name:password:gid:members_list

每行有四项组成,项与项之间用":"隔开.

group_name 用户组名

password 用户组密码,一般为空

gid 用户组识别号(Group ID),是一数值,每个组的识别号不同

members_list
该组成员列表,由一个或多个用户名组成,用户名之间用逗号隔开

注:一个最简单的文件系统至少需要包含以下几个目录,/sbin,/bin,/dev(需要console和ttyS0两个文件),/proc,/etc(需要inittab,rcS文件),/home.

Linux文件系统启动过程及login的实现的更多相关文章

  1. linux文件系统启动流程、启动脚本

    linux文件系统启动流程.启动脚本 下面是一张Linux启动流程图: 在了解启动流程之前,我们应该先知道系统的几个重要脚本和配置文件,他们对应的路径为: 1. /sbin/init 2. /etc/ ...

  2. linux文件访问过程和权限

    第1章 文件访问过程详解 1.1 文件访问过程 第2章 权限 2.1 对于文件rwx含义 r读取文件内容 w修改文件内容 需要r权限配合 只有w权限的时候,强制保存退出会导致源文件内容丢失 x权限表示 ...

  3. 【转】嵌入式Linux文件系统启动脚本及分析

    原文网址:http://www.linuxidc.com/Linux/2011-03/33728.htm 在内核初始化完成后,嵌入式linux 文件系统的启动过程主要包含以下几个步骤: 1. 执行/s ...

  4. linux 在系统启动过程

    从学习<鸟哥linux私人厨房> 用于在计算机系统启动,计算机硬件和软件由(它包含的操作系统软件)包括.对于操作系统在同一台计算机硬件方面的表现,该系统配备有硬件是公用,不同的系统是 的操 ...

  5. linux下系统启动时,几个配置文件 /etc/profile、~/.bash_profile 等几个文件的执行过程,先后顺序

    1. 在登录Linux时要执行文件的过程如下: 在刚登录Linux时, 首先启动 /etc/profile 文件, 然后再启动用户目录下的 ~/.bash_profile. ~/.bash_login ...

  6. Linux系统启动过程

    1. 从BIOS到KERNEL BIOS自检->MBR(GRUB)->KERNEL->KERNEL自解压->内核初始化->内核启动 BIOS自检 当电脑开机的时候,电脑会 ...

  7. linux系统启动过程的列表

    linux系统启动过程的列表 载入BIOS的硬件信息并进行自检.然后根据设置取得第一个可启动的设备: 读取并运行第一个启动设备内MBR(master boot record,主引导分区)的boot l ...

  8. 一起学Linux02之Linux系统启动过程

    这个Linux系统启动过程啊,说实话,我认为,刚学习的时候看几遍,了解一下就好.现在的主要任务是用.熟练了之后再来深究这个不急. 下面我就简单地说说吧. Linux系统的启动主要分为下列步骤: 1 内 ...

  9. Linux 系统启动过程,Linux 系统目录结构

    一.Linux 系统启动过程 linux启动时我们会看到许多启动信息. Linux系统的启动过程并不是大家想象中的那么复杂,其过程可以分为5个阶段: 内核的引导. 运行 init. 系统初始化. 建立 ...

随机推荐

  1. HTTP/2 最新漏洞,直指 Kubernetes!

    Java技术栈 www.javastack.cn 优秀的Java技术公众号 在这个数据.应用横行的时代,漏洞的出现早已屡见不鲜.在尚未造成大面积危害之前,我们该如何做好防御措施?或许从过往经常发生漏洞 ...

  2. 打印页面内容,<input>不好使,用<textarea> 代替

    <textarea class="sld-textarea" onchange="changeTextareaValue(this)">123< ...

  3. python3—廖雪峰之练习(二)

    函数的参数练习 请定义一个函数quadratic(a, b, c), 接收3个参数,返回一元二次方程 : $ ax^2+b+c=0 $ 的两个解 提示:计算平方根可以调用math.sqrt()函数: ...

  4. rem和css3的相关知识点

    ☆☆☆rem和css3的相关知识点☆☆☆ 一. Web front-end development engineer rem是根据页面的根元素的font-size的一个相对的单位,即 html{ fo ...

  5. Agreeing to the Xcode/iOS license requires admin privileges, please run “sudo xcodebuild -license” a...

    报错: 从错误信息来看,似乎需要通过管理员身份来接受许可协议,于是试着从这个角度google,终于在这里找到了解决方法: 1.打开终端,输入  sudo xcodebuild -license 2.终 ...

  6. wordpress各个文件作用详解

    1.index.php:wordpress核心索引文件,即博客输出文件. 2.license.txt:WordPress GPL许可证文件. 3.my-hacks.php:定义了博客输出之前处理的追加 ...

  7. DEV控件的分页控件,实现勾选复选框

    /// <summary> /// 单元格的点击事件 /// </summary> /// <param name="sender"></ ...

  8. C# 中的DevExpress控件的使用

    使用教程:http://training.evget.com/video/5110 C#  System 程序集https://msdn.microsoft.com/zh-cn/library/mt4 ...

  9. Spring基础17——使用注解来配置Bean

    1.组件扫描 组件扫描(component scanning):Spring能够从classpath下自动扫描,侦测和实例化具有特定的注解的组件. 特定组件包括: —@Component:基本注解,标 ...

  10. flask框架上下文

    上下文 上下文:相当于一个容器,保存了 Flask 程序运行过程中的一些信息. Flask中有两种上下文,请求上下文和应用上下文 请求上下文(request context) 在 flask 中,可以 ...