Linux_transplantation
NOTE_1
———— 系统移植前的准备:交叉编译
Vine Farer
2016. 08. 16
关于移植
为什么要移植Linux?
开源、免费、包括安卓开发,应用广泛
基于计算机系统应用,软硬件可裁剪
移植的主体有哪些?
bootloader
、内核、文件系统最终,我们需要将
bootloader
放在EMMC
中;内核、文件系统都放到ARM
的Flash
内这样每次上电
CPU
先将bootloader
加载到RAM
内运行,再引导内核、文件系统加载到RAM
内运行然而,当前调试我们是通过
nfs
挂载映射,ARM
挂载主机,直接将系统加载到RAM
里运行方便调试bootloader
在内核运行之前执行的一小段引导代码(类似于
PC
中的BIOS
,用于引导Windows
),当内核与文件系统启动后,它的使命结束功能:初始化硬件、引导内核、为内核传参
bootloader
自带包括网卡、串口的设备驱动,方便我们通过这些连接设备直接移植内核、文件系统因此,其移植难度最高,它的移植无法借助网卡、串口等设备;需要半年到一年的学习,此处我们主要学习原理即实现方式
我们用的
uboot
是bootloader
的一种内核
在目前的实验中,我们直接使用一个已经裁剪完毕的内核成品。包括:
uImage
、exynos4412-fs4412.dtb
在主机与裸板之间构建
tftp
传输将
uImage
、exynos4412-fs4412.dtb
拷贝到ubuntu/tftpboot
目录下,在uboot
命令行通过命令执行将内核与设备树加载到soc
的CPU
内的相应地址uImage
是内核(包含驱动),经过裁剪后仅 3M;
exynos4412-fs4412.dtb
是设备树,存放了仍保留在系统中的设备信息。由此我们的驱动代码编写可以屏蔽底层细节,通过总线在设备树中找到对应外设文件系统
同内核一样暂时使用一个文件系统成品
开启
nfs
服务,将文件系统放在共享文件夹/rootfs
下,同样在uboot
终端执行命令在ARM
内启动文件系统将
ARM
的文件系统根目录挂载到主机的/rootfs
,在主机与裸板之间实时共享文件,可以让编译好的a.out
映射到裸板的内存上在ARM
的文件系统下运行
交叉编程是什么?
何谓交叉编程
在主机上编写程序,编译程序,在目标板上运行
为何需要交叉编程
arm
的gcc
编译器高达几十兆,不适合装在arm
的ROM
里我们在
PC
上完成代码的arm
式编译,在通过文件挂载的方式在裸板上运行可执行文件如何实现交叉编程
前文中已提到,通过
tftp
将内核与设备树存到SOC
上Flash
的指定位置通过
nfs
挂载文件系统,实现主机上的程序在内核中运行
移植的相关准备与操作
交叉编译器配置
解压缩
sudo tar xvf gcc-4.6.4.tar.xz
配置环境变量
/etc/profile
当前终端下有效
/etc/environment
系统的配置
/etc/bash.bashrc
推荐使用sudo vi /etc/bash.bashrc
在最后一行加入:
export PATH=$PATH:/home/linux/gcc-4.6.4/bin
立即生效
source /etc/bash.bashrc
测试:
arm-n
tab键
uboot启动
将拨码开关
emmc
,给开发板上电,在倒计时结束之前按任意键。进入到uboot
的命令行uboot
命令:help
:查看uboot
帮助信息md
:显示内存的信息mm
:修改内存的地址,地址自增nm
:修改内存的地址,地址不自增printenv(print)
:打印环境变量
ipaddr
:指定开发板的 ip 地址
serverip
:指定服务器的 ip 地址(ubuntu
)setenv
设置环境变量saveenv
保存环境变量设置开发板的ip地址:
setenv ipaddr 172.24.1.173
设置服务器的ip地址:
setenv serverip 172.24.1.171
保存环境变量信息:
save
测试:
fs4412 # ping 172.24.1.247
打印测试结果
dm9000 i/o: 0x5000000, id: 0x90000a46 DM9000: running in 16 bit mode MAC: 11:22:33:44:55:66 operating at 100M full duplex mode Using dm9000 device host 172.24.1.247 is alive
uboot
启动时,如果没有按任意键,uboot
执行bootcmd
后面的内容
内核启动
将
uImage、exynos4412-fs4412.dtb
拷贝到ubuntu/tftpboot
进入到uboot的命令行:
setenv bootcmd tftp 41000000 uImage \;tftp 42000000 exynos4412-fs4412.dtb \;bootm 41000000 - 42000000
将uImage
加载到内存地址的41000000处,exynos4412-fs4412.dtb
加载到内存的42000000处save
重新给开发板上电(自启动模式)
如果出现 TTTTTTTT,检查网线
确定通过
uboot
命令行ping``ubuntu
服务器的ip地址,看能否ping
通如果不能
ping
通,解决方法:把windows
的wifi
关闭如果还是出现 TTTTTTTTT,重启ubuntu的tftp服务器
sudo /etc/init.d/tftpd-hpa restart
或sudo service tftpd-hpa restart
如果还是出现 TTTTTTTT,检查ubuntu的ip地址是否正确
文件系统启动
bootargs=root=/dev/nfs nfsroot=服务器ip:/source/rootfs rw console=ttySAC2,115200 init=/linuxrc ip=172.23.1.250
bootargs:uboot
为内核传递的启动参数root=/dev/nfs
:指定挂在文件系统的类型nfs
nfsroot=172.23.1.77:/source/rootfs
:指定ubuntu
服务器nfs
的共享目录(vi /etc/exports
);console= ttySAC2,115200
:指定串口终端(ttyS0
:lcd屏)init=/linuxrc
:内核执行后,执行的第一个应用程序 linuxrcip
:uboot
启动之后为内核传递的参数(开发板的ip地址)将
rootfs.tar.xz
拷贝到 /rm -rf /rootfs
sudo tar xvf rootfs.tar.xz
chmod 777 /rootfs
设置两边的通信
ip
地址setenv bootargs root=/dev/nfs nfsroot=ubuntu的ip地址:/rootfs rw console=ttySAC2,115200 init=/linuxrc ip=开发板的ip地址
保存save
重新上电