目录
Shell    2
脚本Script    2
目标程序    3
交叉编译    5
进程 线程 和任务    7
工具链    7
文件系统    8
什么是ioctl    8
根文件系统    10
分散加载    12
文件系统    13
Busybox    13
驱动程序和内核的关系    14
文件描述符    14
struct file    17
struct inode    19
Shell
文字操作系统与外部最主要的接口就叫做shell。
shell是操作系统最外面的一层。
shell管理你与操作系统之间的交互:等待你输入,向操作系统解释你的输入,并且处理各种各样的操作系统的输出结果。
GNU/Linux
由于GNU/Linux这个词太长,下面如果没有特别指明,“Linux”就是指“GNU/Linux”。
Bash
Bash(Bourne Again Shell)是目前大多数 Linux(Red Hat,Slackware等)系统默认使用
的Shell,它由Brian Fox和Chet Ramey共同完成,内部命令一共有 40 个,它是 Bourne Shell
的扩展,与Bourne Shell完全向后兼容,并且在 Bourne Shell的基础上增加了很多特性。Bash
是GNU计划的一部分,用来替代Bourne Shell。
Linux 下使用 Shell 非常简单,打开终端就可以到Shell的提示符了,登录系统之后,系统将执行个称为 Shell的程序, 正是Shell进程提供了命令提示符。作为 Linux 默认的 Bash,对于普通用户“$”作为Shell提示符,而对于根用户(root)用“#”作提示符。如图3.2。     
脚本Script
动态程序一般有两种实现方式,一是二进制方式,一是脚本方式。
二进制方式是先将我们编写的程序进行编译,变成机器可识别的指令代码(如.exe文件),然后再执行。这种编译好的程序我们只能执行、使用,却看不到他的程序内容。
脚本简单地说就是一条条的文字命令,这些文字命令是我们可以看到的(如可以用记事本打开查看、编辑),脚本程序在执行时,是由系统的一个解释器,将其一条条的翻译成机器可识别的指令,并按程序顺序执行。因为脚本在执行时多了一道翻译的过程,所以它比二进制程序执行效率要稍低一些。
简单地说,脚本就是指通过记事本程序或其它文本编辑器(如Windows Script Editor,EditPlus等)创建,并保存为特定扩展名(如.reg , .vbs, .js, .inf等)的文件,对于注册表脚本文件就是利用特定的格式编辑的.reg文件;对于VBScript脚本编程语言来说,脚本文件扩展名就是.vbs;对于JScript脚本编程语言来说,脚本文件扩展名就是.js;另外,.wsf格式是Microsoft定义的一种脚本文件格式,即Window Script File.
脚本同我们平时使用的VB、C语言的区别主要是:
1、脚本语法比较简单,比较容易掌握;
2、脚本与应用程序密切相关,所以包括相对应用程序自身的功能;
3、脚本一般不具备通用性,所能处理的问题范围有限。
目标程序
我们开始都是字符文件,就是源文件。第一步先把源文件翻译成一种中间代码,这就是目标文件,然后再把目标文件翻译为机器代码,这就是可置执行的EXE文件了。所以说,目标就是一个中间程序。
Makefile
这里先介绍makefile最基本的知识。
假设现有三个 c 程序 main.c, mytool1.c, mytool2.c,其中主程序在 main.c中。
gcc -c main.c 
gcc -c mytool1.c 
gcc -c mytool2.c 
gcc -o main main.o mytool1.o mytool2.o 
这样的话我们可以产生main程序,而且也不是很麻烦.但是我们考虑一下,如果有一天我们修改了其中的一个文件(比如说mytool1.c),那么我们难道还要重新输入上面的命令吗?也许你会说,这个很容易解决啊,我写一个SHELL脚本,让它帮我去完成不就可以了.是的对于这个程序来说,是可以起到作用的.但是当我们把事情想的更复杂一点,如果我们的程序有几百个源程序的时候,难道也要编译器重新一个一个的去编译吗? 
为此,聪明的程序员们想出了一个很好的工具来做这件事情,这就是make.
什么是make
    linux系统中,提供了一个自动生成和维护目标程序的工具---make。make是一个单独工作
的程序,根据程序模块的修改情况重新编译链接目标代码,以保证目标代码总是由最新的模块组成。
    源程序编译链接的顺序和范围取决于模块之间的关联关系。make 从指定文件中读取说明模块之间关系的信息,然后根据这些信息维护和更新目标文件。具体地说,make 首先判断哪些文件过时了。所谓过时,就是一个文件生成以后,用来生成该文件的源文件或者所依赖的模块被修改了,而他自己没有修改。其判断依据是文件生成时间。到过时的文件,就根据指定文件中的有关信息进行更新操作。
    make 默认从GNUmakefile makefile 或者 Makefile 读取信息。可以用 -f 指定文件。
    我们只要执行以下make,就可以把上面的问题解决掉.在我们执行make之前,我们要先编写一个非常重要的文件.--Makefile(或 makefile).对于上面的那个程序来说,可能的一个Makefile的文件是: 
#这是上面那个程序的Makefile文件
main:main.o mytool1.o mytool2.o
      gcc -o main main.o mytool1.o mytool2.o
main.o:main.c mytool1.h mytool2.h
      gcc -c main.c
mytool1.o:mytool1.c mytool1.h
      gcc -c mytool1.c
mytool2.o:mytool2.c mytool2.h
      gcc -c mytool2.c
有了这个Makefile文件,不过我们什么时候修改了源程序当中的什么文件,我们只要执行make命令,我们的编译器都只会去编译和我们修改的文件有关的文件,其它的文件它连理都不想去理的. 
如何编写 makefile文件
在Makefile中以#开始的行都是注释行.Makefile中最重要的是描述文件的依赖关系的说明. 一般的格式是: 
target: components
TABrule(TAB表示tab键)
第一行表示的是依赖关系.第二行是规则(命令行).  每一个命令行的开头都必须是一个tab键。
比如说我们上面的那个Makefile文件的第二行  main:main.o mytool1.o mytool2.o 
表示我们的目标(target)main的依赖对象(components)是main.o mytool1.o mytool2.o 当倚赖的对象在目标修改后修改的话,就要去执行规则一行所指定的命令.就象我们的上面那个Makefile第三行所说的一样要执行 gcc -o main main.o mytool1.o mytool2.o 
Makefile有几个非常有用的变量:分别是 $@、$*、$^、$< 。代表的意义分别是: 
$@ -- 目标文件
$* -- 目标文件去掉后缀的部分
$^ -- 所有的依赖文件
$< -- 比目标文件更新的依赖文件 
如果我们使用上面几个变量,那么我们可以简化我们的Makefile文件为: 
# 这是简化后的Makefile
main:main.o mytool1.o mytool2.o
      gcc -o $@ $^
main.o:main.c mytool1.h mytool2.h
      gcc -c $*.c
mytool1.o:mytool1.c mytool1.h
c语言基本名词概念      gcc -c $*.c
mytool2.o:mytool2.c mytool2.h
      gcc -c $*.c
交叉编译
在一种计算机环境中运行的编译程序,能编译出在另外一种环境下运行的代码,我们就称这种编译器支持交叉编译。这个编译过程就叫交叉编译。简单地说,就是在一个平台上生成另一个平台上的可执行代码。这里需要注意的是所谓平台,实际上包含两个概念:体系结构(Architecture)、操作系统(Operating System)。同一个体系结构可以运行不同的操作系统;同样,同一个操作系统也可以在不同的体系结构上运行。举例来说,我们常说的x86 Linux平台实际上是Intel x86体系结构和Linux for x86操作系统的统称;而x86 WinNT平台实际上是Intel x86体系结构和Windows NT for x86操作系统的简称。
交叉编译这个概念的出现和流行是和嵌入式系统的广泛发展同步的。我们常用的计算机软件,都需要通过编译的方式,把使用高级计算机语言编写的代码(比如C代码)编译(compile)成计算机可以识别和执行的二进制代码。比如,我们在Windows平台上,可使用Visual C++开发环境,编写程序并编译成可执行程序。这种方式下,我们使用PC平台上的Windows工具开发针对Windows本身的可执行程序,这种编译过程称为native compilation,
中文可理解为本机编译。然而,在进行嵌入式系统的开发时,运行程序的目标平台通常具有有限的存储空间和运算能力,比如常见的 ARM 平台,其一般的静态存储空间大概是16到32MB,而CPU的主频大概在100MHz到500MHz之间。这种情况下,在ARM平台上进行本机编译就不太可能了,这是因为一般的编译工具链(compilation tool chain)需要很大的存储空间,并需要很强的CPU运算能力。为了解决这个问题,交叉编译工具就应运而生了。通过交叉编译工具,我们就可以在CPU能力很强、存储控件足够的主机平台上(比如PC上)编译出针对其他平台的可执行程序。