Linux系统移植学习笔记1
一、U-boot的移植
1.准备工作
1.本地开发和交叉开发
①本地开发:本地编写代码,本地编译代码,本地运行代码
②交叉开发:本地编写代码,本地编译代码,开发板运行代码
2.ubuntu系统=linux内核+GUI+动态库+命令+文件系统
3.GNU命令(GNU’s not unix一个提倡软件*的组织)
1. gcc/g++
2. gdb
3. ld 链接
将所有的.o文件链接生成.elf文件
4. objdump
将elf文件生成反汇编文件(.dis)
5. objcopy
将elf文件生成纯粹的二进制文件(.bin)
6. nm 查看符号表 (了解)
nm ***.elf
7. size 查看文件各个段的大小 (了解)
size ***.elf
8. readelf 查看elf文件的信息 (了解)
readelf -h ***.elf
9. strip 用于缩小文件的体积 (重点)
注意: 不可以对中间文件执行strip,
比如***.o
strip ***.elf // 不影响程序的正常运行
10. addr2line 根据地址定位错误信息 (重点)
常用于段错误,
addr2line 地址 -e ***.elf -f
-e:指定可执行文件
-f:回显函数名
定位错误的信息,函数名及函数所在的文件及行号
gnu命令 --help : 查看gun命令的帮助手册,借助百度。
4.安装ubuntu版本的交叉编译工具链
1. 在ubuntu的家目录下创建toolchains
2. 拷贝交叉编译工具链到toolchains目录下,
并进行解压缩
FS6818(学生资料)\工具软件\ubuntu版本交叉编译器\gcc-4.5.1.tar.bz2
tar -xvf gcc-4.5.1.tar.bz2
3. 配置ubuntu系统的环境变量
/etc/envirenment
/etc/profile
/etc/bash.bashrc
~/.bashrc
修改/etc/bash.bashrc,在最后边添加一下内容
export PATH=$PATH:/home/linux/toolchains/gcc-4.5.1/bin
4. 使环境变量立即生效
source /etc/bash.bashrc
./xxx.sh
bash xxx.sh 开一个子终端执行shell脚本
source xxx.sh 当前终端执行shell脚本
5. 测试交叉编译工具链是否安装成功
arm-none-linux-gnueabi-gcc -v
64位ubuntu系统 :
sudo apt-get install libncurses5-dev
sudo apt-get install lib32z1
ps.不同的硬件平台,或者不同的linux和u-boot,源码的版本不一致,用到的交叉编译工具链版本也不一样。
5.安装tftp服务
(Trivial File Transfer Protocol:基于TCP/IP协议的一个用来在客户机与服务器之间进行简单文件传输的协议)
作用: 通过TFTP服务下载文件到开发板中
1. 检查ubuntu是否安装了tftp服务
sudo 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 跟新依赖
安装tftp服务的命令:
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/ttpboot"
tftp服务下载文件的存放的路f径,需要修改
改成自己的对应的tftpboot的路径
5 TFTP_ADDRESS="0.0.0.0:69"
tftp服务默认使用的69端口号
6 TFTP_OPTIONS="-c -s -l"
tftp服务的参数,这个需要修改
-l:以standalone/listen模式启动TFTP服务
-c:可创建新文件。默认情况下,
TFTP只允许覆盖原有文件,不能创建新文件。
-s:改变TFTP启动的根目录。
加了-s后,客户端使用TFTP时,
不再需要输入指定目录,填写文件的完整路径,
而是使用配置文件中写好的目录。
这样也可以增加安全性。
4. 重启tftp服务(只需要执行一个)
1. sudo service tftpd-hpa start 启动TFTP服务
2. sudo service tftpd-hpa restart 重启TFTP服务(默认执行重启)
注意:有时一旦重启系统或者长时间不使用tftp服务,
都需要重启tftp服务
5. 本地测试tftp服务是否安装成功
$ tftp 127.0.0.1 # 本地回环测试IP地址
tftp> get 1.txt # 从tftpboot目录下下载,
# 需要在tftpboot目录下创建1.txt
# 1.txt文件到当前目录
tftp> put 2.txt # 把当前目录中的2.txt文件,当前目录下需要创建2.txt
# 上传到tftpboot文件夹中
tftp> q <回车> 退出
6. 可能出现的问题
下载或上传是,一直卡,
原因:
1. tftp服务安装成功,需要重启tftp服务
2. tftp服务安装不成功,重新安装tftp服务
3. tftp安装成功,检查/etc/default/tftpd-hpa
环境变量修改是否正确,如果修改环境变量,
必须重启tftp服务
4. 关闭windows和ubuntu的防火墙
(ubuntu的防火墙默认都是关闭的)
sudo ufw disable
6.安装nfs服务
(Network File System:网络文件系统,通过网络的方式远程挂载根文件系统)
1. 检查nfs服务是否安装
sudo 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目录下
根文件系统一会发给你们(rootfs-ok.tar.bz2)
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/hqyj/nfs/rootfs/ *(rw,sync,no_subtree_check,no_root_squash)
****************************
解析:
/home/hqyj/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/hqyj/nfs/rootfs/ /mnt
nfs:使用nfs服务,将本机IP地址:/home/hqyj/nfs/rootfs/
文件挂载到/mnt目录下
3》检查/mnt目录下是否挂载成功
cd /mnt
ls
4》卸载挂载的文件
sudo umount /mnt
注意:不可以在/mnt目录下执行卸载的命令
2.u-boot的移植
1.bootloader概念
boot : 引导
loader: 加载
bootloader:用于引导加载内核的程序的一种统称。
2.u-boot和bootloader区别 ?
bootloader:是一系列引导启动程序的统称。
u-boot:属于bootloader中的一种引导程序。
vivi redboot u-boot bios都属于bootloader
在实际开发中大多数使用的是u-boot。
3.u-boot的特点?引导内核启动
1. u-boot是开源的软件
2. u-boot支持多种架构和硬件平台
ARM X86 Mips PowerPC ...
3. u-boot源码短小精悍。
4. u-boot就是一个裸机程序。
5. u-boot是一个短命鬼,
主要作用就是引导内核启动,
内核一旦启动成功,u-boot的使命结束。
6. u-boot启动时完成部分硬件的初始化
内存,flash,串口,时钟系统,电源系统...
7. u-boot用于引导linux内核启动,
并且给内核传递参数。
4.u-boot支持的命令 <重点>
1. help
查看u-boot支持的所有的命令
help u-boot命令 : 查看某个命令的帮助手册
2. loadb 下载应用程序
3. go 运行应用程序
4. printenv/print/pri : 打印u-boot的环境变量
baudrate=115200 # 串口波特率
board_name=FS6818 # 板子名字
bootargs=root=/dev/nfs nfsroot=192.168.2.200:/home/hqyj/nfs/rootfs tcp,v4 rw console=/dev/ttySAC0,115200 init=/linuxrc ip=192.168.2.100
bootcmd=loadb 43c00000;go 43c00000
bootdelay=50 # 引导的倒计时时间
gatewayip=192.168.2.1 # 开发板网关
ipaddr=192.168.2.100 # 开发板IP地址
netmask=255.255.255.0 # 开发板的子网掩码
serverip=192.168.2.200 # ubuntu的IP地址
stderr=serial # 标准出错
stdin=serial # 标准输入
stdout=serial # 标准输出
5. 设置环境变量
setenv : 设置环境变量 增加/删除/修改
设置环境变量时,默认修改的是内存中的值
saveenv :保存环境变量
保存环境变量从内存到flash中
1> 增加一个新的环境变量:
setenv 新的环境变量名 环境变量的值
eg:
setenv target fs6818
saveenv
setenv target name fs6818
环境变量的名字之间不允许出现空格
2> 修改环境变量的值
setenv 旧的环境变量名 新的环境变量值
saveenv
eg:
setenv bootdelay 10
注: 不可以将倒计时时间设置为0
saveenv
3> 删除环境变量
setenv 要删除的环境变量名
eg:
setenv target
saveenv
练习以上命令:
1. 设置开发板的环境变量:
gatewayip ipaddr netmask serverip
网段跟自己的ubuntu系统一致,
IP地址,每个人保证唯一性。
6. tftpboot/tftp命令 <后边练习>
使用tftp服务,从ubuntu的tftpboot目录下,
下载文件到开发板中。
前提:
1> ubuntu必须安装好tftp服务
2> u-boot支持tftp的客户端
3> u-boot阶段必须完成网卡的初始化
tftpboot [loadAddress] [bootfilename] :
下载bootfilename文件到内存的loadAddress地址中
7. ping命令 <后边练习>
pingu-boot是否可以和ubuntu的服务器通信
ping pingAddress
8. md 命令
md address
回显内存地址中的值。
9. nm 命令
nm address
设置内存地址中的值。
5.ping和tftp命令的练习
[准备]
1. ubuntu必须安装tftp服务
2. 关闭windows和ubuntu的防火墙
3. 设置windows的网卡为百兆全双工
控制面板-》网络和Internet-》网络和共享中心-》
更改适配器设置-》以太网(USB转网卡)-》属性-》
配置-》高级-》Speed & Duplex -》100M full Duplex
[配置ubuntu的网络地址]:配置ubuntu为固定的IP地址
[配置开发板的网络地址]
gatewayip # 开发板网关
ipaddr # 开发板IP地址
netmask # 开发板的子网掩码
serverip # ubuntu的IP地址
setenv gatewayip 192.168.1.1
setenv ipaddr 192.168.1.250
setenv netmask 255.255.255.0
setenv serverip 192.168.1.222
saveenv
[使用ping命令测试开发板是否可以ping通ubuntu]
FS6818# ping 192.168.1.222 # 在串口工具上执行
打印以下信息表示可以开发板可以ping通ubuntu
dwmac.c0060000 Waiting for PHY auto negotiation to complete.... done
Speed: 100, full duplex
Using dwmac.c0060000 device
host 192.168.1.222 is alive
总结卡发板无法ping通ubuntu的原因。
1> windows和ubuntu防火墙灭有关闭
2> ubuntu系统和开发板的网络的配置,是否在同一个网段
3> 检查网线
[使用tftp命令下载interface.bin文件到内存中]
1. 拷贝interface.bin到tftpboot
2. 使用tftp命令进行下载
FS6818# tftp 43c00000 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: #
1.1 MiB/s
done
Bytes transferred = 9076 (2374 hex)
总结: tftp下载不成功的原因
1》 ping不通的原因
2》 tftp服务安装成功,需要重启tftp服务
3》 tftp服务安装不成功,重新安装tftp服务
4》 tftp安装成功,检查/etc/default/tftpd-hpa
环境变量修改是否正确,如果修改环境变量,
必须重启tftp服务
5》关闭windows和ubuntu的防火墙
(ubuntu的防火墙默认都是关闭的)
sudo ufw disable
3. 运行应用程序
6.开发板系统的部署方式
ubootpak.bin : u-boot的镜像文件
uImage :linux内核的镜像文件
rootfs :根文件系统
ramdisk.img : 根文件系统的镜像,通过rootfs打包压缩生成ramdisk.img
[1. 开发阶段的系统部署]
ubootpak.bin : EMMC/SD
uImage : tftp服务下载程序到内存中
rootfs : nfs服务挂载根文件系统
[2. 产品阶段的系统的部署]
ubootpak.bin : EMMC/SD
uImage : EMMC/SD
ramdisk.img : EMMC/SD
7.开发阶段的系统部署步骤
1> 启动开发板,进入uboot的交互模式
2> 拷贝uImage内核镜像文件到ubuntu的tftpboot目录下
3> 使用tftp命令下载uImage内核镜像到内存中
tftp 0x48000000 uImage
4> 设置uboot环境变量中的bootargs环境变量<重要>
setenv bootargs root=/dev/nfs nfsroot=192.168.1.222:/home/hqyj/nfs/rootfs tcp,v4 rw console=/dev/ttySAC0,115200 init=/linuxrc ip=192.168.1.250
saveenv
bootargs环境变量的作用:
自启动的参数,内核启动成功之后,需要从uboot的环境变量的分区读取bootargs
环境变量对应的值。
root=/dev/nfs : 使用网络文件系统
nfsroot=192.168.1.222:/home/hqyj/nfs/rootfs :网络文件系统的服务器的地址和路径
tcp,v4 : tcp v4版本
rw : 可读可写的权限
console=/dev/ttySAC0,115200 : 串口
init=/linuxrc : 挂载跟文件系统成功之后,运行的1号进程
ip=192.168.1.250 : 开发版的IP地址
只需要设置1次
5> 启动内核,内核启动成功之后会自动挂载根文件系统
bootm 0x48000000 # 引导启动内核的命令
# 注: 不可以是用go命令
6> 观察现象,并进行应用程序测试
可以写一个hello world的应用程序在开发板上进行测试,
注:需要使用交叉编译工具链进行编译。
7> 以上启动方式属于交互的方式,
设置系统为自启动的方式。
设置uboot中的bootcmd环境变量,
bootcmd的作用?
自启动的环境变量,uboot启动之后,
倒计时减到0之前,不按任意键,默认会自动执行
bootcmd环境变量中的所有的命令会被依次执行。
bootcmd的格式:
setenv bootcmd uboot命令1\;uboot命令2\;.....
setenv bootcmd tftp 48000000 uImage\; bootm 48000000
saveenv
如果进入到uboot的交互模式可以执行boot命令,
bootcmd环境变量中的命令也会被依次执行。
8.移植u-boot源码
1. 准备u-boot源码
1) 拷贝u-boot源码到ubuntu中
u-boot-2014.07-netok.tar.bz2
2) 解压缩
tar -vxf u-boot-2014.07-netok.tar.bz2
3) 进入到u-boot源码目录
cd u-boot-2014.07
注:u-boot源码不要再共享目录或者windows下解压
2. 分析u-boot源码的目录结构
平台相关代码:跟硬件有关的代码
平台相关代码,所有的硬件都有自己的一套代码
arch : 架构
board : 板子
平台无关代码:跟硬件无关的代码,
平台无关代码,所有的硬件都共用一套代码
common : uboot命令
drivers : 驱动
fs : 文件系统
include : 头文件
lib : 库
net : 网络
tools : 工具
.....
3. 配置编译u-boot源码
配置:让u-boot源码支持s5p6818芯片
编译: 有选择性的编译uboot源码,生成ubootpak.bin
1> 配置交叉编译工具链
240 ifeq ($(HOSTARCH),$(ARCH))
241 CROSS_COMPILE ?=
242 endif
修改为:
198 ifeq (arm,arm)
199 CROSS_COMPILE ?= arm-none-linux-gnueabi-
200 endif
2> make help 获取对uboot源码make编译时的信息
清除中间文件
make clean
make distclean
编译uboot源码生成uboot的可执行文件
make/make all
3> 读README
254 For all supported boards there are ready-to-use default
255 configurations available; just type "make <board_name>_config".
256
257 Example: For a TQM823L module type:
258
259 cd u-boot
260 make TQM823L_config
4> 配置uboot源码支持fs6818开发板
make fs6818_config
注: 一旦执行了make distclean,需要重新执行
make fs6818_config 命令
make fs6818_config命令只需要在最开始的时候执行一次。
5> 编译uboot源码
make -j4 all
最终就可以生成ubootpak.bin
生成windows版本的ubootpak.bin
dd if=/dev/zero of=512B bs=512 count=1
chmod 777 512B
cat 512B ubootpak.bin > win_ubootpak.bin
6> 测试新生成的uboot镜像是否可以使用
烧写ubootpak.bin到EMMC中
可以使用开发阶段系统部署的方式启动一下系统。
- loadb命令的移植
自己移植的uboot支持大多数的uboot命令,但不支持uboot命令
1. 使用grep命令搜索loadb
grep "loadb" * -nR
搜索结果如下:
common/cmd_load.c:389: * loadb command (load binary) included
common/cmd_load.c:1059: loadb, 3, 0, do_load_serial_bin,
2. 打开common目录下的Makefile文件
133 obj-y += cmd_load.o
说明cmd_load.o文件被编译到ubootpak.bin
all:${obj-y}
3. CONFIG_CMD_LOADB宏没有定义
在板子的头文件中添加宏定义
find . -name fs6818.h
打开:vi include/configs/fs6818.h
添加以下内容
121 #define CONFIG_CMD_LOADB
4. 重新编译uboot源码,进行测试。