嵌入式学习笔记_第1页
嵌入式学习笔记_第2页
嵌入式学习笔记_第3页
嵌入式学习笔记_第4页
嵌入式学习笔记_第5页
已阅读5页,还剩109页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、nand 启动时 bank0 失效,即用不了NOP FLASHnand flash 前4K被强制复制到片内 SRAM 4K内存中,然后CPU会从零地址(SRAM)开始执行。nor 启动时 nor flash 零地址在nor flash cpu从零地址执行。nor flash特征是可以像内存一样读数据,但是不能像内存一样直接写数据, 要通过命令先擦除后才能写数据。 GPIO实验:main 没什么特别的,一样要被别人调用,执行往也要返回。启动文件: 调用 main,调用完之后要返回,所以要设置返回地址。最后要进行一些清理工作。软件初始化: 设置栈 /*设置栈就是把栈指针SP指向某个内存,假如指向S

2、DRAM则要先初始化SDRAM才能设置栈 */设置返回地址 /*bl指令会跳转到main函数,并且把返回地址保存在LR寄存器里面。*/调用main清理工作硬件初始化:关看门狗 /*上电时候看门狗启动,会倒数计时三秒内没有关闭就会重启系统。所以要关掉*/初始化时钟 /*想要跑的更快要初始化时钟*/初始化SDRAM/*/设置返回地址:blmain /*bl指令会跳转到main函数,并且把返回地址保存在LR寄存器里面。*/ /*bl 指令会把返回地址存在lr寄存器里面。*/#defineGPFCON (*(volatile unsigned long *)0x56000050) /* volatil

3、e让编译器不要优化变量*/ #defineGPF4_out(1<<(4*2)#defineGPF5_out(1<<(5*2)#defineGPF6_out(1<<(6*2)#defineGPF7_out(1<<(7*2) GPFCON |= GPF4_out|GPF5_out|GPF6_out;/ 将LED1-3对应的GPF4/5/6三个引脚设为输出按位操作:想要清零 : 按位与 /*例如清bit3 则 a&=(1<<3)*/想要置“1” : 按位或 /*例如置bit3 则 a|= (1<<3)*/SRAM在芯片手

4、册里面称为 steppingstoneCPU通过存储管理器才知道怎么访问外部的设备 例如 SDRAM DM9000网卡等想访问一个芯片,需要哪些条件1:地址线(例如SDRAM 行地址13位,列地址9位) 看芯片手册2:数据线 /* 8/16/32位 数据宽度 例如SDRAM 位宽32位 SDRAM32位,所以 ADDR0,ADDR1就不需要使用。 */ 看原理图3:时钟/频率 (刷新周期 8192/64ms 即刷新8192次需要64ms)看芯片手册4:芯片相关:例如SDRAM(行地址,列地址,Bank) 看芯片手册SDRAM32位,所以 ADDR0,ADDR1就不需要使用。因为2440的地址的

5、单位是byte(8位),所以CPU发出的0,1,2,3这四个地址都是访问到SDRAM地址中的同一个单元。返回都是返回同一个四字节(32位)的数据。假如访问的芯片去16位的,则ADDR0 就不需要使用。想要访问某个芯片(如SDRAM)先要配置存储管理器(位宽,行列地址,刷新周期)。所谓配置也就是设置寄存器。2440可以接8个外设(SDRAM,DM9000网卡,NOR FLASH等等),因为有8个Bank,有8条片选信号(CS信号)。 Bank05都是一样的结构。Bank67比较特别,它们可以接SDRAM。 内存可以分为SRAM,SDRAM,DDR等等。SRAM很快但是比较贵,使用方法简单,直接发

6、地址信号就可以了。SDRAM比较便宜且访问比较复杂,它的地址还分为Bank地址,行地址,列地址。还要不断的刷新SDRAM(REFRESH寄存器就是用来设置刷新周期的),不刷新数据就会丢失。网卡,NOR FLASH它们的接口跟根SRAM的接口是一样的,术语上称为 RAM like。每个Bank可以外接128M的东西,寻址空间是128M。bank7/bank6可以组(128M/128M,64M/64M,32M/32M等)大程序启动过程:1:一上电nand flash前4K被拷贝到SRAM中。2:程序会先关看门狗,初始化存储管理寄存器,SDRAM。3:拷贝到SRAM中的4K代码再把nand flas

7、h中的代码拷贝到SDRAM中去,然后继续执行(在SDRAM中运行)。arm-linux-ld -Ttext 0x3000000 -g led_on.o -o led_on_elf (Ttext 0x3000000 是链接地址)所谓链接地址就是说,运行时程序“应该”位于哪里。所以head.s 就应该从片内SRAM拷到SDRAM中去。当前PC值 = 当前指令的地址 + 8 / pc = 当前指令地址 + 8MMU:权限管理,地址映射。使用MMU时,使用CPU发出的地址是虚拟地址。或者是真实的物理地址。CPU发出的是物理地址还是虚拟地址CPU是不在乎的,CPU没有虚拟地址和物理地址概念。写程序的时候

8、,我们说的地址例如链接地址,也没有虚拟地址,物理地址概念。就是一个单纯的地址。地址只是从CPU角度看到的。虚拟地址(VA)怎么转换为物理地址(PA)。 对于mips架构来说 VA=0xA000,0000 + PA /* VA=fun(PA)*/对于ARM结构来说:表格: 一级页表,二级页表。 对于ARM来说有两种映射:段和页段映射: 表格里面每一个表项对应一段,表示大小是 1M。假如CPU的地址数是4G,则需要的表格数位4G/1M=4*1024=4096个。创建页表:启动前和启动瞬间,地址要连续。A:所以04096的虚拟地址要对应04096的物理地址使用MMU会加快程序的运行速度,因为有DCA

9、CH,ZCACH。这些会加快程序运行速度。1,MMU首先知道你创建的这些页表项都放在哪里;2,MMU通过虚拟地址的高12位可以找到对应的页表项,并且这个页表项的高12位就是物理地址的高12位;3,虚拟地址的低20位就是物理地址的低20位;4,页表项的高12位+虚拟地址的低20位=物理地址。SDRAM程序中mem_cfg_val结构体中的的数字为寄存器BWSCON,BANKCON0,BANKCON1,BANKCON2,BANKCON3,BANKCON4,BANKCON5,BANKCON6,BANKCON7,REFRESH,BANKSIZE,MRSRB6,MRSRB7寄存器赋值。目的是初始化SDR

10、AM。unsigned long *p = (unsigned long *)MEM_CTL_BASE; 此语句是将指针P指向寄存器 0x48000000MMU代码:/*复制第二段代码到SDRAM中*/void copy_2th_to_sdram(void) unsigned int *pdwSrc = (unsigned int *)2048; unsigned int *pdwDest = (unsigned int *)0x30004000;/*地址为0x30004000是因为前16K用来存放页表 */ while (pdwSrc < (unsigned int *)4096) *

11、pdwDest = *pdwSrc; pdwDest+; pdwSrc+; 寄存器: NFCMMD NFADDR NFDATANand flash 没有地址总线跟CPU相连,不同于SDRAM,DM9000网卡,SRAM,寄存器等都有地址总线与CPU相连,所以SDRAM,DM9000网卡,SRAM,寄存器与Nand flash的寻址方式不一样。SDRAM,DM9000网卡,SRAM,寄存器的地址是CPU发出来的,或称为CPU统一编址。 而Nand flash 的地址是Nand flash 自己编址的,CPU “看不到”的。 所以CPU说的“0”地址与Nand flash 说的“0”地址不是一个概

12、念。那Nand flash 是怎么编址的呢?从原理图上,Nand flash 与CPU相连的只有 数据总线,控制总线。所以CPU发出的 地址,命令都是由数据总线进行传输。但是如何分辨是 地址还是命令呢?显然是通过控制总线进行区分。 CLE(高电平) 信号是命令, ALE(高电平) 信号是地址, 两个信号都无效的话 传输的就是数据。 是读数据 还是写数据 又由 nFWE(读) 引脚 nFRE(写)引脚控制。Nand flash 的典型结构是 大页,一个大页有2K 也就是2048字节。有64页。 注意:每一个大页中都有一个叫 OOB的空间(64字节)。一般来说用不到OOB这个空间,例如我们要访问第

