-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathday1.txt
executable file
·289 lines (217 loc) · 6.67 KB
/
day1.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
Linux设备驱动开发 9天
【1】课程大纲
1.Linux内核模块
2.字符设备驱动
3.并发和竞态的解决方法
4.IO模型
5.linux内核中断
6.Platform总线驱动
7.i2c总线驱动
8.spi总线驱动
9.块设备驱动
10.网卡设备驱动
【2】工作岗位
Linux设备驱动开发
Android设备驱动开发
【3】什么是驱动?arm裸机驱动和Linux设备驱动有什么区别?
驱动:通过软件驱动硬件工作的代码
共同点:
都可以驱动硬件工作
不同点:
arm裸机驱动:只能执行一份代码,在main中按照先后
顺序来执行,这份代码可以单独执行,不需要依赖其
他的代码。
Linux设备驱动:它是基于Linux内核才能够操作硬件,
如果没有Linux内核,驱动不能单独执行,也不能自动
执行(必须通过应用层控制才能执行)。可以同时安装
多个Linux设备驱动
【4】Linux系统层次
应用层: [0-3G]
APP glibc
---------------(系统调用swi)------------------------------
内核层:5大功能 [3-4G]
文件管理:通过文件系统ext2 ext3 ext4 yaffs jiffe等来
组织管理文件
内存管理:通过内存(slab)管理单元来分配和释放内存的。
进程管理:管理的是进程的创建,销毁,进程的调度等功能
网络管理:通过网络协议栈进行网络数据的收发
设备管理:设备驱动的管理
字符设备驱动:按照字节流来访问,并且是顺序访问的。
块设备驱动:按照块来访问(512字节),可以顺序访问
也可以无序访问
网卡设备驱动:网卡设备驱动是没有设备文件存在的。
(通过这种设备进行网络数据传输)
----------------------------------------------------------
硬件层:LED CAMERA LCD TOUCHSCREEN
声卡 显卡 BEEP USB鼠标 U盘 硬盘
FLASH 交换机 路由器 猫 网卡等
【5】Linux设备驱动的使用
demo.c <==== 字符设备驱动
Kconfig :生成选项菜单的文件
/home/linux/kernel/kernel-3.4.39/drivers/char
config FARSIGHT_DEMO (选项名)
tristate "test test test ..." (选项菜单名)
help
this is a driver demo
.config :保存选配号的选项
CONFIG_FARSIGHT_DEMO=y
CONFIG_FARSIGHT_DEMO=m
#CONFIG_FARSIGHT_DEMO is not set
Makefile :用来编译驱动模块的
obj-$(CONFIG_FARSIGHT_DEMO) += demo.o
obj-y +=demo.o
obj-m +=demo.o
编译:
y:
make uImage ===>将驱动编译到uImage中
m:
make modules ===>将驱动编译生成xxx.ko文件
【6】linux内核模块
模块三要素:内核模块不能单独执行,也不能自动自行
入口
static int __init demo_init(void)
{
return 0;
}
module_init(demo_init);
出口
static void __exit demo_exit(void)
{
}
module_exit(demo_exit);
许可证
MODULE_LICENSE("GPL");
内部编译:在内核源码树中编译
外部编译:在内核源码树外进行编译
Makefile:
KERNELDIR:= /lib/modules/$(shell uname -r)/build/
//这是Makefile中的一个变量,记录ubuntu内核的路径的
//$(shell 命令) 在Makefile中起一个终端,执行命令,将
//将命令执行的结果作为返回值
PWD:=$(shell pwd)
//PWD它是记录驱动所在目录的一个变量。
all:
//all是make执行的时候的默认的标签,
//这个all的名字也可以随意指定(如modules)
make -C $(KERNELDIR) M=$(PWD) modules
//make -C dir 进入到dir目录下执行它里面的Makefile文件
//M 它是记录程序当前路径的一个变量
//make modules 编译模块,只编译M指定的目录下的模块
clean:
make -C $(KERNELDIR) M=$(PWD) clean
//make -C dir 进入到dir目录下执行它里面的Makefile文件
//M= 它是记录程序当前路径的一个变量
//make clean 清除编译,只清除M指定的目录下的模块文件
obj-m:=demo.o
//指定的要编译的模块的名字
Makefile中四种赋值的区别?
=
查找Makefile中变量最后一次被赋值
的结果,然后将它赋值给新的变量
var1=abc
var2=$(var1)
var1=def
all:
@echo $(var1) #def
@echo $(var2) #def
:= 立即赋值
var1=abc
var2:=$(var1)
var1=def
all:
@echo $(var1) #def
@echo $(var2) #abc
+= 附加赋值
var1=abc
var2=def
var2+=$(var1)
all:
@echo $(var1) #abc
@echo $(var2) #def abc
?= 询问赋值:询问变量之前是否被赋值过,
如果变量之前没有被赋值过本次赋值成立,
否则本次赋值不成立
var1?=def
all:
@echo $(var1) #def
var1=abc
var1?=def
all:
@echo $(var1) #abc
【7】驱动安装和卸载的命令
sudo insmod xxx.ko 安装驱动
lsmod 查看模块是否被安装了
sudo rmmod xxx 卸载驱动
modinfo xxx.ko 查看模块中的各种信息的命令
dmesg 查看printk打印的消息
sudo dmesg -c 先在终端上显示一遍,然后清空消息
sudo dmesg -C 直接清空消息
【8】内核打印函数
printk(打印级别 "控制格式",变量);
printk("控制格式",变量); //使用的是默认级别
内核的八个打印级别如下,数字越小优先级越高。
#define KERN_EMERG "<0>"
/* system is unusable */
#define KERN_ALERT "<1>"
/* action must be taken immediately */
#define KERN_CRIT "<2>"
/* critical conditions */
#define KERN_ERR "<3>"
/* error conditions */
#define KERN_WARNING "<4>"
/* warning conditions */
#define KERN_NOTICE "<5>"
/* normal but significant condition */
#define KERN_INFO "<6>"
/* informational */
#define KERN_DEBUG "<7>"
/* debug-level messages */
打印级别问题:
proc/sys/kernel$ ls printk
cat /proc/sys/kernel/printk
4 4 1 7
终端的级别 消息的默认级别 终端的最大级别 终端的最小级别
只有当消息的级别大于终端的级别的
时候,消息才会显示。
由于ubuntu的终端已经被开发者修改过了,所以
即使消息的级别大于控制台的级别,消息依然不会
显示,使用虚拟控制台才执行代码
ctrl +alt +[F1-F6] 进入虚拟终端
ctrl +alt + F7 退出虚拟终端
修改默认级别的办法:
su root
echo 4 3 1 7 > /proc/sys/kernel/printk
【9】内核模块传参问题
在工作中做开发的时候,在购买屏幕硬件的时候,给你提供了
这个屏幕的驱动(xxx.ko),比如通过命令行传参的形式修改
屏幕的默认最大亮度。
Standard types are:
byte, short, ushort, int, uint, long, ulong 注意:没有char类型!!
charp: a character pointer
bool: a bool, values 0/1, y/n, Y/N.
invbool: the above, only sense-reversed (N = true).
module_param(name, type, perm)
功能:接收命令行传的参数
参数:
@name:变量名
@type: 变量的类型
@perm: 权限 0664 0775
MODULE_PARM_DESC(_parm, desc)
功能:对命令行传递的参数进行描述
参数:
@_parm:变量
@desc:描述的字符串
安装驱动的时候传参:
sudo insmod demo.ko light=80
在运行的使用传参
/sys/module/驱动命名的目录/parameters/
以变量命名的文件
su root
echo 70 > light
【10】如何下载笔记
www.github.com/daizhansheng/
【11】作业:
1.通过命令行传参的形式传递字符类型
2.通过命令行传参的形式传递字符串
3.通过命令行传参的形式传递数组
module_param_array(name, type, nump, perm)