龙芯1C300B开发板Linux系统移植启动调试记录

基础知识学习记录

开发板照片如下:
龙芯1C300B开发板
开发板上有GD25B128CP1G型号的NOR Flash(应该是16M),对于龙芯开发板来说,系统的pmon引导程序就存放在里面;

编译pmon的编译器是mips-elf-gcc

目前,大多数嵌入式交叉编译工具都基于glibc和Linux内核构建的ARCH-linux-(ARCH可以是ppc,mips或mips64)形式的交叉编译器。这种交叉编译器主要针对运行Linux操作系统的机器,它依赖于指定的C语言库glibc,且需要有MMU的支持,使得这种编译器编译出来的目标文件占用较大空间。本文构建的交叉编译工具链采用ARCH-elf-。其特点是:

  1. 灵活性强,ARCH-elf-*是一个独立的编译体系,不依赖于指定的C语言库glibc,可以使用newlib等其他C语言库,不需要操作系统的支持,可移植到很多CPU结构上。
  2. 支持基于UCLinux的操作系统,且不需要MMU支持,编译出来的目标文件占空间相对要少。
  3. 速度比ARCH-linux-*要快。

龙芯1C300B采用的是MIPS指令集架构
MIPS是最早的,最成功的RISC(Reduced Instruction Set Computer)处理器之一
MIPS架构的机顶盒提供了六种交叉编译工具GCC,如下:
· mipsel-linux-gcc
· mipsel-linux-uclibc-gcc
· mipsel-uclibc-gcc
· mips-linux-gcc
· mips-linux-uclibc-gcc
· mips-uclibc-gcc

首先,mips和mipsel的主要区别在于Big Endian(大端)和Little Endian(小端)结构。

  • mips对应的是Big Endian;
  • mipsel对应的是Little Endian。

其次,要明白uclibc库。
uclibc库是面向嵌入式Linux系统开发优化的C语言库。比GNU C Library更小,但接口兼容,且更易于配置。

uclibc可运行于标准的以及无MMU的Linux系统之上,支持i386、x86、x64、ARM、AVR32、Blackfin、H8300、M68K、MIPS、PowerPC、SuperH、SPARC和V850等处理器下列。
mips-uclibc-gcc表示采用uclibc库进行编译的GCC。

GCC是一套由GNU开发的编译器集,为什么是编辑器集而不是编译器呢?那是因为它不仅支持C语言编译,还支持C++, Ada, Objective C等许多语言,不仅支持X86处理器架构, 还支持ARM, Motorola 68000, Motorola 8800, Atmel AVR, MIPS等处理器架构

GCC内部结构主要由Binutils、gcc-core、Glibc等软件包组成。

  1. Binutils:它是一组开发工具,包括连接器,汇编器和其他用于目标文件和档案的工具。【这个软件包依赖于不同的目标机的平台。因为不同目标机的指令集是不一样的,比如arm跟x86就不一样】
  2. gcc-core:顾明之意是GCC的核心部分,这部分是只包含c的编译器及公共部分,而对其他语言【C++、Ada等】的支持包需要另外安装,这也是GCC为何如此强大的重要原因。【它依赖于Binutils,可以参考安装GCC】
  3. Glibc:包含了主要的c库,这个库提供了基本的例程,用于分配内存,搜索目录,读写文件,字符串处理等等。【这个包GCC编译生成的库,前辈们为了方便大家开发,就把Glibc放到GCC中】
#include <stdio.h>

int main(int argc, char *argv[])
{
	printf("Hello Linux!!\n");
	return 0;
}

对于上述代码:
gcc编译流程分为四个步骤:预处理、编译、汇编、链接。个人认为预处理和编译主要由gcc-core来完成,汇编和链接主要由Binutils来完成。那么何时用到glibc呢?看到源码中的printf函数没有,这个函数在GCC中是以库函数的形式存在,这个库函数在glibc库中,在stdio.h头文件中被声明。

