uboot移植及linux移植
uboot编译
一、Windows下使用OTG烧写系统
1、在Windos使用NXP提供的mfgtool来向开发烧写系统。需要用先将开发板的USB_OTG接口连接到电脑上。
Mfgtool工具是向板子先下载一个Linux系统,然后通过这个系统来完成烧写工作。
切记!使用OTG烧写的时候要先把SD卡拔出来,等USB OTG与电脑连接成功以后就可以再将SD卡插进去了。
烧写系统都是烧写到NAND或者EMMC里面,
二、Ubuntu下通过脚本烧写系统
1、首先向SD卡烧写一个系统,然后使用SD卡启动,启动以后在Linux中执行烧写到EMMC或NAND中。
四、何为uboot?
1、uboot是一个裸机程序,比较复杂。
2、uboot就是一个bootloader,作用就是用于启动Linux或其他系统。Uboot最主要的工作就是初始化DDR。因为Linux是运行在DDR里面的。一般Linux镜像zImage(uImage)+设备树(.dtb)存放在SD、EMMC、NAND、SPI FLASH等等外置存储区域。
这里就牵扯到一个问题,需要将Linux镜像从外置flash拷贝到DDR中,再去启动。
Uboot的主要目的就是为系统的启动做准备。
Uboot不仅仅能启动Linux,也可以启动其他系统,比如vxworks。
Linux不仅仅能通过uboot启动。
Uboot是个通用的bootloader,他支持多种架构。
Uboot获取:
- 首先就是uboot官网。缺点就是支持少,比如某一款具体芯片驱动等不完善。
- SOC厂商会从uboot官网下载某一个版本的uboot,然后在这个版本的uboot上加入相应的SOC以及驱动。这就是SOC厂商定制版的uboot。NXP官方的I.MX6ULL EVK板子,
- 做开发板的厂商,开发板会参考SOC厂商的板子。开发板必然会和官方的板子不一样。因此开发板厂商又会去修改SOC厂商做好的uboot,以适应自己的板子。
五、正点原子官方uboot编译
- 编译UBOOT的时候需要先配置
- 编译完成以后就会生成一个u-boot.bin。必须向u-boot.bin添加头部信息。Uboot编译最后会通过/tools/mkimage软件添加头部信息,生成u-boot.imx。
- 如果配置过uboot,那么一定要注意
shell脚本会清除整个工程
,那么配置的文件也会被删除,配置项也会被删除掉。 - 为了方便开发,建议直接在uboot顶层Makefile里面设置好ARCH和CORSS_COMPILE这两个变量的值。
六、正点原子官方uboot烧写
linux驱动开发基础
一、裸机驱动开发回顾
- 底层,跟寄存器打交道,有些MCU提供了库。
二、Linux驱动开发思维
- Linux下驱动开发直接操作寄存器不现实。
- 根据Linux下的各种驱动框架进行开发。一定要满足框架,也就是Linux下各种驱动框架的掌握。
- 驱动最终表现就是/dev/xxx文件。打开、关闭、读写、。。。
- 现在新的内核支持设备树,这个一个.dts文件,此文件 描述了板子的设备信息。
三、Linux驱动开发分类
linux驱动分为三大类:
- 字符设备驱动,最多的。
- 块设备驱动,存储
- 网络设备驱动
一个设备不说是一定只属于某一个类型。比如USB WIFI,SDIO WIFI,属于网络设备驱动,因为他又有USB和SDIO,因此也属于字符设备驱动。
四、应用程序和驱动的交互原理
1、驱动就是获取外设、或者传感器数据,控制外设。数据会提交给应用程序。Linux驱动编译既要编写一个驱动,还要我们编写一个简单的测试应用程序,APP。单片机下驱动和应用都是放到一个文件里面,也就是杂糅到一起。Linux下驱动和应用是完全分开的。
用户空间(用户态)和内核空间(内核态):
- Linux操作系统内核和驱动程序运行在内核空间、应用程序运行在用户空间。
- 应用程序想要访问内核资源,怎么办,有三种方法:系统调用、异常(中断)和陷入。
- 应用程序不会直接调用系统调用,而是通过API函数来间接的调用系统调用,比如POSIX、API和C库等。unix类操作系统中最常用的编程接口就是POSIX。
- 应用程序使用open函数 打开一个设备文件。
- 每个系统调用都有一个系统调用号。系统调用处于内核空间,应用程序无法直接访问,因此需要“陷入“到内核,方法就是软中断。陷入内核以后还要指定系统调用号。
五、字符设备驱动开发流程
- Linux里面一切皆文件,驱动设备表现就是一个/dev/下的文件,/dev/led。应用程序调用open函数打开设备,比如led。应用程序通过write函数向/dev/led写数据,比如写1表示打开,写0表示关闭。如果要关闭设备那么就是close函数。
- 编写驱动的 时候也需要编写驱动对应的open、close,write函数。字符设备驱动fileoptions_struct.
- 驱动最终是被应用调用的,在写驱动的时候要考虑应用开发的便利性。
- 驱动是分驱动框架的,要按照驱动框架来编写,对于字符设备驱动来说,重点编写应用程序对应的open、close、read、write等函数。
六、字符设备驱动框架
字符设备驱动的编写主要就是驱动对应的open、close、read。。。其实就是
file_operations结构体的成员变量的实现。
linux驱动学习
一、字符设备驱动框架
字符设备驱动的编写主要就是驱动对应的open、close、read。。。其实就是
file_operations结构体的成员变量的实现。
二、驱动模块的加载与卸载
Linux驱动程序可以编译到kernel里面,也就是zImage,也可以编译为模块,.ko。测试的时候只需要加载.ko模块就可以。
调试模块注意事项!
- 编译驱动的时候需要用到linux内核源码!因此要解压缩linux内核源码,编译linux内核源码。编译得到zImage和.dtb。需要使用编译后的到的zImage和dtb启动系统。
- 从SD卡启动,SD卡烧写了uboot。uboot通过tftp从ubuntu里面获取zimage和dtb,rootfs也是通过nfs挂载。
- 设置bootcmd和bootargs
- 其实还需要重新配置网络
bootargs=console=ttymxc0,115200 rw root=/dev/nfs nfsroot=192.168.1.66:/home/zzk/linux/nfs/rootfs ip=192.168.1.50:192.168.1.66:192.168.1.1:255.255.255.0::eth0:off
bootcmd=tftp 80800000 zImage;tftp 83000000 imx6ull-alientek-emmc.dtb;bootz 80800000 - 83000000;
- 将编译出来的.ko文件放到根文件系统里面。加载驱动会用到加载命令:insmod,modprobe。移除驱动使用命令rmmod。对于一个新的模块使用modprobe加载的时候需要先调用一下depmod命令。
- 驱动模块加载成功以后可以使用lsmod查看一下。
- 卸载模块使用rmmod命令
三、字符设备的注册与注销
- 我们需要向系统注册一个字符设备,使用函数register_chrdev。
- 卸载驱动的时候需要注销掉前面注册的字符设备,使用函数unregister_chrdev,注销字符设备。
四、设备号
1、Linux内核使用dev_t。
typedef __kernel_dev_t dev_t;
typedef __u32 __kernel_dev_t;
typedef unsigned int __u32;
2、Linux内核将设备号分为两部分:主设备号和次设备号。主设备号占用前12位,次设备号占用低20位。
3、设备号的操作函数,或宏
从dev_t获取主设备号和次设备号,MAJOR(dev_t),MINOR(dev_t)。也可以使用主设备号和次设备号构成dev_t,通过MKDEV(major,minor)
五、应用程序编写
Linux下一切皆文件,首先要open
六、测试
1、加载驱动。
modprobe chrdevbase.ko
2、进入/dev查看设备文件,chrdevbase。/dev/chrdevbase。但是实际没有,因为我们没有创建设备节点。
mknod /dev/chrdevbase c 200 0
c代表时字符设备,200是主设备号,0是次设备号
3、测试
./chrdevbaseAPP /dev/chrdevbase 1
七、chrdevbase虚拟设备驱动的完善
目的:应用程序可以对驱动读写操作,读的话就是从驱动里面读取字符串,写的话就是应用向驱动写字符串。
1、chrdevbase_read驱动函数编写
驱动给应用传递数据的时候需要用到copy_to_user函数。