开发板使用步骤
交叉编译器
一、固化系统
参考用户快速体验,也可参考“开发板与pc传输文件、单步更新固件xxxx”。
可以只更新uboot、zImage、设备树或根文件系统中的一个,即单步更新。其实单步更新的原理就是改变emmc中的uboot、zImage等,因为Linux系统启动后就可以操作emmc了,就可以把最新的uboot、设备树这些放到emmc中对应的位置,然后重启即可(从emmc启动Linux内核)。详见3.单步更新。
1. 使用mfgtool上位机固化系统(OTG方式)
所需材料:
把->开发板光盘->5、开发工具->4、正点原子 MFG_TOOL 出厂固件烧录工具->mfgtool 文件夹拷贝到 PC 机(电脑),启动方式选为USB启动。
1.1 固化到SD卡
-
准备一张TF卡
-
选择对应的vbs脚本
-
设置为从SD卡启动系统
1.2 固化到eMMC
通过mfgtool将uboot、zImga、dtb固化到eMMC后,通过emmc方式启动可以观察这些文件在emmc中的位置,如下:
mmc的分区0存放的是uboot,分区1是zimage和设备树,分区2是根文件系统,这些都是通过mfgtoo烧录进去的。mmc分区2的根文件系统可以通过``ext4ls mmc 1:2`进行查看,因为其是ext4类型的文件系统,如下:
ext4ls mmc 1:2 dir
可查看mmc1的分区2的dir文件夹下的内容:
1.2.1 续
上面说明了通过mfgtool将固件烧录到emmc后的一些情况,比如mmc1的part0是存放的uboot。在后面讲Linux内核启动方式的时候和这里有关,所以就先说明一下,加强记忆。启动方式有sd卡、emmc/nand、网络启动,相关的uboot环境变量和命令有bootargs、bootcmd、run。
bootargs环境变量中的console值指定所使用的终端,一般为console=ttymxc0,115200
,root值指定根文件系统所在位置,该值根据不同需求需设置不同的值,如下:
# 通过nfs挂载根文件系统,就需要告诉内核。即root设置如下值
root=/dev/nfs nfsroot=169.254.30.41:/home/cdj/Linux/nfs/rootfs,proto=tcp rw ip=169.254.30.42:169.254.30.41:169.254.1.1:255.255.0.0::eth0:off
# 告诉Linux内核根文件系统在emmc1的分区2,即使用mmc中的根文件系统
root=/dev/mmcblkp2 rootwait rw
# boot命令通过读取bootcmd环境变量的值进行启动Linux内核,boot delay倒计时结束后也会从bootcmd启动Linux内核。
setenv bootcmd 'tftp 80800000 zImage;tftp 83000000 imx6ull_alientek_emmc.dtb;bootz 80800000 - 83000000'
# run命令可以运行用户自己设置的环境变量
# 1.设置用于从mmc启动的环境变量的命令,镜像和设备树的名称可根据fatls mmc 1:1 查看。mmc 1:2 保存的是根文件系统
setenv mybootmmc 'fatload mmc 1:1 80800000 zimage;fatload mmc 1:1 83000000 imx6ull-14x14-emmc-4.3-800x480-c.dtb;bootz 80800000 - 83000000'
# 2.设置用于从网络启动的环境变量的命令
setenv mybootnet 'tftp 80800000 zImage;tftp 83000000 imx6ull_alientek_emmc.dtb;bootz 80800000 - 83000000'
saveenv
# 通过上面的设定,boot和run mybootnet的效果是一样的(都是从网络启动),run mybootmmc是从mmc启动。
2. 使用脚本固化系统
省略
3. 单步更新
3.1 单步更新uboot到emmc
- 将最新的uboot拷贝到开发板的/home/root中去
- 使用命令
echo 0 > /sys/block/mmcblk1boot0/force_ro
使能emmc启动分区,这样才能烧写。 - 使用命令开始烧写
dd if=u-boot-imx6ull-14x14-ddr512-emmc.imx of=mmcblk1boot0 bs=1024 seek=1 conv=fsync
。 - 烧写完后,关闭烧写的启动分区,即
echo 1 >/sys/block/mmcblk1boot0/force_ro
3.2 单步更新设备树到emmc中
-
用
ls /run/media/mmcblk1p1
查看mmc1的分区1有那些设备树 -
将对应的设备树拷贝到/run/media/mmcblk1p1 目录下,也可以把全部设备树拷贝。
3.3 单步更新内核到emmc
- 同更新设备树一样,直接将zImage拷贝到/run/media/mmcblk1p1 目录下即可。
- 将内核模块拷贝到开发板,然后解压到/lib/modules目录下即可,即
tar xf modules.tar.bz2 -C /lib/modules/
。
3.4 单步更新根文件系统到emmc
**注意:**不能用 eMMC 启动来更新 eMMC 分区里的文件系统,应要使用 SD 卡启动(即根文件系统在SD卡中,启动时直接从SD卡搬移到SRAM中去)来更新 eMMC的文件系统!正在运行的一个系统不能把自己给格式化。还需要注意的是内核模块是在 eMMC 的第二个分区(rootfs 分区)里的,更新文件系统时会把这个分区里的东西全部删除,请更新文件系统后,重新更新内核模块。
- 拷贝根文件系统到开发板,如/home/root下。
- 删除emmc的第二个分区(rootfs分区),即
rm -rf /run/media/mmcblk1p2/*
。 - 解压根文件系统到emmc的文件系统分区,即
tar vxf fsl-image-qt5-v1.3.tar.bz2 -C /run/media/mmcblk1p2/
,然后sync一下。
单步更新到SD卡道理一样,就是将上面的东西复制到SD卡相应的区域
二、USB WIFI 测试
所需材料:E:\Embedded\Alpha Linux\阿尔法Linux开发板光盘资料(A盘)\9、测试文件\shell\wifi\alientek_usb_wifi_setup.sh
source命令通常用于重新执行刚修改的初始化文件,使之立即生效,而不必注销并重新登录。
ping -I 192.168.1.126 www.baidu.com。-I 是指定执行 ping 操作的网卡 IP 地址,我们要使用 wlan0 去 ping 百度网站,因此要通过 “-I”指定 wlan0 的 IP 地址。
1. Station(上网)模式
即usbwifi作为station,连接其它热点。
-
插入usb wif
-
wpa_cli -i wlan0 scan_result
或iwlist wlan0 scan
扫描周围的热点 -
source ./alientek_usb_wifi_setup.sh -m station -i 'vivo Y93' -p CDJxxxxx -d wlan0
:用wlan0(即usbwifi)这个设备连接vivo Y93这个热点。参数解释: -m station :设置成 station 模式 -i vivo Y93 :无线网络名称(ssid) -p CDJ**** :无线网络密码(psk) -d wlan0 :USB WIFI 节点
若未能正常获取 ip,等待
RTL871X: set group key camid:5
这句话出现后输入udhcpc -i wlan0
指令重新获取 ip。
2. SoftAP(热点)模式
即usbwifi开启热点,供其它设备连接,如手机。
source ./alientek_usb_wifi_setup.sh -m softap -d wlan0
3. Bridge(桥接)模式
测试 USB WIFI 开启热点,并桥接到有线网络,让手机连接到热点并上网。
- 开发板的网口插上网线,并保证能上网。
- 用 ifconfig 查看有线网络 eth0 或者 eth1 能否获取 ip,并测试 eth0 是否能上网。
source ./alientek_usb_wifi_setup.sh -m bridge -d wlan0 -e eth0
3. uboot相关环境变量
1. 自启动时间-bootdelay
setenv bootdelay 10 # 设置uboot自启动延时时间
saveenv
2. 启动Linux内核的参数-bootargs
bootargs 保存着传递给Linux kernel 的参数。如果Linux内核启动时,没有指定根文件系统,那么启动会失败。
启动时通过nfs挂载Ubuntu中的根文件系统,启动后可以再挂载一个文系统,命令如下:mount -t nfs -o nfsvers=3 169.254.30.41:/home/cdj/Linux/nfs/rootfs ./nfs_mnt
setenv bootargs 'console=ttymxc0,115200 root=/dev/mmcblk1p2 rootwait rw'
saveenv
bootargs变量的console值表示所用的终端,root值代表根文件系统在哪里(上面表示的是根文件系统在emmc的块1分区2)。
根据上面的格式 bootargs 环境变量的 root 值(告诉Linux内核根文件系统在Ubuntu主机中,即用nfs挂载根文件系统)如下:参见
root=/dev/nfs nfsroot=169.254.30.41:/home/cdj/Linux/nfs/rootfs,proto=tcp rw ip=169.254.30.42:169.254.30.41:169.254.1.1:255.255.0.0::eth0:off # 告诉内核根文件系统用nfs挂载,位置是xxx处的Ubuntu主机
root=/dev/mmcblkp2 rootwait rw # 告诉内核根文件系统在mmc1的分区2
“proto=tcp”表示使用 TCP 协议,“rw”表示 nfs 挂载的根文件系统为可读可写。启动开发板,进入 uboot 命令行模式,然后重新设置 bootargs 环境变量,命令如下:
setenv bootargs 'console=ttymxc0,115200 root=/dev/nfs nfsroot=169.254.30.41:/home/cdj/Linux/nfs/rootfs,proto=tcp rw ip=169.254.30.42:169.254.30.41:169.254.1.1:255.255.0.0::eth0:off' //设置 bootargs
saveenv //保存环境变量
设置好以后使用“boot”命令启动 Linux 内核。
3. 网络操作
3.1 设置开发板ip
setenv ipaddr 169.254.30.42
setenv ethaddr 00:04:9f:04:d2:35
setenv gatewayip 169.254.1.1
setenv netmask 255.255.0.0
setenv serverip 169.254.30.41 # Ubuntu主机ip
saveenv
3.2 nfs命令
我们一般使用 uboot 中的 nfs 命令将 Ubuntu 中的文件下载到开发板的 DRAM 中,在使用 之前需要开启 Ubuntu 主机的 NFS 服务,并且要新建一个 NFS 使用的目录,以后所有要通过 NFS 访问的文件都需要放到这个 NFS 目录中。
nfs [loadAddress] [[hostIPaddr:]bootfilename]
loadAddress 是要保存的 DRAM 地址,[[hostIPaddr:]bootfilename]是要下载的文件地址。
nfs 80800000 192.168.1.250:/home/zuozhongkai/linux/nfs/zImage
这 里我们将正点原子官方编译出来的 Linux 镜像文件 zImage 下载到开发板 DRAM 的 0x80800000 这个地址处。
3.3 tftp命令
先搭建好、配置好tftp服务器(即Ubuntu)。tftp 命令 不需要输入文件在 Ubuntu 中的完整路径,只需要输入文件名即可,如tftp 80800000 zImage
(也是下载到开发板的DRAM中去,而不是EMMC)。
3.3 scp拷贝命令
参考:开发板与pc传输文件、单步更新固件参考手册V1.0.pdf
开发板通过网线与Ubuntu直连或在同一路由器下,配置好ip后,使用命令:
scp ubuntu中的文件 开发板用户名@开发板ip:拷贝到那去
scp file1 root@169.254.30.42:/home/root
# 如:
scp CReadme.md root@169.254.30.42:/home/root
4. 启动Linux内核命令
4.1 bootz
bootz [addr [initrd[:size]] [fdt]] 命令 bootz 有三个参数,addr 是 Linux 镜像文件在 DRAM 中的位置,initrd 是 initrd 文件在 DRAM 中的地址,如果不使用 initrd 的话使用‘-’代替即可,fdt 就是设备树文件在 DRAM 中 的地址。
tftp 80800000 zImage
tftp 83000000 imx6ull-alientek-emmc.dtb
bootz 80800000 – 83000000
4.1 boot
boot 命令也是用来启动 Linux 系统的,只是 boot 会读取环境变量 bootcmd 来启动 Linux 系统,bootcmd 是一个很重要的环境变量!
4.1.1 比如我们想使用tftp命令从网络启动Linux
setenv bootcmd 'tftp 80800000 zImage; tftp 83000000 imx6ull-alientek-emmc.dtb; bootz 80800000 - 83000000'
saveenv
boot
4.1.2 想从emmc启动
setenv bootcmd 'fatload mmc 1:1 80800000 zImage;fatload mmc 1:1 83000000 imx6ull_alientek_emmc.dtb;bootz 80800000 - 83000000'
savenev
boot
5. uboot中的run命令
run 命令用于运行环境变量中定义的命令,比如可以通过“run bootcmd”来运行 bootcmd 中的启动命令,但是 run 命令最大的作用在于运行我们自定义的环境变量。因为bootcmd只能用一次,如果我既想通过网络启动,又想通过emmc启动的话就需要对bootcmd重新赋值。但是通过run命令,就能不用重新赋值。
# 设置mybootnet环境变量用于从网络启动
setenv mybootnet 'tftp 80800000 zImage;tftp 83000000 imx6ull_alientek_emmc.dtb;bootz 80800000 - 83000000'
# 设置mybootmmc环境变量用于从emmc启动
setenv mybootmmc 'fatload mmc 1:1 80800000 zImage;fatload mmc 1:1 83000000 imx6ull_alientek_emmc.dtb;bootz 80800000 - 83000000'
saveenv
run mybootnet
rum mybootmmc
三、uboot移植
四、Linux内核移植
五、根文件系统构建
六、模块驱动
Linux三巨头移植好后,开发板就能启动了,然后就是驱动的开发编写了。
驱动有两种被加载的方式:一是编译进内核(Linux内核启动时驱动模块也会被启动)、二是编译成模块,动态加载进内核。下面重点讲编译成模块,动态加载进内核。
-
编写驱动程序(设备树、platform、等)
-
编译成ko文件
-
把ko文件放到/lib/modules/‘uname -r’下去
uname -r
代表Linux的版本,我的是4.1.15。uname参考 -
depmod,modprobe xxx
注意,加载模块时不要写后缀名,不然会报“找不到文件的错误”。
-
使用驱动。
下面以正点原子提供的usbwifi进行说明。
-
编写驱动(正点原子已提供源码,只需编译成模块即可/也可直接编译进内核,详见第七十章第一节)。
-
加载驱动(/lib/modules/‘uname -r’/路径下)。
depmod //第一次加载驱动的时候需要运行此命令 modprobe 8188eu.ko //RTL8188EUS 模块加载 8188eu.ko 模块
使用
ifconfig -a
查看usbWiFi是否加载成功. -
剩下的就是用应用程序使用加载进内核的驱动程序了,使用usbwifi的后续如下:
-
在开发板根文件系统的/etc 目录下创建一个名为“wpa_supplicant.conf”的配置文件,此文件用于配置要连接的 WIFI 热点以及 WIFI 秘密,比如我要连接到“ZZK”这个热点上,因此 wpa_supplicant.conf 文件内容如下所示:
ctrl_interface=/var/run/wpa_supplicant ap_scan=1 network={ ssid="vivo Y93" psk="XXXXXXXX" } # 注意=前后不要有空格,不要用tab键进行缩进。
-
在 开 发 板 根 文 件 系 统 下 创 建 一 个“/var/run/wpa_supplicant”目录,wpa_supplicant 工具要用到此目录!
-
连接热点,当 RTL8188 连接到 WIFI 热点上以后会输出
“wlan0: CTRL-EVENT-CONNECTED”
字样。wpa_supplicant -D wext -c /etc/wpa_supplicant.conf -i wlan0 &
-
设置wlan0的IP地址,使用
udhcpc
从路由器(热点)申请,即udhcpc -i wlan0
。 -
ping -I wlan0 www.baidu.com
-
wpa_supplicant -D wext -c /etc/wpa_supplicant.conf -i wlan0 &
-