13、2049这个字节空间,不会访问到OOB这个空间而是访问第二页开始的第二个字节。所以真实的一页是 2K+64字节。只是64字节基本上不用。那怎么访问 Nand flash ?1:发出命令 CLE NFCMMD 寄存器2:发出地址 ALE NFADDR 寄存器3:发出数据 R/W NFDATA 寄存器4:状态 NFSTAT 寄存器 /发出擦除命令不可能马上就擦除成功,用状态寄存器确定NAND FLASH的状态判断是否擦除成功代码: ldr r0, =0x30000000 1. 目标地址=0x30000000,这是SDRAM的起始地址 mov r1, #4096 2. 源地址 = 4096,连接的时

14、候,main.c中的代码都存在NAND Flash地址4096开始处 mov r2, #2048 3. 复制长度= 2048(bytes),对于本实验的main.c,这是足够了 bl nand_read 汇编和C语言传递参数: 如上例子,r0为传递给C函数(nand_read)的第一个参数,r1为第二个,r2为第三个。 void nand_read(unsigned char *buf, unsigned long start_addr, int size);中断:ARM体系CPU的7种工作模式:用户模式(usr):ARM处理器正常的程序执行状态该模式下的寄存器:r0 r1 r2 r3 r4

15、r5 r6 r7 r8 r9 r10 r11 r12 r13 r14 r15(pc)系统模式(sys):运行具有特权的操作系统任务该模式下的寄存器:r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 r13 r14 r15(pc)快速中断模式(fiq):用于高速数据传输或通道处理该模式下的寄存器:r0 r1 r2 r3 r4 r5 r6 r7 “r8_fiq” “r9_fiq” “r10_fiq” “r11_fiq” “r12_fiq” “r13_fiq” “r14_fiq” r15(pc)中断模式(irq):用于通用的中断处理该模式下的寄存器:r0 r1 r2

16、 r3 r4 r 5 r6 r7 r8 r9 r10 r11 r12 “r13_irq” “r14_irq” r15(pc)管理模式(svc):操作系统使用的保护模式该模式下的寄存器:r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 “r13_svc” “r14_svc” r15(pc)数据访问终止模式(abt):当数据或指令预取终止时进入该模式,可用于虚拟存储及存储保护该模式下的寄存器:r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 “r13_abt” “r14_abt” r15(pc)未定义指令中止模式(und):当未定

17、义的指令执行时进入该模式,可用于支持硬件协处理器的软件仿真该模式下的寄存器:r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 “r13_und” “r14_und” r15(pc)由上可知除了系统模式和用户模式的寄存器相同,其余的5个模式下的寄存器不相同。其中 快中断模式 拥有7个独立寄存器,其余模式都是 r13 r14 两个寄存器独立。中断也是一种异常发生了异常之后:1:CPU 强制进入异常模式,就是切换寄存器(如上) /*这里就是说发生异常之后CPU进入异常模式 2:PC(r15) = 异常入口 然后程序自动跳到异常入口*/设置栈,栈 sp 就是 r13。

18、异常入口是什么: 就是CPU固定的地址。 如下:* 异常向量,本程序中,除Reset和HandleIRQ外,其它异常都没有使用* .extern main.text .global _start _start: _start 表示0地址入口复位异常的入口就是0地址,发生复位之后CPU自动跳到0地址取指执行 b Reset 0x04: 未定义指令中止模式的向量地址HandleUndef: b HandleUndef /*死循环*/ 0x08: 管理模式的向量地址,通过SWI指令进入此模式HandleSWI: b HandleSWI /*死循环*/ 0x0c: 指令预取终止导致的异常的向量地址Ha

19、ndlePrefetchAbort: b HandlePrefetchAbort /*死循环*/ 0x10: 数据访问终止导致的异常的向量地址HandleDataAbort: b HandleDataAbort /*死循环*/ 0x14: 保留HandleNotUsed: b HandleNotUsed /*死循环*/ 0x18: 中断模式的向量地址 b HandleIRQ 0x1c: 快中断模式的向量地址HandleFIQ: b HandleFIQ /*死循环*/Reset: ldr sp, =4096 设置栈指针,以下都是C函数,调用前需要设好栈 bl disable_watch_dog

