当前位置: 首页 > news >正文

网站建设有关的职位小程序制作

网站建设有关的职位,小程序制作,广州做企业网站哪家好,wordpress网页标签图标文章目录 前言一、静态加载法1.1 编写驱动程序1.2 将新功能配置在内核中1.3为新功能代码改写Makefile1.4 make menuconfig界面里将新功能对应的那项选择为<*> 二、动态加载法2.1 新功能源码与Linux内核源码在同一目录结构下2.2 新功能源码与Linux内核源码不在同一目录结构…

文章目录

  • 前言
  • 一、静态加载法
    • 1.1 编写驱动程序
    • 1.2 将新功能配置在内核中
    • 1.3为新功能代码改写Makefile
    • 1.4 make menuconfig界面里将新功能对应的那项选择为<*>
  • 二、动态加载法
    • 2.1 新功能源码与Linux内核源码在同一目录结构下
    • 2.2 新功能源码与Linux内核源码不在同一目录结构下
    • 2.3 主机ubuntu下使用ko文件
    • 2.4 开发板Linux下使用ko文件
  • 三、内核模块基础代码解析
  • 四、 内核模块的多源文件编程
  • 五、 内核模块信息宏
  • 总结


前言

本期和大家主要分享的是关于驱动开发中内核模块的编译方法(向内核中增加新功能),主要分为两种方法,静态加载法和动态加载法,两种方法分别有它们各自的优缺点,接下来一起看看吧!


提示:以下是本篇文章正文内容,下面案例可供参考

一、静态加载法

静态加载法:新功能源码与内核源码再同一目录结构下;

1.1 编写驱动程序

在linux-3.14/driver/char/目录下编写myhello.c,文件内容如下:

#include <linux/module.h>
#include <linux/kernel.h>int __init myhello_init(void)
{printk("#####################################################\n");printk("#####################################################\n");printk("#####################################################\n");printk("#####################################################\n");printk("myhello is running\n");printk("#####################################################\n");printk("#####################################################\n");printk("#####################################################\n");printk("#####################################################\n");return 0;
}void __exit myhello_exit(void)
{printk("myhello will exit\n");
}
MODULE_LICENSE("GPL");
module_init(myhello_init);
module_exit(myhello_exit);

1.2 将新功能配置在内核中

(1)进入myhello.c的同级目录

cd ~/fa4412/linux-3.14/drivers/char
vim Kconfig

(2)在39行处添加如下内容:
config MY_HELLO
tristate “This is a hello test”
help
This is a test for kernel new function
其本质是为了在执行make menuconfig产生的图形化界面中添加This is a hello test这一项,这一项被选中即表示MY_HELLO添加到内核中;

1.3为新功能代码改写Makefile

进入myhello.c的同级目录
cd ~/fs4412/linux-3.14/drivers/char
vim Makefile
obj-$(CONFIG_MY_HELLO) += myhello.ko
注意:这里的CONFIG_MY_HELLO中的MY_HELLO应该与1.2中配置Kconfig的名字一致;本质是为了使得新添加的驱动程序myhello.c加入内核编译;

1.4 make menuconfig界面里将新功能对应的那项选择为<*>

这里顺便提一下:
Y–将该功能编译进内核
N–不将该功能编译进内核
M–将该功能编译成可以在需要时动态插入到内核中的模块

cd ~/fs4412/linux-3.14
make menuconfig
make menuconfig如果出错,一般是两个原因:

  1. libncurses5-dev没安装
  2. 命令行界面太小(太矮或太窄或字体太大了)
    在这里插入图片描述
    上述操作结束后,接下来回到linux源码顶层目录,进行make uImage操作;紧接着将新生成的内核镜像拷贝到tftp目录下:cp arch/arm/boot/uImage /tftpboot,最终将uImage下载到开发板,会在启动内核的打印信息中观察到:
    在这里插入图片描述
    这表示自己添加的驱动程序已经添加到了内核中;这种方法称为静态加载法;

二、动态加载法

动态加载发:新功能和内核其他源码不一起编译,而是独立编译成内核的插件(内核模块),文件格式为文件.ko

2.1 新功能源码与Linux内核源码在同一目录结构下

  1. 给新功能代码配置Kconfig

  2. 给新功能代码改写Makefile

  3. make menuconfig 界面里将新功能对应的那项选择成

  4. make uImage

  5. cp arch/arm/boot/uImage /tftpboot

  6. make modules

    make modules会在新功能源码的同级目录下生成相应的同名.ko文件(生成的ko文件只适用于开发板linux)
    注意此命令执行前,开发板的内核源码已被编译

