linux系统移植

安装系统:在基于ARM处理器的开发板上安装Linux系统

1.基础

1.1 嵌入式系统分层

1.2 移植的目的

        不同架构的处理器指令集不兼容,即便是相同的处理器架构,板卡不同驱动代码也不兼容

        Linux是一个通用的内核并不是为某一个特定的处理器架构或板卡设计的,所以从官方获取Linux源码后我们要先经过相应的配置使其与我们当前的硬件平台相匹配后才能进行编译和安装

1.3 移植的过程

2.开发板启动过程

2.1 开发板启动流程

  • 开发板上电后首先运行SOC内部iROM中固化的代码(BL0),这段代码先对基本的软硬件环境(时钟等...)进行初始化,然后再检测拨码开关位置获取启动方式,然后再将对应存储器中的uboot搬移到内存,然后跳转到uboot运行。
  • uboot开始运行后首先对开发板上的软硬件环境做进一步初始化,然后将linux内核、设备树(dtb)、根文件系统(rootfs)从外部存储器(或网络)搬移到内存,然后跳转到linux运行。
  • linux开始运行后先对系统环境做初始化,当系统启动完成后,Linux再从内存中(或网络)挂载根文件系统。

2.2 系统移植步骤

  • uboot移植
  • linux内核移植(包含设备树)
  • 根文件系统移植

3.交叉开发环境搭建

网络环境、tftp、nfs

3.1 ubuntu网络环境配置

3.2 tftp服务器环境

3.3 nfs服务器环境

4.uboot概述及SD卡制作

4.1Bootloader

4.2常见Bootloader

Bootloader

Monitor

描述

X86

ARM

PowerPC

LILO

Linux磁盘引导程序

GRUB

GNULILO替代程序

Loading

DOS引导linux

ROLO

ROM引导linux而不需要BOIS

Etherboot

通过以太网卡启动linux系统的固件

LinuxBOIS

完全替代BUISlinux引导程序

BLOB

LART等硬件平台的引导程序

U-boot

通用引导程序

RedBoot

基于eCos的引导程序

Vivi

Mizi公司针对于三星的arm cpu设计的引导程序

4.3SD卡启动盘制作

5.uboot应用

5.1启动命令

5.1 uboot模式
    自启动模式:
        uboot启动后若没有用户介入,倒计时结束后会自动执行。自启动环境变量(bootcmd)中设置的命令(一般作加载和启动内核)
    交互模式:
        倒计时结束之前按下任意按键uboot会进入交互模式,交互模式下用户可输入uboot命令 

5.2 uboot帮助命令
    help        查看uboot支持的所有命令
    help 命令   查看当前命令的使用方法 

5.3 uboot环境变量命令
    printenv    打印uboot中所有的环境变量
    setenv      设置指定的环境变量(保存在RAM中)
    setenv      环境变量 环境变量的值 
    saveenv     保存所有环境变量到EMMC中

5.4 uboot常用环境变量
    ipaddr        uboot的IP地址
    serverip      服务器的IP地址(即ubuntu的IP) 
    bootdelay     进入自启动模式之前倒计时的秒数

5.5 uboot网络传输命令
    loadb    通过Kermit协议下载文件到指定的内存地址
    loadb    地址
    tftp     通过tftp协议下载文件到指定的内存地址
        tftp  地址  文件名        
        注:使用tftp之前要配置好网络及tftp服务器

5.6 uboot存储器访问命令
    mmc read
        将EMMC中指定扇区中的内容读取到内存中指定的地址
        mmc read  <addr> <blk#> <cnt>
            addr:  内存地址
            blk#:  EMMC中的扇区编号
            cnt:  读取的扇区的个数
    mmc write
        将内存中指定地址中的内容写入到EMMC中指定的扇区
        mmc write <addr> <blk#> <cnt> 

5.7 uboot自启动环境变量
    bootcmd
        自启动的环境变量
        该环境变量可以设置成一到多个uboot命令的集合(若有多个使用\;分割)
        自启动模式下uboot就会按照bootcmd中命令的顺序逐条执行
	eg:
	    setenv bootcmd tftp 40008000 interface.bin\;go 40008000
	    saveenv

5.8 uboot内核启动命令
bootm
    启动指定内存地址上的Linux内核并为内核传递参数
	bootm kernel-addr ramdisk-addr dtb-addr
	注:
	    kernel-addr:	内核的下载地址  
	    ramdisk-addr:	根文件系统的下载地址  	
	    dtb-addr:		设备树的下载地址
	    若不使用相应的地址,对应的位置写“-”
	eg: 
	    bootm 0x41000000 - 0x42000000	

5.9 uboot自启动参数环境变量
bootargs
    eg:
    setenv bootargs root=/dev/nfs nfsroot=xxx.xxx.xxx.xxx:/opt/4412/rootfs     
    rw console=ttySAC2,115200 init=/linuxrc ip=***.***.***.***
    注:
	    root		根文件系统类型(nfs)
	    nfsroot		网络文件系统路径(xxx.xxx.xxx.xxx:/opt/4412/rootfs)
	    rw      	操作网络文件系统的权限(rw)
	    console		控制台(使用串口2,波特率115200)
	    init        init进程的位置(/linuxrc)
	    ip          linux启动后自身的IP(***.***.***.***)

6.linux内核安装及交叉编译

6.1 tftp加载kernel、rootfs

6.2 emmc加载kernel、rootfs

6.3 tftp加载kernel、xxx.dtb,nfs挂载rootfs

6.4 emmc加载uboot

文件:
uboot         : uboot.bin
kernel        : uImage
device tree   : xxx.dtb
rootfs        : rootfs.img

重启tftp、nfs服务器
sudo service tftpd-hpa restart
sudo service nfs-kernel-server restart


6.1 tftp加载kernel、xxx.dtb、rootfs
    kernel、rootfs放到tftp工作目录
uboot加护模式下设置uboot启动参数:
    setenv ipaddr 192.168.10.200
    setenv serverip 192.168.10.100
    setenv bootcmd tftp 0x41000000 uImage\;tftp 0x42000000 xxx.dtb\;tftp 0x43000000 rootfs.img\;bootm 0x41000000 0x43000000 0x42000000
    setenv bootargs root=/dev/nfs nfsroot=192.168.10.100:/home/linux/fs4412/tftpboot                rw console=ttySAC2,115200 init=/linuxrc ip=192.168.10.200
    saveenv


6.2 emmc加载kernel、xxx.dtb、rootfs.img
    下载内核镜像到内存中:
        tftp 0x41000000 uImage
    将内核镜像写入emmc指定扇区
        mmc write 0 0x41000000 0x800 0x2000
    下载设备树到内存中:
        tftp 0x41000000 xxx.dtb
    将内核镜像写入emmc指定扇区
        mmc write 0 0x41000000 0x2800 0x800
    下载根文件系统镜像到内存中:
        tftp 0x41000000 rootfs.img
    将内核镜像写入emmc指定扇区
        mmc write 0 0x41000000 0x3000 0x2000
修改uboot启动参数:
    setenv bootcmd mmc read 0 0x41000000 0x800 0x2000\;mmc read 0 0x42000000 0x2800 0x800\;mmc read 0 0x43000000 0x3000 0x2000\;bootm 0x41000000 0x43000000 0x42000000
    saveenv

saveenv失败时可以尝试这个格式:
    setenv bootcmd 'mmc read 0 0x41000000 0x800 0x2000\;mmc read 0 0x42000000 0x2800 0x800\;mmc read 0 0x43000000 0x3000 0x2000\;bootm 0x41000000 0x43000000 0x42000000'



6.3 tftp加载内核、设备树,nfs挂载rootfs
开发阶段:根文件系统中经常添加驱动、应用程序,反复将内核、设备树、根文件系统安装到emmc中比较繁琐,一般采用tftp加载内核、设备树,nfs挂载rootfs。产品定型以后再安装到emmc中

文件存储位置:
    uboot烧录到SD卡中,uImage、xxx.dtb放到tftp工作目录,rootfs放到nfs工作目录
uboot启动参数:
    setenv bootcmd tftp 0x41000000 uImage\;tftp 0x42000000 xxx.dtb\;bootm 0x41000000-0x42000000
    bootargs=root=/dev/nfs nfsroot=192.168.10.100:/home/linux/fs4412/source/rootfs rw console=ttySAC2,115200 init=/linuxrc ip=192.168.10.200
    saveenv保存


6.4 uboot安装到emmc
uboot交互模式下,下载并安装uboot
下载:
    tftp 0x41000000 uboot.bin
安装:
    (将内核镜像安装到emmc指定扇区,往emmc的引导分区里面刷写)
    emmc open 0
    mmc write 0 0x41000000 0x0 0x800
    emmc close 0
调整拨码开关位emmc启动
重新配置uboot环境变量

7.交叉编译工具链

可执行文件格式、交叉编译工具链安装

bsp板级开发支持包中获取交叉编译工具链

7.1 交叉编译