20、关闭WATCHDOG,否则CPU会不断重启 msr cpsr_c, #0xd2 进入中断模式 ldr sp, =3072 设置中断模式栈指针 msr cpsr_c, #0xd3 进入管理模式 ldr sp, =4096 设置管理模式栈指针, 其实复位之后,CPU就处于管理模式, 前面的“ldr sp, =4096”完成同样的功能,此句可省略 bl init_led 初始化LED的GPIO管脚 bl init_irq 调用中断初始化函数,在init.c中 msr cpsr_c, #0x53 设置I-bit=0,开IRQ中断 ldr lr, =halt_loop 设置返回地址 ldr pc, =m

21、ain 调用main函数halt_loop: b halt_loopHandleIRQ: sub lr, lr, #4 计算返回地址 /*这个是ARM架构决定的,所以就是这个。*/ stmdb sp!, r0-r12,lr 保存使用到的寄存器 注意,此时的sp是中断模式的sp 初始值是上面设置的3072 ldr lr, =int_return 设置调用ISR即EINT_Handle函数后的返回地址 ldr pc, =EINT_Handle 调用中断服务函数,在interrupt.c中int_return: ldmia sp!, r0-r12,pc 中断返回, 表示将spsr的值复制到cpsr怎

22、么用中断? “被中断”1:中断发生。 要做什么事情? “保存”“别人”的状态 先初始化引脚等,然后使能中断2:中断处理 分辨中断源,根据中断源进行不同的处理,然后进行清理工作(清中断)3:恢复“别人”的状态 就是恢复寄存器。中断控制器:1:使能中断 2:状态寄存器(分辨中断源) 3:设置 高电平 低电平 上升沿 下降沿 等触发。4:引脚设置 设置为输入,输出,中断。 5:优先级寄存器 设置栈,栈 sp 就是 r13。 切换到中断模式(或其他异常模式)时,要重新设置栈,因为r13 (sp)是每个模式下独有的。怎么进入中断? msr cpsr_c, #0xd2 进入中断模式,运行这个msr cps

23、r_c 指令就可以进入中 断,而x0d2表示进入哪个中断。具体如下。0xd2 二进制为:110 10010除r0 r15 这16个寄存器外 还有第17个寄存器 cpsr(当前状态寄存器) (详见MSR和MRS文本)控制位:(以0xd2 为例)I中断禁止位 F快速中断禁止位 TCPU状态位 M4工作模式位 M3工作模式位 M2工作模式位 M1工作模式位 M0工作模式位1 1 0 1 0 0 1 0以上就是表示中断模式。M4:010000 User 表示用户模式10001 FIQ 表示快中断模式10010 IRQ 表示中断模式10011 Supervisor 表示管理模式10111 Abort 表

24、示数据访问中止模式11011 Undefined 表示未定义指令中止模式11111 System 表示系统模式系统时钟:2440 CPU : 400M (FCLK) 如果什么都不设置,CPU 是以晶振的频率 12M HZ 在跑。SDRAM,MD900,NOR FLASH等: 100M 133M (HCLK)UART,定时器,I2C等 : 50M (PCLK)2440 的晶振只有12M设置 PLL 寄存器 设置频率怎么设置 FCLK PCLK HCLK1:晶振PLL400M HZ PLL (LOCKTIME)锁定时间寄存器(使用默认值就可以了),MPLLCON 设置晶振频率的寄存器2:400M

25、HZ 分频(HCLK PCLK) 分频寄存器 CLKDIVN 设置 波特率 UBRDIVn(n=01) 有一个公式 看数据手册位置相关:PCnew = 某个绝对值引入一个新的概念:位置无关码 bl和b 指令就是位置无关码。 PCnew = PC(当前) +偏移 /*偏移值是编译器帮我们算好的。*/ PCnew = (4+8) + 0x28 =0x34 /* +8是ARM架构决定的。 */那怎么写位置无关码的代码?1:汇编中使用 bl或 b 指令进行跳转2:C语言中不使用全局变量,静态变量 当PC指针跳到应该位于的位置时 就不用考虑全局变量,静态变量这些限制 以上详情看 视频例子 UART 的代

26、码。关于位置无关的一些心得:当程序被拷贝到4K RAM里面开始执行。如果用位置无关码写程序,程序之间的跳转都是用相对跳转的(PC = 当前地址 + XXX)。而不是用绝对地址(链接地址)也就是说,当程序再4K里面运行的时候,PC的值就是在这4K里面,当用相对跳转的时候,要跳转的地址也就只能出现在4K。但是如果用了位置相关码,那么一跳转就到SDRAM了LCD原理图:有哪些信号:1:垂直方向的同步信号 VSYNC2:水平方向的同步信号 HSYNC3:使能信号 VDEN4:背光信号 LED- LED+ GPB0 输出高电平 背光芯片才会工作 LCD才会点亮。 所以第一步就是要设置 GPB0 为输出高

27、电平5:时钟信号 VCLK6:数据信号 VD0 VD23写程序:1:打开背光2:时序设置3:在Frame Buffer写数据LCD选定之后,像素宽度是固定的。 JZ2440的 LCD的像素宽度就是 16bpp(一个像素用16位数据表示)JZ2440 LCD 上每一个像素对应 Frame Buffer 里的2字节(因为16bpp)。那要使LCD的像素与 Frame Buffer 对应? 设置BSWP HWSWP两个寄存器。详情见手册。因为LCD 的像素宽度是固定的16bpp,但是如果硬是要使用 8bpp。就要涉及 “调色板(Palette)”。8bpp 的数据宽度可以有 256 种颜色。 所以调

28、色板(Palette)中也是256中颜色,但是为了跟LCD的 16bpp 对应。所以调色板(Palette)上 用16位来存一种颜色。要使用调色板,需要将调色板初始化 LCD 控制器: LCDCONn (n=15)清屏: 可以将一种颜色 发给 TPAL寄存器,然后使能 TPAL寄存器。之后 2440 LCD控制器就会从TPAL寄存器取颜色发给LCD(全屏)LCD 代码中 LCDSADDR1 = (LCDFRAMEBUFFER>>22)<<21) | LOWER21BITS(LCDFRAMEBUFFER>>1); LCDSADDR2 = LOWER21BITS

29、(LCDFRAMEBUFFER+ (LINEVAL_TFT_240320+1)*(HOZVAL_TFT_240320+1)*2)>>1); LCDSADDR3 = (0<<11) | (LCD_XSIZE_TFT_240320*2/2);这一段是2440要我们怎么做我们就怎么做 没什么好说的。UBOOT 的最终目的是要 启动内核 1:从flash 读出内核,放到SDRAM 2:启动内核所以UBOOT要实现的核心功能:1:读flash,写flash。2:初始化SDRAM,初始化时钟,关看门狗。3:从flash 读出内核4:启动内核为了开发方便: 开发功能:1:烧写flas

30、h2:初始化网卡(用网络下载文件)3:初始化USB(用USB下载文件)4:初始化串口(在PC机上中断操作UBOOT)UBOOT make 的时候为什么知道要先 make 100ask_24x0.config? 是因为UBOOT文件中有一个 README 文件。里面写有了关于UBOOT的约定。分析UBOOT文件源码时首先要分析 MakeFile 找到链接地址,然后根据链接地址找到第一个源文件,然后根据源文件一路分析贯通。 视频以后多看几遍。UBOOT heads.S 完成步骤1:设为svc 管理模式2:关看门狗3:屏蔽中断4:初始化SDRAM5:设置栈6:初始化时钟7:重定位(将代码从 nand

31、 flash 中拷到 SDRAM )8:清bss段。所谓bss段就是,未定义的一些静态变量,全局变量。以免占用内存。9:调用 start_armboot C函数。UBOOT的核心是命令,读出内核以及启动内核都是需要命令的。所以可以想象到UBOOT的代码中一定有一个命令的结构体,这个结构体中包含了所有的命令,当我们在UBOOT界面上输入命令是会去匹配,匹配到哪个命令就执行哪个命令。内核启动流程分析:1:解压缩2:打补丁 打补丁用 patch 命令 patch -p_ <某个目录下的补丁文件3:配置 配置有三种方式 a:make menuconfig b:使用默认配置在上面修改 c:使用厂家