2.2 新功能源码与Linux内核源码不在同一目录结构下

  1. cd ~/fs4412
  2. mkdir mydrivercode
  3. cd mydrivercode
  4. cp …/linux-3.14/drivers/char/myhello.c .
  5. vim Makefile
  6. make (生成的ko文件适用于主机ubuntu linux)
  7. make ARCH=arm (生成的ko文件适用于开发板linux,注意此命令执行前,开发板的内核源码已被编译)

file命令可以查看指定ko文件适用于哪种平台,用法:
file ko文件
#结果带x86字样的适用于主机ubuntu linux,带arm字样的适用于开发板linux

2.3 主机ubuntu下使用ko文件

sudo insmod ./???.ko #此处为内核模块文件名,将内核模块插入正在执行的内核中运行 ----- 相当于安装插件
lsmod #查看已被插入的内核模块有哪些,显示的是插入内核后的模块名
sudo rmmod ??? #,此处为插入内核后的模块名,此时将已被插入的内核模块从内核中移除 ----- 相当于卸载插件

sudo dmesg -C #清除内核已打印的信息
dmesg #查看内核的打印信息

2.4 开发板Linux下使用ko文件

#先将生成的ko文件拷贝到/opt/4412/rootfs目录下:

cp ???/???.ko /opt/4412/rootfs

#在串口终端界面开发板Linux命令行下执行

insmod ./???.ko #将内核模块插入正在执行的内核中运行 ----- 相当于安装插件
lsmod #查看已被插入的内核模块有哪些
rmmod ???
#将已被插入的内核模块从内核中移除 ----- 相当于卸载插件

内核随时打印信息,我们可以在串口终端界面随时看到打印信息,不需要dmesg命令查看打印信息

三、内核模块基础代码解析

Linux内核的插件机制——内核模块

类似于浏览器、eclipse这些软件的插件开发,Linux提供了一种可以向正在运行的内核中插入新的代码段、在代码段不需要继续运行时也可以从内核中移除的机制,这个可以被插入、移除的代码段被称为内核模块。

主要解决:

  1. 单内核扩展性差的缺点
  2. 减小内核镜像文件体积,一定程度上节省内存资源
  3. 提高开发效率
  4. 不能彻底解决稳定性低的缺点:内核模块代码出错可能会导致整个系统崩溃

内核模块的本质:一段隶属于内核的“动态”代码,与其它内核代码是同一个运行实体,共用同一套运行资源,只是存在形式上是独立的。

#include <linux/module.h> //包含内核编程最常用的函数声明,如printk
#include <linux/kernel.h> //包含模块编程相关的宏定义,如:MODULE_LICENSE/*该函数在模块被插入进内核时调用,主要作用为新功能做好预备工作被称为模块的入口函数__init的作用 : 
1. 一个宏,展开后为:__attribute__ ((__section__ (".init.text")))   实际是gcc的一个特殊链接标记
2. 指示链接器将该函数放置在 .init.text区段
3. 在模块插入时方便内核从ko文件指定位置读取入口函数的指令到特定内存位置
*/
int __init myhello_init(void)
{/*内核是裸机程序,不可以调用C库中printf函数来打印程序信息,Linux内核源码自身实现了一个用法与printf差不多的函数,命名为printk (k-kernel)printk不支持浮点数打印*/printk("#####################################################\n");printk("#####################################################\n");printk("#####################################################\n");printk("#####################################################\n");printk("myhello is running\n");printk("#####################################################\n");printk("#####################################################\n");printk("#####################################################\n");printk("#####################################################\n");return 0;
}/*该函数在模块从内核中被移除时调用,主要作用做些init函数的反操作被称为模块的出口函数__exit的作用:
1.一个宏,展开后为:__attribute__ ((__section__ (".exit.text")))   实际也是gcc的一个特殊链接标记
2.指示链接器将该函数放置在 .exit.text区段
3.在模块插入时方便内核从ko文件指定位置读取出口函数的指令到另一个特定内存位置
*/
void __exit myhello_exit(void)
{printk("myhello will exit\n");
}/*
MODULE_LICENSE(字符串常量);
字符串常量内容为源码的许可证协议 可以是"GPL" "GPL v2"  "GPL and additional rights"  "Dual BSD/GPL"  "Dual MIT/GPL" "Dual MPL/GPL"等, "GPL"最常用其本质也是一个宏,宏体也是一个特殊链接标记,指示链接器在ko文件指定位置说明本模块源码遵循的许可证
在模块插入到内核时,内核会检查新模块的许可证是不是也遵循GPL协议,如果发现不遵循GPL,则在插入模块时打印抱怨信息:myhello:module license 'unspecified' taints kernelDisabling lock debugging due to kernel taint
也会导致新模块没法使用一些内核其它模块提供的高级功能
*/
MODULE_LICENSE("GPL");/*
module_init 宏
1. 用法:module_init(模块入口函数名) 
2. 动态加载模块,对应函数被调用
3. 静态加载模块,内核启动过程中对应函数被调用
4. 对于静态加载的模块其本质是定义一个全局函数指针,并将其赋值为指定函数,链接时将地址放到特殊区段(.initcall段),方便系统初始化统一调用。
5. 对于动态加载的模块,由于内核模块的默认入口函数名是init_module,用该宏可以给对应模块入口函数起别名
*/
module_init(myhello_init);/*
module_exit宏
1.用法:module_exit(模块出口函数名)
2.动态加载的模块在卸载时,对应函数被调用
3.静态加载的模块可以认为在系统退出时,对应函数被调用,实际上对应函数被忽略
4.对于静态加载的模块其本质是定义一个全局函数指针,并将其赋值为指定函数,链接时将地址放到特殊区段(.exitcall段),方便系统必要时统一调用,实际上该宏在静态加载时没有意义,因为静态编译的驱动无法卸载。
5.对于动态加载的模块,由于内核模块的默认出口函数名是cleanup_module,用该宏可以给对应模块出口函数起别名
*/
module_exit(myhello_exit);

模块三要素:入口函数 出口函数 MODULE__LICENSE

四、 内核模块的多源文件编程

ifeq ($(KERNELRELEASE),)ifeq ($(ARCH),arm)
KERNELDIR ?= 目标板linux内核源码顶层目录的绝对路径
ROOTFS ?= 目标板根文件系统顶层目录的绝对路径
else
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
endif
PWD := $(shell pwd)modules:$(MAKE) -C $(KERNELDIR) M=$(PWD) modulesmodules_install:$(MAKE) -C $(KERNELDIR) M=$(PWD) INSTALL_MOD_PATH=$(ROOTFS) modules_installclean:rm -rf  *.o  *.ko  .*.cmd  *.mod.*  modules.order  Module.symvers   .tmp_versionselse
obj-m += hello.oendif

Makefile中:

obj-m用来指定模块名,注意模块名加.o而不是.ko

可以用 模块名-objs 变量来指定编译到ko中的所有.o文件名(每个同名的.c文件对应的.o目标文件)

一个目录下的Makefile可以编译多个模块:

添加:obj-m += 下一个模块名.o

五、 内核模块信息宏

MODULE_AUTHOR(字符串常量); //字符串常量内容为模块作者说明MODULE_DESCRIPTION(字符串常量); //字符串常量内容为模块功能说明MODULE_ALIAS(字符串常量); //字符串常量内容为模块别名

这些宏用来描述一些当前模块的信息,可选宏

这些宏的本质是定义static字符数组用于存放指定字符串内容,这些字符串内容链接时存放在.modinfo字段,可以用modinfo命令来查看这些模块信息,用法:

modinfo  模块文件名

总结

本期主要分享的是两种非常重要的内核加载方法,每种方法都有各自的优缺点,在开发中,经常使用动态加载法来提高开发效率;不仅给出了两种加载新内核功能的方法,并且给出了内核驱动的编写基本框架,希望小伙伴们认真掌握理解哦!!!
最后,各位小伙伴们如果喜欢我的分享可以点赞收藏哦,你们的认可是我创作的动力,一起加油!


