系统移植第一天

一、什么是系统移植

1.1 系统移植就是给开发板搭建一个Linux操作系统

1.2 从官方获取源码,进行配置和编译,生成板子需要的镜像文件

二、为什么学习系统移植

2.1 为后面学驱动开发课程打基础

2.2 驱动开发工程必备技能

三、如何学习系统移植

3.1 重点掌握配置和编译的流程

3.2 不要深追源码中的内容

四、课程安排

1.环境搭建 + gnu二进制工具集 + Makefile ----->1天
2.uboot移植和TF-A移植 ----->3天
3.内核移植 ----->1.5天
4.根文件系统 ----->1.5天

五、安装tftp服务器

5.1 安装步骤

重要内容:需要让ubuntu连接外网
tftp服务器:基于UDP协议完成简单文件的传输
作用:通过网线下载程序到开发板中
​
1.安装tftp服务器安装包
    sudo apt-get install tftpd-hpa tftp-hpa
    tftpd-hpa:tftp服务器端
    tftp-hpa:tftp客户端
2.在家目录下,创建一个文件夹,文件夹名字为tftpboot
        cd ~
        mkdir tftpboot
        chmod 777 tftpboot
3.配置tftp服务器
    1)打开配置文件 sudo vi /etc/default/tftpd-hpa 
    2)需要配置如下内容   
        3 TFTP_USERNAME="tftp"  #tftp服务器名字
        4 TFTP_DIRECTORY="/home/linux/tftpboot/"        #tftp服务器下载路径,大家需要更改为自己的路径                                                                
        5 TFTP_ADDRESS="0.0.0.0:69" #tftp服务器下载ip地址和端口号
        6 TFTP_OPTIONS="-c -l -s"  #保持默认的参数
 4.重启配置文件
     source /etc/default/tftpd-hpa 
5.重启tftp服务器
    sudo service tftpd-hpa restart
6.测试tftp服务器是否安装成功
    1>在家目录创建huyue.c,在~/tftpboot目录下创建1.c
    2>实验目的:将~/huyue.c上传到~/tftpboot,将~/tftpboot目录下1.c下载到当前目录
    3>上传和下载步骤参考下图所示

5.2 作用

5.3 总结

1.在开发板中emmc设备或者TF卡设备中固化uboot镜像文件
2.在ubuntu中~/tftpboot目录下,准备好基于tftp服务器下载的文件
3.通过开发板的拨码开关,选择开发板的启动方式
4.开发板上电,uboot镜像文件加载到开发板内存中
5.在串口工具打印uboo信息,在倒计时时间进入0之前,按下enter键,进入交互模式
6.使用tftp命令通过网线下载程序到开发板中

六、安装nfs服务器

6.1 安装步骤

注意:一定保证ubuntu有网
nfs服务器:网络文件系统
作用:ubuntu通过网络的方式挂载文件到开发板中
1.安装nfs服务器安装包
    sudo apt-get install nfs-kernel-server 
2.在家目录下创建一个文件夹,文件夹的名字为nfs
    cd ~
    mkdir nfs
    chmod 777 nfs
3.将rootfs-ok.tar.xz文件拷贝到~/nfs目录下
4.对文件进行解压
    tar -vxf rootfs-ok.tar.xz 
