[正点原子]Linux驱动学习笔记--0.基本环境准备

作者 by adtxl / 2022-10-22 / 暂无评论 / 67 个足迹

1. 代码准备

为了使用、学习方便,在github上新建了两个仓库,将正点原子提供的linux和uboot code放到了上面。
https://github.com/ADTXL/imx_uboot
https://github.com/ADTXL/imx_linux

2. uboot编译

编译命令如下

// 安装ncurses库
sudo apt-get install libncurses5-dev

// 512MB+8GB 的 EMMC 核心板
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- distclean
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- mx6ull_alientek_emmc_defconfig
make V=0  ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j16

或者直接运行正点原子提供的脚本

./mx6ull_alientek_emmc.sh

编译完成后如下所示:

image.png

其中,u-boot.bin就是编译出来的uboot二进制文件。uboot是个裸机程序,因此需要在其前面加上头部(IVT、DCD等数据)才能在I.MX6U上执行。
u-boot.imx文件就是添加头部以后的u-boot.bin,u-boot.imx就是我们最终要烧写到开发板中的uboot镜像文件。

3. linux编译

直接运行脚本

./mx6ull_alientek_emmc.sh

编译完成后,有两个以后烧写需要用到的文件,即kernel image(arch/arm/boot)和dtb(arch/arm/boot/dts目录)文件.

4. 烧写image

4.1 使用tftp烧写

uboot是支持网络的,在使用uboot的网络功能之前先用网线将开发板的的ENET2接口(ALPHA开发板靠近vga线的那个)和电脑或者路由器连接起来。

然后设置下面几个环境变量

环境变量 描述
ipaddr 开发板ip地址,可以不设置,使用dhcp命令来从路由器获取ip地址
ethaddr 开发板的mac地址,一定要设置
gatewayip 网关地址
netmask 子网掩码
serverip 服务器ip地址,也就是ubuntu主机地址,用于调试代码

我的开发板是直连windows的,没有使用路由器,使用了这个博客里的方法超全详细,解决校园网没有路由器实现开发板和虚拟机直连,亲测可用.

setenv ipaddr 192.168.10.101
setenv ethaddr 00:04:9f:04:d2:35
setenv gatewayip 192.168.10.1
setenv netmask 255.255.255.0
setenv serverip 192.168.10.100
saveenv

使用ping命令测试下,是ok的

=> ping 192.168.10.100
Using FEC1 device
host 192.168.10.100 is alive

tftp使用tftp协议,将ubuntu主机作为tftp服务器,通过网络把镜像烧写到dram中。因此,需要在ubuntu上搭建TFTP服务器,需要安装tftp-hpa和tftpd-hpa,命令如下:

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

然后,需要创建一个目录存放镜像文件/home/user/linux/tftpboot,需要注意,需要给此目录读写权限,否则的话uboot不能从tftpboot文件夹里下载文件。

最后配置 tftp,安装完成以后新建文件/etc/xinetd.d/tftp,如果没有/etc/xinetd.d 目录的话自行创建,然后在里面输入如下内容:

server tftp
{
        socket_type = dgram
        protocol = udp 
        wait = yes 
        user = root
        server = /usr/sbin/in.tftpd
        server_args = -s /home/user/linux/tftpboot 9
        disable = no
        per_source = 11
        cps = 100 2
        flags = IPv4
}

完了以后启动 tftp 服务,命令如下:
sudo service tftpd-hpa start
打开/etc/default/tftpd-hpa 文件,将其修改为如下所示内容:

# /etc/default/tftpd-hpa

TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/home/user/linux/tftpboot"
TFTP_ADDRESS="0.0.0.0:69"
TFTP_OPTIONS="-l -c -s"

最后输入如下命令, 重启 tftp 服务器:
sudo service tftpd-hpa restart

最后,我们测试下能否烧写成功,tftp命令格式如下
tftpboot [loadAddress] [[hostIPaddr:]bootfilename]
例如下面的命令,我们通过tftp命令把kernel镜像Image文件,烧写到dram中的80800000地址。

=> tftp 80800000 Image
Using FEC1 device
TFTP from server 192.168.10.100; our IP address is 192.168.10.101
Filename 'Image'.
Load address: 0x80800000
Loading: #################################################################
     #################################################################
     #################################################################
     #################################################################
     #################################################################
     #################################################################
     #################################################################
     #################################################################
     #################################################################
     #################################################################
     #################################################################
     #######################################################
     2.2 MiB/s
