复杂度3/5
机密度4/5
最后更新2021/05/18
前面介绍过内核扩展也是一种执行程序,与普通执行程序不同的是它需要被加载到内核中执行,拥有内核权限。我们先来看看加载、卸载和内核扩展程序本体。
加载需要用到cfg_kmod结构和sysconfig系统调用,前者对要加载的程序进行描述,后者完成加载(或卸载)过程。要注意,不止sysconfig,还有好几个类似的系统调用都完成类似的功能,他们之间没有本质区别,只是适用场景(方便程度)不同,例如,有的调用一步完成加载及初始化,有的则分为若干步,需要使用不同参数,重复执行几次。
int sysconfig (Cmd, Parmp, Parmlen)
int Cmd; /* 子功能,使用同一调用,设置不同功能可以分别完成加载、
初始化、卸载等多个功能,例如:
SYS_KLOAD 加载内核扩展;
SYS_SINGLELOAD 同上,不同的是会检测内核扩展是否已加载,如果没加载过,则加载,而前者则是不管是否加载过,都再加载一次。此功能等于帮你做了查询+加载;
SYS_QUERYLOAD 查询内核扩展是否已经被加载。那查询的依据是什么?
很傻的,依据是被加载程序的路径,而且只是路径字符,如果分别给绝对
路径和相对路径,那该命令会人为是不同的内核扩展。再回到SINGLELOAD
的疑问,如果使用SYS_KLOAD加载了两次怎么办?凉拌,内核不管的,
随便你加载几次,卸载的时候根据kmid这个唯一值卸载。
另一个问题?谁会被使用?如果能定位(通过kmid)则用确定的程序,
如果不能定位,一般是最后加载的最优先,前面的就变成死代码;
SYS_KULOAD 卸载;
SYS_QDVSW 查询设备表,设备表是让被加载程序能被执行的关键方案之一,
我们以后说(另一个方案是export 函数名,把加载的程序当成库函数使用)
当然还有一次性的,由用用户态加载程序触发的初始化dd方案,既下一个命令;
SYS_CFGDD 告知内核去执行被加载的程序,一般内核扩展被加载到内存,
下一件事就是执行这个,让它自己把自己初始化好。sysconfig调用执行这个命令后
会让内核从被加载程序的入口点执行(关于入口设置稍后介绍);
SYS_CFGKMOD 与上一