使用crosstool-ng进行linux系统移植

本文介绍了如何在Fedora 33和CentOS 5环境下,使用crosstool-ng进行Linux系统移植到PowerPC 440平台的过程。内容涉及kermit的安装、串口配置、TFTP服务器设置、crosstool-ng的配置和交叉编译环境搭建,以及在遇到的兼容性问题中如何解决,最终成功在CentOS 5上构建出适用于PowerPC的交叉编译工具链,并完成了u-boot和kernel的移植。

前言

嵌入式开发,特别是针对老旧芯片,老旧开发板的开发工作是十分艰难的,因为现有版本的工具已经很难做到对老旧版本软件,老旧芯片的支持,存在大量的兼容性错误。所以本文旨在探索一条现阶段可行的针对powerpc 440的嵌入式开发方法。希望有看到这篇文章的人能学习到我的失败经验,少走一些弯路。
这篇文章写的挺多,其实更偏向于笔记。主要的原因就是失败了太多次,每次都得重新安装,而安装的时间又太长,只能写写笔记消磨点时间,也为日后重装的时候累积经验。

开始

本次使用的硬件平台为XILINX Virtex-5 ML507开发板,对上面的powerpc440硬核进行开发。
系统为Fedora 33
就后续开发经验来看,这个版本显然太高了,可能造成很多的兼容性问题。
最好在fedora 20以下或者ubuntu 18以下
果然fedora 33上失败了,转到了CentOS5上进行。

编译环境搭建使用crosstool-ng-1.24.0
http://crosstool-ng.org/download/crosstool-ng/

u-boot使用2015.4
https://ftp.denx.de/pub/u-boot/

kermit

kermit是连接串口和网络的通信软件,使用此软件来设置linux主机的串口和与目标的网络通信。
对于fedora 33,可也直接使用

kermit的安装

sudo yum install ckermit

来进行安装。
或者访问
http://www.columbia.edu/kermit/
下载kermit这个软件时,你会发现有两个kermit包。你只需要安装ckermit。其中gkermit仅仅是实现kermit传输协议的一个命令行工具。
如果是手动下载的话,解压后输入make linux进行安装,成功后会生成一个wermit。
按照官网的意思wermit是用来测试的,运行正常即可改名为kermit放到/usr/bin里

进行串口配置

CH340串口驱动

https://blog.csdn.net/bingyu9875/article/details/80651778

不知道什么原因,linux串口驱动无法安装。
fedora 33好像是kernel太新目录结构改了,导致驱动无法编译。不过新版本的linux自带驱动了。
CentOS 5感觉像是编译器版本不对,编译.c大面积报错。

但是CentOS最起码能识别到usb,但是fedora好像一点反应都没有

暂时用win上的串口显示吧

kermit串口配置

主要看看这个
https://blog.csdn.net/u013029731/article/details/88877350

在这里插入图片描述
u-boot的ml507板的设置。
波特率9600。

kermit在执行其它命令之前,会执行你的用户目录下的初始文件.kermrc,所以可以非常简单的通过初始化命令来定制kermit。
~/.kermrc:
set line /dev/ttyS0
set speed 9600
set carrier-watch off
set handshake none
set flow-control none
robust
set file type bin
set file name lit
set rec pack 1000
set send pack 1000
set window 5
这个设置假定你使用的是主机第一个串口(/dev/ttyS0),以115200这个波特率与目标板的串口连接。
然后你可以连接目标板了:
$ kermit -c
Connecting to /dev/ttyS0, speed 115200.
The escape character is Ctrl-/ (ASCII 28, FS)
Type the escape character followed by C to get back,
or followed by ? to see other options.

配置TFTP服务器

使用U-Boot下载Linux内核或者应用程序的最快捷的方法是通过网络传输。为了这一目的,U-Boot实现了TFTP协议(参见U-Boot中的tftpboot命令)。为了使主机支持TFTP,你必须确保TFTP后台程序/usr/sbin/in.tftpd已经安装。

在RedHat系统中,你可以运行下面的命令来确认:
$ rpm -q tftp-server
如果没有安装,请从你的Linux安装盘或者其它媒介安装。

在fedora 33中,也可以直接使用yum来安装

$ sudo yum install tftp-server

