主题: 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节的全部函数都会被运行一遍. 在初始化完毕后,用这些keyword标识的函数或数据所占的内存会被释放掉。 三:全部的__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