arm-elf-gcc跟arm-linux-gcc一样,也是是基于ARM目标机的交叉编译软件。但是它们不是同一个交叉编译软件,两者是有区别的,两者区别主要在于使用不同的C库文件。arm-linux-gcc使用GNU的Glibc,而arm-elf-gcc一般使用 uClibc/uC-libc或者使用REDHAT专门为嵌入式系统的开发的C库newlib。Glibc是针对PC开发的,uClibc/uC-libc是与Glibc API兼容的小型化C语言库,实现了Glibc部分功能。

开始准备工作

文章许多内容参考来自孙冬梅老师和石南老师编著的《嵌入式Linux系统设计及应用》(书中存在的一些小错误和一些小坑已经在下面的内容记录中修正了,可对照学习),相关资料和代码可以从书中找到,另外还可以从龙芯开源社区中下载:

https://www.loongnix.cn

在此声明,本文章以记录为主,其中有不足或者有错误的地方欢迎留言交流 如有错误,望大神轻点喷

搭建tftp服务器环境:

安装tftp功能包

apt-get install xinetd
apt-get install tftp-hpa
apt-get install tftpd-hpa

建立传输目录

mkdir /tftproot

获取权限

chmod 777 /tftpboot

修改配置文件

vi /etc/default/tftpd-hpa3

修改内容为:

#/etc/default/tftpd-hpa
TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/tftproot"
TFTP_ADDRESS="0.0.0.0:69"
TFTP_OPTIONS="-l -c -s"

重启 tftp 使配置生效

service tftpd-hpa restart

交叉编译环境配置:

下载并解压缩交叉编译工具:

tar zxvf gcc-4.3-ls232.tar.gz -C /opt

在root用户下执行

vi ~/.bashrc

在其末尾添加语句:

export PATH=/opt/gcc-4.3-ls232/bin:$PATH

安装完成后,可在任何目录下执行 mipsel-linux-gcc –v
终端执行界面显示
如果提示 No such file or directory ,使用 which 命令可以找到,环境变量没有问题。原因是计算机上安装的是 64 位的操作系统,但是交叉工具链是 32 位的,出现兼容问题,安装32 位共享库之后,能解决绝大部分兼容性问题。which 及库安装命令如下:
终端界面显示

sudo apt-get install libstdc++6:i386
sudo apt-get install lib32z1

然后安装编译pmon所需要的工具

apt-get install bison
apt-get install flex
apt-get install xutils-dev

PMON编译

方法一:百度网盘中资料

从淘宝上找到客服问他们要百度网盘资料,我手中大部分资料来源于此
使用网盘下载的V2版本资料,经过试验完全启动不起来,不知道问题出在哪里,可能是本人技术有限,最终以失败告终;

方法二:Github资料

https://github.com/lshw/loongson1-pmon

下载后解压缩,运行build_ls1b_dev.sh ,在zloader.ls1c文件夹中生成龙芯1B的gzrom.bin
然后从网上购买CH341A编译下载器,将板载NOR Flash芯片拆下后安装到编译器上,方向如下图所示:
下载器照片

然后打开编译器配套上位机,先配置好储存芯片型号等,然后先点击擦除,再点击查空,一切没有问题以后,再导入groom.bin文件,然后点击编程;

注:为了稳妥起见,建议每次刷写的时候都重新打开软件

烧录器配套软件界面
然后重新安装NOR Flash到开发板上后上电启动,按空格键进入pmon命令行配置界面,否则就会直接寻找内核和加载文件系统启动;

注:智龙开发板有三块储存区域,GD25B128CP1G型号的NOR Flash,K9F1G08UOC型号的NAND Flash和K4S511632D型号的SDRAM,在pmon中要有关于NAND Flash区域的配置,在/Workstation/tools/loongson1-pmon-master/Targets/LS1X/dev目录下的ls1x_nand.c文件中有:
ls1x_nand.c文件描述
对于宏定义MTDPARTS,在/Workstation/tools/loongson1-pmon-master/Targets/LS1X/conf目录下的ls1c文件中有定义:
在这里插入图片描述

使用广州源码包调试:

pmon包编译:loongson1-pmon-lshw.zip --> loongson1-pmon-master