大多数的Linux发行版都默认关闭TFTP服务。以RedHat系统为例,如果要使能TFTP服务,编辑文件/etc/xinetd.d/tftp,移除这一行:
disable = yes
或者注释掉它,或者修改disable = no
此外,确保/tftpboot目录存在,而且有访问权限(至少应该"dr-xr-xr-x")。

对于新版的linux,比方说我用到的fedora 33,使用指令即可开启服务

$ sudo systemctl start tftp
$ sudo systemctl enable tftp

$ sudo firewall-cmd --permanent --add-service tftp
$ sudo firewall-cmd --reload

使用crosstool-ng搭建交叉编译环境

crosstool-ng,全称是crosstool Next Generation,即下一代crosstool。

对于CentOS 5的配置

因为centos5已经停更,原来的yum源已经失效,需要更改yum源来使用yum。

gedit /etc/yum.repos.d/CentOS-Base.repo

将以下内容替换原来的内容

#
# If the mirrorlist= does not work for you, as a fall back you can try the
# remarked out baseurl= line instead.
#
#

[base]
name=CentOS-$releasever - Base
#mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=os
#baseurl=http://mirror.centos.org/centos/$releasever/os/$basearch/
baseurl=http://vault.centos.org/5.11/os/$basearch/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-5

#released updates
[updates]
name=CentOS-$releasever - Updates
#mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=updates
#baseurl=http://mirror.centos.org/centos/$releasever/updates/$basearch/
baseurl=http://vault.centos.org/5.11/updates/$basearch/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-5

#additional packages that may be useful
[extras]
name=CentOS-$releasever - Extras
#mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=extras
#baseurl=http://mirror.centos.org/centos/$releasever/extras/$basearch/
baseurl=http://vault.centos.org/5.11/extras/$basearch/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-5

#additional packages that extend functionality of existing packages
[centosplus]
name=CentOS-$releasever - Plus
#mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=centosplus
#baseurl=http://mirror.centos.org/centos/$releasever/centosplus/$basearch/
baseurl=http://vault.centos.org/5.11/centosplus/$basearch/
gpgcheck=1
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-5

#contrib - packages by Centos Users
[contrib]
name=CentOS-$releasever - Contrib
#mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=contrib
#baseurl=http://mirror.centos.org/centos/$releasever/contrib/$basearch/
baseurl=http://vault.centos.org/5.11/contrib/$basearch/
gpgcheck=1
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-5

再执行yum clean all来清除原来的缓存。

安装crosstool-ng

对于powerpc-440和ML507这种老旧的U和板不要安装太新的版本,否则兼容性会有问题。
1.24.0已经证明不可用了。

wget http://crosstool-ng.org/download/crosstool-ng/crosstool-ng-1.22.0.tar.xz

或者在官网下载
http://crosstool-ng.org/download/crosstool-ng/

注意centos5最好使用crosstool1.20及以下版本

解压

tar xvf crosstool-ng-1.22.0.tar.xz
cd xvf crosstool-ng-1.22.0

编译安装

./configure --prefix=
make
make install

中间可能报错缺少工具,缺什么安什么。下面是一些必须的软件:

sudo yum install gperf bison flex texinfo help2man gawk automake libtool glibc-devel glibc-staticyy
sudo yum -y install patch ncurses-devel

使用新系统安装老软件报错:
错误信息:error: could not find bash >= 3.1

首先确定你本机上安装的版本确实达到了要求。

修改crosstool-ng目录下的configure和configure.ac

找到行|$EGREP ‘^GNU bash, version (3.[1-9]|4)’)

改成:|$EGREP ‘^GNU bash, version ([0-9.]+)’)

centos5 automake也可能出错,只要确定安装后按上面类似修改即可。

在这里插入图片描述1.22版本特有的bug,根据报错提示可以看到kconfig文件夹下zconf.has.c文件里kcon_id_lookup这个函数定义上下冲突了,估计是作者写代码上下忘了。
把下面的size_t len改成和上面一样的unsigned int。

添加全局变量

gedit ~/.bashrc
export PATH=/home/mark/crosstool/ct-build/bin:$PATH
source ~/.bashrc

使用

ct-ng help

测试是否安装成功

设置编译交叉编译链选项

使用ct-ng list-samples命令查看具有哪些默认配置。
在这里插入图片描述
选择

ct-ng powerpc-405-linux-gnu

进行设置

ct-ng menuconfig

在这里插入图片描述

目录最好都设置一下
在这里插入图片描述主要注意在此把405改成440

在这里插入图片描述这里可以设置一个名称方便以后调用。

对于2015.04 ML507的u-boot,交叉编译gcc版本不能太高否则后面编译u-boot会出错!!!
1.24.0的8和5的gcc我已经试过都不行,
所以交叉编译gcc版本最好选择低于4.8.5。
此时就需要把crosstool-ng降到1.22版本以下。

*** gcc other options *** 

[ ] Optimize gcc libs for size
[ ] Link libstdc++ statically into the gcc binar
把下面这个关了,否则要报错

[ERROR] >> Build failed in step ‘Checking that gcc can statically link libstdc++ (CT_CC_GCC_STATIC_LIBSTDCXX)’

这个错

其他设置可以看看这个:
https://blog.csdn.net/cztqwan/article/details/79428341
https://blog.csdn.net/lisemi/article/details/91045791

感谢以下的参考
https://stackoverflow.com/questions/23937266/cant-compile-statically-programs
https://blog.csdn.net/hqjma/article/details/8885050
http://blog.sina.com.cn/s/blog_bf7859030102x02v.html
https://github.com/pfalcon/esp-open-sdk/issues/365

设置完成退出保存即可。

安装低版本gcc

此章对于高版本linux安装低版本gcc有效,但是到gcc4.2.4就出现别的错误,暂未解决。最下面给出了一个解决方法,但我没试过。
所以对于安装gcc-4.2.4来说参考价值不大,建议自己研究一下或者直接换个Linux吧。

其实最简单的方法还是再装一个低版本的linux,省了不少麻烦。

参考
https://blog.csdn.net/weixin_36023181/article/details/108292273
https://blog.csdn.net/agave7/article/details/88865757

下载gcc-4.8.5

wget http://ftp.tsukuba.wide.ad.jp/software/gcc/releases/gcc-4.8.5/gcc-4.8.5.tar.bz2

或者把crosstool-ng下的拿过来
这时候还不能直接编译,因为当前版本gcc过高,编译低版本会报错

修改要编译的低版本gcc代码,参考链接:

https://gcc.gnu.org/git/?p=gcc.git;a=commitdiff;h=ec1cc0263f156f70693a62cf17b254a0029f4852

需要修改四个文件
目录为gcc-4.8.5/gcc/cp
按照参考链接进行修改即可,行最前面是 + 的代表要加进代码里的内容,行最前面是 - 的代表要从代码里减去的,对应的行数可能会稍有不同,仔细查看即可发现。

链接:https://pan.baidu.com/s/1gmixd5wOb192joy11-YneQ
提取码:1pqz
这个是我改好的

我忽然有个想法,如果把这四个文件替换成交叉编译解压出来的gcc里是不是就可以编译了,只需编译处交叉编译的gcc,后面的库都是用交叉编译gcc来编译的嘛。这样省去编译一遍gcc再连接再重新编译的麻烦。

如果你没在上面的设置里修改过目录和路径的话,crosstool-ng的默认中间文件夹为.build的隐藏目录。在这个中间目录下的src里有解压好的,把上面四个文件替换进gcc-4.8.5对应位置。
注意不要在menuconfig里选强制解压,否则会把上面的更改覆盖。
在这里插入图片描述成功了!那上面的猜想确实可以实现。
然而4.8.5的gcc仍然不能编译u-boot。。
在研究了u-boot内ppc4xx的链接脚本后,了解到这个脚本编写的时间大概是08年左右,找到对应的gcc大概是4.2版本。

经过测试发现这种方法无法用来高版本编译4.2.4版本的gcc,还是会报错。
可以参考一下这个,但是我没试过。
https://unix.stackexchange.com/questions/219708/arch-compiling-toplev-o-fails-in-gcc-install

编译交叉工具链

ct-ng build

开始编译

开始build后有一些软件可能crosstool内部链接失效了,下不下来会报错。可以先手动下载或者wget到指定的src文件里。

最好下载bz2格式,xz有概率出错

出现有些问题无法解决的时候,尝试换一下glibc、kernel的版本再安装,说不定就解决了

