linux-kernel-module

Linux-kernel-module

目录
 

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中,而是在暂存区域中,则能够指定一个基于目录名称的b​​asedir。从生成的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 -l
249
看起来,配置信息就是别名和符号信息了。
$ 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 i915
Module = "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)来实现整数到浮点模式的转换。然而在内核空间中这些陷阱难以使用。替代方案是手工保存和恢复浮点运算,这是最好的避免方式,并将处理留给用户空间代码。
 
 
 
更多信息:
相关文章
相关标签/搜索
本站公众号
   欢迎关注本站公众号,获取更多信息