从给内核单独编译设备驱动模块,到使用模块
2013-09-13 08:59
141 查看
Using Linux Device Drivers as Modules
This page contains instructions on using Linux device drivers as loadable kernel modules.
Linux has a facility for linking device drivers into the running kernel. This is called Modules support. With the vast variety of supported devices, pre-linking a kernel with all device drivers is impractical. Using loadable modules allow a commercial Linux distribution to use a small initial kernel and link in the device support needed after the machine has booted.
Compiling a Device Driver Module
You may skip this step if a pre-compiled module is available for your Linux distribution. In many cases drivers compiled for similar kernel versions will work. Pre-compiled modules in the form of RPMS for popular distributions are frequently available for Scyld provided device drivers.
If a pre-compiled module is not available, you'll have to compile one from the driver source code, or the source code RPM (SRPM). In the instructions below driver.c refers to the name of the driver source file for your device e.g. 3c59x.c, and driver.o refers to the compiled driver module binary.
* Verify that the source code for your current kernel version is installed.
* If you don't have a /usr/include/linux/version.h file, do
cd /usr/src/linux; make include/linux/version.h
* Copy the driver source code to a source directory. I usually use /usr/src/modules/driver.c.
* Compile the file using the compile-command at the bottom of the driver source file. If a compile-command is not there use the following compile command:
gcc -DMODULE -D__KERNEL__ -O6 -c driver.c
* As 'root', test the module by doing "insmod driver.o".
* Install the driver module in the proper location for your distribution. This is usually /lib/modules/kernel-version/net/driver.o. The command to do this is
install -m 644 driver.o /lib/modules/`uname -r`/net/
Possible problems and solutions
If you get an "linux/version.h no such file or directory" message when compiling the driver, you either have not installed the kernel source code, or you haven't run
cd /usr/src/linux; make include/linux/version.h
yet. Most modern distributions install the essential header files of the kernel source code, including a pre-built "version.h", so this isn't always necessary.
If you get a "modversions.h not found" message when compiling the driver, delete '-DMODVERSIONS' from the command used to compile the driver module.
Testing the New Module
As 'root', load the module using "insmod driver.o" and execute the appropriate 'route add -net ...' for your local network.
If the networking works correctly, add the module to your system configuration. For Slackware and most other systems, add the insmod command to /etc/rc.d/rc.inet1 or /etc/rc.d/rc.local. RedHat users should add the insmod line to /etc/rc.d/rc.modules or copy driver.o to /lib/modules/`uname -r`/net/ and add the following line to /etc/conf.modules:
alias eth0 driver
Modifying Driver Operation Through Options
Drivers are designed with the goal that no options should be needed in most environments. However not all cards and networks can be automatically configured, thus drivers allow operational parameters to be modified when they are loaded as a module. Typically the following variables may be set:
name type description
debug int The debug message level, 0 (no messages) to 6 (wordy).
options int[] Per-card media type override and card operation
settings, typically the media type.
full_duplex int[] Set to '1' to force this interface to always be used in FD mode.
To test an option, load the module (as above) with a command such as "/sbin/insmod driver.o full_duplex=1,0,1". This command sets the full_duplex flag for the first and third cards of this type.
To set module parameters when the module is loaded automatically, add the following line to /etc/conf.modules
alias eth0 driver options driver full_duplex=1,0,1 debug=0
Note that spaces are permitted only between parameter names, not between the comma-separated numeric options.
Problems and Solutions
What if the card is detected with a ff:ff:ff:ff:ff:ff station address?
There are three known causes of this problem.
* Warm-booting from Win95 OSR2.1 or Win98 (power-managed cards only)
* "PnP OS" is set in the PCI BIOS setup.
* Broken PCI BIOSes (reportedly version "AI78" is broken).
The "D3-cold" problem
Quick summary: restore operation by unplugging the machine after running an OS that disables the card. Merely using the "soft-off" pushbutton on a ATX case is not sufficient.
Many modern PCI chips have ACPI power management capability. Some include a mode known as "D3-cold", where the chip can power itself off. When in this mode the chip uses only the tiny amount of stand-by power always available when an ATX power supply is plugged in. In the D3-cold mode the chip can be turned on only by writing a PCI configuration space register. This works great if you have a ACPI-aware BIOS that knows how to re-enable the chip on a warm boot, but older BIOS don't know that the chip cannot retain configuration information. When the machine is warm booted the chip has only invalid configuration information.
The PnP OS problem occurs because Microsoft has convinced BIOS makers to modify their PCI device configuration from the previous rational standard, to one that works well only with Microsoft operating systems. Where previously the BIOS allocated resources for and enabled the PCI device by default, it now does so only for boot devices and audio devices. (Why are audio devices specifically an exception? Because MS-Windows can't handle the resource allocation for them!)
The solution is to either update to the latest driver, (the drivers are being re-worked to enable the devices) or to disable the "PnP OS" setting in the machine's BIOS setup.
The reason Microsoft had to have this change implemented for them was that MS-Windows still handles some devices with "real-mode" drivers, and this change makes it easier to mix real-mode and protected-mode device drivers. This is an excellent example of Microsoft using its dominant position in the software industry force a technical change that is detrimental to other operating systems.
Legal Info
This a not a legal statement. Read the Gnu General Public License (GPL) to find your actual rights. These are just guidelines to assist in interpreting that document.
Legal status of a loaded Module
Loading a device driver module is functionally identical to conventionally building a kernel. The final result is a single Work, as that term is used in the license. The time that the linking is done does not affect the legal status of the individual parts or the whole: legally, changes in structure, procedure or nomenclature are evaluated by the conventional usage.
What does the GPL mean by a "Work"?
Device drivers are not Works (as that term is used in the license), merely componets of a Work. At minimum a network device driver must be linked with a queuing system, protocol stack and a widely used "API" (such as the Berkeley socket interface) to be an independent Work. Similarly a block device driver must be linked with a buffer layer, a memory management or file system, and a commonly used API to be consider a minimum Work. More commonly, multiple types of drivers are linked into a complete Operating System, and that collection is a single Work. Once again, novel structures are legally evaluated by their functionally-equivalent conventional counterparts. If you implement an operating system by putting each function in its own address space, that doesn't mean that each function is a program and the collection is a "mere aggregation"! The message passing used to communicate is just another method of linking the parts into a single complete Work.
"Porting" device drivers
Converting a driver licensed under the GPL to work with a non-GPLed OS is permitted, however you are not permitted to distribute the resulting Work. You may describe to others how to do the conversion, but an automated kit, such as a "patch" file, is equivalent to distributing a converted Work and is not permitted.
"Third party" ports
If a third party writes an interface layer between a non-GPL program and a GPL function (note: here I'm concerned only with device drivers), distribution of that interface layer necessarily violates one of the licenses. In the special case of a non-licensed "public domain" program, the entire Work must be place under the GPL.
"Second party" ports
If the copyright holder writes to the non-public interface of a GPL device driver, their entire Work falls under the GPL. Merely having access to the source code does not make every line break or function a public interface: that would make the word "interface" meanless! Things that are clearly public interfaces:
* Written industry standards, such as those from the IEEE or ISO.
* De facto standard used by a large number of unrelated parties.
* Any programming or scripting language that a user sees.
* Any frequently repeated keystroke sequence or action that a user must do.
* Anything the copyright holder declares or presents as a public interface.
There are questionable areas that require judgement here: if many independent parties are using an interface, then it's a de facto standard. But if only one other party is, it might not be a public interface.
Summary
* You have the freedom to write any code you like.
* You are free to use any code you are licensed to use.
* But you are not always free to distribute the result.
You must respect the copyright of the people that wrote the original code and observe their license.
A personal note about legal issues
GPLed source code is *not* in the public domain. People that wouldn't consider using "warez" (stolen binary software) somehow don't have the same moral aversion to violating the license of software provided to them under much more generous terms. The result is that I must spend much more time tracking down copyright violations than if I had a restrictive license. I hope this is merely a lack of cultural experience with the GPL.
This page contains instructions on using Linux device drivers as loadable kernel modules.
Linux has a facility for linking device drivers into the running kernel. This is called Modules support. With the vast variety of supported devices, pre-linking a kernel with all device drivers is impractical. Using loadable modules allow a commercial Linux distribution to use a small initial kernel and link in the device support needed after the machine has booted.
Compiling a Device Driver Module
You may skip this step if a pre-compiled module is available for your Linux distribution. In many cases drivers compiled for similar kernel versions will work. Pre-compiled modules in the form of RPMS for popular distributions are frequently available for Scyld provided device drivers.
If a pre-compiled module is not available, you'll have to compile one from the driver source code, or the source code RPM (SRPM). In the instructions below driver.c refers to the name of the driver source file for your device e.g. 3c59x.c, and driver.o refers to the compiled driver module binary.
* Verify that the source code for your current kernel version is installed.
* If you don't have a /usr/include/linux/version.h file, do
cd /usr/src/linux; make include/linux/version.h
* Copy the driver source code to a source directory. I usually use /usr/src/modules/driver.c.
* Compile the file using the compile-command at the bottom of the driver source file. If a compile-command is not there use the following compile command:
gcc -DMODULE -D__KERNEL__ -O6 -c driver.c
* As 'root', test the module by doing "insmod driver.o".
* Install the driver module in the proper location for your distribution. This is usually /lib/modules/kernel-version/net/driver.o. The command to do this is
install -m 644 driver.o /lib/modules/`uname -r`/net/
Possible problems and solutions
If you get an "linux/version.h no such file or directory" message when compiling the driver, you either have not installed the kernel source code, or you haven't run
cd /usr/src/linux; make include/linux/version.h
yet. Most modern distributions install the essential header files of the kernel source code, including a pre-built "version.h", so this isn't always necessary.
If you get a "modversions.h not found" message when compiling the driver, delete '-DMODVERSIONS' from the command used to compile the driver module.
Testing the New Module
As 'root', load the module using "insmod driver.o" and execute the appropriate 'route add -net ...' for your local network.
If the networking works correctly, add the module to your system configuration. For Slackware and most other systems, add the insmod command to /etc/rc.d/rc.inet1 or /etc/rc.d/rc.local. RedHat users should add the insmod line to /etc/rc.d/rc.modules or copy driver.o to /lib/modules/`uname -r`/net/ and add the following line to /etc/conf.modules:
alias eth0 driver
Modifying Driver Operation Through Options
Drivers are designed with the goal that no options should be needed in most environments. However not all cards and networks can be automatically configured, thus drivers allow operational parameters to be modified when they are loaded as a module. Typically the following variables may be set:
name type description
debug int The debug message level, 0 (no messages) to 6 (wordy).
options int[] Per-card media type override and card operation
settings, typically the media type.
full_duplex int[] Set to '1' to force this interface to always be used in FD mode.
To test an option, load the module (as above) with a command such as "/sbin/insmod driver.o full_duplex=1,0,1". This command sets the full_duplex flag for the first and third cards of this type.
To set module parameters when the module is loaded automatically, add the following line to /etc/conf.modules
alias eth0 driver options driver full_duplex=1,0,1 debug=0
Note that spaces are permitted only between parameter names, not between the comma-separated numeric options.
Problems and Solutions
What if the card is detected with a ff:ff:ff:ff:ff:ff station address?
There are three known causes of this problem.
* Warm-booting from Win95 OSR2.1 or Win98 (power-managed cards only)
* "PnP OS" is set in the PCI BIOS setup.
* Broken PCI BIOSes (reportedly version "AI78" is broken).
The "D3-cold" problem
Quick summary: restore operation by unplugging the machine after running an OS that disables the card. Merely using the "soft-off" pushbutton on a ATX case is not sufficient.
Many modern PCI chips have ACPI power management capability. Some include a mode known as "D3-cold", where the chip can power itself off. When in this mode the chip uses only the tiny amount of stand-by power always available when an ATX power supply is plugged in. In the D3-cold mode the chip can be turned on only by writing a PCI configuration space register. This works great if you have a ACPI-aware BIOS that knows how to re-enable the chip on a warm boot, but older BIOS don't know that the chip cannot retain configuration information. When the machine is warm booted the chip has only invalid configuration information.
The PnP OS problem occurs because Microsoft has convinced BIOS makers to modify their PCI device configuration from the previous rational standard, to one that works well only with Microsoft operating systems. Where previously the BIOS allocated resources for and enabled the PCI device by default, it now does so only for boot devices and audio devices. (Why are audio devices specifically an exception? Because MS-Windows can't handle the resource allocation for them!)
The solution is to either update to the latest driver, (the drivers are being re-worked to enable the devices) or to disable the "PnP OS" setting in the machine's BIOS setup.
The reason Microsoft had to have this change implemented for them was that MS-Windows still handles some devices with "real-mode" drivers, and this change makes it easier to mix real-mode and protected-mode device drivers. This is an excellent example of Microsoft using its dominant position in the software industry force a technical change that is detrimental to other operating systems.
Legal Info
This a not a legal statement. Read the Gnu General Public License (GPL) to find your actual rights. These are just guidelines to assist in interpreting that document.
Legal status of a loaded Module
Loading a device driver module is functionally identical to conventionally building a kernel. The final result is a single Work, as that term is used in the license. The time that the linking is done does not affect the legal status of the individual parts or the whole: legally, changes in structure, procedure or nomenclature are evaluated by the conventional usage.
What does the GPL mean by a "Work"?
Device drivers are not Works (as that term is used in the license), merely componets of a Work. At minimum a network device driver must be linked with a queuing system, protocol stack and a widely used "API" (such as the Berkeley socket interface) to be an independent Work. Similarly a block device driver must be linked with a buffer layer, a memory management or file system, and a commonly used API to be consider a minimum Work. More commonly, multiple types of drivers are linked into a complete Operating System, and that collection is a single Work. Once again, novel structures are legally evaluated by their functionally-equivalent conventional counterparts. If you implement an operating system by putting each function in its own address space, that doesn't mean that each function is a program and the collection is a "mere aggregation"! The message passing used to communicate is just another method of linking the parts into a single complete Work.
"Porting" device drivers
Converting a driver licensed under the GPL to work with a non-GPLed OS is permitted, however you are not permitted to distribute the resulting Work. You may describe to others how to do the conversion, but an automated kit, such as a "patch" file, is equivalent to distributing a converted Work and is not permitted.
"Third party" ports
If a third party writes an interface layer between a non-GPL program and a GPL function (note: here I'm concerned only with device drivers), distribution of that interface layer necessarily violates one of the licenses. In the special case of a non-licensed "public domain" program, the entire Work must be place under the GPL.
"Second party" ports
If the copyright holder writes to the non-public interface of a GPL device driver, their entire Work falls under the GPL. Merely having access to the source code does not make every line break or function a public interface: that would make the word "interface" meanless! Things that are clearly public interfaces:
* Written industry standards, such as those from the IEEE or ISO.
* De facto standard used by a large number of unrelated parties.
* Any programming or scripting language that a user sees.
* Any frequently repeated keystroke sequence or action that a user must do.
* Anything the copyright holder declares or presents as a public interface.
There are questionable areas that require judgement here: if many independent parties are using an interface, then it's a de facto standard. But if only one other party is, it might not be a public interface.
Summary
* You have the freedom to write any code you like.
* You are free to use any code you are licensed to use.
* But you are not always free to distribute the result.
You must respect the copyright of the people that wrote the original code and observe their license.
A personal note about legal issues
GPLed source code is *not* in the public domain. People that wouldn't consider using "warez" (stolen binary software) somehow don't have the same moral aversion to violating the license of software provided to them under much more generous terms. The result is that I must spend much more time tracking down copyright violations than if I had a restrictive license. I hope this is merely a lack of cultural experience with the GPL.
相关文章推荐
- 从 2.4 到 2.6:Linux 内核可装载模块机制的改变对设备驱动的影响—linux2.4单独编译驱动模块
- 内核子系统或设备驱动可以直接编译到内核,也可以编译成模块,如果编译到内核,可以使用前一节介绍的方法通过内核启动参数来向它们传递参数,如果编译成模块,则可以通过命令行在插入模块时传递参数,或者在运行时,
- 编译时向内核添加新设备 模块的方式动态的将驱动加入内核,但这种方式加入的驱动程序,当系统重新启动时, 还需要重新用模块的方式进行插入,如果是系统内常用的设备驱动采用这种方式进行加载, 就会很不方便。
- Linux下使用内核源码单独编译某一模块
- 嵌入式重新记录1.将驱动模块编译进内核
- 如何将驱动或模块编译进内核
- linux驱动编译进内核或模块配置
- 从 2.4 到 2.6:Linux 内核可装载模块机制的改变对设备驱动的影响
- linux设备驱动--内核等待队列知识点---结合中断使用
- 使用内核定时器的second字符设备驱动
- 从 2.4 到 2.6:Linux 内核可装载模块机制的改变对设备驱动的影响
- 单独编译使用WebRTC的音频处理模块 - android
- Linux 内核编译,解决网卡驱动缺少的问题,使用更新的内核来完善驱动
- 内核驱动模块编译方法
- 从 2.4 到 2.6:Linux 内核可装载模块机制的改变对设备驱动的影响
- 【转】Linux驱动模块编译进内核中
- 【单独编译使用WebRTC的音频处理模块 - android】
- 从 2.4 到 2.6:Linux 内核可装载模块机制的改变对设备驱动的影响
- 如何把自己的驱动编译进内核或模块(Kconfig和Makefile)
- Linux 内核模块编程的第一个字符设备驱动