部分下载地址:
https://mirrors.edge.kernel.org/pub/linux/kernel/
https://ftp.gnu.org/gnu/glibc/

编译前确保有gcc和c++的编译环境

这里的gcc和c++的编译器版本最好和交叉编译的gcc对应,或者不要差的太远,否则后面编译的时候会出错

对于高版本的linux,如果要编译低版本的gcc不要使用下面的指令!!因为直接yum安装的是高版本的,编译低版本的会报错!

sudo yum install gcc gcc-c++

在这里插入图片描述
这就是高编低的错误之一。

编译完成后工具就在指定或者默认的目录下

添加环境变量并测试

第一次的8.5.0
在这里插入图片描述这个版本u-boot不能用

重新安装4.8.5后
在这里插入图片描述这个版本仍然不行

在这里插入图片描述
gcc 4.2.4版本,cent os 5环境。

U-boot的安装(使用crosstool-ng)

u-boot的作用是启动硬件后引导linux。

相关参考
https://blog.csdn.net/weixin_42015463/article/details/82055013
https://blog.csdn.net/wangweijundeqq/article/details/79127800

这一次为了确保成功,换了一个新的版本,
u-boot-2015.04,有目标板ml507的支持

使用gcc-8.3.0安装(失败)

最开始的8.3.0的后面编译u-boot的话就不行了。
无法安装u-boot,gcc版本和u-boot不符,目前知道4.8.5及以上版本都不行。

在这里插入图片描述

使用gcc-4.8.5安装(失败)

make distclean
make ml507_config
make ARCH=powerpc CROSS_COMPILE=powerpc-linux-g4ct122- all

在安装crosstool里使用了别名,生成了同名的软连接,所以使用的是 powerpc-linux-g4ct122-。
在这里插入图片描述
这个错误好像是链接脚本相关的问题。
_GLOBAL_OFFSET_TABLE_未在链接器生成的.got里定义。
查了一下目录里的链接脚本,看时间好像是2009年freescale写的,可能我的gcc又太新了,对于曾经的写法不支持了。
仔细看报错的内容,链接脚本里.got没定义
查了一下资料
https://blog.csdn.net/da895/article/details/6147761
浏览了include/ppc_asm.tmpl和arch/powerpc/cpu/ppc4xx/start.S,没有找到.got定义的块,只找到了.got2定义的块。
在这里插入图片描述https://www.cnblogs.com/li-hao/p/4107964.html
在这篇文章里,讲到了PROVIDE的用处:
在这里插入图片描述
感觉相当于链接脚本提供了一个参数。
但是为什么会出错呢?
因为错误没有生成uboot这个文件,导致现在也无法看代码分析了。
估计还是gcc版本问题,导致有些关键字用法改变了、
现在唯一能做的就只能再降低gcc版本了。
这次选择了crosstool-ng-1.22支持最低的gcc版本4.2.4,大概是08年左右发布的,如果再不行就得降低crosstool-ng的版本了。
修改上面四个文件后还是会报错,本来想看源码改改的,但是看了感觉单个好像没有问题,可能是调用的文件和这个文件重定义了吧,只能先装个低版本的gcc了。
换低版本的gcc也很麻烦,刚好我手头上有一个CentOS5,gcc版本为4.1接下来转到那里进行。

使用gcc-4.2.4安装(CentOS 5)

make distclean
make ml507_config
make menuconfig
make ARCH=powerpc CROSS_COMPILE=powerpc-linux-g42ct120- all

在这里插入图片描述
终于成功了!!!
但是这最后的warning看不太懂什么意思。
是版权到期了吗?
一会上板试试。

U-boot的调试

开始前先了解一下U-boot编译好的文件

编译好后,u-boot文件夹下出现了两个文件u-boot和u-boot.bin
这两者的差别,可以看看这个文章
http://t.zoukankan.com/jiangzhaowei-p-4368474.html

对于我这块xilinx的板,有专门的调试助手xmd,可以直接下载.elf文件,所以我先试试.elf能否使用,在考虑把bin烧进flash里。
对于怎么使用xmd,以后我会专门写一篇文章。

下载并运行,先用win端的串口助手。

新建一个ISE工程,把需要用到的IP添加进去。