7.2 编译原理

  • 机器码(二进制)是处理器能直接识别的语言,不同的机器码代表不同的运算指令,处理器能够识别哪些机器码是由处理器的硬件设计所决定的,不同的处理器机器码不同,所以机器码不可移植
  • 汇编语言是机器码的符号化,即汇编就是用一个符号来代替一条机器码,所以不同的处理器汇编也不一样,即汇编语言也不可移植
  • C语言在编译时我们可以使用不同的编译器将C源码编译成不同架构处理器的汇编,所以C语言可以移植

7.3 编译过程

7.4 ELF、BIN文件格式

ELF文件格式:
    ELF格式是Linux平台上应用最广泛的二进制工业标准之一
    ELF格式的文件内包含了很多个段不同的段存储了不同的信息;因为ELF格式的文件要通过Linux系统的加载和管理才能运行,所以除了最基本的代码段和数据段之外,其中还存储了很多其它的信息,如符号表、调试信息等

ELF文件相关命令:
    file
        file + 文件名		查看文件的详细信息   
    readelf
        readelf -h + 文件名 	列出elf文件的头部信息
        readelf -a + 文件名 	列出elf文件的所有信息

BIN文件格式:
    BIN文件一般是直接运行在CPU之上的可执行文件,文件内只包含了CPU能够直接识别和运行的指令和数据,不包含其它系统相关的信息

7.5 交叉编译工具链常用工具

size
    列出目标文件每一段的大小以及总体的大小
    size + 文件名		
nm
    列出目标文件中的符号表(标示符)
    nm + 文件名		
strip
    丢弃目标文件中的符号
    strip + 文件名		
objdump			
    从目标文件中显示信息	
    eg:		
    objdump -d + 文件名	将目标文件反汇编(机器码->汇编)

objcopy			
    对目标文件进行复制和转换
    eg:
    	objcopy --gap-fill=0xff -o binary a.out a.bin		
	    将目标文件转换为bin格式

注:对于嵌入式开发,这个命令很重要

        代码段、初始化变量、未初始化变量、总大小、十六进制大小

7.6 安装交叉编译工具链

1、打开家目录文件下的配置文件.bashrc,
2、在最后一行添加如下内容,将交叉编译工具链的安装路径添加到了全局环境变量中
3、重启配置文件使配置生效
4、检查是否安装成功

vi ~/.bashrc
export PATH=$PATH:~/fs4412/toolchain/gcc-4.6.4/bin/
source ~/.bashrc
arm-none-linux-gnueabi-gcc -v

8.uboot原码配置编译

8.1 uboot原码结构

uboot特点:
     代码结构清晰
     支持丰富的处理器与开发板,易于移植
     支持丰富的用户命令
     支持丰富的网络协议
     支持丰富的文件系统
     支持丰富的设备驱动
     更新活跃、用户较多、资料丰富
     开放源代码
     较高的稳定性
     不具有通用性(不同的处理器、开发板uboot不可通用)

uboot源码结构:
    平台相关代码:
        即与CPU架构或开发板硬件相关的源码,硬件的改动对应的代码也需要进行修改
        arch:与CPU架构相关的源代码
        board:与开发板相关的源代码,包含各种官方评估板对应的源码

    平台无关代码
        api:	应用接口
        common:	uboot命令源码
        disk:	对磁盘设备的支持
        drivers:	设备驱动源码
        fs:		对文件系统的支持	
        include:	头文件
        lib:	库
        net:	对网络协议的支持
        post:	上电自检程序
        ... ...

    配置文件、帮助文档、示例程序、工具等:
        README:	说明文档
        doc:	帮助文档
        Makefile:	编译管理
        CREDITS:	开发者
        COPYING:	版权
        examples:	示例程序
        tools:	工具
        ... ...

8.2 uboot的配置与编译

uboot配置:
1.指定当前使用的硬件平台
	make <board_name>_config 
	注1:<board_name>为当前使用的开发板的名字
	注2:执行该命令的前提是uboot源码支持该开发板
	注3:该命令必须在uboot源码的顶层目录下执行
	
2.指定编译uboot源码使用的编译器
	在uboot源码顶层目录下的Makefile中指定(CROSS_COMPILE变量)

uboot编译:
1.编译uboot
	make 
	注1:该命令必须在uboot源码的顶层目录下执行
	注2:该命令执行后在uboot源码顶层目录下生成u-boot.bin
	
2.清除编译过程中生成的中间文件
	make clean删除生成的所有.o文件
	make distclean删除编译生成的所有文件,包含最终可执行文件u-boot
	注1:该命令必须在uboot源码的顶层目录下执行

9.linux内核移植

9.1 linux内核特点、源码结构

linux内核特点:
     代码结构清晰、模块化设计
     支持丰富的硬件平台
     较高的稳定性
     轻量化及较强的裁剪性
     开放源代码
     更新活跃、用户较多、资料丰富
     支持丰富的网络协议
     ... ...

