linux系统构建学习笔记
嵌入式系统构架:(硬件+软件)
应用软件层:
Application
GNU C
Library(glibc)
文件系统:
系统层:
API(Systern Call Interface)
OS Core + Power Mannager+
File Manager + GUI Mannager
TCP/IP HTTP WAP DataBase
Browser
DDI(Device Drver Interface)
板级支持:BSP:Board Support
Package
OEM Adaptation
Layer
Device Driver
Inerface
Bootloader
硬件层:
CPU,Exiternal devices
嵌入式linux系统组成:
启动加载:bootloader:vivi u-boot
内核:kernel
根文件系统:yaffs
系统应用:web server
图形界面系统:QTE
搭建基于ARM的嵌入式的linux交叉开发环境:
构建嵌入式Linux开发环境=构建交叉编译环境
目标机资源少,开发机(PC)不能编译和运行。
PC机编写调试,下载到目标机运行,实现跨平台开发。
包含:
开发机linux操作系统:redHat,fedora,ubuntu
基本服务:
tftp
文件传输,下载内核或文件
先安装xinuetd服务。
xinetd-2.3.14-18.fc9.i386.rpm
tftp-server-0.48-3.fc9.i386.rpm
tftp-0.48-3.fc9.i386.rpm
nfs :Network File
System网络文件系统(默认已安装)
开发板的根文件系统挂接在PC机的共享目录上。
基本软件:Qemu:在PC机上模拟ARM开发板运行环境
如果没有zlib库,先安装zlib库。
zlib-1.2.7.tar.gz
mini2440-HEAD1.tar.gz
交叉编译工具链(设备提供商定制)
arm-linux-gcc-4.3.2.tgz
交叉编译器
arm-linux-gcc,arm-linux-g++
交叉汇编器: arm-linux-as
交叉链接器:arm-linux-ld
调试器:gdb
库:lib
二进制工具:binutils:arm-linux-readelf,arm-linux-ar,arm-linux-ranlib,arm-linux-objcopy
开发所需各种源代码:
内核源代码:linux-2.6.32.2-mini2440-20100113.tgz
qt工具源代码:x86-qtopia-20100108.tar.gz
arm-qtopia-20100108.tar.gz
文件系统源代码:busybox-1.13.3-mini2440.tgz
测试实例程序源代码:examples-20100108.tar.gz
启动引导程序源代码:vboot-src-20100106.tar.gz
bootloader.tgz
目标文件系统源代码:root_qtopia-20100108.tar.gz
开发所需各种工具:
目标文件系统映象制作工具mkyaffs2image:把root_qtopia目录制作成镜像文件(可烧入目标板中)
mkyaffs2image.tgz
安装logo制作工具LogoMaker:
logomaker.tgz
*****************---BootLoader---*******************
开机后运行的第一个软件代码,初始化硬件,和读入操作系统。基于特定的硬件平台。
Nand Flash存储结构:
BootLoader +Boot
parameters
Kernel
Root filesystem
vivi: 韩国Mizi公司,被三星收购
RedBoot :红帽子公司嵌入式调试程序
U-Boot:Univeral
Bootloader 德国DENX小组开发,支持多种处理器。多种嵌入式操作系统。
两种模式:
启动加载模式:(自举Autonomous)
stage1(汇编):地址:0x00000000
1.基本硬件设备初始化
关闭中断,关闭看门狗,配置PLL,配置内存,初始化各工作模式堆栈,配置中断,拷贝RW段,初始化ZI段
2.为阶段2代码准备RAM空间
3.拷贝stage2代码到RAM空间
4.设置好堆栈
5.跳转到stage2的C程序入口点
stage2(C语言):
1.初始化本阶段使用到的硬件
至少一个串口,网络,USB等,用来和用户I/O输出信息。
2.检测系统内存映射(memory
map)。
3.将kernel和根文件系统映像从flash读到RAM空间。
4.为kernel设置启动该参数
5.调用内核
CPU寄存器:R0为0;R1为机器类型ID;R2为启动参数。(机器类型参见
linux/arch/arm/tools/mach-types目录)
CPU模式:SVC模式,禁止中断IRQs,FIQs
MMU和Cache设置:MMU必须关闭,指令Cache可开可不开,数据Cache必须关闭。
下载模式:(DownLoading)
1.supervivi命令中【a】能将文件下载到nandFlash中,而【d】只下载到内存并执行
2.下载线下载到flash用USB,而串口线来传输命令,与用户进行交互,以用来控制
系统引导方式:
1.是用flash存储设备
2.使用磁盘设备
3.通过网络引导,适合在开发阶段
1.通过tftp下载系统内核
2.内核运行时,通过NFS挂装根文件系统
U-Boot源代码目录结构:
Board:开发板相关文件
Cpu:CPU架构相关代码
Common:实现Uboot支持命令
Disk:对磁盘的支持
Doc:文档目录
Drivers:设备驱动程序
Fs:文件系统的支持
Include:头文件
configs:开发板相关配置头文件
asm:CPU体系结构相关头文件
Net:网络协议栈相关代码,tftp,rarp
Tool:生成Uboot的工具源代码,mkigmage,crc等。
Makefile:1.执行各种board相关配置
2.编译生成uboot.bin文件
生成Uboot.bin步骤:
1.选择要使用的board
make
smdk2410_config
2.编译生成u-boot.bin
make
CROSS_COMPILE=arm-linux-
已经移植好的MINI2440的UBOOT软件包:
tekkamanninja-U-boot-2009.11_tekkaman-16deca6.tar.gz
1.使用:在board下已经做好了一个/tekkamanninja/nini2440/
修改Makefile文件,编译工具为arm-linux-
make mini2440_config
make
2.自己修改.
1.board下建立自己的开发板目录my2440,复制相近的各种板文件,改名字my2440.c
2.在include/configs下通过复制增加自己的my2440.h头文件
3.修改第一阶段代码cpu/arm920t/start.s
4.修改第二阶段代码lib_arm/board.c
5.Makefile修改:1.board下my2440的Makefile中的生成目标文件
2.顶层的Makefile中的综合资源编译方式
6.按照上面的方式生成u-boot.bin文件。
u-boot代码分析:
第一阶段:cpu/arm920t/start.s
从start_code 开始,
_start_armboot跳转到.c文件
设置CPU的模式为SVC模式
关闭看门狗
禁掉所有中断
设置以CPU的频率
把自己拷贝到RAM
配置内存区控制寄存器
配置的栈空间
进入C代码部分
第二阶段:lib_arm/board.c,进入到main_loop()命令行循环,接受用户的输入命令。然后进项相应工作。
main_loop()函数定义在include/common.h中,实现在common目录下的main.c中
输入启动linux命令,u-boot将kernel映像(zImage)从NandFlash上读到RAM中,为内核设置启动参数,启动liunx
编译完成后,在连接前,需要读取链接分配文件cpu/arm920t/uboot.lds
OUTPUT_FORMAT("elf32-littlearm",
"elf32-littlearm",
"elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
.
= 0x00000000;
. = ALIGN(4);
.text
:
{
cpu/arm920t/start.o (.text)
board/tekkamanninja/mini2440/lowlevel_init.o (.text)
board/tekkamanninja/mini2440/nand_read.o (.text)
*(.text)
}
. = ALIGN(4);
.rodata : {
*(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
. = ALIGN(4);
.data : { *(.data) }
. = ALIGN(4);
.got : { *(.got) }
. = .;
__u_boot_cmd_start = .;
.u_boot_cmd : {
*(.u_boot_cmd) }
__u_boot_cmd_end = .;
. = ALIGN(4);
__bss_start = .;
.bss (NOLOAD) : {
*(.bss) . = ALIGN(4); }
_end = .;
}
*****************---Linux内核---*******************
Linux组成结构:
用户空间
User
Applications
GNU C Library(glibc)
系统空间
Systerm Call
Interface
Kernel
Architectur-Dependent Kernel Code
在x86中,用户运行于cpu的Ring3,系统空间运行在Ring0(特权指令);
在ARM中,用户运行于cpu的usr用户模式(有限制),系统空间运行在sys系统模式(特权指令);
用户程序通过系统调用和硬件中断转到内核空间。
内核组成:
System Call Interface(SCI)
为用户空间提供标准系统调用函数。
Memory Management(MM) 内存管理
控制多个进程安全共享内存
Process Management(PM)
进程管理
1.创建进程
2.停止进程
3.控制:进程调度,共享CPU
4.通信
Virtual File System(VFS) 虚拟文件系统
Ext2,FAT,NFS
Network Stack 网络协议栈
网络协议
Arch
Device Drivers(DD)
源代码分析(树形结构):
arch
存放平台相关的代码
arm/boot:内核引导代码(compressed/head.S,内核解压缩)
arm/kernel,lib,mm:内核实现(信号,时钟),硬件相关工具函数,内存管理
arm/mach-s3c2410:
arm/tools:在mach-types中保存了linux支持的所有开发板机器编号
arm/configs:可参考的内核配置文件
block
部分块设备驱动程序
crypto
加密,压缩,CRC校验算法
documentation
内核的文档
drivers
设备驱动程序,占整个内核代码一大半。
fs
ext2
fat
每个子目录对应一种文件系统实现
include
内核所需要的头文件
与平台相关的头文件放在相应的子目录中
include/asm-arm/s3c2410
与平台无关的头文件在linux子目录下。
init
内核初始化代码(非引导代码),相当于main函数
main.c
version.c
ipc
进程间通信的实现代码
kernel
Linux主核心大妈,包括进程管理和irq
与平台相关的代码在arch/arm/kernel下
lib
库文件代码
mm
与平台无关的内存管理部分
与平台相关的代码在arch/arm/mml下
net
网络协议的实现代码
ipv4
samples
一些内核编程的范例
scripts
配置内核的脚本
security
SElinux的模块
sound
音频设备驱动程序
usr
cpio命令实现
virt
内核虚拟机
内核配置步骤:
配置
Kconfig:arch/arm/Kconfig
1.控制make menuconfig时出现配置选项
2.根据用户的选择生成.config配置文件
.config:编译的时候,Makefile将用它来决定哪些要,哪些是模板,哪些不要。
1.make menuconfig 手动选择来配置(生成).config
2.make
mini2440_defconfig 按开发板的默认配置.config
1.*清理:make distclean
2.配置:make menuconfig
编译:
顶层Makefile
1.决定根目录下哪些文件和目录编进内核
2.设置文件编译链接选项
3.根据链接脚本arch/arm/kernel/**.lds组织文件生成映像文件
子目录Makefile(Kbuild)
1.决定当前子目录下哪些文件和目录编进内核
2.设置当前目录下所有文件编译链接选项
3.编译:make zImage
make
uImage
make
modules
vmlinux(未压缩)->zImage(压缩)->bzImage(解压缩至高端内存,内核较大用)
->uImage(U-boot用)
定制自己的linux系统:
在arch/arm/tools/mach_types有对mini2440的支持1999,内核启动时传入MACH_TYPE确定启动哪种平台。
由于mini2440和smdk2440电路一样,所以可以用smdk2440.c来复制一个自己的mini2440.c
一、搭建环境
二、定义系统硬件资源驱动部分
1.NandFlash
2.移植yaffs2文件系统
*****************---文件系统---*******************
文件管理系统:操作系统中负责管理和存储文件信息的软件机构。
组成:管理软件+文件+数据结构
常用文件系统
日志文件系统:数据完整,但系统资源消耗多,适用于硬盘
Ext3
Ramdisk文件系统
RomFS文件系统
CRAMFS
JFFS2 文件系统
YAFFS2(Yet Another Flash filesystem)
为Nandflash设计的日志文件系统
启动过程:
1.内核最后启动init进程。位于init/main.c中的(init_post()函数)
打开/dev/console设备文件
ramdisk_exiecut_command变量指定了要寻星的程序:
依次寻找:/sbin/init,
/etc/int, /bin/init
,bin/sh中的程序, 启动找到的第一个程序
执行/sbin/init时的环境参数为“HOME=/”,"TERM=linux"
init启动系统:位于busybox/init/init.c
初始化控制台:若内核init启动搞了console则使用指定设备,若没有打开则用/dev/null
解析inittab
执行inittab命令,每个条目用来定义一个子进程的启动方式。
启动后,运行的第一程序是根目录下的linuxrc,指向/bin/busybox连接
busybox试图解析/etc/inittab进一步获取初始化信息
在init/init.c中的parse_inittab()函数中的new_init_action(SYSINIT,INIT_SCRIPT,""),所以接下来执行
INIT_SCRIPT定义的值,为/etc/init.d/rcS
文件系统的构建所需文件:
busyBox:集成压缩了许多linux工具和命令。
root_qtopia:提供了文件系统所需的库文件。
Mkyaffs2image:yaffs文件系统制作工具(在yaffs2中也有)。
文件系统的构建步骤:
1.创建自己定制的文件系统的目录结构
2.完成库文件的定制
3.编译配置busuybox
4.文件系统中配置文件的制作
5.制作文件系统映像
qt移植
qtcreator在windows下编写了qt应用程序 - 交叉编译 - 下载到开发板上运行
qt应用程序的跨平台性特点 --
一次编程到处编译
对于在windows下开发的qt应用程序,在移植到开发板之前必须在linux下使用交叉编译工具进行编译
实现过程
开发板上构建交叉编译环境
在windows下或者linux下开发应用程序
使用交叉编译器进行编译
下载
运行
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。