在这里插入图片描述
参考u-boot根目录下board里对应板子的设置,再检查一下这个地址和实际工程的地址和核心频率和PLB总线频率是不是一样的,不一样的话可以改一下这个但是得重新编译u-boot。

经过测试发现这里的波特率为最高支持波特率.

测试暂时不能用,因为ISE的bit流生成出了问题,一直报错。
问了相关大佬后总结的笔记
https://blog.csdn.net/EinsamMark/article/details/116068742

14.7ISE好像不能生成带ddr2的bitstream,可以单独使用xps生成,过程类似。

注意生成的uart有两个,地址不一样,注意u-boot里uart地址得对应,要不串口没输出。

在这里插入图片描述
从这也看出上面那个warning是什么意思了,原来是ppc的东西从2014开始已经不更新了。
在这里插入图片描述部分指令,可以看出u-boot是可以运行的。

u-boot暂时交给另一个同学,稍后再更,我先编译一下kernel。

移植kernel

kernel的编译

因为有之前调试官方例程的linux的经验,这次的kernel版本选择在2.6左右,为2.6.38
https://mirrors.edge.kernel.org/pub/linux/kernel/v2.6/

下载解压

首先修改makefile

ARCH		?= powerpc
CROSS_COMPILE	?= powerpc-linux-g42ct120-

修改这两个地方,交叉编译按你制作工具链的时候编译。

在kernel目录下arch/xxx/configs/下找到对应的开发板,这样可以免去配置编译的烦恼。

然后用对应的defconfig替换kernel目录下的.config

本例为

cp arch/powerpc/configs/ppc44x_defconfig .config

或者用make ppc44x_defconfig,然后检查目录下是否生成了一个.config文件

然后执行

make menuconfig

因为我们之前已经把对应板的设置拷贝到.config了,这时我们不用设置,直接保存退出就行了。

当然也可以看看下面这篇文章自己定制一些功能

https://blog.csdn.net/zhenguo26/article/details/79641322

最后就是编译内核了

编译前把uboot/tools的目录加入环境变量里,要不无法生成uimage。

make -uImage

因为目标是嵌入式开发板,空间有限,所以使用了压缩格式的zImage

文件系统

根文件系统的建立

https://blog.csdn.net/xie0812/article/details/11366137

这篇文章介绍的很详细了。
我再讲讲要注意的点
linux的核心思想就是一切都是文件,所以没有根文件系统只有kernel是无法启动的,所以这个还是得做。
再然后就是上面的包括网上很多的都是采用的nfs的形式,需要网线连接,所以我考虑做一个板上的。

制作jffs2格式的根文件系统

制作板上的得有合适的文件系统

https://blog.csdn.net/jasper_JA/article/details/104168893
https://blog.csdn.net/yobwoc/article/details/4470281

将上面制作好的rootfs转换为jffs2格式的image
安装工具

https://blog.csdn.net/flyingnosky/article/details/104038040

先安装lzo,否则后面报错

http://www.oberhumer.com/opensource/lzo/

安装mtd-utils
https://infraroot.at/pub/mtd/

高版本的用低版本gcc会报错
我选择的是1.4.2版本,解压进入目录直接make make install
然后
在制作的根目录上一级执行:

mkfs.jffs2 -s 0x1000 -e 0x20000 -p 0x1800000 -b -d rootfs/ -o rootfs.jffs2

就能生成jffs2的根文件系统

使用官方镜像,根文件系统块内存空间4028使用,mkfs.jffs2 -s 0xFBC -e 0x20000 -p 0x1800000 -b -d rootfs/ -o rootfs.jffs2

重新编译

修改各参数,使得其更符合实际的要求。

重新编译u-boot

主要修改地址,能保存到flash里,分别是环境变量的存储地址和u-boot代码的地址。
分别在include/config里面和make menuconfig里。
在这里插入图片描述环境变量
在这里插入图片描述
flash区域,0xD8000000到0xD8200000区域为u-boot代码,0xD8200000后面为u-boot环境变量,kernel保险起见起始地址分配为0xD8500000。

kernel的重新编译

对于kernel主要是增加对jffs2文件系统的支持。
在这里插入图片描述在图上这个地方设置。
使用make zImage

因为改变了kernel,不知道对文件系统有没有影响,对文件系统的make modules我也重新生成了一下,也就是说重新生成了一下文件系统。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值