1. kernel module
loadable kernel module (LKM) 可加載內核模塊
LKM一般用於添加對新硬件(做爲設備驅動程序)和/或文件系統的支持,或用於添加系統調用。
當再也不須要LKM提供的功能時,能夠卸載它以釋放內存和其餘資源。
目前大多數類Unix系統和微軟的Windows都支持可裝載內核模塊,雖然他們可能會使用不一樣的名稱:
- loadable kernel module (LKM) in Linux, 可加載內核模塊
- kernel loadable module (kld) in FreeBSD, 內核可加載模塊
- kernel extension (kext) in macOS, 內核擴展(Apple)
- kernel extension module in AIX, 內核擴展模塊(IBM)
- kernel-mode driver in Windows NT, 內核模式驅動(Microsoft)
- downloadable kernel module (DKM) in VxWorks, 可下載內核模塊
- kernel loadable modules (or KLM), 內核可加載模塊
- and simply as kernel modules (KMOD). 內核模塊
2. Linux kernel module
Linux內核是一個自由和開放源碼,單片,類Unix 操做系統 內核。負責管理計算機硬件資源。
操做系統中的實現
Linux中的可加載內核模塊由modprobe命令加載(和卸載)。
內核模塊文件位於/lib/modules中,從2.6版開始使用擴展名.ko(「內核對象」)(之前的版本使用.o擴展名)。
$ ls -Rl /lib/modules/5.1.15-arch1-1-ARCH //列出全部內核模塊
在緊急狀況下,當系統因爲模塊損壞而沒法啓動時,能夠經過修改內核啓動參數列表來啓用或禁用特定模塊
(例如,若是使用GRUB,則經過在GRUB開始菜單中按「e」,而後編輯內核參數行)。
2.1 管理模塊的實用程序。
- insmod 加載內核模塊的簡單程序。建議使用modprobe (8), 這更聰明,能夠處理模塊依賴。
- rmmod 卸載(可卸載內核模塊)的簡單程序。建議使用(modprobe -r)。
-
lsmod 列出當前加載的內核模塊,(地格式化/proc/modules的內容).
- $ lsmod
- $ cat /proc/modules
-
depmod 輸出適合modprobe實用程序的依賴項列表。(生成modules.dep和映射文件)
- $ cat /lib/modules/'uname -r'/modules.dep
- $ cat /lib/modules/5.1.15-arch1-1-ARCH/modules.dep
- modprobe 在Linux內核中加載/卸載模塊, 可自動加載依賴模塊。
- modinfo 顯示有關Linux內核模塊的信息
modinfo(8)可用於從模塊自己提取模塊的依賴關係,但不知作別名或安裝命令。
僅報告最多見的錯誤消息:因爲嘗試連接模塊的工做如今在內核中完成,所以dmesg一般會提供有關錯誤的更多信息。
2.1.1 depmod 選項
depmod將輸出適合modprobe實用程序的依賴項列表。
-a, | --all | Probe all modules | 探測全部模塊 (默認選項) |
-A, | --quick | Only does the work if there's a new module | 只有在有新模塊時才能工做 |
-e, | --errsyms | Report not supplied symbols | 報告未提供符號 |
-n, | --show | Write the dependency file on stdout only | 僅在stdout上寫入依賴文件 |
-P, | --symbol-prefix | Architecture symbol prefix | 建築符號前綴. 指定要忽略的前綴字符 (例如"_")。 |
-C, | --config=PATH | Read configuration from PATH | 從PATH中讀取配置 |
-v, | --verbose | Enable verbose mode | 啓用詳細模式. 打印(stdout)每一個模塊所依賴的全部符號以及提供該符號的模塊文件名。 |
-w, | --warn | Warn on duplicates | 警告重複的依賴項,別名,符號版本等。 |
-V, | --version | show version | 顯示版本 |
-h, | --help | show this help | 顯示這個幫助 |
如下選項對於管理分發的人員很是有用:
-b, | --basedir=DIR | If your modules are not currently in the (normal) directory /lib/modules/version, but in a staging area, you can specify a basedir which is prepended to the directory name. This basedir is stripped from the resulting modules.dep file, so it is ready to be moved into the normal location. Use this option if you are a distribution vendor who needs to pre-generate the meta-data files rather than running depmod again later. |
使用模塊樹的圖像。 若是您的模塊當前不在(普通)目錄/lib/modules/version中,而是在暫存區域中,則能夠指定一個基於目錄名稱的basedir。從生成的modules.dep文件中刪除此basedir,所以能夠將其移動到正常位置。若是您是須要預生成元數據文件而不是稍後再次運行depmod的分發供應商,請使用此選項。 |
-e, | --errsyms | When combined with the -F option, this reports any symbols which a module needs which are not supplied by other modules or the kernel. Normally, any symbols not provided by modules are assumed to be provided by the kernel (which should be true in a perfect world), but this assumption can break especially when additionally updated third party drivers are not correctly installed or were built incorrectly. |
報告未提供符號 與-F選項結合使用時,會報告模塊須要的任何符號,這些符號不是由其餘模塊或內核提供的。一般,模塊未提供的任何符號都假定由內核提供(在完美的世界中應該是真的),可是當額外更新的第三方驅動程序未正確安裝或構建不正確時,此假設可能會中斷。 |
-F, | --filesyms=FILE | Supplied with the System.map produced when the kernel was built, this allows the -e option to report unresolved symbols. This option is mutually incompatible with -E. |
使用該文件而不是當前的內核符號。 隨內核生成時生成的System.map一塊兒提供,這容許-e選項報告未解析的符號。此選項與-E互不兼容。 |
-E, | --symvers=FILE | When combined with the -e option, this reports any symbol versions supplied by modules that do not match with the symbol versions provided by the kernel in its Module.symvers. This option is mutually incompatible with -F. |
使用Module.symvers文件檢查符號版本。 與-e選項結合使用時,會報告模塊提供的任何符號版本,這些符號版本與其Module.symvers中內核提供的符號版本不匹配。此選項與-F互不兼容。 |
2.1.2 modprobe 選項
Management Options:
-a, | --all | Consider every non-argument to be a module name to be inserted or removed (-r) | 載入所有的模塊。將每一個非參數視爲要插入或刪除的模塊名稱(-r) |
-r, | --remove | Remove modules instead of inserting | 刪除模塊而不是插入 |
--remove-dependencies | Also remove modules depending on it | 此外,根據它刪除模塊 | |
-R, | --resolve-alias | Only lookup and print alias and exit | 打印與別名匹配的全部模塊名稱。 |
--first-time | Fail if module already inserted or removed | 若是已插入或刪除模塊,則失敗 | |
-i, | --ignore-install | Ignore install commands | 忽略安裝命令 |
-i, | --ignore-remove | Ignore remove commands | 忽略刪除命令 |
-b, | --use-blacklist | Apply blacklist to resolved alias. | 將黑名單應用於已解決的別名。一般由udev(7)使用。 |
-f, | --force | Force module insertion or removal. Implies --force-modversions and –force-vermagic |
強制模塊插入或移除。 (保護機制 謹慎使用) 暗示--force-modversions和-force-vermagic |
--force-modversion | Ignore module's version | 忽略模塊的版本 (保護機制 謹慎使用) | |
--force-vermagic | Ignore module's version magic | 忽略模塊的版本魔力(保護機制 謹慎使用) |
Query Options:
-D, | --show-depends | Only print module dependencies and exit | 打印模塊依賴項. 以「insmod」開頭,一般由分發使用,以肯定生成initrd/initramfs映像時要包含哪些模塊。 |
-c, | --showconfig | Print out known configuration and exit | 打印已知配置並退出 arch:(wc -l 43700) |
--show-modversions | Dump module symbol version and exit | 轉儲模塊符號版本並退出 ( --dump-modversions) | |
--show-exports | Only print module exported symbol versions and exit | 僅打印模塊導出符號版本並退出 |
General Options:
-n, | --dry-run --show | Do not execute operations, just print out | 不要執行操做,只需打印出來。與-v結合使用,可用於調試問題。 |
-C, | --config=FILE | Use FILE instead of default search paths | 使用FILE而不是默認搜索路徑。會覆蓋缺省配置目錄(/etc/modprobe.d)。 |
-d, | --dirname=DIR | Use DIR as filesystem root for /lib/modules | 使用DIR做爲/lib/modules的文件系統根目錄 |
-S, | --set-version=VERSION | Use VERSION instead of `uname -r` | 使用VERSION而不是`uname -r` (它決定了在哪裏找到模塊) |
-s, | --syslog | print to syslog, not stderr | 打印到syslog,而不是stderr。當stderr不可用時,也會自動啓用此功能。 |
-q, | --quiet | disable messages | 禁用消息 但仍將以非零退出狀態返回。內核使用它來機會性地探測使用request_module可能存在的模塊。 |
-v, | --verbose | enables more messages | 啓用更多消息 |
-V, | --version | show version | 顯示版本 |
-h, | --help | show this help | 顯示這個幫助 |
2.1.3 modinfo 選項
-a, | --author | Print only 'author' | 僅打印'做者' |
-d, | --description | Print only 'description' | 僅打印'描述' |
-l, | --license | Print only 'license' | 僅打印'許可' |
-p, | --parameters | Print only 'parm' | 僅打印'參數' |
-n, | --filename | Print only 'filename' | 僅打印'文件名' |
-0, | --null | Use \0 instead of \n | 使用\0(ASCII零字符)分隔字段,而不是\n換行. |
-F, | --field=FIELD | Print only provided FIELD | 僅打印提供FIELD, (author, description, license, parm, depends, alias) |
-k, | --set-version=VERSION | Use VERSION instead of 'uname -r' | 使用VERSION而不是'uname -r' |
-b, | --basedir=DIR | Use DIR as filesystem root for /lib/modules | 使用DIR做爲/lib/modules的文件系統根目錄 |
-V, | --version | Show version | 顯示版本 |
-h, | --help | Show this help | 顯示此幫助 |
2.2 內核目錄
/lib/modules/'uname -r'/
$ ls -Rl /lib/modules/5.1.15-arch1-1-ARCH/ |grep ko.xz |wc -l //列出全部內核模塊,這裏的arch裏有 5474個
$ lsmod |wc -l //當前arch系統加載的有96個。
$ ls -l /lib/modules/'uname -r'/
$ ls -l /lib/modules/5.1.15-arch1-1-ARCH/
size | /lib/modules/’uname -r’/ | 描述 n/示例內容 | wc -l |
213.9 kb | modules.order | (.ko) 模塊 [清單] kernel/drivers/gpu/drm/i915/i915.ko |
5474 |
685.4 kb | modules.dep | (.ko.xz) 全部模塊路徑及 [依賴] 關係 kernel/drivers/gpu/drm/i915/i915.ko.xz: kernel/drivers/gpu/drm/drm.ko.xz ...(9個文件) |
5474 |
919.6 kb | modules.dep.bin | ||
1.4 Mb | modules.alias | 從模塊自己提取的 [別名]. modinfo -F alias alias pci:v00008086d00008A70sv*sd*bc03sc*i* i915 (...239行) |
30142 (3850) |
1.4 Mb | modules.alias.bin | ||
576.8 kb | modules.symbols | [符號] 別名,由symbol_request()使用。 alias symbol:i915_gpu_raise i915 (...7行) |
13526 (1207) |
705 kb | modules.symbols.bin | ||
5.2 kb | modules.builtin | (.ko) [內置] kernel/kernel/configs.ko |
161 |
6.9 kb | modules.builtin.bin | ||
0.4 kb | modules.devname | 觸發按需加載模塊的 [設備節點]。 fuse fuse c10:229 |
17 |
0.8 kb | modules.softdep | 從模塊自己提取的 [軟依賴項]。 softdep ext4 pre: crc32c |
26 |
2.3 查看linux內核模塊依賴關係的n種方法
2.3.1 lsmod 命令 (僅載入的部分)
$ lsmod |grep i915
i915 2166784 11
i2c_algo_bit 16384 1 i915
drm_kms_helper 212992 1 i915
drm 495616 8 drm_kms_helper,i915
intel_gtt 24576 2 intel_agp,i915
2.3.2 modinfo -F depends 命令 (僅載入的部分)
$ sudo modinfo i915 -F depends
drm,drm_kms_helper,intel-gtt,i2c-algo-bit
2.3.3 cat modules.dep 文件
$ cat /lib/modules/5.1.15-arch1-1-ARCH/modules.dep |grep i915
kernel/drivers/gpu/drm/i915/i915.ko.xz:
kernel/drivers/i2c/algos/i2c-algo-bit.ko.xz
kernel/drivers/gpu/drm/drm_kms_helper.ko.xz
kernel/drivers/gpu/drm/drm.ko.xz
kernel/drivers/char/agp/intel-gtt.ko.xz
kernel/drivers/char/agp/agpgart.ko.xz
kernel/drivers/video/fbdev/core/syscopyarea.ko.xz
kernel/drivers/video/fbdev/core/sysfillrect.ko.xz
kernel/drivers/video/fbdev/core/sysimgblt.ko.xz
kernel/drivers/video/fbdev/core/fb_sys_fops.ko.xz
2.3.4 modprobe -D 命令
$ sudo modprobe -D i915
insmod /lib/modules/5.1.15-arch1-1-ARCH/kernel/drivers/video/fbdev/core/fb_sys_fops.ko.xz
insmod /lib/modules/5.1.15-arch1-1-ARCH/kernel/drivers/video/fbdev/core/sysimgblt.ko.xz
insmod /lib/modules/5.1.15-arch1-1-ARCH/kernel/drivers/video/fbdev/core/sysfillrect.ko.xz
insmod /lib/modules/5.1.15-arch1-1-ARCH/kernel/drivers/video/fbdev/core/syscopyarea.ko.xz
insmod /lib/modules/5.1.15-arch1-1-ARCH/kernel/drivers/char/agp/agpgart.ko.xz
insmod /lib/modules/5.1.15-arch1-1-ARCH/kernel/drivers/char/agp/intel-gtt.ko.xz
insmod /lib/modules/5.1.15-arch1-1-ARCH/kernel/drivers/gpu/drm/drm.ko.xz
insmod /lib/modules/5.1.15-arch1-1-ARCH/kernel/drivers/gpu/drm/drm_kms_helper.ko.xz
insmod /lib/modules/5.1.15-arch1-1-ARCH/kernel/drivers/i2c/algos/i2c-algo-bit.ko.xz
insmod /lib/modules/5.1.15-arch1-1-ARCH/kernel/drivers/gpu/drm/i915/i915.ko.xz
2.4 查看其餘信息
2.4.1 符號信息
$ cat /lib/modules/5.1.15-arch1-1-ARCH/modules.symbols |grep i915
alias symbol:i915_gpu_lower i915
alias symbol:i915_gpu_raise i915
alias symbol:i915_gpu_busy i915
alias symbol:i915_gpu_turbo_disable i915
alias symbol:i915_read_mch_val i915
alias symbol:intel_gvt_register_hypervisor i915
alias symbol:intel_gvt_unregister_hypervisor i915
alias symbol:snd_hdac_i915_set_bclk snd_hda_core
alias symbol:snd_hdac_i915_init snd_hda_core
alias symbol:ips_link_to_i915_driver intel_ips
2.4.2 別名
sudo modinfo i915 -F alias |wc -l
239
cat /lib/modules/5.1.15-arch1-1-ARCH/modules.alias |grep i915 |wc -l
239
2.4.3 模塊配置信息
$ sudo modprobe -c |grep i915 |wc -l249
看起來,配置信息就是別名和符號信息了。
$ cat /lib/modules/5.1.15-arch1-1-ARCH/modules.alias |grep i915 |wc -l
239
$ cat /lib/modules/5.1.15-arch1-1-ARCH/modules.symbols |grep i915 |wc -l
10
全部模塊配置信息
$ modprobe -c | less
2.4.4 顯示一個裝入模塊使用的選項
$ sudo systool -v -m i915Module = "i915"
Attributes:
coresize = "2166784"
initsize = "0"
initstate = "live"
refcnt = "11"
srcversion = "8352F0188F789229AD1F3A8"
taint = ""
uevent = <store method only>
Parameters:
alpha_support = "Y"
...
Sections:
.altinstr_aux = "0xffffffffc0bf6ad5"
...
2.4.5 配置文件目錄及文件
如下是當前的arch linux/etc/modprobe.d/
/etc/modules-load.d/
/etc/mkinitcpio.d/
/etc/mkinitcpio.d/linux.preset
/etc/mkinitcpio.conf
2.5 加載模塊
2.5.1 自動處理
目前,全部必要模塊的加載均由 udev 自動完成。因此,若是不須要使用任何額外的模塊,就沒有必要在任何配置文件中添加啓動時加載的模塊。
可是,有些狀況下可能須要在系統啓動時加載某個額外的模塊,或者將某個模塊列入黑名單以便使系統正常運行。
systemd 讀取 /etc/modules-load.d/ 中的配置加載額外的內核模塊。
配置文件名稱一般爲 /etc/modules-load.d/<program>.conf。
格式很簡單,一行一個要讀取的模塊名,而空行以及第一個非空格字符爲#或;的行會被忽略,如:
/etc/modules-load.d/virtio-net.conf
# Load virtio-net.ko at boot
virtio-net
2.5.2 手動加載卸載
控制內核模塊載入/移除的命令是kmod 軟件包提供的, 要手動裝入模塊的話,執行:# modprobe module_name
若是要移除一個模塊:
# modprobe -r module_name
2.6 配置模塊參數
要將參數傳遞給內核模塊,可使用modprobe手動傳遞它們,或者確保始終使用modprobe配置文件或使用內核命令行應用某些參數。2.6.1 使用modprobe手動加載時設置
傳遞參數的基本方式是使用 modprobe 選項,格式是 key=value:# modprobe module_name parameter_name=parameter_value
2.6.2 使用 /etc/modprobe.d/中的文件
/etc/modprobe.d/目錄中的文件可用於將模塊設置傳遞給udev,udev將用於modprobe管理系統引導期間模塊的加載。此目錄中的配置文件能夠具備任何名稱,前提是它們以.conf擴展名結尾。好比:/etc/modprobe.d/thinkfan.conf
# On thinkpads, this lets the thinkfan daemon control fan speed
options thinkpad_acpi fan_control=1
注意:若是從initramfs加載了任何受影響的模塊,那麼您須要在mkinitcpio.conf中添加相應的.conf文件或使用鉤子,以便它將包含在initramfs中。
要查看默認initramfs的內容使用。FILES modconf lsinitcpio /boot/initramfs-linux.img
2.6.3 使用內核命令行
若是模塊直接編譯進內核,也能夠經過啓動管理器(GRUB, LILO 或 Syslinux)的內核行加入參數:例如:
thinkpad_acpi.fan_control=1
2.7 別名的操做
別名是模塊的備用名稱。例如:alias my-mod really_long_modulename意味着您可使用modprobe my-mod而不是modprobe really_long_modulename。您也可使用shell樣式的通配符,所以alias my-mod* really_long_modulename意味着modprobe my-mod-something具備相同的效果。建立別名:/etc/modprobe.d/myalias.conf
alias mymod really_long_module_name
有些模塊具備別名,以方便其它程序自動加載模塊。禁用這些別名能夠阻止自動加載,可是仍然能夠手動加載。
/etc/modprobe.d/modprobe.conf
# Prevent autoload of bluetooth
alias net-pf-31 off
# Prevent autoload of ipv6
alias net-pf-10 off
2.8 黑名單
在內核模塊的上下文中,黑名單是一種阻止內核模塊加載的機制。例如,若是不須要關聯的硬件,或者加載該模塊會致使問題,這可能頗有用:例如,可能有兩個內核模塊嘗試控制同一塊硬件,並將它們加載到一塊兒會致使衝突。一些模塊做爲initramfs的一部分加載。
mkinitcpio -M 將打印出全部自動檢測到的模塊.
爲防止initramfs加載其中一些模塊,將它們列入「/etc/modprobe.d」下的「.conf」文件中(例如/etc/modprobe.d/modprobe.conf),並在 image 生成過程當中經過「modconf」掛鉤添加。
mkinitcpio -v 將列出由各類鉤子(例如filesystems鉤子,block鉤子等)拉入的全部模塊。
若是您的「HOOKS」數組中沒有「modconf」掛鉤(例如,您偏離了默認配置),請記住將「.conf」文件添加到「/etc/mkinitcpio.conf」中的「FILES」數組中 ),一旦你列入黑名單,模塊就會從新生成initramfs,而後從新啓動。
https://wiki.archlinux.org/index.php/Regenerate_the_initramfs
2.8.1 使用/etc/modprobe.d/中的文件
.conf在裏面建立一個文件,/etc/modprobe.d/並使用blacklist關鍵字爲要列入黑名單的每一個模塊添加一行。例如,若是要阻止pcspkr模塊加載:/etc/modprobe.d/nobeep.conf
# Do not load the pcspkr module on boot
blacklist pcspkr
注意: blacklist 命令將屏蔽一個模板,因此不會自動加載,可是若是其它非屏蔽模塊須要這個模塊,系統依然會加載它。
要避免這個行爲,可讓 modprobe 使用自定義的 install 命令,直接返回導入失敗:
/etc/modprobe.d/blacklist.conf
...
install MODULE /bin/false
...
這樣就能夠 "屏蔽" 模塊及全部依賴它的模塊。
2.8.2 使用內核命令行
提示:若是損壞的模塊沒法啓動系統,這將很是有用。在引導加載程序中(位於 GRUB、LILO 或 Syslinux)將模塊列入黑名單。
只需添加module_blacklist=modname1,modname2,modname3到引導加載程序的內核行,如內核參數中所述。
https://wiki.archlinux.org/index.php/Kernel_parameters
注意:當您將多個模塊列入黑名單時,請注意它們僅以逗號分隔。[空格]或其餘任何東西均可能會破壞語法。
2.8.3 經常使用參數
parameter | Description | 描述 |
root= | Root filesystem. See init/do_mounts.c for supported device name formats. | 根文件系統。有關支持的設備名稱格式,請參閱init/do_mounts.c。 |
rootflags= | Root filesystem mount options. | 根文件系統掛載選項。 |
ro | Mount root device read-only on boot (default1). | 在啓動時將根設備設置爲只讀(默認值爲1)。 |
rw | Mount root device read-write on boot. | 在啓動時掛載根設備讀寫。 |
initrd= | Specify the location of the initial ramdisk. | 指定初始ramdisk的位置。 |
init= | Run specified binary instead of /sbin/init as init process. The systemd-sysvcompat package symlinks /sbin/init to /usr/lib/systemd/systemd to use systemd. |
運行指定的二進制文件而不是/sbin/initinit進程。 該systemd-sysvcompat包符號鏈接/sbin/init到/usr/lib/systemd/systemd使用systemd。 |
init=/bin/sh | Boot to shell. | 引導到shell。 |
systemd.unit= | Boot to a specified target. | 引導到指定目標。 |
resume= | Specify a swap device to use when waking from hibernation. | 指定從休眠狀態喚醒時要使用的交換設備。 |
nomodeset | Disable Kernel mode setting. | 禁用內核模式設置。 |
zswap.enabled | Enable Zswap. | 啓用Zswap。 |
panic= | Time before automatic reboot on kernel panic. | 在內核崩潰上自動重啓以前的時間。 |
debug | Enable kernel debugging (events log level). | 啓用內核調試(事件日誌級別)。 |
mem= | Force usage of a specific amount of memory to be used. | 強制使用特定數量的內存。 |
maxcpus= | Maximum number of processors that an SMP kernel will bring up during bootup. | 啓動期間SMP內核將提供的最大處理器數。 |
selinux= | Disable or enable SELinux at boot time. | 在引導時禁用或啓用SELinux。 |
netdev= | Network devices parameters. | 網絡設備參數。 |
video= | Override framebuffer video defaults. | 覆蓋幀緩衝視頻默認值。 |
完整的內核參數
https://www.kernel.org/doc/Documentation/admin-guide/kernel-parameters.txt
module_blacklist= [KNL] Do not load a comma-separated list of modules. Useful for debugging problem modules.
2.9 故障排除
模塊沒法加載若是某個特定模塊未加載且啓動日誌(可訪問journalctl -b)表示該模塊已列入黑名單,但該目錄/etc/modprobe.d/未顯示相應的條目,請檢查另外一個modprobe源文件夾以/usr/lib/modprobe.d/查找列入黑名單的條目。
若是內核模塊中包含的「vermagic」字符串與當前運行的內核的值不匹配,則不會加載模塊。若是已知模塊與當前運行的內核兼容,則能夠忽略「vermagic」檢查modprobe --force-vermagic。
警告:忽略內核模塊的版本檢查可能會致使內核崩潰或系統因不兼容而出現未定義的行爲。請務必--force-vermagic謹慎使用。
3. 內核模塊與應用程序的區別
3.1 模塊代碼
傳統計算機程序的運行生命週期至關簡單。加載器爲程序分配內存,而後加載程序和所須要的動態連接庫。指令從一些入口開始執行(傳統 C/C++ 程序以 main() 函數做爲入口),語句被執行,異常被拋出,動態內存被分配和釋放,程序最終運行完成。當程序退出時,操做系統識別任何內存泄露,並釋放到內存池。
3.2 內核模塊和普通應用程序的區別有:
> 內核模塊不是應用程序,從一開始就沒有 main() 函數。
> 非順序執行:內核模塊使用初始化函數將自身註冊並處理請求,初始化函數運行後就結束了。內核模塊處理的請求在模塊代碼中定義。這和經常使用於圖形用戶界面(graphical-user interface,GUI)應用的事件驅動編程模型比較相似。
> 沒有自動清理:任何由內核模塊申請的內存,必需要模塊卸載時手動釋放,不然這些內存將沒法使用,直到系統重啓。
> 不要使用 printf() 函數:內核代碼沒法訪問爲 Linux 用戶空間編寫的庫。內核模塊運行在內核空間,它有本身獨立的地址空間。內核空間和用戶空間的接口被清晰的定義和控制。內核模塊能夠經過 printk() 函數輸出信息,這些輸出能夠在用戶空間查看到。
> 會被中斷:內核模塊一個概念上困難的地方在於他們可能會同時被多個程序 / 進程使用。構建內核模塊時須要當心,以確保在發生中斷的時候行爲一致和正確。BeagleBone 有一個單核處理器(目前爲止),可是咱們仍然須要考慮多進程同時訪問對模塊的影響。
> 更高級的執行特權:一般內核模塊會比用戶空間程序分配更多的 CPU 週期。這看上去是一個優點,然而須要特別注意內核模塊不會影響到系統的綜合性能。
> 無浮點支持:對用戶空間應用,內核代碼使用陷阱(trap)來實現整數到浮點模式的轉換。然而在內核空間中這些陷阱難以使用。替代方案是手工保存和恢復浮點運算,這是最好的避免方式,並將處理留給用戶空間代碼。
更多信息: