array(2) { ["docs"]=> array(10) { [0]=> array(10) { ["id"]=> string(3) "428" ["text"]=> string(77) "Visual Studio 2017 单独启动MSDN帮助(Microsoft Help Viewer)的方法" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(8) "DonetRen" ["tagsname"]=> string(55) "Visual Studio 2017|MSDN帮助|C#程序|.NET|Help Viewer" ["tagsid"]=> string(23) "[401,402,403,"300",404]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400964" ["_id"]=> string(3) "428" } [1]=> array(10) { ["id"]=> string(3) "427" ["text"]=> string(42) "npm -v;报错 cannot find module "wrapp"" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(4) "zzty" ["tagsname"]=> string(50) "node.js|npm|cannot find module "wrapp“|node" ["tagsid"]=> string(19) "[398,"239",399,400]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400760" ["_id"]=> string(3) "427" } [2]=> array(10) { ["id"]=> string(3) "426" ["text"]=> string(54) "说说css中pt、px、em、rem都扮演了什么角色" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(12) "zhengqiaoyin" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400640" ["_id"]=> string(3) "426" } [3]=> array(10) { ["id"]=> string(3) "425" ["text"]=> string(83) "深入学习JS执行--创建执行上下文(变量对象,作用域链,this)" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "Ry-yuan" ["tagsname"]=> string(33) "Javascript|Javascript执行过程" ["tagsid"]=> string(13) "["169","191"]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511399901" ["_id"]=> string(3) "425" } [4]=> array(10) { ["id"]=> string(3) "424" ["text"]=> string(30) "C# 排序技术研究与对比" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(9) "vveiliang" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(8) ".Net Dev" ["catesid"]=> string(5) "[199]" ["createtime"]=> string(10) "1511399150" ["_id"]=> string(3) "424" } [5]=> array(10) { ["id"]=> string(3) "423" ["text"]=> string(72) "【算法】小白的算法笔记:快速排序算法的编码和优化" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(9) "penghuwan" ["tagsname"]=> string(6) "算法" ["tagsid"]=> string(7) "["344"]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511398109" ["_id"]=> string(3) "423" } [6]=> array(10) { ["id"]=> string(3) "422" ["text"]=> string(64) "JavaScript数据可视化编程学习(二)Flotr2,雷达图" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "chengxs" ["tagsname"]=> string(28) "数据可视化|前端学习" ["tagsid"]=> string(9) "[396,397]" ["catesname"]=> string(18) "前端基本知识" ["catesid"]=> string(5) "[198]" ["createtime"]=> string(10) "1511397800" ["_id"]=> string(3) "422" } [7]=> array(10) { ["id"]=> string(3) "421" ["text"]=> string(36) "C#表达式目录树(Expression)" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(4) "wwym" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(4) ".NET" ["catesid"]=> string(7) "["119"]" ["createtime"]=> string(10) "1511397474" ["_id"]=> string(3) "421" } [8]=> array(10) { ["id"]=> string(3) "420" ["text"]=> string(47) "数据结构 队列_队列实例:事件处理" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "idreamo" ["tagsname"]=> string(40) "C语言|数据结构|队列|事件处理" ["tagsid"]=> string(23) "["246","247","248",395]" ["catesname"]=> string(12) "数据结构" ["catesid"]=> string(7) "["133"]" ["createtime"]=> string(10) "1511397279" ["_id"]=> string(3) "420" } [9]=> array(10) { ["id"]=> string(3) "419" ["text"]=> string(47) "久等了,博客园官方Android客户端发布" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(3) "cmt" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511396549" ["_id"]=> string(3) "419" } } ["count"]=> int(200) } 222 内核 模块开发 - 爱码网

linux内核的整体结构非常庞大,组件合成分为2种:

(1):把所有的组件都编译进内核文件,即zImage或bzImage。这种有两个缺点:

  a、生成的内核文件过大。

  b、如果想要添加或删除某个组件,需要重新编译整个内核。

(2)内核模块机制:需要该组件时,动态地添加到正在运行的内核中。

内核模块特点:

(1)模块本身并不被编译进内核文件(ZImage/bzImage).

(2)可以根据需求,在内核运行期间动态的安装或卸载。

 

模块加载函数

安装模块时被系统自动调用的函数,通过module_init宏来指定,如hello_init。

模块卸载函数:

卸载模块时被系统自动调用的函数,通过module_exit宏来指定,如hello_exit。

 

模块编译:在linux2.6下编译内核模块,通常使用makefile

单个源文件(hello.c)编译:

ifneq ($(KERNELRELEASE),)                //如果KERNELRELEASE不等于空

obj-m := hello.o

else

KDIR := /lib/modules/2.6.18-53.el5/build    //内核源代码路径
all:

    make -C $(KDIR)  M=$(PWD)   modules    //modules:makefile的目标, 
  //-C:进入后面紧跟的目录中使用它的makefile来编译,后面紧跟的是一个目录。
  //M:build文件中要求的,表示内核代码所在。
clean: rm -f *.ko *.o *.mod.o *.mod.c *.symvers endif

 

多个源文件(main.c add.c)编译

ifneq  (($KERNELRELEASE),)

obj-m := hello.o            //内核模块的名字
hello-objs := main.o  add.o   //hello-objs中hello与模块名字必须一样,如果多个文件,add文件名

else 

KDIR := /lib/modules/2.6.18-53.el5/build
all:

    make  -C  $(KDIR)  M=$(PWD)  modules
clean:
    rm -f  *.ko  *.o  *.mod.o  *.mod.c  *.symvers

endif

 

1.加载insmod  (insmod hello.ko)

2.卸载rmmod   (rmmod hello)

3.查看 lsmod

4.加载modprobe (modprobe hello)

modprobe如同insmod,也就是加载一个模块到内核。它的不同之处在于它会根据文件

/lib/modules/<$version>/modules.dep

来查看要加载的模块,看它是否还依赖于其他模块,如果是,modprobe会首先找到这些模块,把它们先加载到内核。

 

1.许可证申明:

MODULE_LICENSE用来告知内核,该模块遵守的许可证协议,如“GPL”、“GPL v2”。

MODULE_LICENSE("遵守的协议")

MODULE_LICENSE("GPL")

2.作者申明

MODULE_AUTHOR("作者")

3.模块描述

MODULE_DESCRIPTION("模块的功能描述")

4.模块版本

MODULE_VERSION("V1.0")

5.模块别名

MODULE_ALIAS("别名");

6.模块参数:通过宏module_param指定保存模块参数的变量。模块参数用于在加载模块时传递参数给模块。

module_param(name,type,perm)

name:变量的名称

type:变量类型,bool:布尔型  int:整形  charp:字符串型

perm是访问权限。 S_IRUGO:读权限  S_IWUSR:写权限

如:

在hello.c中  int a = 9;
module_param(a,int,S_IRUGO);


命令行中输入:insmod  test.ko  a=100   //把100赋给a

 

内核符号导出:

EXPORT_SYMBOL(符号名)

EXPORT_SYMBOL_GPL(符号名)    //只能用于包含GPL许可证的模块

如两个模块A、B模块:需在A(定义变量或者函数)中利用EXPORT_SYMBOL(符号名)导出,在B模块中用extern 再声明下。

 

uname -r   //查看内核版本

内核打印:printk。允许根据严重程度,通过附加不同的“优先级”来对消息分类

printk(KERN_WARNING  "hello world");
printk("<0> hello world");

在<linux/kernel.h>中定义了8种记录级别:

KERN_EMERG     "<0>"     紧急消息

KERN_ALERT      "<1>"    需要立即处理

KERN_CRIT        "<2>"    严重情况

KERN_ERR        "<3>"    错误情况

KERN_WARNING  "<4>"   有问题的警告

KERN_NOTICE    "<5>"    正常情况,但仍然需要注意

KERN_INFO       "<6>"     信息型消息 

KERN_DEBUG   "<7>"     用作调试消息

注意:没有指定优先级printk默认使用DEFAULT_MESSAGE_LOGLEVEL优先级,定义在kernel/printk.c中

如:

#define DEFAULT_MESSAGE_LOGLEVEL 4

 

屏幕上没有打印的消息全在:/var/log/message

 

内核打印控制台优先级配置

在/proc/sys/kernel/printk文件中,cat  /proc/sys/kernel/printk

6 4 1 7   //console_loglevel    default_message_loglevel   minimum_console_level   default_console_loglevel

相关文章: