linux内核模块笔记

主题:	1. 嵌入式基础知识
	2. linux内核介绍
	3. 内核的编译和安装(x86)
	4. 第一个模块
	5. 模块的相关工具
	6. 模块的符号导出
	7. 模块的参数

作业:
1.看linux/module.h。以后每天看课程中接触到的头文件
  这个文件所在的位置:/home/zshh/work/driver/kernel/linux-3.5/include/linux

重点看module结构体(模块的计数就在module结构体中)
   再module这个结构体中包含模块的状态,模块的初始化话函数指针的定义,
   还由exit函数指针的定义.
   其中还包括对内核参数的操作,struct kernel_param *kp 这个结构体的定义如下:
   struct kernel_param{
	const char *name;
	const struct kernel parm_ops *ops;
	u16 perm;
        s16 level;
        union
        {
		void *arg;
		const struct  kparam_string *str;
		const struct kparam_array * arr;
        };
   };

  const struct kernel parm_ops *ops;
  这个函数包含了一些读写参数的相关操作.
  struct kernel_param_ops
  {
    int (*set)(const char* val, const struct kernel_param *kp)

    int (*set)(char *buffer, const struct kernel_param *kp)

    void(*free)(void * arg)

  }

2.看__init宏

#define __init _section(.init.text)
#define __section(s) __attribute__((__section__(#S)))

这个宏最红替换出来就是 __attribute__((__section__(".init.text")

代表他会被存放再.init.text.
 __init, __initdata等属性标志,
是要把这种属性的代码放入目标文件的.init.text节,
数据放入.init.data节──这一过程是通过编译内核时为相关目标平台提供了xxx.lds链接脚本来指导ld完成的。

//这个函数的执行分两种情况如下:
一:当编译为模块的时候.使用insmod,或者是modprob插入模块到内核的时候,他会被执行.
	如果插入成功, __init属性的函数就被执行;

二:当代码被编译进入zImage中是,再内核引导时,执行
	do_basic_setup()函数调用do_initcalls函数,.init节的所有函数都会被执行一遍.
        在初始化完成后,用这些关键字标识的函数或数据所占的内存会被释放掉。
三:所有的__init函数在initcall.init都有一个指针指向它.

3.看linux/list.h

4.实验模块参数的bool型,测试可否使用0/1,y/n等;
如果模块的参数为数组,则需要使用module_param_array宏来声明
自己写个例子,测试该宏的使用

1. 嵌入式基础知识
=======================
嵌入式行业的当前发展情况,嵌入式系统构成等

2.linux内核的说明
=======================
kernel目录下有两个内核,一个是从www.kernel.org下载的标准内核,一个是由google修改、三星移植的内核;
解压缩内核后说明一下目录结构,并介绍内核的核心功能

3.内核的编译安装(x86)
=======================
(1)内核的配置
$>make menuconfig
通过图形界面(依赖于ncurses库),决定编译的内核都包含哪些部分。
最终的配置结果,存储在.config文件中
决定代码是否编译,如果编译,是编译到zImage中,还是编译为.ko模块

(2)内核的编译
$>make
编译生成zImage内核和.ko模块

(3)内核模块的安装
$>make modules_install
将生成的.ko安装到磁盘上的特定位置(就是拷贝)
一般是/lib/modules/xxx/目录(xxx为编译的内核的版本)

(4)内核的安装
$>make install
将生成的zImage安装到/boot目录下
(zImage在x86上称为bzImage,位于arch/x86/boot/目录下)

接下来可以重新启动系统,看看新编译的内核能否使用(要看运气)

4.第一个模块
=========================
参考x86-drv/01mod/目录下的mod_test01.c和Makefile
认真了解这两个文件中每部分的作用

5. 模块的相关工具(5个)
=========================
(1)模块的手工加载
$>insmod mod_test01.ko
会调用模块的入口函数,如果是printk的信息,用$>dmesg查看

(2)模块的手工卸载
$>rmmod mod_test01

(3)显示模块信息
$>modinfo xxx.ko

(4)列出内核中已经加载的模块
$>lsmod

(5)自动加载模块
模块的自动加载工具。该工具可以自动将模块所依赖的模块也一起加载。
modprobe只能加载/lib/modules/xxx下的模块。
$>modprobe xxx		//加载
$>modprobe -r xxx  	//卸载

tip:
$>dmesg
显示printk的信息
$>dmesg -c
清除printk的缓冲区

6.模块的符号导出
==========================
为了避免命名空间污染,内核规定,.ko模块中的所有符号默认都为局部。必须通过EXPORT_SYMBOL宏导出后,才具有全局属性;
EXPORT_SYMBOL宏可用于全局函数和全局变量;

写01mod/mod_test02.c和mod_test03.c
生成模块mod_test02.ko和mod_test03.ko
可以用insmod/rmmod或modprobe测试

$>make install  //执行Makefile中的目标install
$>modprobe mod_test03
会把依赖的mod_test02也加载

$>modprobe -r mod_test03
用-r可以卸载模块

7.模块的参数
=========================
用module_param宏来声明模块参数
参考01mod/mod_test04.c

模块参数对应的文件是/sys/module/mod_test03/parameters/name和value
module_param宏的第3个参数,就用来确定这两个文件的permission

时间: 2024-12-09 11:00:27

linux内核模块笔记的相关文章

linux 文件系统笔记

文件格式: windows:PE linux:  ELF 文件系统: rootfs FHS:规定linux应该创建哪些目录 /下的目录结构: /boot: 系统启动相关的文件,如内核,initrd,以及 grub(bootloader) /dev :设备文件(例如:光盘,cdrom) 类型: 块设备:随机访问, 数据块 字符设备:线性访问, 以字节为单位 设备号:主设备号(major),次设备号(minor) /etc:  配置文件(绝大多数为纯文本格式) /home: 用户的家目录,默认为/h

linux学习笔记二:linux文件系统

各大linux的版本都遵循着FHS(Filesystem Hierarchy Standard)文件系统目录标准,是一个树形结构的组织文件.在此简要记录各目录. linux下所有文件都处在/文件下. 树形结构图: /boot:  系统启动相关的文件 主要文件 1.vmliunx:内核    2.initramfs:磁盘映像文件   3.grub(bootloader) /dev:设备文件 块设备:随机访问设备. 字符设备:线性设备,顺序访问.按字符为单位.键盘.鼠标. 设备号:主设备号(majo

linux学习笔记(一)-文件目录相关的命令&&文件通配符

一.几个命令概述 1.查看目录以及目录底下的文件:ls(-a显示隐藏文件:-d显示目录本身:-l显示详细内容:-R递归显示,即把子目录的文件也显示出来:-h以更加被人类理解的格式显示,比如显示文件大小的时候用M为单位显示:-i显示文件索引ID) 2.查看文件内容:cat,head,tail,less,more,tac cat:将文件连接起来,输出在屏幕上,可接多个文件(-E:显示隐藏的换行符:-n:显示出行号) head:默认查看文件的前10行(-n#:查看文件的前#行.空白行也是一行) tai

3、Linux内核模块学习

一.内核模块的学习   内核的整体框架是非常的大,包含的组件也是非常多,如何将需要的组件包含在内核中呢?选择一,就是将所有的组件全部编译进内核,虽然需要的组件都可以使用,但是内核过分庞大,势必带来效率影响:选择二是,将组件编译为模块,需要的时候,就自行加载进内核,这种就是我们称之为的模块,当模块被加载到内核的机制,不仅控制了内核大小,同时被加载的内核与被编译进内核的部分,功能意义.    3.1.内核的加载与卸载     将 hello.c 编译为模块,hello.ko, insmod hell

Linux内核模块编写详解

内核编程常常看起来像是黑魔法,而在亚瑟 C 克拉克的眼中,它八成就是了.Linux内核和它的用户空间是大不相同的:抛开漫不经心,你必须小心翼翼,因为你编程中的一个bug就会影响到整个系统,本文给大家介绍linux内核模块编写,需要的朋友可以参考下 内核编程常常看起来像是黑魔法,而在亚瑟 C 克拉克的眼中,它八成就是了.Linux内核和它的用户空间是大不相同的:抛开漫不经心,你必须小心翼翼,因为你编程中的一个bug就会影响到整个系统.浮点运算做起来可不容易,堆栈固定而狭小,而你写的代码总是异步的,

linux 内核模块函数调用

在编写linux内核模块的时候,有时候我们需要调用一只内核模块里面的函数,然而如果是在不同目录下面编译生成的内核模块,此时A模块去调用B模块的函数时候会出现函数未定义,无法调用的情况.那么以前我是在同一个目录下面,先后写两个makefile,然后编译生成两个不同的内核模块,这种方式可以正常实现A模块调用B模块里面的函数,不过非常麻烦.本博文将会针对这种情况提出一种可以同时生成多个内核模块,不要再次编译的方面,下面贴出源码: 内核模块cal.ko: #include <linux/module.h

Linux学习笔记四:Linux的文件搜索命令

1.文件搜索命令  which 语法:which [命令名称] 范例:$which ls  列出ls命令所在目录 [[email protected] ~]$ which ls alias ls='ls --color=auto' /bin/ls 另外一个命令:whereis [名称名称],也可以列出命令所在目录. [[email protected] ~]$ whereis ls ls: /bin/ls /usr/share/man/man1/ls.1.gz /usr/share/man/ma

Linux学习笔记——例说makefile 增加系统共享库

0.前言 从学习C语言开始就慢慢开始接触makefile,查阅了很多的makefile的资料但总感觉没有真正掌握makefile,如果自己动手写一个makefile总觉得非常吃力.所以特意借助博客总结makefile的相关知识,通过例子说明makefile的具体用法. 例说makefile大致分为4个部分 1.只有单个C文件 2.含有多个C文件 3.需要包括头文件路径 4.增加宏定义 5.增加系统共享库 6.增加自定义共享库 7.一个实际的例子 [代码仓库]--makefile-example

Linux内核模块编程与内核模块LICENSE -《详解(第3版)》预读

Linux内核模块简介 Linux内核的整体结构已经非常庞大,而其包含的组件也非常多.我们怎样把需要的部分都包含在内核中呢?一种方法是把所有需要的功能都编译到Linux内核.这会导致两个问题,一是生成的内核会很大,二是如果我们要在现有的内核中新增或删除功能,将不得不重新编译内核. 有没有一种机制使得编译出的内核本身并不需要包含所有功能,而在这些功能需要被使用的时候,其对应的代码被动态地加载到内核中呢?Linux提供了这样的一种机制,这种机制被称为模块(Module).模块具有这样的特点. 模块本