系统移植学习

本文详细介绍了系统移植的概念,包括Linux系统移植到开发板的过程。内容涵盖系统移植的原因、目的,以及学习方法。同时讲解了本地与交叉开发的区别,并涉及到安装交叉编译工具链、gnu命令的使用,如nm。还提到了PC与Target的硬件连接、tftp和nfs服务的安装。此外,文章深入探讨了uboot的命令、环境变量及其作用,以及如何测试ping和tftp命令,最后讲述了如何给开发板部署uboot和Linux内核。

系统移植
【1】什么是系统移植?
为什么学习系统移植?
学习系统移植的目的?
如何学习系统移植?

  1. 什么是系统移植?
    就是将操作系统移植到对应的硬件平台
    linux系统移植到开发板

  2. 为什么学习系统移植?
    软硬件可裁剪

    公司新的硬件平台—》移植linux系统
    到硬件平台

  3. 学习系统移植的目的?
    1》工作的需要
    2》为后边的驱动开发搭建一个系统环境
    3》嵌入式应用层的开发离不开操作系统

  4. 如何学习系统移植?
    1》跟上我上课的思路,
    2》掌握系统移植的流程,不要关心代码

【2】概念:本地开发和交叉开发
本地开发:PC端编写代码,编译代码,运行代码
交叉开发:PC端编写代码,编译代码,Target运行代码

PC 					Target 
X86架构 			arm架构

使用交叉编译工具链将源码编译成支持ARM架构的可执行程序,
再讲可执行程序拷贝到目标板上运行。

PC:gcc
交叉编译工具链:arm-none-linux-gnueabi-gcc 
arm-none-linux-gnueabi-:交叉编译工具链的名字,
名字就是一个代码

【3】安装交叉编译工具链
1. 获取交叉编译工具链
一般交叉编译工具链和uboot和linux内核源码,
都具有配套的关系。

	1》自己去gnu官网获取交叉编译工具链的源码,
		自己进行编译生成对应的交叉编译工具链。
		不推荐:编译过程很繁琐
	2》直接从芯片厂家获取交叉编译工具链
	3》直接跟开发板的生成厂家获取交叉编译工具链
	4》直接找主管获取交叉编译工具链

安装交叉编译工具链:
将代码编译成ARM架构的可执行程序
安装步骤:
1. 在ubuntu的家目录(~)下,创建toolchain 
	mkdir toolchain 
2. 拷贝gcc-4.5.1.tar.bz2到toolchain目录下
	cp 目录/gcc-4.5.1.tar.bz2 ~/toolchain
3. 解压缩交叉编译工具链
	tar -vxf gcc-4.5.1.tar.bz2
4. 配置环境变量
	打开 sudo vi /etc/bash.bashrc 
	在最后一行添加以下内容:
5. 使环境变量立即生效
	source /etc/bash.bashrc
	export PATH=$PATH:/home/hqyj/toolchain/gcc-4.5.1/bin/
						修改为自己的路径

6. 测试交叉编译工具链是否安装成功
	arm-none-linux-gnueabi-gcc -v
	打印以下内容,表示成功
	gcc version 4.5.1 (Sourcery G++ Lite 2010.09-50) 

【4】gnu命令
1. nm
格式:nm 可执行文件
列出可执行文件中的符号

	$ arm-none-linux-gnueabi-nm interface.elf
	符号的地址   类型   符号名字
	43c016e4       T    delay_ms
	43c01754       T    do_irq
	43c00200       T    fiq
	43c01a24       T    hal_irq_gicc_init
	43c01988       T    hal_irq_gicd_init
	43c01844       T    hal_irq_gpio_init
	43c01a6c       T    hal_led_init
	43c000c4       t    init_stack
	43c001e0       T    irq
	43c01b44       T    main
2. strip
	删除可执行文件中符号表,对可执行文件进行压缩
	符号表不影响程序的运行。
	切记,不可以对中间文件进行压缩
	格式:strip 可执行文件
	使用ls -al可以查看文件的大小
3. size	
	查看文件中各个段的大小
	格式:size 可执行文件
	$ arm-none-linux-gnueabi-size interface.elf 
   text	   data	    bss	    dec	    hex	filename
   7140	   2304	      0	   9444	   24e4	interface.elf
4. objcopy
	将可执行文件(elf)生成纯粹的二进制文件(.bin)
	格式:arm-none-linux-gnueabi-objcopy 
		-O binary ***.elf ***.bin
	-O:输出
	binary:二进制文件
5. objdump
	将可执行文件(elf)生成反汇编文件(.dis)
	格式:格式:arm-none-linux-gnueabi-objdump
		-D ***.elf > ***.dis 
	可以看反汇编代码,查看代码具体的实现,
	
	通过可执行文件生成的汇编代码叫做反汇编(汇编指令集)代码

  7 43c00000 <_start>:
指令存放的地址   机器码       通过机器码生成反汇编代码
   8 43c00000:   ea00000d    b   43c0003c <reset>
   9 43c00004:   e59ff014    ldr pc, [pc, #20]   ; 43c00020 <_undefined
  10 43c00008:   e59ff014    ldr pc, [pc, #20]   ; 43c00024 <_software_
  11 43c0000c:   e59ff014    ldr pc, [pc, #20]   ; 43c00028 <_prefetch_
  12 43c00010:   e59ff014    ldr pc, [pc, #20]   ; 43c0002c <_data_abor
  13 43c00014:   e59ff014    ldr pc, [pc, #20]   ; 43c00030 <_not_used>
  14 43c00018:   e59ff014    ldr pc, [pc, #20]   ; 43c00034 <_irq>
  15 43c0001c:   e59ff014    ldr pc, [pc, #20]   ; 43c00038 <_fiq>

6. readelf
	获取可执行文件的头部信息
	格式:readelf -h 可执行文件 
	
	ELF Header:
  Magic:   7f 45 4c 46 01 01 01 61 00 00 00 00 00 00 00 00 
  Class:                             ELF32
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            ARM
  ABI Version:                       0
  Type:                              EXEC (Executable file)
  Machine:                           ARM
  Version:                           0x1
  Entry point address:               0x43c00000
  Start of program headers:          52 (bytes into file)
  Start of section headers:          53124 (bytes into file)
  Flags:                             0x602, has entry point, GNU EABI, software FP, VFP
  Size of this header:               52 (bytes)
  Size of program headers:           32 (bytes)
  Number of program headers:         2
  Size of section headers:           40 (bytes)
  Number of section headers:         18
  Section header string table index: 15

7. addr2line 
	跟地址可以定位到地址对应的函数
	格式:addr2line -e ****.elf 地址 -a -f 
	作用:可以用于追踪代码的错误,追踪段错误或者空指针
	
	-e:后边跟可执行文几番
	-a -f:显示函数名和行号
	
	$ arm-none-linux-gnueabi-addr2line -e interface.elf 0x43c01a74 -a -f
	0x43c01a74
	hal_led_init
	/home/thf/1997/arm/key_irq/main.c:92


	gun命令前边什么都不加,表示X86架构下的GUN指令
		gcc g++ nm addr2line readelf strip objdump objcopy
	
	gnu命令前边添加arm-none-linux-gnueabi-的前缀
		表示支持arm架构的gnu命令
		
			
	对于交叉编译工具的的前缀到底是什么?
	/home/thf/toolchain/gcc-4.5.1/bin
	在交叉编译工具链的bin目录下查看交叉编译工具链的前缀。


	arm-none-linux-gnueabi-gcc --help  查看命令的帮助手册

	ubuntu中gnu命令存在的路径在:
	/usr/bin 
	thf@thf:bin$ pwd
	/usr/bin
	thf@thf:bin$ ls -al gcc
	lrwxrwxrwx 1 root root 7 10月 28 12:21 gcc -> gcc-4.8
	thf@thf:bin$ ls -al objcopy
	-rwxr-xr-x 1 root root 217000  4月 26  2017 objcopy
	thf@thf:bin$ ls -al gdb
	-rwxr-xr-x 1 root root 5094584  6月 10  2017 gdb
	thf@thf:bin$ ls -al g++
	lrwxrwxrwx 1 root root 7  4月  8  2014 g++ -> g++-4.8

【5】PC和Target如何进行硬件连接
pc Target
---------------- -----------------
| | 串口线 | |
| |-----------| |
| | | |
| | 网线 | |
| |-----------| |
| | | |
| | | |
| | | 电源 |
---------------- -----------------

串口线:打印各种调试信息得到串口工具上
网线:用于下载uboot和内核的镜像
	通过网络去挂载根文件系统
	
	需要在ubuntu中安装对应的服务器
	通过网线下载文件---》tftp服务
	通过网线挂载根文件系统---》nfs服务

	tftp服务和nfs服务的客户端uboot和内核源码默认已经安装

【6】安装tftp服务
一个简单的文本文件传输协议,基于udp协议

1. 检查ubuntu是否安装了tftp服务
	dpkg -s tftpd-hpa
	打印以下内容表示安装了tftp服务:
	Architecture: i386
	Source: tftp-hpa
	Version: 5.2-7ubuntu3.1

2. 安装tftp服务 (前提:ubuntu必须能连接外网)
	sudo apt-get update 更新源
	sudo apt-get install -f 更新依赖
	sudo apt-get install tftpd-hpa tftp-hpa 

3. 配置tftp服务
	1. 在家目录下创建一个tftpboot文件夹
		mkdir tftpboot 
		目的:tftpboot目录下存放的是你要下载到
		开发板上的可执行文件
	2. 修改tftpboot的权限
		chmod 777 tftpboot
	3. 配置tftp服务的环境变量
		打开sudo vi /etc/default/tftpd-hpa 
		修改一下内容:
		  1 # /etc/default/tftpd-hpa
		  2 
		  3 TFTP_USERNAME="tftp" 
				tftp用户名,不需要修改
		  4 TFTP_DIRECTORY="/home/hqyj/tftpboot"
				tftp服务下载文件的存放的路径,需要修改
				改成自己的对应的tftpboot的路径
		  5 TFTP_ADDRESS="0.0.0.0:69"
				tftp服务默认使用的69端口号
		  6 TFTP_OPTIONS="-c -s -l"  
				tftp服务的参数,这个需要修改

4. 重启tftp服务
	1. sudo service tftpd-hpa start  启动TFTP服务
	2. sudo service tftpd-hpa restart  重启TFTP服务
5. 本地测试tftp服务是否安装成功
	$ tftp 127.0.0.1
	tftp> get 1.txt   # 从tftpboot目录下下载
					  # 1.txt文件到当前目录 
	tftp> put 2.txt   # 把当前目录中的2.txt文件
					  # 上传到tftpboot文件夹中

	tftp> q   <回车>  退出

6. 可能出现的问题
	下载或上传是,一直卡,
	原因:tftp服务安装成功,需要重启tftp服务
		tftp服务安装不成功
	
	关闭windows和ubuntu的防火墙

【6】nfs服务的安装
Network File System

1. 检查nfs服务是否安装
	dpkg -s nfs-kernel-server
2. 安装nfs服务(前提:可以上网)
	sudo apt-get install nfs-kernel-server
3. 配置nfs服务
	1》在家目录下创建nfs文件夹
		mkdir nfs 
	2》设置文件夹的权限最大
		chmod 777 nfs 
	3》拷贝根文件系统到nfs目录下
		cp /mnt/hgfs/share/rootfs-ok.tar.bz2 ~/nfs
	4》对根文件系统的压缩包进行解压缩
		cd ~/nfs
		tar -vxf rootfs-ok.tar.bz2
	5》配置nfs服务的环境变量
		sudo vi /etc/exports
		在文件的最后一行添加以下内容:
		****************************************
		 /home/thf/nfs/rootfs/ *(rw,sync,no_subtree_check,no_root_squash) 
		****************************
		解析:
		/home/thf/nfs/rootfs/:自己的根文件系统的路径
		*:所有的用户,注:*和后边的左括号"("之间不可以出现空格.
		rw:可读可写的权限
		sync:同步文件
		no_subtree_check:不对字目录检查文件的权限
		no_root_squash:如果客户端位root用户,那么他对整个文件具有root的权限
		
		注意:这段话前边不要加#,#号是这个文件中的注释符号
		
4. 重启nfs服务
	1. sudo service nfs-kernel-server start  启动nfs服务
	2. sudo service nfs-kernel-server restart  重启nfs服务
		
5. 本地测试nfs服务是否安装成功
	1》回到家目录下
		cd ~
	2》sudo mount -t nfs 本机IP地址:/home/thf/nfs/rootfs/ /mnt
	
	nfs:使用nfs服务,将本机IP地址:/home/thf/nfs/rootfs/
	文件挂载到/mnt目录下
	3》检查/mnt目录下是否挂载成功
		cd /mnt 
		ls 
	4》卸载挂载的文件
		sudo umount /mnt
		注意:不可以在/mnt目录下执行卸载的命令

#####################################################
【8】uboot中的命令
1.help命令
FS6818# help 查看当前uboot支持的所有的命令
命令就是一个字符串,uboot收到字符串之后,
会解析字符串,完成对应的功能。

FS6818# help
	0       - do nothing, unsuccessfully
	1       - do nothing, successfully
	?       - alias for 'help'
	base    - print or set address offset
	bdinfo  - print Board Info structure
	boot    - boot default, i.e., run 'bootcmd'
	bootd   - boot default, i.e., run 'bootcmd'
	bootm   - boot application image from memory
	bootp   - boot image via network using BOOTP/TFTP protocol
	cmd     - cmd [command] options...
	cmp     - memory compare
	cp      - memory copy
	crc32   - checksum calculation
	dhcp    - boot image via network using DHCP/TFTP protocol
	drawbmp - darw bmpfile on address 'addr' to framebuffer 
	env     - environment handling commands
	exit    - exit script
	ext4load- load binary file from a Ext4 filesystem
	ext4ls  - list files in a directory (default /)
	ext4write- create a file in the root directory
	fastboot- fastboot- use USB Fastboot protocol

	fatinfo - print information about filesystem
	fatload - load binary file from a dos filesystem
	fatls   - list files in a directory (default /)
	fatwrite- write file into a dos filesystem
	fdisk   - mmc list or create ms-dos partition tables (MAX TABLE 7)
	go      - start application at address 'addr'
	goimage - start Image at address 'addr'
	help    - print command description/usage
	i2c     - I2C sub-system
	i2cmod  - set I2C mode
	iminfo  - print header information for application image
	loadb   - load binary file over serial line (kermit mode)
	loadbmp - load bmpfile with command or 'bootlog' environment 
	loads   - load S-Record file over serial line
	loadx   - load binary file over serial line (xmodem mode)
	loady   - load binary file over serial line (ymodem mode)
	loop    - infinite loop on address range
	md      - memory display
	mdio    - MDIO utility commands
	mii     - MII utility commands
	mm      - memory modify (auto-incrementing address)
	mmc     - MMC sub system
	mmcinfo - display MMC info
	mtest   - simple RAM read/write test
	mw      - memory write (fill)
	nm      - memory modify (constant address)
	ping    - send ICMP ECHO_REQUEST to network host
	pmic    - PMIC
	printenv- print environment variables
	reset   - Perform RESET of the CPU
	run     - run commands in an environment variable
	saveenv - save environment variables to persistent storage
	saves   - save S-Record file over serial line
	sdfuse  - sdfuse  - read images from FAT partition of SD card and write them to booting device.

	setenv  - set environment variables
	showvar - print local hushshell variables
	source  - run script from memory
	test    - minimal test like /bin/sh
	tftpboot- boot image via network using TFTP protocol
	udown   - Download USB
	update_mmc- update mmc data

	version - print monitor, compiler and linker version	
	
2. help 命令 
	查看命令的帮助手册
		
3. loadb 
	loadb 下载到内存的那个地址 
	下载二进制文件到内存的某个地址,使用kermit协议
		
	flash              memery
	掉电不丢失        掉电丢失
	速度慢			  速度快
	价格便宜		  价格贵
	flash访问通过     内存以字节为单位进行访问
	块去访问,
	每块大小位512字节

4. go 
	go  内存地址
	跳转到内存地址处,运行程序

5. printenv   打印uboot的环境变量
	FS6818# printenv
	baudrate=115200
	bootargs=root=/dev/nfs nfsroot=192.168.0.222:/home/hqyj/nfs/rootfs,v4,tcp rw console=/dev/ttySAC0,115200 init=/linuxrc ip=192.168.0.250
	bootcmd=loadb 43c00000;go 43c00000
	bootdelay=3
	bootfile=uImage
	ethact=dwmac.c0060000
	ethaddr=00:e2:1c:ba:e8:60
	ethprime=RTL8211
	fastboot=flash=mmc,2:ubootpak:2nd:0x200,0x78000;flash=mmc,2:2ndboot:2nd:0x200,0x4000;flash=mmc,2:bootloader:boot:0x8000,0x70000;flash=mmc,2:boot:ext4:0x00100000,0x04000000;flash=mmc,2:system:ext4:0x04100000,0x2F200000;flash=mmc,2:cache:ext4:0x33300000,0x1AC00000;flash=mmc,2:misc:emmc:0x4E000000,0x00800000;flash=mmc,2:recovery:emmc:0x4E900000,0x01600000;flash=mmc,2:userdata:ext4:0x50000000,0x0;
	gatewayip=192.168.0.1
	ipaddr=192.168.0.250
	loadb=0x43c00000;go 0x43c00000
	netmask=255.255.255.0
	serverip=192.168.0.222
	stderr=serial
	stdin=serial
	stdout=serial

	Environment size: 872/32764 bytes

	注意:uboot对命令进行匹配是,是部分匹配
	
	pri/print/printenv 常用

5. bootm  (启动内核是在用)
	bootm 内核的运行地址 根文件系统的运行地址 设备树的运行地址  
	
	引导linux内核启动的

6. ping命令   
	ping  ip地址
	用于开发板和电脑是否可以ping通

7. setenv  设置环境变量
	1》给uboot添加环境变量
		setenv  环境变量名  环境变量对应的值
		eg:setenv  xiaoming  nozuonodie
		注:等号会自动添加
	2》删除环境变量
		setenv  要删除的环境变量名
		eg:setenv  xiaoming 
	3》修改环境变量
		setenv 旧的环境变量名  新的环境变量值
		eg:setenv xiaoming qusiba
		
		设置完环境变量之后,环境变量存在于内存中,
		重新上电数据会丢失
8. saveenv  保存环境变量到flash中

9. tftpboot    
	使用tftp服务,将可执行程序通过网线下载到内存中
	tftpboot/tftp  内存地址   要下载的可执行文件
	
	要求:可执行文件必须存放在tftp服务配置是指定的目录下
		我的目录:/home/hqyj/tftpboot 

【8】uboot中环境变量的作用
baudrate=115200 波特率
bootdelay=3 uboot启动后倒计时时间
gatewayip=192.168.1.1 网关
ipaddr=192.168.1.250 开发板的ip地址(FS6818)
netmask=255.255.255.0 子网掩码
serverip=192.168.1.222 服务器的ip地址(PC:Ubuntu)

【9】测试ping命令和tftp命令的使用
0》开发板和PC电脑如何连接
查看:开发板和PC网线进行连接.png
1》设置ubuntu的IP地址
1>修改电脑的网卡由自动切换到百兆全双工
查看:网卡百兆全双工设置.png
2>修改ubuntu的ip地址
(1) 设置ubuntu系统使用有线网卡
查看:ubuntu网络配置1.png
(2) 设置ubuntu系统为固定的IP地址
查看:Ubuntu网络配置2.png
(3)查看IP地址是否设置成功
ifconfig
2》设置开发板的IP地址
setenv serverip 192.168.1.222
setenv ipaddr 192.168.1.250
setenv gatewayip 192.168.1.1
setenv netmask 255.255.255.0
saveenv
3》测试开发板能够平通Ubuntu
在超级终端上执行以下命令
FS6818# ping 192.168.1.222
如果ping失败打印一下信息:
dwmac.c0060000 Waiting for PHY auto negotiation to complete… TIMEOUT !
Waiting for PHY realtime link… TIMEOUT !
done
dwmac.c0060000: No link.
ping failed; host 192.168.1.222 is not alive

	如果ping成功打印一下信息:
	Speed: 100, full duplex
	Using dwmac.c0060000 device
	host 192.168.1.222 is alive
	
	总结:
	ping 失败的原因
	1》windows的防火墙可能没关
	2》检查开发板和电脑之间的网线
	3》重启tftp服务
	4》检查tftp服务的环境配置是否正确
	
4》测试tftp命令的使用
	拷贝ARM课程中的interface.bin文件到tftpboot目录下
	在超级终端上执行以下命令:
	FS6818# tftp 0x43c00000 interface.bin 
	如果打印一下内容表示下载成功:
	Speed: 100, full duplex
	Using dwmac.c0060000 device
	TFTP from server 192.168.1.222; our IP address is 192.168.1.250
	Filename 'interface.bin'.
	Load address: 0x43c00000
	Loading: #
			 708 KiB/s
	done
	Bytes transferred = 8700 (21fc hex)
	
	FS6818# go 0x43c00000   # 运行代码

	总结:tftp失败的原因
	1》包含上边ping失败的原因
	2》检查uboot的环境变量设置是否正确
		serverip ipaddr gatewayip netmask
	3》检查ubuntu的网络设置
		切记,开发板和ubuntu的ip地址在同一个网段

【10】给开发板部署操作系统

  1. 部署uboot
    1》新的开发板,一切都是空白,制作一个SD卡启动盘
    1> 将sd卡启动盘的制作工具拷贝到ubuntu的toolchain目录下
    cp /mnt/hgfs/share/sdtool ~/toolchain -raf
    2> 进入到sdtool目录下
    cd ~/toolchain/sdtool
    3> 将sd卡插到电脑上,让你的ubuntu识别sd卡
    注意:必须使用读卡器,不可以使用电脑自带的SD卡卡槽
    将SD卡插到读卡器上,读卡器插到电脑上,
    在windows下讲SD卡进行格式化。

     	虚拟机--》可移动设备--》realtek USB3.0-CRW
     	---》连接
     	sdtool文件中的文件是什么?
     	s5p6818-sdmmc.sh :烧写uboot到sd卡的脚本
     	ubootpak.bin:uboot的可执行文件
     4> 烧写ubootpak.bin到sd卡中
     	在ubuntu中执行命令
     	sudo ./s5p6818-sdmmc.sh /dev/sdb ubootpak.bin
     	
     	/dev/sdb: sd卡的设备文件
     	
     	如果打印一下信息表示,部署成功:
     	688+1 records in
     	689+0 records out
     	352768 bytes (353 kB) copied, 0.00914641 s, 38.6 MB/s
     	^_^ The image is fused successfully
     	
     	总结: 报SD卡只读的错误,
     		将sd卡中开关拨到lock的位置,
     		lock靠近sd卡的触点位置
    
     5> 测试sd卡是否制作成功
     	将sd卡插到开发板板上,
     	设置开发板上的拨码开关,为sd卡启动,
     	
     	拨码开关用于设置开发板上uboot的启动方式的
     	OM1   OM2	OM3   Device
     	ON	  ON    X      nand flash
     	OFF   ON    X      USB 
     	ON    OFF   ON     EMMC   本开发板flash为EMMC
     	OFF   OFF   OFF    SD/TF 
     		
     6> 开发板重新上电,启动成功。
    
    1. 部署Linux内核
    2. 部署根文件系统
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值