32、提供的配置文件 如果直接 make menuconfig 的话里面成千上万的配置选项,是很复杂的。所以我们用默认的配置文件。那我们不知道默认的配置文件怎么办呢? 可以再终端输入 fine -name "*defconfig*"查找有哪些默认的配置文件的目录,然后在相应目录下找到自己需要的配置文件。2440开发板 用的配置文件是 s3c2410_defconfig。然后执行 make s3c2410_defconfig。最后执行 make menuconfig执行完 make menuconfig 后就会在s3c2410_defconfig 的基础上出现一个配置菜单,然后就可

33、以自己修改配置项了。由上述的步骤可以知道,当执行 make s3c2410_defconfig 后,终端提示 所有的配置项被写入.config里面。所以make menuconfig 是去.config里面读取需要的配置项。所以使用厂家的配置文件,只需要将厂家的配置文件CP成.config就行了。(cp config_ok .config)结合makefile进行分析以一个配置项为例:CONFIG_DM90001:c源码中定义了 CONFIG_DM9000 是个宏 宏对C语言来说只能在C语言和头文件中定义。所以这个宏来源于autoconfig.h2:子目录下Makefile :drivers/

34、net/makefile3:include/config/autoconfig 中定义了 CONFIG_DM9000 。4:include/linux/autoconfig.h 由名字可以知道autoconfig.h是配置的时候自动根据.config生成的。查看autoconfig.h的时候发现里面的宏大部分都被定义为“1”。也就是说在配置内核的时候无论配置项(DM9000)被设置为“Y” “N” 还是“M”都被定义为“1”。那么 Y N M 之间的差别怎么体现呢?竟然C语言和头文件中不能体现区别,那么只能在子目录中的Makefile中体现。这里插讲一下子目录的Makefile。 格式比较简单

35、 obj-y +=xxx.o 表明xxx.c这个文件最后会编译进内核 obj-m += yyy.o 表示 yyy.c这个文件最后会变编译成一个可加载的模块。所以子目录中的Makefile 写成 obj-$(config_DM9000) +=dm9000.o 分析内核的Makefile 可以找到第一个文件,还有链接脚本。第一个文件 arch/arm/kernel/head.s链接脚本 arch/arm/kernel/vmlinux.lds内核: 最终目的是要运行应用程序1:处理UBOOT传入的参数 a:判断是否支持这个CPU b:判断是否支持这个单板(UBOOT启动内核时传入的机器ID) c:使

36、能MMU d:跳到start_kernel2:挂接根文件系统内核怎样启动第一个应用程序1:打开一个设备open(dev/console) /*这三个程序代表 printf scanf err() */ sys_dup(0) sys_dup(0)2:然后用run_init_process(某个目录下的程序); 例如:run_init_process(“/sbin/init”); 这个函数启动某个程序busybox:ls cp cd等等的组合 我们执行ls cp cd 等命令时,实际上就是执行busybox这个程序 ls cp cd 等都是指向busybox内核的最终目的不是启动第一个文件 sbi

37、n/init 而是要启动用户程序。但是怎么知道要启动什么程序呢? 做手机的启动手机程序 做监控的启动监控程序。 所以需要一个配置文件 指定应用程序还有指定何时执行。 而内核的配置文件一般来说在etc/目录下如果没有配置文件的话,内核会自动执行一个默认的配置项。busybox-> init_main parse_inittab() file = fopen(INITTAB,"r"); /打开配置文件 /etc/inittab 如果没有配置文件的话,内核会自动执行一个默认的配置项 如果有的话就会对配置文件进行解析,例如 #开头的忽略当做注释,为id加个/dev/的前缀。

38、解析完之后最终要调用 new_init_action(a->action,command,id) new_init_action 要做什么事情 1:创建一个init_action结构,这个结构的内容用new_init_action(a->action,command,id)中的参数进行填充。 2:把这结构放入init_action_list链表 run_actions(SYSINIT); /*执行*/ waitfor(a,0); /*执行程应用序,等待它执行完毕*/ run(a); /*创建子进程,子进程就是process里面指定的应用程序*/ waitpid(runpid,&am

39、p;status,0); /* 等待它结束*/ delete_init_action(a); /*把init_action结构在init_action_list链表里删掉,所以用run_actions(SYSINIT); 定义的程序 执行一次就被删掉了。*/ run_actions(WAIT); waitfor(a,0); /*执行程应用序,等待它执行完毕*/ run(a); /*创建子进程,子进程就是process里面指定的应用程序*/ waitpid(runpid,&status,0); /* 等待它结束*/ delete_init_action(a); /*把init_actio

40、n结构在init_action_list链表里删掉,所以用run_actions(SYSINIT); 定义的程序 执行一次就被删掉了。*/ run_actions(ONCE); /*ONCE 跟前面的 SYSINIT,WAIT有点不一样,因为没有 waitpid(runpid,&status,0); 所以init进程不会等待它执行完毕。*/ run(a); delete_init_action(a); while(1) run_actions(RESPAWN); if (a->pid = 0) a->pid = run(a); run_actions(ASKFIRST);

41、if (a->pid = 0) a->pid = run(a); wpid = wait(NULL); /*等待子进程退出*/ while(wpid>0) a->pid = 0; /*退出后,就这是pid=0*/ inittab格式:<id>:<runlevels>:<action>:<process>id-> /dev/id :用作终端,stdin,stdout,stderr: printf scanf err /*<id>: WARNING: This field has a non-traditio

42、nal 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.*/由上可知,一个最小的

43、根文件系统需要的项:1: /dev/console /dev/null2:init->busybox3:/etc/inittab /*配置文件*/4: 配置文件里指定的应用程序5:库 init本身,即busybox 编译busybox在源码中找到“INSTALL”文件,阅读文件知道怎么编译busybox make menuconfig # This creates a file called ".config" make # This creates the "busybox" executable make install # or make C

44、ONFIG_PREFIX=/path/from/root install /*默认是安装到PC机中的文件系统的,为了避免破坏整个系统。 所以我们应该安装到我们指定的目录里面*/ 配置 busybox 的时候 配置上 Tab completion 以后使用的时候比较好用。 Tab completion (Tab 补全) 输入命令的时候按 tab键会自动补全命令 例如:cd /work/ cd/wo此时按tab键 会自动补全为 cd /work/ make menuconfig 后 make 编译busybox 的时候可能会出现错误,出现措错误的话就重新编译,将出现错误的命令配置项去掉。如果实在是

45、想要用这个命令就上网搜。解决办法。make好之后千万不要直接 make install 因为默认安装到 PC机,这样会破坏我们的电脑。先创建一个目录(/work/nfs_root/first_root/tmp),然后 make CONFIG_PREFIX=/work/nfs_root/tmp install根据这五项:1: /dev/console /dev/null2:init->busybox3:/etc/inittab /*配置文件*/4: 配置文件里指定的应用程序5:库 创建最小的根文件系统(在 /work/nfs_root 目录下)第一 创建 /dev/console /dev

46、/null 这两个设备文件。怎么创建呢? 用sudo mknod console 【设备类型】 【主设备号】 【次设备号】先看看PC机上/dev/console /dev/null 这两个文件是怎么回事。 用 ls /dev/console /dev/null -l 命令行查看设备的 主设备号 次设备号 crw-1 root root 5,1 2010-11-26-07:47 /dev/console /*开头的“C”表示该设备是字符设备,“5”是主设备号,“1”是次设备号*/ crw-rw-rw-1 root root 1,3 2010-11-26-07:47 /dev/null /*开头的

47、“C”表示该设备是字符设备,“1”是主设备号,“3”是次设备号*/由上可知 sudo mknod console c 5 1 sudo mknod null c 1 3 第二 要构造一个 inittab第三 安装glibc库mkdir /work/nfs_root/first_root/libcd /work/tools/gcc-3.4.5-glibc-2.3.6/arm-linux/lib 进入含有glibc库的目录下。cp *.so* /work/nfs_root/first_root/lib -d 将glibc库拷贝到 最小根文件系统目录下。注意拷贝的时候要加个“-d”选项,否则库文件会很大。至此我们已经做好了最少根文

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论