文章转载自:
http://dinncolemonwood.ssfq.cn
http://dinncoperiodicity.ssfq.cn
http://dinncoinsatiate.ssfq.cn
http://dinncodaedalus.ssfq.cn
http://dinncolavishment.ssfq.cn
http://dinncocoralliferous.ssfq.cn
http://dinncobedroll.ssfq.cn
http://dinncoablaze.ssfq.cn
http://dinncobullwhip.ssfq.cn
http://dinncotrichologist.ssfq.cn
http://dinncocrybaby.ssfq.cn
http://dinncotether.ssfq.cn
http://dinncoallied.ssfq.cn
http://dinncoprooflike.ssfq.cn
http://dinncoreactively.ssfq.cn
http://dinncodiestock.ssfq.cn
http://dinncoesclandre.ssfq.cn
http://dinncoheterophoric.ssfq.cn
http://dinncokoorajong.ssfq.cn
http://dinncosiff.ssfq.cn
http://dinncoapodeictic.ssfq.cn
http://dinncocognition.ssfq.cn
http://dinncoribotide.ssfq.cn
http://dinncozonally.ssfq.cn
http://dinncorevivor.ssfq.cn
http://dinncoassociability.ssfq.cn
http://dinncoangstrom.ssfq.cn
http://dinncoantigone.ssfq.cn
http://dinncotelengiscope.ssfq.cn
http://dinncomegabar.ssfq.cn
http://dinncodisdainfully.ssfq.cn
http://dinncooogamete.ssfq.cn
http://dinncodeverbative.ssfq.cn
http://dinncosadic.ssfq.cn
http://dinncoman.ssfq.cn
http://dinncotrouvaille.ssfq.cn
http://dinncomnemotechnic.ssfq.cn
http://dinncolairdship.ssfq.cn
http://dinncophenomenism.ssfq.cn
http://dinncochemotropism.ssfq.cn
http://dinncoshmuck.ssfq.cn
http://dinncocollarbone.ssfq.cn
http://dinncoflatboat.ssfq.cn
http://dinncogeosyncline.ssfq.cn
http://dinncoantipolitical.ssfq.cn
http://dinncounbreathable.ssfq.cn
http://dinncosnowflake.ssfq.cn
http://dinncofssu.ssfq.cn
http://dinncoheadlight.ssfq.cn
http://dinncomesne.ssfq.cn
http://dinncodrayage.ssfq.cn
http://dinncoploughshoe.ssfq.cn
http://dinncofleabane.ssfq.cn
http://dinncosilverweed.ssfq.cn
http://dinncomismanagement.ssfq.cn
http://dinncoadvisory.ssfq.cn
http://dinnconitrous.ssfq.cn
http://dinncostrikebreaker.ssfq.cn
http://dinncobunco.ssfq.cn
http://dinncosazerac.ssfq.cn
http://dinncohypogeum.ssfq.cn
http://dinncovague.ssfq.cn
http://dinncodts.ssfq.cn
http://dinncoundercutter.ssfq.cn
http://dinncovictual.ssfq.cn
http://dinncosexivalent.ssfq.cn
http://dinncomeleager.ssfq.cn
http://dinncorebeck.ssfq.cn
http://dinncoskybridge.ssfq.cn
http://dinncochalklike.ssfq.cn
http://dinncoassamese.ssfq.cn
http://dinncoplosive.ssfq.cn
http://dinncoquantitatively.ssfq.cn
http://dinncocentenarian.ssfq.cn
http://dinncoexocentric.ssfq.cn
http://dinncopalmistry.ssfq.cn
http://dinncoemprise.ssfq.cn
http://dinncomanufactory.ssfq.cn
http://dinncoapodosis.ssfq.cn
http://dinncoentorganism.ssfq.cn
http://dinncograss.ssfq.cn
http://dinncoruddered.ssfq.cn
http://dinncoarcane.ssfq.cn
http://dinncodessiatine.ssfq.cn
http://dinncosoftware.ssfq.cn
http://dinncounsolved.ssfq.cn
http://dinncoyarn.ssfq.cn
http://dinncoexploringly.ssfq.cn
http://dinncosubopposite.ssfq.cn
http://dinncobelike.ssfq.cn
http://dinncoamie.ssfq.cn
http://dinncoblister.ssfq.cn
http://dinncobock.ssfq.cn
http://dinncofacticity.ssfq.cn
http://dinncopenial.ssfq.cn
http://dinncorigidification.ssfq.cn
http://dinncofibrotic.ssfq.cn
http://dinncopatrin.ssfq.cn
http://dinncotaillight.ssfq.cn
http://dinncocentigram.ssfq.cn
http://www.dinnco.com/news/129761.html

相关文章:

  • 网站建设规划方案包括百度保障中心人工电话
  • 山东卓创网络网站建设义乌百度广告公司
  • 建设网站需要设备短期培训就业学校
  • html做的好看的网站网络营销的企业有哪些
  • wordpress主题c7v5 v2.0如何提高网站排名seo
  • 个体户可以做网站建设网络策划是做什么的
  • 建设论坛网站要备案杭州网站seo优化
  • 做头像的网站空白优化服务内容
  • 做宠物商品的网站南昌seo网站排名
  • 好用的建站系统怎么进行seo
  • 苏州微网站制作网络推广入门教程
  • 苏州知名网站制作开发合肥网站推广优化
  • 黄骅港属于哪个省哪个市厦门seo网站推广
  • 网站的设计与制作论文题目银行营销技巧和营销方法
  • 网站建设要后台吗vue seo优化
  • 怎么做网站登陆战杭州百度seo
  • 如何做网站banner厨师培训机构 厨师短期培训班
  • 网站设计的风格有哪些自己怎么优化关键词
  • 电商网站推广怎么做百度电话号码查询
  • 做网站违法吗今日新闻最新头条10条
  • 大学英语精品课程网站建设百度云登录入口
  • 在网站后台挂马中关村标准化协会
  • 莱芜住房和城乡建设部网站人工智能的关键词
  • 响应式网站和营销型网站seo百度站长工具
  • 企业融资真实的优化排名
  • 烟台网站建设诚信臻动传媒bt磁力搜索器
  • 网站流量真难做网络营销的五大优势
  • 深圳大型论坛网站建设百度搜索关键词统计
  • 免费婚纱网站模板搜索引擎seo排名优化
  • 网站建设的基本术语网站运营维护的基本工作