因为之前linux的经验基本都在应用层,内核和驱动这块涉及的不是很多,直接做实验感觉还是有很多不很清楚和没有准备好的地方,在这里做一个总结,更像一个流水账的备忘,也可以帮助同样入门经历的朋友,做一些借鉴吧。
也可能会存在一些错误,对于我来说,也是边收集边验证边总结,请大家不吝指教,后面也会持续更新。
这部分我可能会尽量写的比较细碎,请大神们无视。
开发板用的正点原子 ALTHA 阿尔法 开发板,配置应该是原子主推的一个配置
家里有一个不怎么用的笔记本,被我改成了Linux服务器,做了SSH(SFTP)的端口映射到外网,用来做自己的编译服务器(这部分实现可以参见我的 免费内网穿透方案)
主要是配置交叉工具链。
这里刚开始遇到一个疑惑,正点原子书《Linux驱动开发指南 v1.0》第四章里是让用 gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf。在《用户快速体验v1.0》,又让用的是arm-poky-linux-gnueabi-。
其实两个编译器,用哪个都可以,但是推荐看什么文档就先用什么编译器。
这个带了poky字眼的编译器,是yocto 编译产生的arm-poky-linux-gnueabi-gcc,可以说是freescale的IMX6平台用的交叉编译
arm-none-linux-gnueabi-gcc:是 Codesourcery 公司(目前已经被Mentor收购)基于GCC推出的的ARM交叉编译工具。可用于交叉编译ARM(32位)系统中所有环节的代码,包括裸机程序、u-boot、Linux kernel、filesystem和App应用程序。
arm-linux-gnueabihf-gcc:是由 Linaro 公司基于GCC推出的的ARM交叉编译工具。可用于交叉编译ARM(32位)系统中所有环节的代码,包括裸机程序、u-boot、Linux kernel、filesystem和App应用程序。
aarch64-linux-gnu-gcc:是由 Linaro 公司基于GCC推出的的ARM交叉编译工具。可用于交叉编译ARMv8 64位目标中的裸机程序、u-boot、Linux kernel、filesystem和App应用程序。
arm-none-elf-gcc:是 Codesourcery 公司(目前已经被Mentor收购)基于GCC推出的的ARM交叉编译工具。可用于交叉编译ARM MCU(32位)芯片,如ARM7、ARM9、Cortex-M/R芯片程序。
arm-none-eabi-gcc:是 GNU 推出的的ARM交叉编译工具。可用于交叉编译ARM MCU(32位)芯片,如ARM7、ARM9、Cortex-M/R芯片程序。
不同工具链具体对比可以参见结尾的参考链接,不过没有找到poky的说明,倒是觉得
Linaro 的 arm-linux-gnueabihf-gcc 和 aarch64-linux-gnu-gcc基本够用了。
这里我们就用 arm-linux-gnueabihf-gcc。
这个比较简单,网上教程很多,把下载到的工具链放到一个路径下,添加到环境变量里能找到即可,就像windows下的添加:
linux也是一样,不过不是图形化的。
要把交叉工具链的bin路径加到系统中。
简单说一下,几个文件的区别:
etc下的是公共的配置
~下的是个人配置
就我个人,我是直接写在 /etc/profile 下的。
有时候要从PC向开发板传输文件,这时候,TFTP用的就比较多。在PC上架一个TFTP的服务器,开发板就可以通过TFTP命令来获取文件。
命令:
//Uboot中,下载zImage到内存0x80800000处(已经配置过severip这个环境变量)
tftp 80800000 zImage
//linux中,下载zImage文件到当前目录
tftp 192.168.0.111 -g -r zImage
windows自带了tftp的客户端,服务器可以使用tftpd32软件来实现。
在linux中搭建tftp服务器的步骤网上介绍的很多,就是通过tftp-hpa、tftpd-hpa 和 xinetd来实现。
具体可以参考结尾的参考链接。
sudo apt-get install xinetd
sudo apt-get install tftp-hpa tftpd-hpa
配置各自的配置文件,配置内容参见参考链接。
sudo vi /etc/xinetd.conf
vi /etc/default/tftpd-hpa
NFS也是一种网络传输文件的常用方法,同时也可以作为根文件系统的挂载方式。
安装方法在结尾的参考链接。
//Uboot 传输文件
nfs [loadAddress] [[hostIPaddr:]bootfilename]
nfs 80800000 192.168.0.110:/home/tao/smb/nfs/zImage
//挂载根文件系统
root=/dev/nfs nfsroot=[<server-ip>:]<root-dir>[,<nfs-options>] ip=<client-ip>:<server-ip>:<gwip>:<netmask>:<hostname>:<device>:<autoconf>:<dns0-ip>:<dns1-ip>
setenv bootargs 'console=ttymxc0,115200 root=/dev/nfs rw nfsroot=192.168.0.110:/home/tao/smb/tftp/rootfs ip=192.168.0.200:192.168.0.110:192.168.0.1:255.255.255.0::eth0:off'
目前使用的是原子的阿尔法开发板,配置资料用的是原子的资料包。
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- distclean
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- mx6ull_14x14_ddr512_emmc_defconfig
make V=1 ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j12
三句话的意思就是:
Uboot中最重要的环境变量就是bootcmd 和 bootargs。可以说,其他所有的变量都是为这两个变量服务
一些指令
#!/bin/sh
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- distclean
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- imx_v7_defconfig
#make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfig
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- all -j16
bootm ${kernel_load_address} ${ramdisk_load_address} ${devicetree_load_address};
bootz ${kernel_load_address} - ${devicetree_load_address}
这部分流程比较多,使用busybox的话,就按照《I.MX6U嵌入式Linux驱动开发指南V1.0》第三十八章。
书里的附录也给了buildroot 、 yocto 等方式。
根文件系统有挺多种格式的,这里一开始有点晕的。
jffs2/yaffs/…
cd rootfs/
tar -vcjf rootfs.tar.bz2
看I.MK6ULL的memory map,0x80000000以上是DDR。
目前使用的是原子自带的系统,
内存分配是
目前有这么几种调试方式:
总结一下:
Uboot | zImage | dtb | rootfs | |
---|---|---|---|---|
EMMC | √ | √ | √ | √ |
tf卡 | √ | √ | √ | √ |
tftp | X | √ | √ | √ |
nfs | X | √ | √ | √ |
其他 | … | … | … | … |
注意:rootfs没法通过TFTP的方式,把压缩包tar.bz2下载到内存某个地址来运行,压缩包我目前只看到mfgtools使用了。
常用的方法主要有:
如果uboot 和 zImage从tftp下载,rootfs从nfs启动
root=/dev/nfs nfsroot=[<server-ip>:]<root-dir>[,<nfs-options>] ip=<client-ip>:<server-ip>:<gwip>:<netmask>:<hostname>:<device>:<autoconf>:<dns0-ip>:<dns1-ip>
setenv bootargs 'console=ttymxc0,115200 root=/dev/nfs rw nfsroot=192.168.0.110:/home/tao/smb/tftp/rootfs ip=192.168.0.200:192.168.0.110:192.168.0.1:255.255.255.0::eth0:off'
tftp 80800000 zImage
tftp 83000000 imx6ull-14x14-evk.dtb
bootz 80800000 - 83000000
完整写起来就是
setenv bootcmd 'tftp 80800000 zImage;tftp 83000000 imx6ull-14x14-evk.dtb;bootz 80800000 - 83000000;'
setenv bootargs 'console=ttymxc0,115200 root=/dev/nfs rw nfsroot=192.168.0.110:/home/tao/smb/tftp/rootfs ip=192.168.0.200:192.168.0.110:192.168.0.1:255.255.255.0::eth0:off'
boot
如果需要zImage、dtb、rootfs这些都从nfs启动。
即先通过nfs获取zImage和dtb,然后挂载nfs的文件系统
setenv bootargs 'console=ttymxc0,115200 root=/dev/nfs rw nfsroot=192.168.0.110:/home/tao/smb/nfs/rootfs ip=192.168.0.200:192.168.0.110:192.168.0.1:255.255.255.0::eth0:off'
nfs 80800000 192.168.0.110:/home/tao/smb/nfs/zImage
nfs 83000000 192.168.0.110:/home/tao/smb/nfs/imx6ull-14x14-emmc-4.3-480x272-c.dtb
bootz 80800000 - 83000000
完整写起来就是
setenv bootcmd 'nfs 80800000 192.168.0.110:/home/tao/smb/nfs/zImage;nfs 83000000 192.168.0.110:/home/tao/smb/nfs/imx6ull-14x14-emmc-4.3-480x272-c.dtb;bootz 80800000 - 83000000;'
setenv bootargs 'console=ttymxc0,115200 root=/dev/nfs rw nfsroot=192.168.0.110:/home/tao/smb/nfs/rootfs ip=192.168.0.200:192.168.0.110:192.168.0.1:255.255.255.0::eth0:off'
boot