nfs挂载设备树失败
VFS: Cannot open root device “nfs” or unknown-block(2,0)首先说明一下问题,之前根文件系统一直正常使用,突然今天进行了以上报错,首先是搜索了一下问题,说是开发板内核和Ubuntu的nfs版本不匹配,之前遇到过,系统换成Ubuntu16版本的了,应该可以排除,但是也试了一下不好使。
感觉是ip地址的变化将bootargs变量里的服务器ip地址的数值进行了相应的改变,但是还是没有变化。
查了相关的问题搜索发现,没有解决方案,我先是进行了开发板的固化系统,使用了emmc中的根文件系统,发现没有问题,但是使用网络nfs挂载还是出现了问题,最后通过装载了第二个系统进行挂载发现了问题所在。
问题是:板子的ip地址和别的设备的ip地址冲突了(虽然之前也dhcp了但当时没好使),加上了服务器ip地址的变化导致的。
所以为了一劳永逸,将Ubuntu的动态分配ip地址进行了更改,改为静态分配ip地址。
1ipaddr
可以查看发现网卡的名字。
网卡名字叫做ens33
1sudo vi /etc/network/interfaces
1234567 ...
设备树常用的of操作树
设备树常用 OF 操作函数设备树描述了设备的详细信息,这些信息包括数字类型的、字符串类型的、数组类型的,在编写驱动的时候需要获取到这些信息。比如设备树使用 reg 属性描述了某个外设的寄存器地址为 0X02005482,长度为 0X400,我们在编写驱动的时候需要获取到 reg 属性0X02005482和 0X400 这两个值,然后初始化外设。
Linux 内核给我们提供了一系列的函数来获取设备树中的节点或者属性信息,这一系列的函数都有一个统一的前缀“of_”,所以在很多资料里面也被叫做 OF 函数。这些 OF 函数原型都定义在 include/linux/of.h 文件中。
linux内核使用device_code结构体来描述一个节点,此结构体定义在include/linux/of.h
123456789101112131415161718192021struct device_node { const char *name; /* 节点名字 */ const char *type; /* 设备类型 */ phandle phand ...
linux设备树
设备树定义设备树(Device tree),描述设备树的文件叫做DTS(Tree Source),这个DTS采用树形结构描述板级设备(开发板上的设备信息)。树的主干就是系统总线, IIC 控制器、 GPIO 控制器、 SPI 控制器等都是接到系统主线上的分支。
设备树源文件扩展名为.dts, DTS 是设备树源码文件, DTB 是将DTS 编译以后得到的二进制文件。将.c 文件编译为.o 需要用到 gcc 编译器,那么将.dts 编译为.dtb需要什么工具呢?需要用到 DTC 工具!
DTS语法设备树也支持头文件,设备树的头文件扩展名为.dtsi。例如:在imx6ull-14x14-evk.dts中有
1#include "imx6ulll-14x14-evk.dsti"
设备点12345678910111213141516171819202122232425 示例代码 43.3.2.1 设备树模板1 / {2 aliases {3 can0 = &flexcan1;4 };56 cpu ...
新字符设备驱动开发
设备号Linux的设备管理是和文件系统紧密结合的,各种设备都以文件的形式存放在/dev目录下,称为设备文件。应用程序可以打开、关闭和读写这些设备文件,完成对设备的操作,就像操作普通的数据文件一样。为了管理这些设备,系统为设备编了号,每个设备号又分为主设备号和次设备号。主设备号用来区分不同种类的设备,而次设备号用来区分同一类型的多个设备。对于常用设备,Linux有约定俗成的编号,如硬盘的主设备号是3。
一个字符设备或者块设备都有一个主设备号和次设备号。主设备号和次设备号统称为设备号。主设备号用来表示一个特定的驱动程序。次设备号用来表示使用该驱动程序的各设备。例如一个嵌入式系统,有两个LED指示灯,LED灯需要独立的打开或者关闭。那么,可以写一个LED灯的字符设备驱动程序,可以将其主设备号注册成5号设备,次设备号分别为1和2。这里,次设备号就分别表示两个LED灯。
函数定义:
123456#include <sys/sysmacros.h>#include <linux/cdev.h>MKDEV(int major,int minor) //major为 ...
LED驱动开发
地址映射MMU(Memory Manage Unit)为内存管理单元,Linux内核2.6以前必须要有MMU,之后支持无MMU的处理器。MMU的功能有:
①完成虚拟空间到物理空间的映射。②内存保护,设置存储器的访问权限,设置虚拟存储空间的缓冲特性。Linux 内核启动的时候会初始化 MMU,设置好内存映射,设置好以后 CPU 访问的都是虚拟 地 址 。 比 如 I.MX6ULL 的GPIO1_IO03 引 脚 的 复 用 寄 存 器IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03 的地址为 0X020E0068。如果没有开启MMU 的话直接向 0X020E0068 这个寄存器地址写入数据就可以配置 GPIO1_IO03 的复用功能。现在开启了 MMU,并且设置了内存映射,因此就不能直接向 0X020E0068 这个地址写入数据了。我们必须得到 0X020E0068 这个物理地址在 Linux 系统里面对应的虚拟地址,这里就涉及到了物理内存和虚拟内存之间的转换,需要用到两个函数: ioremap 和 iounmap。
ioremap函数12345#define iore ...
字符设备驱动开发
字符设备驱动简介字符设备是Linux驱动基本的一类设备驱动,字符设备就是一个一个字节,按照字节流进行读写操作的设备,读写数据是分先后顺序的;数据是实时传输的,没有缓存,字符设备是没有文件系统的。
绝大部分设备驱动是字符设备:LED、按键、声卡、IIC、SPI、LCD、摄像头等都是字符设备。这些设备的驱动都是字符设备驱动。
在 Linux 中一切皆为文件,驱动加载成功以后会在“/dev”目录下生成一个相应的文件,应用程序通过对这个名为“/dev/xxx” (xxx 是具体的驱动文件名字)的文件进行相应的操作即可实现对硬件的操作。
应用程序运行在用户空间,而 Linux 驱动属于内核的一部分,因此驱动运行于内核空间。当我们在用户空间想要实现对内核的操作,比如使用 open 函数打开/dev/led 这个驱动,因为用户空间不能直接对内核进行操作,因此必须使用一个叫做“系统调用”的方法来实现从用户空间“陷入” 到内核空间,这样才能实现对底层驱动的操作。
驱动模块加载和卸载Linux 驱动有两种运行方式,第一种就是将驱动编译进 Linux 内 ...
驱动开发流程
嵌入式linux驱动开发流程嵌入式系统中,操作系统是通过各种驱动程序来驾驭硬件设备的。设备驱动程序是操作系统内核和硬件设备之间的接口,它为应用程序屏蔽了硬件的细节,这样在应用程序看来,硬件设备只是一个设备文件,可以像操作普通文件一样对硬件设备进行操作。设备驱动程序是内核的一部分,完成以下功能:◇ 驱动程序的注册和注销。◇ 设备的打开和释放。◇ 设备的读写操作。◇ 设备的控制操作。◇ 设备的中断和轮询处理。
在 Linux 中一切皆为文件,驱动加载成功以后会在“/dev”目录下生成一个相应的文件,应用程序通过对这个名为“/dev/xxx” (xxx 是具体的驱动文件名字)的文件进行相应的操作即可实现对硬件的操作。
应用程序对驱动程序的调用为:应用程序->库->内核->驱动程序->硬件
Linux主要将设备分为三类:字符设备、块设备和网络设备。字符设备是指发送和接收数据以字符的形式进行,没有缓冲区的设备;块设备是指发送和接收数据以整个数据缓冲区的形式进行的设备;网络设备是指网络设备访问的BSD socket 接口。
基于操作系统的驱 ...
根文件系统构建
根文件系统定义根文件系统首先是内核启动时所 mount(挂载)的第一个文件系统,内核代码映像文件保存在根文件系统中,而系统引导启动程序会在根文件系统挂载之后从中把一些基本的初始化脚本和服务等加载到内存中去运行。
根文件系统是 Linux 内核启动以后挂载(mount)的第一个文件系统,然后从根文件系统中读取初始化脚本,比如 rcS, inittab 等。根文件系统和 Linux 内核是分开的,单独的 Linux 内核是没法正常工作的,必须要搭配根文件系统。
常用子目录
目录
含义
/bin
存放可执行文件一般都是命令
/dev
设备文件
/etc
各种配置文件
/lib
linux所需的必备库文件(共享库)
/mnt
临时挂载目录(一般为空)
/proc
作为 proc 文件系统的挂载点(文件是临时存在的,一般存储系统运行信息文件)
/usr
Unix 操作系统软件资源目录
/var
存放一些可以改变的数据
/sbin
此目录页用户存放一些可执行文件
...
内核移植
内核移植首先是要将官方的板载内核进行下载,在其之上进行改动来支持自己的板子。
例如可以下载nxp关于imx6ull的linux内核,github的地址GitHub - Freescale/linux-fslc at 5.4-2.1.x-imx
交叉编译器使用的为arm-linux-gnueabihf-
随便弄一个内核下来,编译顶层的Makefile
12ARCH ?= armCROSS_COMPILE ?= arm-linux-gnueabihf-
这两个后面不要加空格直接回车,不然找不到交叉编译器。
添加自己的板子之后复制一份自己的配置文件
123cd arch/arm/configslscp imx_v7_mfg_defonfig imx_alientek_emmc_defconfig
之后进入arch/arm/boot/dts,复制一份imx6ull-14x14-evk.dts
1cp imx6ull-14x14-evk.dts imx6ull-alientek-emmc.dts
修改makefile的dtb-$(CONFIG_SOC ...
Linux 内核分析
内核分析linux内核组成部分linux内核主要由进程调度(SCHED)、内存管理(MM)、虚拟文件系统(VFS)、网络接口(NET)、进程间通信(IPC)5个子系统组成。
5个子系统依赖关系如下:
进程调度与内存管理之间的关系:这两个子系统相互依赖,在多程序环境下,程序要运行,则必须创建进程,而创建进程第一件事情就是将程序和数据装入内存。
进程间通信与内存管理的关系:进程间通信子系统要依赖内存管理支持共享内存通信机制,这种机制允许两个进程除了拥有自己的私有空间外,还可以存取共同的内存区域。
虚拟文件系统与网络接口之间的关系:虚拟文件系统利用网络接口支持网络文件系统(NFS),也利用内存管理支持RAMDISK设备。
内存管理与虚拟文件系统之间的关系:内存管理利用虚拟文件系统支持交换,交换进程定期由调度程序调度,这也是内存管理依赖于进程调度的原因。
详情参考Makefile.txt文件翻译
内核Makefile分类在Linux内核里,每个子目录都有一个makefile,它被称作Kbuilt-makefile,它将当前目录的文件编译成built-in.o、以及库文件、模块文件。然后顶层M ...