linux内核源码结构:
    平台相关代码
        arch:	与CPU架构相关的源代码
   
    平台无关代码
        block:磁盘设备的支持			crypto:加密相关
        drivers:设备驱动				firmware:固件
        fs:文件系统				include:头文件
        init:内核初始化				ipc:进程间通信
        kernel:内核核心调度机制等		lib:库
        mm:内存管理				net:网络协议
        scripts:工具、脚本等			security:安全
        usr:打包与压缩				virt:虚拟
  
    帮助文档、示例程序、工具等
        COPYING:		版权
        CREDITS:		内核贡献者
        README:		说明文档
        Documentation:	帮助文档
        Makefile:		编译管理
        samples:		示例
        tools:		工具
        ... ...

9.2 linux内核源码配置

linux内核源码配置:
指定处理器架构及编译工具:
    在Linux内核源码顶层目录下的Makefile中指定(ARCH、CROSS_COMPILE)
导入当前处理器的默认配置:
    make <soc_name>_defconfig
    注1:soc_name为当前使用的处理器的名字
    注2:内核源码的arch/arm/configs下对各个厂商的soc都有一个默认配置文件
    执行该命令后就会将对应的配置文件中的信息导入到源码顶层目录下的.config
    文件中CONFIG_xxx=y表示内核选中了该功能,内核编译时就会将该功能对应的
    代码编译,内核的体积也会增大。#CONFIG_xxx is not set表示内核没有选中
    该功能,内核编译时该功能对应的代码不会被编译,内核的体积也会减小。


修改配置:
    默认配置只能保证内核拥有最基本的功能,我们需要根据自己的实际需求对内核做进一步的配置
    方法1:
        直接修改.config文件(不推荐)
    方法2:
        make menuconfig

make menuconfig:
    [ ] 有两种状态
    	输入Y,显示“*”,内核中该功能被选中,相关代码会被编译进内核
	    输入N,显示“ ”,内核中该功能不被选中,相关代码不会被编译进内核
    < > 有三种状态
    	输入Y,显示“*”,内核中该功能被选中,相关代码会被编译进内核
	    输入N,显示“ ”,内核中该功能不被选中,相关代码不会被编译进内核
        输入M,显示“M”,内核中该功能被选为模块(被编译为独立的模块)

    注:使用make menuconfig配置的本质还是修改.config文件

9.3 内核源码编译

内核编译:
    (以下命令均在内核源码的顶层目录下执行)
    make uImage	
        编译内核(编译选为“*”的选项到内核)
    make modules   	
        编译内核模块(编译选为“M”的选项为独立模块)
    make dtbs      	
        编译设备树(将设备树源文件dts编译为二进制文件dtb)
    make clean     
        删除编译过程中产生的中间文件

9.4 设备树

        设备树是一种描述硬件信息的数据结构,Linux内核运行时可以通过设备树将硬件信息直接传递给Linux内核,而不再需要在Linux内核中包含大量的冗余编码

设备树文件
    dts  设备树源文件
    dtsi 类似于头文件,包含一些公共的信息,可被其它设备树文件引用
    dtb  编译后的设备树文件
设备树语法
    设备树的语法为树状结构,由一系列的节点和属性组成,根节点下包含子节点
    子节点下还可以包含子节点,节点内部包含了对应设备的属性
Linux内核驱动移植
    1.在make menuconfig界面中选中要安装的驱动
    2.在设备树中添加/修改相应的设备信息
    3.重新编译内核/设备树

10.linux内核调试及rootfs移植

根文件系统
    根文件系统是内核启动后挂载的第一个文件系统系统引导程序会在根文件系统挂载后从中把一些基本的初始化脚本和服务等加载到内存中去运行

根文件系统内容
     bin		shell命令(elf格式)(通过busybox编译生成)
     dev		设备文件(内核启动后会将设备信息写入该目录)
     etc		内核配置文件
     lib		共享库(elf格式)(从交叉编译工具链中获取)
     linuxrc	内核运行的第一个应用程序(通过busybox编译生成)
     mnt		挂载目录(非必要)
     proc		进程相关文件(内核启动后会将进程信息写入该目录)
     root		超级用户家目录(非必要)
     sbin   	系统管理shell命令(elf格式)(通过busybox编译生成)
     sys		驱动相关文件(内核启动后会将驱动信息写入该目录)
     usr		shell命令(elf格式)(通过busybox编译生成)

BusyBox
    BusyBox将很多常用的工具集成到一个很小的可执行文件中,为普通用户提供大多数常用的命令,BusyBox实现的命令都是精简版的,很多扩展都不支持。BusyBox被称为Linux工具里的瑞士军刀

  • 6
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值