done
Bytes transferred = 11302188 (ac752c hex)

除了tftp,还有其他的烧写方法,这里就先不研究了~

5. 搭建NFS环境

NFS(Network File System),网络文件系统,是由SUN公司研制的UNIX表示层协议,能使使用者访问网络上别处的文件就像在使用自己的计算机一样。我们可以使用NFS加载文件系统到开发板上,方便开发。

5.1 配置NFS服务

  • 安装NFS服务

在 Ubuntu 终端执行以下指令安装 NFS。
sudo apt-get install nfs-kernel-server

  • NFS共享目录

新建NFS共享目录,并给予rwx权限,本地新建目录为/home/user/linux/nfs

  • 配置NFS服务

执行以下指令打开 etc/exports 文件
sudo vi /etc/exports
进入 etc/exports 文件,在最后添加如下内容
/home/user/linux/nfs *(rw,sync,no_root_squash)
/home/user/linux/nfs 表示 NFS 共享的目录
*表示允许所有的网络段访问
rw 表示访问者具有可读写权限
sync 表示将缓存写入设备中,可以说是同步缓存的意思
no_root_squash 表示访问者具有 root 权限。

修改完如下图所示。

# /etc/exports: the access control list for filesystems which may be exported
#               to NFS clients.  See exports(5).
#
# Example for NFSv2 and NFSv3:
# /srv/homes       hostname1(rw,sync,no_subtree_check) hostname2(ro,sync,no_subtree_check)
#
# Example for NFSv4:
# /srv/nfs4        gss/krb5i(rw,sync,fsid=0,crossmnt,no_subtree_check)
# /srv/nfs4/homes  gss/krb5i(rw,sync,no_subtree_check)
#

/home/user/linux/nfs *(rw,sync,no_root_squash)

修改完以后保存退出。
执行以下指令重启 NFS 服务器。

sudo /etc/init.d/nfs-kernel-server restart

执行以下指令查看 NFS 共享目录。

showmount -e,如下所示

user@ubuntu:~/linux/nfs$ showmount -e
Export list for ubuntu:
/home/user/linux/nfs *

5.2 开发板测试

确保网络环境正常,Ubuntu、Windows 和开发板能相互 ping 通。
这里结合 4.1 小节的配置来验证,即:

setenv ipaddr 192.168.10.101
setenv ethaddr 00:04:9f:04:d2:35
setenv gatewayip 192.168.10.1
setenv netmask 255.255.255.0
setenv serverip 192.168.10.100
saveenv

开发板 IP:192.168.10.101
windows 有线IP: 192.168.10.99
虚拟机 IP:192.168.10.100

开发板开机后,需要手动设置ip,

ifconfig eth0 up
ifconfig eth0 192.168.10.101
ifconfig
root@ATK-IMX6U:~# ifconfig
eth0      Link encap:Ethernet  HWaddr 88:36:fd:16:f1:cc  
          inet addr:192.168.10.101  Bcast:192.168.10.255  Mask:255.255.255.0
          inet6 addr: fe80::8a36:fdff:fe16:f1cc/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:152 errors:0 dropped:0 overruns:0 frame:0
          TX packets:56 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:12135 (11.8 KiB)  TX bytes:15504 (15.1 KiB)

eth1      Link encap:Ethernet  HWaddr 88:af:c1:a1:1c:7d  
          UP BROADCAST MULTICAST DYNAMIC  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:158 errors:0 dropped:0 overruns:0 frame:0
          TX packets:158 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:10652 (10.4 KiB)  TX bytes:10652 (10.4 KiB)

在/home/user/linux/nfs 目录下创建一个 mytest.c 文件,在里面写入 hello world!

执行以下指令设置开发板 IP,创建一个 get 目录,将虚拟机(192.168.10.100)NFS 共享目
录挂载到到开发板的 get 目录中。

mkdir get
mount -t nfs -o nolock,nfsvers=3 192.168.10.100:/home/user/linux/nfs get/

使用df命令查看挂载的 NFS 目录:

root@ATK-IMX6U:~/get# df
Filesystem                          1K-blocks     Used Available Use% Mounted on
/dev/root                             7342568   645076   6301460  10% /
devtmpfs                               187632      120    187512   1% /dev
tmpfs                                      40        0        40   0% /mnt/.psplash
tmpfs                                  253432      192    253240   1% /run
tmpfs                                  253432      144    253288   1% /var/volatile
/dev/mmcblk1p1                          32248     6902     25347  22% /run/media/mmcblk1p1
192.168.10.100:/home/user/linux/nfs 205312000 24284160 170525696  13% /home/root/get

root@ATK-IMX6U:~# mount -t nfs -o nolock,nfsvers=3 192.168.10.100:/home/user/linux/nfs get/
root@ATK-IMX6U:~# cd get/
root@ATK-IMX6U:~/get# ls -al
total 11M
drwxrwxr-x 2 1000 tracing 4.0K Nov 12  2022 .
drwx------ 5 root root    4.0K Jul 21 15:12 ..
-rwxrwxr-x 1 1000 tracing  11M Nov 12  2022 Image
-rw-rw-r-- 1 1000 tracing   13 Nov 12  2022 mytest.c
root@ATK-IMX6U:~/get# cat mytest.c 
hello world!

卸载 NFS 目录:
umount get

root@ATK-IMX6U:~# umount get
root@ATK-IMX6U:~# df
Filesystem     1K-blocks   Used Available Use% Mounted on
/dev/root        7342568 645076   6301460  10% /
devtmpfs          187632    120    187512   1% /dev
tmpfs                 40      0        40   0% /mnt/.psplash
tmpfs             253432    188    253244   1% /run
tmpfs             253432    144    253288   1% /var/volatile
/dev/mmcblk1p1     32248   6902     25347  22% /run/media/mmcblk1p1

可以看到 192.168.10.100:/home/user/linux/nfs 已经卸载了。

6. 使用NFS挂载rootfs

6.1 网络环境准备

如前所述,搭建好tftf和nfs网络环境,

6.2 内核文件准备

将光盘中提供的内核镜像和dtb文件服务到tftp工作目录,并给予rwx权限。

6.3 文件系统准备

在nfs共享目录创建一个rootfs目录用于存放文件系统。
将光盘里的busybox文件系统拷贝、解压缩到上面创建的rootfs文件夹中

6.4 tftp烧写内核、设备树

进入到uboot命令行,设置开发板ip信息

setenv ipaddr 192.168.10.101
setenv ethaddr 00:04:9f:04:d2:35
setenv gatewayip 192.168.10.1
setenv netmask 255.255.255.0
setenv serverip 192.168.10.100
saveenv

可以ping下开发机地址,看能否ping通
image.png

设置环境变量 bootcmd 来烧写 tftp 目录下的内核、设备树文件到开发板内存中,

setenv bootcmd 'tftp 80800000 zImage;tftp 83000000 imx6ull-alientek-emmc.dtb;bootz 80800000 - 83000000'
saveenv

这样每次开机时将自动烧写kernel镜像和dtb。一般没必要每次都重烧,所以上面的命令也可以手动执行

6.5 NFS挂载文件系统

设置环境变量bootargs来挂载nfs目录下的rootfs,

setenv bootargs 'console=ttymxc0,115200 root=/dev/nfs nfsroot=192.168.10.100:/home/user/linux/nfs/rootfs,proto=tcp rw ip=192.168.10.101:192.168.10.100:192.168.10.1:255.255.255.0::eth0:off'
saveenv

imagebab445f0084df749.png

如果使用的时ubuntu18或更高的版本,uboot无法通过nfs启动ubuntu系统内的共享目录。需要在
/etc/default/nfs-kernel-server 文件进行修改,改好了保存退出,然后重启一下 nfs 就可以了,或
者报错 Loading:*ww ERROR:File lookup fail 的也是按照下面的方法来解决。

image99ce3d4cd64c67a7.png

按照上面截图改完后保存退出,再执行以下指令重启 nfs 服务。
sudo service nfs-kernel-server restart

(这里遇到个问题,不知道是不是我上传zIamge的时候有问题,换了个出厂系统自带的zImage才可以)经测试OK,

image86b3129c08b3d3b2.png

独特见解