sudo unzip loongson1-pmon-lshw.zip

1:修改/Workstation/tools/loongson1-pmon-master/Targets/LS1X/dev下ls1x_nand.c
内春相关代码
进入如下目录

cd /Workstation/tools/pmon/pmon-ls1x-openloongson/tools/pmoncfg

直接编译

make

然后将pmoncfg可执行文件复制到交叉编译工具链的 bin 目录下

cp pmoncfg /opt/gcc-4.3-ls232/bin

进入目录
目录
方法一:

cd /Workstation/tools/pmon/pmon-ls1x-openloongson/zloader.ls1c.openloongson
make cfg all tgt=rom CROSS_COMPILE=mipsel-linux-

就会生成gzrom.bin文件;
目录
方法二:
切换root用户:在终端输入su然后运行build_openloogson.sh脚本,注意需要联网!

./build_openloogson.sh

然后就会生成pmon_openloongson.bin
目录

linux内核编译:openloongsonV3.tar.gz --> linux-3.0.101

解压缩文件:

tar zxvf linux-3.0.101.tar.gz

启动图形化配置界面

make ARCH=mips CROSS_COMPILE=mipsel-linux- menuconfig

源码中已经全部配置好,这里不需要进行任何改动,直接保存退出
进入到/Workstation/tools/linux-3.0.101/arch/mips/loongson1/ls1c文件下ls1c300b_cbiiv0a_board.c
修改nand分区内容如下:要和pmon中的分区保持一致,否则系统启动不了!
内存相关代码
保存好后回到linux根目录,编译

make ARCH=mips CROSS_COMPILE=mipsel-linux-

生成内核镜像文件 vmlinux(未压缩)和 vmlinuz(压缩后)

根文件系统编译:

1:配置编译BusyBox

拷贝源码并解压

tar jxvf busybox1.23.0.tar.bz2
cd busybox-1.23.0

运行图形化配置命令

make menuconfig

配置选项简述,其他按默认配置:
Busybox Settings —>
Build Options —>(以下为二选一)

[ * ] Build BusyBox as a static binary (no shared libs)(静态编译)
[ * ] Build shared libbusybox(动态编译)

指定交叉编译器,交叉编译器的绝对路径前缀
(/opt/gcc-4.3-ls232/bin/mipsel-linux-) Cross Compiler prefix
Busybox Library Tuning —>

[ * ] vi-style line editing commands
[ * ] Username completion(文件系统识别 PS1,以命令行提示符)
[ * ] Fancy shell prompts

Miscellaneous Utilities —>

[ ] ubiattach
[ ] ubidetach
[ ] ubimkvol
[ ] ubirmvol
[ ]ubirsvol
[ ] ubiupdatevol
[ ] ionice

配置完后编译

make clean all
make CONFIG_PREFIX=/Workstation/tools/makefs/rootfs/ install
2:创建文件系统目录
cd /Workstation/tools/makefs/rootfs/
mkdir dev home proc tmp var etc lib mnt sys opt root etc/init.d var/log
3:创建系统配置文件

1:etc/inittab 文件

cd /Workstation/tools/makefs/rootfs/
vi etc/inittab

添加内容如下:

::sysinit:/etc/init.d/rc.sysinit //指定系统启动后首先执行的文件 
ttyS2::respawn:-/bin/sh //串口终端,串口号 ttyS2 要与启动参数一致
#tty1::respawn:-/bin/sh //用于开发板屏幕终端显示
#Stuff to do when restarting the init process
#::restart:/sbin/init
#Stuff to do before rebooting 
::ctrlaltdel:/sbin/reboot //按 Ctrl+Alt+Delete 组合键,重启文件系统 
::shutdown:/bin/umount -a –r //当关机时卸载所有文件系统
#::shutdown:/sbin/swapoff –a //保存退出

2:etc/init.d/rc.sysinit 文件

vi etc/init.d/rc.sysinit

添加如下内容:

#!/bin/sh
#Set binary path
export PATH=/bin:/sbin:/usr/bin:/usr/sbin
#Config dev enviornment
mount -t tmpfs -o size=64k,mode=0755 tmpfs /dev
mkdir -p /dev/pts //为 telnetd 创建 pts 目录
mount -t devpts devpts /dev/pts //挂载 pts 目录
#Build console and serial device files
echo "#Build console and serial device files....."
mknod -m 600 /dev/console c 5 1 //建立设备文件
mknod -m 600 /dev/ttyS2 c 4 66 //建立设备文件
#mount all filesystem defined in "/etc/fstab"
echo "#mount all....."
/bin/mount -a
echo "#Starting mdev....."
echo /sbin/mdev > /proc/sys/kernel/hotplug //设置热插拔事件处理程序为 mdev
/sbin/mdev -s //设备节点维护程序 mdev 初始化
#Set ip
ifconfig eth0 123.123.123.110 up
ifconfig lo 127.0.0.1

3:etc/fstab 文件

vi etc/fstab

添加如下内容:

#device mount-point typeoptions dump fsck order
proc /proc proc defaults 0 0
tmpfs /tmp tmpfs defaults 0 0
sysfs /sys sysfs defaults 0 0
tmpfs /dev mdev defaults 0 0

4:etc/profile 文件

vi etc/profile

添加如下内容:

#!/bin/sh
#/etc/profile:system-wide .profile file for the Bourne shells
echo "Processing /etc/profile....."
#set search library path
export LD_LIBRARY_PATH=/lib:/usr/lib
#set user path
export PATH=/bin:/sbin:/usr/bin:/usr/sbin
#Set PS1 modify command prompt
export PS1='[\u@\h:\w]\$'
#Set hostname
/bin/hostname "Loongson"
HOSTNAM=/bin/hostname
export PS1 HOSTNAME
#Set ll aliae
alias ll="ls -l"
echo "Done!"

修改文件权限:

chmod 755 /Workstation/tools/makefs/rootfs/etc/*
chmod 755 /Workstation/tools/makefs/rootfs/etc/init.d/rc.sysinit

然后制作mdev.configresolv.configgrouppasswd和文件夹hotplug
文件复制过程
这些文件内容教程没有给,我是直接从源码中复制出来的;

4:复制库文件:

交叉编译工具的加载器在目录/opt/gcc-4.3-ls232/sysroot/lib/中:librt.so.1、ld.so.1、libc.so.6、libcrypt.so.1、libm.so.6、libdl.so.2、libpthread.so.0、libresolv.so.2。
动态库文件在目录/opt/gcc-4.3-ls232/mipsel-linux/lib/中:libgcc_s.so.1、libstdc++.so.6。
将以上文件复制到根文件系统下的 lib 目录。
使用脚本快速复制所需的基本动态库

vi cplib.sh

添加内容如下:

#!/bin/bash
#copy mipsel-linux lib
libdir=/opt/gcc-4.3-ls232
fsdir=/Workstation/tools/makefs/rootfs/lib
cp -L $libdir/sysroot/lib/librt.so.1 $fsdir
cp -L $libdir/sysroot/lib/ld.so.1 $fsdir
cp -L $libdir/sysroot/lib/libc.so.6 $fsdir
cp -L $libdir/sysroot/lib/libcrypt.so.1 $fsdir
cp -L $libdir/sysroot/lib/libm.so.6 $fsdir
cp -L $libdir/sysroot/lib/libdl.so.2 $fsdir
cp -L $libdir/sysroot/lib/libpthread.so.0 $fsdir
cp -L $libdir/sysroot/lib/libresolv.so.2 $fsdir
cp -L $libdir/mipsel-linux/lib/libgcc_s.so.1 $fsdir
cp -L $libdir/mipsel-linux/lib/libstdc++.so.6 $fsdir

然后添加权限,并运行脚本:

chmod +x cplib.sh
./cplib.sh

为了减少根文件系统的库大小,使用交叉编译工具即 mipsel-linux-strip 的 strip 工具来处
理库文件,把二进制文件中包含的符号表和调试信息删除掉,可有效减少库文件大小。

mipsel-linux-strip rootfs/lib/*so* 
5:制作根文件系统镜像

安装镜像文件制作工具,将如下文件拷贝到Linux系统中:
拷贝目录

1:安装依赖工具 zlib:

tar zxvf 1.zlib-1.2.8.tar.gz
cd zlib-1.2.8
./configure
make
make install

2:安装制作 cramfs 文件系统镜像文件工具 mkcramfs

tar zxvf 2.cramfs-1.1.tar.gz
cd cramfs-1.1
make

在当前目录下生成 mkcramfs,将其复制到/usr/bin 目录下

cp mkcramfs /usr/bin

3:安装制作 yaffs2 文件系统镜像文件工具 mkyaffs2image

tarzxvf 3.yaffs2-d43e901.tar.gz
cd yaffs2-d43e901/utils
make

在当前目录下生成 mkyaffs2image,将其复制到/usr/bin 目录下

cp mkyaffs2image /usr/bin

4:安装依赖工具 lzo

tar zxvf 4.lzo-2.09.tar.gz
cd lzo-2.09
./configure --build= i686-linux-gnu --prefix=/Workstation/tools/makefs/install
make
make install

5:安装依赖工具 e2fsprogs(也可以用 apt-get installe2fsprogs 安装)

tar zxvf 5.e2fsprogs-1.42.13.tar.gz
cd e2fsprogs-1.42.13
./configure --build= i686-linux-gnu --prefix=/Workstation/tools/makefs/install
make
make install
cd lib/uuid
make install

6:安装 ubifs 文件系统镜像文件制作工具
方法 1:用命令安装 ubifs 文件系统镜像文件制作工具 mkfs.ubifs 和 ubinize:

apt-get install mtd-utils

方法 2:用安装包来安装 ubifs 文件系统镜像文件制作工具:

tar jxvf 6.mtd-utils-1.5.2.tar.bz2
cd mtd-utils-1.5.2

修改 Makefile

vi Makefile

在版本说明“VERSION = 1.5.2”一行后面添加

PREFIX = /Workstation/tools/makefs/install/mtd
DEPEND = /Workstation/tools/makefs/install
ZLIBCPPFLAGS = -I/usr/local/include
ZLIBLDFLAGS = -L/usr/local/lib
LZOCPPFLAGS = -I$(DEPEND)/include
LZOLDFLAGS = -L$(DEPEND)/lib
LDFLAGS += $(ZLIBLDFLAGS) $(LZOLDFLAGS)
CFLAGS ?= -O2 -g $(ZLIBCPPFLAGS) $(LZOCPPFLAGS)

修改 common.mk

vi common.mk

找到并注释掉“PREFIX=/usr”一行
编译安装:

WITHOUT_XATTR=1 make
make install

此处报错:
error1:
报错日志,错误1error2:
报错日志,错误2
解决办法:
分别安装库:
(1)sudo apt-get install liblzo2-dev
(2)sudo apt-get install uuid-dev
将在安装目录 install/mtd/sbin 下生成的可执行文件 mkfs.ubifs 和 ubinize 复制到/usr/bin目录下

cp install/mtd/sbin/mkfs.ubifs /usr/bin
cp install/mtd/sbin/ubinize /usr/bin

7:制作镜像文件
文件系统有好几类:
7.1 cramfs 文件系统

mkcramfs rootfs/ rootfs-cramfs.img
chmod +r rootfs-cramfs.img

7.2 yaffs2 文件系统

mkyaffs2image rootfs/ rootfs-yaffs2.img
chmod +r rootfs-yaffs2.img

7.3 ubifs 文件系统

mkfs.ubifs -r rootfs -m 2048 -e 129024 -c 370 -o ubifs.img

通过此命令制作出的 UBIFS 文件系统镜像可在 u-boot 下使用“ubiwrite”命令烧写到NANDFlash 上
新建配置文件 ubinize.cfg,添加内容如下:

[ubifs]
mode=ubi
image=ubifs.img
vol_id=0
vol_size=45MiB
vol_type=dynamic
vol_alignment=1
vol_name=rootfs
vol_flags=autoresize
ubinize -o ubi.img-m 2048 -p 128KiB-s 2048 -O 2048 ubinize.cfg

通过此命令生成的ubi.img 可直接使用 NANDFlash 的烧写命令烧写到 Flash 上

linux系统启动:

将编译生成的gzrom.binvmlinuzrootfs-yaffs2.img放到 /tftproot 文件夹中
将pmon下载到NOR Flash中后启动进入pmon界面
通过set ifconfig syn0 123.123.123.110配置开发板IP
然后先ping 123.123.123.123测试一下与ubuntu主机是否能通,确认无误后输入如下命令

mtd_erase /dev/mtd0 //擦除数据
mtd_erase /dev/mtd1 //擦除 nand 的第 2 个分区数据
mtd_erase /dev/mtd2 //擦除 nand 的第 3 个分区数据
devcp tftp://123.123.123.123/gzrom.bin /dev/mtd0 //下载pmon到 nand 的第 0 个分区
devcp tftp://123.123.123.123/vmlinuz /dev/mtd1 //下载内核到 nand 的第 1 个分区
set al /dev/mtd1 //设置启动参数,自动从 nandflash 的 mtd1 分区 load 内存,设置在一上电时自动执行 load 内核到内存操作
devcp tftp://123.123.123.123/rootfs-yaffs2.img /dev/mtd2 yaf nw //烧写根文件系统到 nand 的第 3 个分区
set append " root=/dev/mtdblock2" //根目录位置,块设备
set append " $append console=ttyS2,115200" //设置串口 2,115200 波特率
set append " $append noinitrd init=/linuxrc rw rootfstype=yaffs2" //没有使用ramdisk;设置内核启动起

来后进入系统中运行的第一个脚本;指明文件系统类型为 yaffs2

reboot //重启系统

执行过程如下图所示:
命令记录
然后就可以正常进入系统了

调试失败案例:
使用网上GitHub上下载的最新pmon和linux内核,pmon软件包生成的.bin文件烧录到开发板中能正常启动,但是linux内核编译时会报错
目录
内核编译报错:
Cannot use CONFIG_CC_STACKPROTECTOR_STRONG: -fstack-protector-strong not supported by compiler
日志记录
网上说这是内核防止堆栈溢出的布丁
使用命令行scripts/config --disable CC_STACKPROTECTOR_STRONG
虽然能继续编译了,但是错误还在,而且最后还是会报错,新的错误是:
日志记录
一头雾水后决定放弃,网上说还有可能是编译器版本的问题,在GitHub上没有看到关于最新版pmon和内核所使用的gcc和g++编译器的版本,故也知道该使用何种版本,立即推,放弃!
该问题已解决:
猜测可能是gcc编译器版本选错了,在编译pmon时候,运行./build_openloogson.sh时会安装3.4.6-2f版本的gcc
如果使用广东刘工的源码,不改nand.c的情况下,启动开发板不会进入linux系统
日志记录
修改pmon-ls1x-openloongson/Targets/LS1X/dev/ls1x_nand.c文件中

#if defined(LS1CSOC)
add_mtd_device(ls1x_mtd, 0, 1024*1024, "bootloader");
add_mtd_device(ls1x_mtd, 1024*1024, 13*1024*1024, "kernel");
add_mtd_device(ls1x_mtd, 14*1024*1024, 50*1024*1024, "rootfs");
add_mtd_device(ls1x_mtd, (50+14)*1024*1024, 64*1024*1024, "data");

重新编译后如下:
日志记录
广州刘工编译后正常能进入linux的代码NAND分区如下:

日志记录
在pmon模式下配置tftp环境:

ifconfig syn0 123.123.123.110

日志记录
至此有关龙芯1C300B开发板Linux系统移植启动调试记录的内容就全部结束了,前前后后也是花了不少时间才完成了,只能说对于国产开发板的道路还是有很长一些路要走,生态和配套资料都无形中增加了入门的难度,但是还是希望想学习的小伙伴们能坚持下,也许我的一点经验就能帮到后面开发的人,与君共勉!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值