在Linux里面有很多的后缀。
.ko 是kernel object 的缩写,是Linux 2.6内核使用的动态连接文件,在Linux系统启动时加载内核模块。
.o 是相当于windows中的.obj文件
注意:.ko与.o的区别在于,.ko是linux 2.6内核编译之后生成的,多了一些module信息,如author,license之类的。.o文件则是linux 2.4内核编译生成的。
.a 是静态库,由多个.o组成在一起,用于静态连接
.so 是shared object的缩写,用于动态连接,和windows的dll差不多
.la 为libtool自动生成的一些共享库。
那么为什么要独独了解一下ko呢?这个上面的描述还不清楚。其实.ko文件是kernel object文件(内核模块),该文件的意义就是把内核的一些功能移动到内核外边, 需要的时候插入内核,不需要时卸载。
而我要去实现一个功能,然后去测试一下,编译整版镜像肯定是很麻烦的。所以就编译个ko,插进去,用完了。卸载掉。(以前刚刚搞这方面的时候,经常有人说写个ko去试一下,我寻思这是啥,怎么用,用在哪里。)
(问问题当是好,但是把这些简单的问题拿去耽误大佬的时间,他也很无奈,我也有点不好意思,于是这里记录一下笔记与兄弟们一起学习。)
这里知道了ko是什么,下面看看怎么实现。
其实怎么写,没什么好多啰嗦的。整个模板一看,你就知道这个玩意大概怎么玩的了。
还是万年的hello word。
本来的源码:
#include "helloworld.h"
MODULE_LICENSE("GPL"); ///module证书?
static int hello_init(void) ///加载ko,insmod
{
printk("999 Hello, world\n");
test_world();
return 0;
}
static void hello_exit(void) ///卸载ko,rmmod
{
printk("Goodbye, cruel world\n");
}
怎么成为一个module:
#include ///这两个为内核编译必备头文件
#include
#include "helloworld.h"
MODULE_LICENSE("GPL"); ///module证书?
static int hello_init(void) ///加载ko,insmod
{
printk("999 Hello, world\n");
return 0;
}
static void hello_exit(void) ///卸载ko,rmmod
{
printk("Goodbye, cruel world\n");
}
module_init(hello_init); ///每个ko文件的最后都必须有module_init和module_exit
module_exit(hello_exit);
有什么区别呢?
增加了几句代码
#include ///这两个为内核编译必备头文件
#include
module_init(hello_init); ///每个ko文件的最后都必须有module_init和module_exit
module_exit(hello_exit);
MODULE_LICENSE("GPL V2");
obj-m := ///这个后面即是最后生成的**.ko,此处为start.ko。可以并列多个。
**-objs := ///**和你上面的ko名字对应,后面的为生成这个ko所需的.o文件(由同名的.c文件编译)
LINUX_KERNEL := $(shell uname -r) ///uname -r 查看内核版本
LINUX_KERNEL_PATH :=/usr/src/linux-headers-${LINUX_KERNEL}/ ///这个即为内核版本文件夹路径
PWD :=$(shell pwd) ///pwd 当前目录
modules :
$(MAKE) -C $(LINUX_KERNEL_PATH) M=$(PWD) modules
.PHONEY:clean
clean : /// make clean 时删除 .o .ko .mod.c
rm -f *.o *.ko *.mod.c
这个makefile文件的大概意思,就是模块名字,编译进去的文件,以及make命令执行的内容。
make一下就会生成对应的ko,要是有什么报错,就根据报错信息解决就行。
编译了以后怎么用呢?很简单。我们前面说过这个ko是对内核的增删丰富。
安装方法一:
insmod mydriver.ko
安装方法二:
将mydriver.ko文件拷贝到可加载驱动所在目录下 /lib/modules/3.10.0-693.el7.x86_64/
需要查看自己的目录是什么。
[root@ht5 src]# uname -r
3.10.0-1160.42.2.el7.x86_64
然后:
[root@ht5 src]# depmod
//depmod 会在/lib/modules/3.10.0-693.el7.x86_64/目录下生成modules.dep和modules.dep.bb文件
[root@ht5 src]# modprobe -r mydriver //注意这里无需输入.ko后缀
那么这两种的方法有啥区别?
modprobe和insmod类似,都是用来动态加载驱动模块的,区别在于modprobe可以解决load module时的依赖关系,
它是通过/lib/modules/#uname -r/modules.dep(.bb)文件来查找依赖关系的;而insmod不能解决依赖问题。也就是说,如果你确定你要加载的驱动模块不依赖其他驱动模块的话,
既可以insmod也可以modprobe,当然insmod可以在任何目录下执行,更方便一些。而如果你要加载的驱动模块还依赖其他ko驱动模块的话,就只能将模块拷贝到上述的特定目录,(这个会在进阶版本整个栗子)
lsmod 查看所有已经安装的ko
[root@ht5 src]# lsmod | grep mydriver
mydriver 12496 0
[root@ht5 src]# modinfo mydriver.ko
filename: /usr/local/src/mydriver.ko
version: 1.0
description: mydriver
author: jinzs
license: GPL
retpoline: Y
rhelversion: 7.9
srcversion: FCA9B81CB0D8E3B092F2759
depends:
vermagic: 3.10.0-1160.59.1.el7.x86_64 SMP mod_unload modversions
[root@ht5 src]# rmmod mydriver
//注:"module_name"是lsmod显示的模块名称,而不是对应的ko文件名
本例子中命令行下执行命令:rmmod mydriver.ko即可。
查看cat /var/log/messages.
可以看到下面这样的信息:“Aug 6 13:40:36 localhost kernel: Goodbye, cruel world”,说明模块卸载成功。
[root@ht5 src]# nm mydriver.ko
0000000000000020 T cleanup_module
U __fentry__
0000000000000020 t mydriver_exit
0000000000000000 t mydriver_init
0000000000000000 T init_module
000000000000004b r __module_depends
U printk
0000000000000000 D __this_module
0000000000000000 r __UNIQUE_ID_license8
000000000000000c r __UNIQUE_ID_retpoline11
0000000000000018 r __UNIQUE_ID_rhelversion10
0000000000000028 r __UNIQUE_ID_srcversion9
0000000000000054 r __UNIQUE_ID_vermagic8
0000000000000000 r ____versions
[root@ht5 src]# cat /lib/modules/$(uname -r)/modules.builtin
kernel/arch/x86/crypto/aes-x86_64.ko
kernel/arch/x86/crypto/sha1-ssse3.ko
kernel/arch/x86/crypto/sha256-ssse3.ko
kernel/arch/x86/events/intel/intel-rapl-perf.ko
kernel/arch/x86/events/intel/intel-uncore.ko
kernel/arch/x86/kernel/msr.ko
kernel/arch/x86/kernel/cpuid.ko
kernel/mm/zpool.ko
kernel/mm/zbud.ko
kernel/mm/zsmalloc.ko
kernel/fs/binfmt_script.ko
kernel/fs/autofs4/autofs4.ko
kernel/fs/configfs/configfs.ko
kernel/fs/efivarfs/efivarfs.ko
kernel/fs/exportfs/exportfs.ko
kernel/fs/nls/nls_base.ko
kernel/fs/nls/nls_cp437.ko
kernel/fs/nls/nls_ascii.ko
kernel/fs/quota/quota_v2.ko
kernel/fs/quota/quota_tree.ko
kernel/security/keys/trusted.ko
kernel/security/keys/encrypted-keys/encrypted-keys.ko
kernel/crypto/crypto.ko
kernel/crypto/crypto_wq.ko
kernel/crypto/crypto_algapi.ko
kernel/crypto/aead.ko
kernel/crypto/crypto_blkcipher.ko
kernel/crypto/chainiv.ko
kernel/crypto/eseqiv.ko
kernel/crypto/seqiv.ko
kernel/crypto/crypto_hash.ko
kernel/crypto/pcompress.ko
kernel/crypto/akcipher.ko
kernel/crypto/kpp.ko
kernel/crypto/acompress.ko
kernel/crypto/scompress.ko
kernel/crypto/cryptomgr.ko
kernel/crypto/hmac.ko
kernel/crypto/md5.ko
kernel/crypto/sha1_generic.ko
kernel/crypto/sha256_generic.ko
kernel/crypto/ecb.ko
kernel/crypto/cbc.ko
kernel/crypto/ctr.ko
kernel/crypto/aes_generic.ko
kernel/crypto/crc32c.ko
kernel/crypto/lzo.ko
kernel/crypto/rng.ko
kernel/crypto/af_alg.ko
kernel/crypto/algif_hash.ko
kernel/crypto/algif_skcipher.ko
kernel/crypto/asymmetric_keys/asymmetric_keys.ko
kernel/crypto/asymmetric_keys/public_key.ko
kernel/crypto/asymmetric_keys/rsa.ko
kernel/crypto/asymmetric_keys/x509_key_parser.ko
kernel/crypto/asymmetric_keys/pkcs7_message.ko
kernel/block/deadline-iosched.ko
kernel/block/cfq-iosched.ko
kernel/block/mq-deadline.ko
kernel/block/kyber-iosched.ko
kernel/drivers/acpi/ac.ko
kernel/drivers/acpi/button.ko
kernel/drivers/acpi/fan.ko
kernel/drivers/acpi/processor.ko
kernel/drivers/acpi/thermal.ko
kernel/drivers/acpi/battery.ko
kernel/drivers/acpi/hed.ko
kernel/drivers/base/firmware_class.ko
kernel/drivers/char/raw.ko
kernel/drivers/char/nvram.ko
kernel/drivers/char/crash.ko
kernel/drivers/char/agp/agpgart.ko
kernel/drivers/char/agp/amd64-agp.ko
kernel/drivers/char/agp/intel-agp.ko
kernel/drivers/char/agp/intel-gtt.ko
kernel/drivers/char/agp/sis-agp.ko
kernel/drivers/char/agp/via-agp.ko
kernel/drivers/char/hw_random/rng-core.ko
kernel/drivers/char/tpm/tpm.ko
kernel/drivers/char/tpm/tpm_tis_core.ko
kernel/drivers/char/tpm/tpm_tis.ko
kernel/drivers/connector/cn.ko
kernel/drivers/cpufreq/cpufreq_performance.ko
kernel/drivers/cpufreq/cpufreq_powersave.ko
kernel/drivers/cpufreq/cpufreq_userspace.ko
kernel/drivers/cpufreq/cpufreq_ondemand.ko
kernel/drivers/cpufreq/cpufreq_conservative.ko
kernel/drivers/dax/dax.ko
kernel/drivers/edac/edac_core.ko
kernel/drivers/firmware/dmi-sysfs.ko
kernel/drivers/firmware/qemu_fw_cfg.ko
kernel/drivers/firmware/efi/efivars.ko
kernel/drivers/firmware/efi/efi-pstore.ko
kernel/drivers/hid/hid.ko
kernel/drivers/hid/hid-generic.ko
kernel/drivers/hid/hid-a4tech.ko
kernel/drivers/hid/hid-apple.ko
kernel/drivers/hid/hid-belkin.ko
kernel/drivers/hid/hid-cherry.ko
kernel/drivers/hid/hid-chicony.ko
kernel/drivers/hid/hid-cypress.ko
kernel/drivers/hid/hid-ezkey.ko
kernel/drivers/hid/hid-kensington.ko
kernel/drivers/hid/hid-logitech.ko
kernel/drivers/hid/hid-magicmouse.ko
kernel/drivers/hid/hid-microsoft.ko
kernel/drivers/hid/hid-monterey.ko
kernel/drivers/hid/hid-ntrig.ko
kernel/drivers/hid/hid-plantronics.ko
kernel/drivers/hid/intel-ish-hid/intel-ishtp.ko
kernel/drivers/hid/intel-ish-hid/intel-ish-ipc.ko
kernel/drivers/hid/intel-ish-hid/intel-ishtp-hid.ko
kernel/drivers/hid/usbhid/usbhid.ko
kernel/drivers/hwmon/hwmon.ko
kernel/drivers/i2c/i2c-core.ko
kernel/drivers/iio/industrialio.ko
kernel/drivers/iio/buffer/industrialio-buffer-cb.ko
kernel/drivers/iio/buffer/kfifo_buf.ko
kernel/drivers/input/input-core.ko
kernel/drivers/input/ff-memless.ko
kernel/drivers/input/input-leds.ko
kernel/drivers/input/mousedev.ko
kernel/drivers/input/evdev.ko
kernel/drivers/input/keyboard/atkbd.ko
kernel/drivers/input/mouse/psmouse.ko
kernel/drivers/input/serio/serio.ko
kernel/drivers/input/serio/i8042.ko
kernel/drivers/input/serio/serport.ko
kernel/drivers/input/serio/libps2.ko
kernel/drivers/iommu/iova.ko
kernel/drivers/leds/led-class.ko
kernel/drivers/macintosh/mac_hid.ko
kernel/drivers/md/md-mod.ko
kernel/drivers/mfd/mfd-core.ko
kernel/drivers/mfd/intel-lpss.ko
kernel/drivers/mfd/intel-lpss-pci.ko
kernel/drivers/mfd/intel-lpss-acpi.ko
kernel/drivers/net/phy/libphy.ko
kernel/drivers/net/phy/realtek.ko
kernel/drivers/net/phy/fixed_phy.ko
kernel/drivers/nvmem/nvmem_core.ko
kernel/drivers/pci/pci-stub.ko
kernel/drivers/pcmcia/pcmcia_core.ko
kernel/drivers/pcmcia/pcmcia_rsrc.ko
kernel/drivers/platform/x86/pvpanic.ko
kernel/drivers/rtc/rtc-cmos.ko
kernel/drivers/scsi/scsi_mod.ko
kernel/drivers/scsi/device_handler/scsi_dh.ko
kernel/drivers/scsi/device_handler/scsi_dh_rdac.ko
kernel/drivers/scsi/device_handler/scsi_dh_hp_sw.ko
kernel/drivers/scsi/device_handler/scsi_dh_emc.ko
kernel/drivers/scsi/device_handler/scsi_dh_alua.ko
kernel/drivers/thermal/thermal_sys.ko
kernel/drivers/thunderbolt/thunderbolt.ko
kernel/drivers/tty/serial/serial_core.ko
kernel/drivers/tty/serial/kgdboc.ko
kernel/drivers/tty/serial/8250/8250.ko
kernel/drivers/tty/serial/8250/8250_pci.ko
kernel/drivers/tty/serial/8250/8250_dw.ko
kernel/drivers/usb/common/usb-common.ko
kernel/drivers/usb/core/usbcore.ko
kernel/drivers/usb/host/ehci-hcd.ko
kernel/drivers/usb/host/ehci-pci.ko
kernel/drivers/usb/host/ohci-hcd.ko
kernel/drivers/usb/host/ohci-pci.ko
kernel/drivers/usb/host/uhci-hcd.ko
kernel/drivers/usb/host/xhci-hcd.ko
kernel/drivers/usb/host/xhci-pci.ko
kernel/drivers/usb/mon/usbmon.ko
kernel/drivers/usb/serial/usbserial.ko
kernel/drivers/usb/typec/typec.ko
kernel/drivers/usb/typec/altmodes/typec_displayport.ko
kernel/drivers/usb/typec/ucsi/typec_ucsi.ko
kernel/drivers/usb/typec/ucsi/ucsi_acpi.ko
kernel/drivers/video/fb.ko
kernel/drivers/video/cfbfillrect.ko
kernel/drivers/video/cfbcopyarea.ko
kernel/drivers/video/cfbimgblt.ko
kernel/drivers/video/backlight/backlight.ko
kernel/drivers/video/console/fbcon.ko
kernel/drivers/video/console/bitblit.ko
kernel/drivers/video/console/font.ko
kernel/drivers/video/console/softcursor.ko
kernel/drivers/video/console/tileblit.ko
kernel/drivers/video/console/fbcon_rotate.ko
kernel/drivers/video/console/fbcon_cw.ko
kernel/drivers/video/console/fbcon_ud.ko
kernel/drivers/video/console/fbcon_ccw.ko
kernel/drivers/xen/xenbus/xenbus_probe_frontend.ko
kernel/arch/x86/pci/vmd.ko
kernel/arch/x86/video/fbdev.ko
kernel/net/core/drop_monitor.ko
kernel/net/core/netprio_cgroup.ko
kernel/net/ipv4/inet_lro.ko
kernel/net/ipv4/tcp_cubic.ko
kernel/net/ipv6/ipv6.ko
kernel/net/ipv6/inet6_hashtables.ko
kernel/net/mpls/mpls_gso.ko
kernel/net/netfilter/x_tables.ko
kernel/net/netfilter/xt_tcpudp.ko
kernel/net/packet/af_packet.ko
kernel/net/sched/cls_cgroup.ko
kernel/net/unix/unix.ko
kernel/net/xfrm/xfrm_algo.ko
kernel/net/xfrm/xfrm_user.ko
kernel/lib/test-kstrtox.ko
kernel/lib/bitrev.ko
kernel/lib/crc16.ko
kernel/lib/crc32.ko
kernel/lib/digsig.ko
kernel/lib/asn1_decoder.ko
kernel/lib/oid_registry.ko
kernel/lib/ucs2_string.ko
kernel/lib/lzo/lzo_compress.ko
kernel/lib/lzo/lzo_decompress.ko
kernel/lib/mpi/mpi.ko
kernel/lib/xz/xz_dec.ko
kernel/lib/zlib_deflate/zlib_deflate.ko
kernel/lib/zlib_inflate/zlib_inflate.ko
在 /sys/module目录下,你可以找到内核模块(包含内置和可加载的)命名的子目录
进入每个模块目录,这里有个“parameters”目录,列出了这个模块所有的参数。
[root@ht5 src]# cd /sys/module
[root@ht5 module]# ls
8250 cryptd hid ipt_REJECT nf_conntrack ppdev suspend vmw_vsock_vmci_transport
ablk_helper debug_core hid_apple ip_tunnel nf_conntrack_ipv4 printk syscopyarea vmxnet3
acpi dm_log hid_magicmouse ipv6 nf_conntrack_ipv6 processor sysfillrect vsock
acpiphp dm_mirror hid_ntrig ip_vs nf_conntrack_netlink psmouse sysimgblt vt
aesni_intel dm_mod i2c_piix4 joydev nf_defrag_ipv4 pstore sysrq watchdog
ata_generic dm_region_hash i8042 kdb_main nf_defrag_ipv6 rcupdate tcp_cubic workqueue
ata_piix drm intel_idle kernel nf_nat rcutree thermal xfs
battery drm_kms_helper intel_ishtp keyboard nf_nat_ipv4 rng_core tpm xhci_hcd
block drm_panel_orientation_quirks iosf_mbi kgdboc nf_nat_ipv6 sb_edac tpm_tis xt_addrtype
bridge dynamic_debug ip6table_nat kgdbts nf_nat_masquerade_ipv4 scsi_dh_alua tpm_tis_core xt_comment
br_netfilter edac_core ip6_tables libata nf_reject_ipv4 scsi_dh_rdac ttm xt_conntrack
cdrom efi_pstore ipip libcrc32c overlay scsi_mod tunnel4 xt_mark
configfs efivars ip_set llc parport scsi_transport_sas uhci_hcd xt_multiport
coretemp ehci_hcd ip_set_hash_ip lrw parport_pc sd_mod usbcore xt_nat
cpuidle fb_sys_fops ip_set_hash_net md_mod pata_acpi serio_raw usbhid xt_recent
crc32c_intel firmware_class iptable_filter module pcie_aspm sg uv_nmi xt_set
crc32_pclmul gf128mul iptable_mangle mousedev pciehp shpchp veth xt_statistic
crc_t10dif ghash_clmulni_intel iptable_nat mptbase pci_hotplug spurious vmd xz_dec
crct10dif_common glue_helper iptable_raw mptsas pci_slot sr_mod vmw_balloon zswap
crct10dif_generic haltpoll ip_tables mptscsih pcmcia_core stp vmwgfx
crct10dif_pclmul mydriver ipt_MASQUERADE netpoll pcspkr sunrpc vmw_vmci
回归初心,现在我们来看看为什么要用ko?
(1)这样可以缩小内核体积;
(2)使用方便。
(1)作为一个功能模块,需要使用时,直接插入运行就行。
如在imx6上连接模拟摄像头,先运行模拟摄像头对应的驱动模块 camera.ko文件,然后对应的工程执行文件运行就行。
[root@ht5 src]# dmesg | grep mydriver
[3334186.411879] mydriver: loading out-of-tree module taints kernel.
[3334186.411922] mydriver: module verification failed: signature and/or required key missing - tainting kernel确认是否签名是否被加载[root@ht5 src]# modinfo -F signer mydriver.ko //执行后无提示
[root@ht5 src]# cd /lib/modules/3.10.0-327.el7.x86_64/kernel/drivers/ [root@ht5 drivers]# ls acpi bcma char dma gpu i2c iommu media misc ntb platform ptp staging uio vhost xen ata block cpufreq edac hid idle isdn memstick mmc parport power rtc target usb video auxdisplay bluetooth crypto firewire hv infiniband leds message mtd pci powercap scsi thermal uwb virtio base cdrom dca firmware hwmon input md mfd net pcmcia pps ssb tty vfio watchdog [root@ht5 drivers]# cd net/ [root@ht5 net]# ls bonding ethernet ieee802154 macvlan.ko mdio.ko netconsole.ko ntb_netdev.ko ppp team usb virtio_net.ko vxlan.ko wireless dummy.ko hyperv ifb.ko macvtap.ko mii.ko nlmon.ko phy slip tun.ko veth.ko vmxnet3 wan xen-netfront.ko [root@ht5 net]# modinfo -F signer ifb.ko CentOS Linux kernel signing key
[root@ht5 net]# modinfo -F signer tun.ko CentOS Linux kernel signing key
[root@ht5 net]# modinfo tun | grep '^sig' signer: CentOS Linux kernel signing key sig_key: 28:FD:E6:60:84:9F:DF:48:DE:A9:1B:48:B8:0B:17:B5:6C:E1:51:98 sig_hashalgo: sha256
[root@ht5 net]# hexdump -C tun.ko | tail 0000bea0 5a da 53 36 67 22 a1 fd 16 ab d1 7c c6 84 e4 8b |Z.S6g".....|....| 0000beb0 45 03 6a 10 dc b3 37 6b 52 18 ea 7b 27 06 0b b2 |E.j...7kR..{'...| 0000bec0 59 a6 86 53 4e 20 72 b2 b0 95 aa 3f 2d e4 28 fc |Y..SN r....?-.(.| 0000bed0 92 18 a3 cf c2 58 40 75 7d 76 f9 65 d1 8c ac dd |.....X@u}v.e....| 0000bee0 ec a1 83 0c 8f 62 ef 4f 30 4d 3d ef db 3b 4a 5e |.....b.O0M=..;J^| 0000bef0 08 9f 18 b9 82 77 3f dc 4c 92 aa 59 c6 01 04 01 |.....w?.L..Y....| 0000bf00 1f 14 00 00 00 00 00 01 82 7e 4d 6f 64 75 6c 65 |.........~Module| 0000bf10 20 73 69 67 6e 61 74 75 72 65 20 61 70 70 65 6e | signature appen| 0000bf20 64 65 64 7e 0a |ded~.| 0000bf25
使用insmod命令加载编写的驱动模块,在用demesg出现信息:loading out-of-tree module taints kernel。 模块还是能够被加载。
并且卸载后再次加载时,该提示信息没有再次出现。关于taint资料很多,查查就知道了
部分内核被污染的原因: 加载非GPL兼容的内核模块 驱动程序的使用,它们是内核源代码的一部分,但尚未经过全面测试 使用内核源代码未包含的树外模块
强制加载不是为当前内核版本构建的模块 某些严重错误,例如machine check exceptions(MCE)和kernel oopses
参考
原文链接:
https://blog.csdn.net/IT_xiao_bai0516/article/details/121778785
https://www.cnblogs.com/aozhejin/p/16070187.html
https://blog.csdn.net/weixin_43690845/article/details/105606112
https://blog.csdn.net/let_he_write/article/details/109782829