一、嵌入式Linux系统组成
zynq平台上的Linux系统由四部分组成:BOOT.bin、devicetree.dtb、uImage、uramdisk.image.gz。
(1)BOOT.bin:启动引导程序,包括第一阶段引导程序(FSBL)和第二阶段引导程序(SSBL),zynq平台上一般还需要一个system.bit文件,用于构建PL部分。
(2)uImage:linux系统核心部分,完成虚拟地址到物理地址的映射、驱动设备的初始化、内存管理、进程间通信等工作。
(3)devicetree.dtb:二进制格式的Device Tree描述,Device Tree是一种用来描述硬件的数据结构,包含了有关CPU、物理内存、总线、外部设备等信息。
(4)uramdisk.image.gz:ramfs格式文件系统。根文件系统,可以重复使用,不需要每次都编译。
二、BOOT.bin的制作
zynq平台上的BOOT.bin的制作需要三个文件:U-boot、fsbl、system.bit。
其中U-boot要在Ubuntu系统上编译生成,fsbl和system.bit要借助xilinx开发平台vivado和SDK生成。
三、各部分详解
1、u-boot结构
├── api 存放uboot提供的接口函数
├── arch 与体系结构相关的代码,uboot的重头戏
├── board 根据不同开发板定制的代码,代码也不少
├── common 通用的代码,涵盖各个方面,已命令行处理为主
├── disk 磁盘分区相关代码
├── doc 文档,一堆README开头的文件
├── drivers 驱动,很丰富,每种类型的设备驱动占用一个子目录
├── examples 示例程序
├── fs 文件系统,支持嵌入式开发板常见的文件系统
├── include 头文件,已通用的头文件为主
├── lib 通用库文件
├── nand_spl NAND存储器相关代码
├── net 网络相关代码,小型的协议栈
├── onenand_ipl
├── post 加电自检程序
└── tools 辅助程序,用于编译和检查uboot目标文件
(1)u-boot配置和编译的流程
1)由于不同厂家和不同的开发板,在编译u-boot之前,进行相应的硬件配置
2)在根目录下进行配置
3)引导配置
主要配置内核、设备树和启动地址等信息。
4)编译
2、内核的概述和编译
linux内核的相关资料:http://www.wowotech.net/linux_kenrel/11.html
内核配置资料:http://blog.chinaunix.net/uid-263488-id-2138150.html
1)内核结构
include/ ---- 内核头文件,需要提供给外部模块(例如用户空间代码)使用。
kernel/ ---- Linux内核的核心代码,包含了3.2小节所描述的进程调度子系统,以及和进程调度相关的模块。
mm/ ---- 内存管理子系统(3.3小节)。
fs/ ---- VFS子系统(3.4小节)。
net/ ---- 不包括网络设备驱动的网络子系统(3.5小节)。
ipc/ ---- IPC(进程间通信)子系统。
arch// ---- 体系结构相关的代码,所有与硬件体系结构相关的代码都在这个目录。
arch//mach- ---- 具体的machine/board相关的代码。
arch//include/asm ---- 体系结构相关的头文件。
arch//boot/dts ---- 设备树(Device Tree)文件。
init/ ---- Linux系统启动初始化相关的代码。
block/ ---- 提供块设备的层次。
sound/ ---- 音频相关的驱动及子系统,可以看作“音频子系统”。
drivers/ ---- 设备驱动(在Linux kernel 3.10中,设备驱动占了49.4的代码量)。
lib/ ---- 实现需要在内核中使用的库函数,例如CRC、FIFO、list、MD5等。
crypto/ ----- 加密、解密相关的库函数。
security/ ---- 提供安全特性(SELinux)。
virt/ ---- 提供虚拟机技术(KVM等)的支持。
usr/ ---- 用于生成initramfs的代码。
firmware/ ---- 保存用于驱动第三方设备的固件。
samples/ ---- 一些示例代码。
tools/ ---- 一些常用工具,如性能剖析、自测试等。
Kconfig, Kbuild, Makefile, scripts/ ---- 用于内核编译的配置文件、脚本等。
2)编译流程
下载解压后,在解压后文件下执行两条编译指令,找到在/arch/arm/boot目录下的 zimage文件
3、设备树的原理及实现
(1)基本概念
设备树是一种描述硬件的数据结构,采用设备树后,许多硬件的细节可以直接被硬编码在arch/arm/plat-xxx和arch/arm/mach-xxx中,采用设备树后,许多硬件的细节可以直接通过它传递给Linux,而不在需要大量的冗余代码。整个设备树牵扯比较广,既增加了新的用于描述设备硬件信息的文本格式,又增加了编译这个文本的工具,同时Bootloader也需要支持将编译后设备树传递给Linux内核。
设备树由一系列被命名的节点和属性组成,而节点本身可包含子节点。所谓属性,其实就是成对出现的名称和值。在设备树中,可描述的信息包括(原先这些信息大多被硬件编码在内核中): CPU的数量和类别 内存基地址 总线和桥 外设链接 中段控制器和中断使用情况 GPIO控制器和GPIO使用情况 时钟控制器和时钟使用情况。
基本上就是一颗电路板上CPU, 总线, 设备组成的树,bootloader会将这棵树传递给内核,然后内核可以识别这棵树,并根据它展开出Linux内核中的Platform_device,i2c_client,spi_device等设备,而这些设备用到的内存,IRQ等资源,也被传递给了内核,内核将这些资源绑定个展开的相应的设备。
(2)操作步骤
下载设备树编译器,执行编译设备树指令
4、文件系统原理及实现
文件系统就是解决如何在存储设备上存储数据的一种方法,其中包括存储布局、文件命名、空间管理、安全控制等。
本文转载自:herryone123