5.配置nfs服务器
    1)打开配置文件:
    2)在配置文件最后一行,添加如下内容:sudo vi /etc/exports 
     11 /home/linux/nfs/rootfs *(rw,sync,no_subtree_check,no_root_squash)   
     解释:
      /home/linux/nfs/rootfs:挂载路径,需要注意填写自己的路径
       *(:之间不要有空格
       rw:可读可写权限
       sync:同步信息
       no_subtree_check:不检查子目录的信息
       no_root_squash:在开发板中默认权限就是管理员权限,不需要加sudo
6.重启nfs服务器
    sudo service nfs-kernel-server restart
7.本地测试nfs服务器是否安装成功:
    1>实验现象:将~/nfs/rootfs目录下内容挂载到/mnt目录下
    2>挂载命令:
        sudo mount -t nfs 192.168.250.100:/home/linux/nfs/rootfs /mnt
        解释: mount:挂载命令
            -t nfs :指定使用nfs服务器进行挂载
            192.168.250.100:挂载的ip地址,通过ifconfig进行查看
            /home/linux/nfs/rootfs:挂载的路径
           /mnt:挂载到的路径 
   3>需要查看/mnt目录挂载的内容,和~/nfs/rootfs目录下内容是否一致
    4>取消挂载命令:
    sudo umount /mnt

6.2 作用

6.3总结

1.在开发板中emmc设备或者TF卡设备中固化uboot镜像文件
2.在Ubuntu中~/tftpboot目录下,准备好基于tftp服务器下载的文件
3.通过开发板的拨码开关,选择开发板的启动方式
4.开发板上电,uboot镜像文件加载到开发板内存中
5.在串口工具打印uboot信息,在倒计时时间进入0之前,按下enter键,进入交互模式
6.使用tftp命令通过网线下载程序到开发板中,下载内容问设备树文件和uImage镜像文件
7.下载成功之后,linux内核进行启动,启动成功之后
8.通过网线实现从ubuntu挂载根文件系统到开发板中
9.挂载成功之后,在串口工具,可以查看到~/nfs/rootfs目录下相关内容

一、gnu二进制工具集

1.1 gcc命令

将.s文件生成.o文件
arm-linux-gnueabihf-gcc -c asm-led -o asm-led.o

1.2 ldd链接器

ld:链接命令,将.o文件链接生成.elf文件,需要指定链接的入口地址
arm-linux-gnueabihf-ld -Ttext=0xc0008000 asm-led.o asm-led.elf

1.3 objdump生成反汇编

objdump:生成反汇编命令,将.elf文件生成反汇编文件
arm-linux-gnueabihf-objdump -D asm-led.elf > asm-led.elf

1.4 objcopy生成二进制文件

objcopy:生成二进制文件,将.elf文件生成存粹二进制文件
.elf文件:包含符号表信息,调试信息
.bin文件:不包含符号表信息,调试信息
arm-linux-gnueabihf-objcoypy -o binary asm-led.elf asm-led.bin

1.5 nm查看符号表信息

命令:arm-linux-gnueabihf-nm asm-led.elf
c00181e8 T __bss_end__
c00181e8 T _bss_end__
c00181e8 T __bss_start
c00181e8 T __bss_start__
c00081a8 t delay_1s
c00181e8 T _edata
c00181e8 T __end__
c00181e8 T _end
c0008000 t led1_init
c000816c t led1_off
c0008130 t led1_on
c0008054 t led2_init
c0008180 t led2_off
c0008144 t led2_on
c00080a8 t led3_init
c0008194 t led3_off
c0008158 t led3_on
c00080fc t loop
c00081ac t mm
c0008000 T _start

1.6 size查看各个段大小

arm-linux-gnueabihf-size asm-led.elf

1.7 readelf查看文件头部信息

arm-linux-gnueabihf-readelf -h asm-led.elf

1.8 strip压缩文件体积

strip压缩文件体积,不可以对中间文件进行压缩(.i,.s,.o)只可以对可执行二进制文件压缩
arm-linux-gnueabihf-strip asm-led.elf

1.9 addr2line调试段错误信息

addr2line:用来调试内核中段错误信息
格式:arm-linux-gnueabihf-addr2line 地址 -e 指定elf文件 -f
	-e:指定elf可执行文件
	-f:回显函数名,行号
	
	linux@ubuntu:~/DC22081/01-asm-led$ arm-linux-gnueabihf-addr2line c000816c -e asm-	 led.elf -f
    led1_off
    /home/linux/DC22081/01-asm-led/asm-led.S:146
	
	以上学习所有命令,支持x86架构和arm架构,如果想生成x86架构,直接使用命令即可,不需要加交叉编译工具链前缀
	如果想生成arm架构,需要加交叉编译链前缀

二、gcc编译流程

2.1 预处理

预处理作用:头文件展开,去掉注释,宏替换,不检查语法错误 
gcc -E *.c -o *.i

2.2 编译

编译:生成汇编文件,检查语法错误 
gcc -S *.i -o *.s

2.3 汇编

汇编:生成二进制文件,检查语法错误 
gcc -c *.s -o *.o

2.4 链接

链接:链接对应的库,生成.elf可执行文件 
gcc *.o -o 可执行文件

三、分析Makefile文件

makefile中四种赋值方式有什么区别?
?= += := =
?= : 作用是当某变量前面已经定义赋值过,则不执行本次定义赋值,否则执行本次赋值
+= : 追加赋值,旧值保持不变,将新值黏贴到旧值后面 
:= : 是覆盖式赋值,假如某变量在前面已经定义赋值过,则将本次赋值作为最新的变量值
=  : 是最基本的赋值方式,与在文中位置无关,系统自动推导将最终的赋值作为该变量的值

# CORTEX-A53 PERI DRIVER CODE
# VERSION 2.0
# ATHUOR www.hqyj.com
# MODIFY DATE
# 2019.04.12  Makefile
# SHELL=C:/Windows/System32/cmd.exe
# 
# 指定交叉编译工具链前缀
CROSS_COMPILE = arm-linux-gnueabihf-
# 指定文件的名字
NAME = interface
#=============================================================================#
#-g:gdb调试信息 -marm:编译生成arm架构 -Wall:显示所有警告信息 -O0::优化等级信息
#-I:指定头文件路径
#-fno-builtin:不使用linux操作系统提供的库函数
#-nostdinc:不实用系统提供的头文件
CFLAGS += -g -marm -Wall -O0 -mabi=apcs-gnu -mfpu=neon -mfloat-abi=softfp -fno-builtin \
			-nostdinc -I./common/include    -I./include  		                       
#ld:链接命令
LD	= $(CROSS_COMPILE)ld
#gcc:编译命令
CC	= $(CROSS_COMPILE)gcc
#nm:查看符号表信息
NM  = $(CROSS_COMPILE)nm
#objcopy:生成二进制文件
OBJCOPY = $(CROSS_COMPILE)objcopy
#objdump:生成反汇编文件
OBJDUMP = $(CROSS_COMPILE)objdump
#============================================================================#
#wildcard是Makefile中内置函数
#函数功能:将某个文件夹下面的内容进行以字符串形式进行展开,并用空格隔开
#函数参数:需要展开目录文件
#函数返回值:以字符串展开后的结果
OBJSss 	:= $(wildcard start/*.S) $(wildcard common/src/*.S) $(wildcard *.S)\
		   $(wildcard start/*.c) $(wildcard common/src/*.c) 			   \
		   $(wildcard src/*.c) $(wildcard *.c) 
#patsubst是Makefile中内置函数
#函数功能:将一个字符串内容替换成另一个字符串
#函数参数:
#第一个参数:源字符串,也就是要替换的字符串
#第二个参数:目标字符串,也就是替换后的字符串
#第三个参数:要替换的字符串目录
#函数返回值:替换后的目标 字符串
#将OBJSss目录下所有以.S结尾的字符串替换成.o
OBJSs  	:= $(patsubst %.S,%.o,$(OBJSss))
#将OBJSs目录下所有以.c结尾的字符串替换成.o
OBJS 	:= $(patsubst %.c,%.o,$(OBJSs))

%.o: %.S 
	@echo "  AS      $@"
	@$(CC) $(CFLAGS) -c -o  $@ $<
	#将所有以.S结尾的文件根据指定参数编译生成.o结尾的文件
	#$@:目标
	#$V:第一个依赖
	#$^:所有依赖
	
%.o: %.c
	@echo "  CC      $@"
	@$(CC) $(CFLAGS) -c -o  $@ $<
	#将所有以.c结尾的文件根据指定参数编译生成.o结尾的文件
all:clean  $(OBJS)
	@echo "  LD      Linking $(NAME).elf"
	@$(LD)  $(OBJS) -T map.lds -o $(NAME).elf
	#将OBJS目录下所有文件,根据链接脚本文件map.lds指定地址信息,生成elf文件
	@echo "  OBJCOPY Objcopying $(NAME).bin"
	@$(OBJCOPY)  -O binary  $(NAME).elf $(NAME).bin 
	#将elf文件生成.bin文件
	@echo "  MAP     Generating $(NAME).map"
	@$(NM) $(NAME).elf > $(NAME).map 
	#将elf文件符号表信息重定向到interface.map文件中
	@echo "  OBJDUMP Objdumping $(NAME).dis"
	@$(OBJDUMP) -DS $(NAME).elf > $(NAME).dis 
	#将elf文件生成反汇编文件到.dis文件中

distclean clean:
	@rm -rf $(OBJS) *.elf *.bin *.dis *.map
	@echo "  CLEAN   complete."

install:
	sudo cp $(NAME).bin /mnt/hgfs/share/

huyue:
	@echo $(OBJSs)
	@echo $(OBJS)

一、uboot概念

1.1 uboot和bootloader关系

1.bootloader:是一系列引导加载程序的统称
    boot:引导
    loader:加载
2.uboot是引导加载程序中的一种

1.2 uboot特点

1.uboot是由德国DNEX小组进行维护的
2.uboot是一个开源分布式系统
3.uboot支持多种硬件架构平台(ARM/X86/POWERPC)
4.uboot短小精悍
5.uboot是一个裸机程序
6.uboot是一个短命鬼,只是引导linux内核进行启动,内核启动成功后,uboot 的生命周期就结束了
7.uboot在启动成功后,会给内核传递两个参数(bootcmd和bootargs)

1.3 uboot环境变量

一下所有学习的命令,都需要在串口工具进行输入
1.help ----->查看uboot中所有的环境变量相关信息内容
2.help uboot命令 ----->查看uboot命令中的环境信息
3.help loadb命令
    help loadb -----> 串口工具输入命令
    loadb - load binary file over serial line (kermit mode) -----> 打印帮助信息
    Usage:
    loadb [ off ] [ baud ] ----->uboot命令格式
        - load binary file over serial line with offset 'off' and baudrate 'baud'
4.help go命令
    FSMP1A> help go
    go - start application at address 'addr'
    Usage:
    go addr [arg...]----->uboot命令格式
    - start application at address 'addr'
          passing 'arg' as arguments
5.help gpio命令
    FSMP1A> help gpio
    gpio - query and control gpio pins
    
    Usage:
    gpio <input|set|clear|toggle> <pin>
        - input/set/clear/toggle the specified pin
    gpio status [-a] [<bank> | <pin>]  - show [all/claimed] GPIOs
    input:设置输入的值
    set:设置相应的值
    clear:设置清除相应的值
    toggle:设置gpio翻转状态
    例子:
        FSMP1A> gpio toggle gpioe10
        gpio: pin gpioe10 (gpio 74) value is 1
        FSMP1A> gpio toggle gpioe10
        gpio: pin gpioe10 (gpio 74) value is 0
        FSMP1A> gpio toggle gpiof10
        gpio: pin gpiof10 (gpio 90) value is 1
        FSMP1A> gpio toggle gpiof10
        gpio: pin gpiof10 (gpio 90) value is 0
        FSMP1A> gpio toggle gpioe8 
        gpio: pin gpioe8 (gpio 72) value is 1
        FSMP1A> gpio toggle gpioe8
        gpio: pin gpioe8 (gpio 72) value is 0
6.pri:打印环境变量信息   ------>串口工具输入:pri
      FSMP1A> help pri
        printenv - print environment variables ------>打印变量信息
    
    Usage:
    printenv [-a] ------> 查看所有环境变量信息
        - print [all] values of all environment variables
    printenv name ... ------>pri uboot变量
        - print value of environment variable 'name'
7.pri/printenv ------>  打印环境变量信息
    arch=arm  ------> 指定架构
    baudrate=115200 ------> 波特率
    board=stm32mp1 ------>板子名称
bootargs=root=/dev/nfs nfsroot=192.168.1.210:/home/linux/nfs/rootfs,tcp,v4 console=ttySTM0,115200 init=/linuxrc ip=192.168.1.250
    bootargs参数功能:自启动参数,设置ubuntu挂载根文件系统到开发板上的路径和ip地址
bootcmd=tftp 0xc2000000 uImage;tftp 0xc4000000 stm32mp157a-fsmp1a.dtb;bootm 0xc2000000 - 0xc4000000
    bootcmd参数功能:自启动命令,倒计时时间进入0之前不按下enter键盘,进入自启动模式,并且执行自启动命令
    bootdelay=3 ------>倒计时时间
    ethaddr=12:56:78:ff:ff:4e ------>物理地址ip
    gatewayip=192.168.1.1 ------>设置开发板网关
    ipaddr=192.168.1.250 ------>设置开发板ip地址
    netmask=255.255.255.0 ------>设置开发板子网掩码
    serverip=192.168.1.210 ------>设置服务器(ubuntu)的ip地址
8.run -------> 运行run后面的命令   格式:run uboot命令 run bootcmd
    1)交互模式:
        当uboot启动成功之后,在倒计时时间进入0之前,按下键盘enter键,进入交互模式,和uboot命令进行交互
    2)自启动模式:
        当uboot启动成功之后,在倒计时时间进入0之前,不按下键盘enter键,进入自启动模式,执行自启动命令(bootcmd)不可以使用uboot命令
    3)设置bootcmd格式
        setenv bootcmd uboot命令1\;uboot命令2\;...............
        saveenv
    4)在arm课程中,需要输入两条命令:loadb 0xc0008000  go 0xc0008000    
        FSMP1A> setenv bootcmd loadb 0xc0008000\;go 0xc0008000
        FSMP1A> saveenv
        Saving Environment to MMC... Writing to MMC(0)... OK
    5)在串口工具中,查看bootcmd环境变量信息
        FSMP1A> pri bootcmd
        bootcmd=loadb 0xc0008000;go 0xc0008000
    6)在串口工具中,执行run bootcmd命令,观察现象
    FSMP1A> run bootcmd
    ## Ready for binary (kermit) download to 0xC0008000 at 115200 bps...
​
    7)在倒计时时间进入0之前,不按下键盘enter键,进入自启动模式,观察现象
    Hit any key to stop autoboot:  0 
    ## Ready for binary (kermit) download to 0xC0008000 at 115200 bps...
9.ping命令 ------->测试开发板和ubuntu组网是否成功
    ping - send ICMP ECHO_REQUEST to network host
​
    Usage:
    ping pingAddress
    格式:ping 服务器(ubuntu)ip地址
    
10.tftp命令 ------->使用tftp命令将文件下载到开发板内存中,一定保证开发板和ubuntu组网成功
    FSMP1A> help tftp
    tftpboot - boot image via network using TFTP protocol
    
    Usage:
    tftpboot [loadAddress] [[hostIPaddr:]bootfilename]
    格式:tftp 地址 文件名
1.4 设置uboot环境变量
1.设置uboot环境变量:setenv  ------>修改环境变量
2.保存uboot环境变量:saveenv ------>保存环境变量
3.修改环境变量格式:
    setenv 要修改的环境变量 修改的值
    saveenv
4.设置开发板倒计时时间为20s
    FSMP1A> setenv bootdelay 20
    FSMP1A> saveenv
    Saving Environment to MMC... Writing to redundant MMC(0)... OK
    FSMP1A> pri bo
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值