WO2016091071A1 - 加载Linux内核驱动的方法及装置 - Google Patents

加载Linux内核驱动的方法及装置 Download PDF

Info

Publication number
WO2016091071A1
WO2016091071A1 PCT/CN2015/095577 CN2015095577W WO2016091071A1 WO 2016091071 A1 WO2016091071 A1 WO 2016091071A1 CN 2015095577 W CN2015095577 W CN 2015095577W WO 2016091071 A1 WO2016091071 A1 WO 2016091071A1
Authority
WO
WIPO (PCT)
Prior art keywords
kernel
driver
initial
information
code
Prior art date
Application number
PCT/CN2015/095577
Other languages
English (en)
French (fr)
Inventor
陈章琪
Original Assignee
北京奇虎科技有限公司
奇智软件(北京)有限公司
Priority date (The priority date is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the date listed.)
Filing date
Publication date
Application filed by 北京奇虎科技有限公司, 奇智软件(北京)有限公司 filed Critical 北京奇虎科技有限公司
Publication of WO2016091071A1 publication Critical patent/WO2016091071A1/zh

Links

Images

Classifications

    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F9/00Arrangements for program control, e.g. control units
    • G06F9/06Arrangements for program control, e.g. control units using stored programs, i.e. using an internal store of processing equipment to receive or retain programs
    • G06F9/44Arrangements for executing specific programs
    • G06F9/445Program loading or initiating

Definitions

  • the present invention relates to the field of computer technologies, and in particular, to a method and apparatus for loading a Linux kernel driver.
  • the way to load the kernel driver is to call the insmod command. Due to the characteristics of Linux, the version information of the loaded kernel driver must be exactly the same as the kernel version information before it can be loaded successfully. And because the kernel version upgrades frequently, and many manufacturers have their own customization, the Linux kernel version on the Android phone in the market is diverse. In order to develop a kernel driver that can run on a certain Android phone, you must find the kernel source of the corresponding phone and compile your own kernel driver code with the kernel code. This method increases the huge development workload, and needs to collect a large number of kernel source code of various versions, compile the corresponding kernel driver for each version of the kernel, and even the kernel source code of some devices cannot be collected at all, thus giving the kernel driver The versatility brings a fatal limitation.
  • the present invention has been made in order to provide a method and apparatus for loading a Linux kernel driver that overcomes the above problems or at least partially solves the above problems.
  • a method for loading a Linux kernel driver comprising: selecting kernel code consistent with a CPU platform of a target system as a reference kernel code for compiling an initial general kernel driver; filling in a structure of a reference kernel code a predetermined size byte, and compile the filled reference kernel code together with the initial general kernel driver; find the kernel driver that is included in the target system as a reference driver in the target system, and modify the above compiled information according to the reference driver information.
  • the initial generic kernel driver generates a generic kernel driver; loads the generated generic kernel driver into the kernel of the target system.
  • the filling of the predetermined size of the byte in the structure of the reference kernel code includes: repairing Refer to the struct module structure in the include/linux/module.h file of the kernel code, and fill in the bytes of the predetermined size at the end of the structure.
  • the filling of the predetermined size of the byte ensures that the struct module structure of the filled reference kernel code is larger than the struct module structure of the target system.
  • the modifying the compiled initial universal kernel driver according to the information of the reference driver comprises: extracting, from the reference driver, verification information that is required to be used for kernel verification; according to the calibration extracted from the reference driver The information is modified to modify the corresponding information in the initial generic kernel driver.
  • the verification information refers to kernel version information: vermagic information; and the modifying the corresponding information in the initial universal kernel driver according to the verification information extracted from the reference driver comprises: referring to the driven modinfo The vermagic information of the area is copied to the vermagic field of the modinfo area of the initial generic kernel driver.
  • the verification information refers to kernel driver version information and version information of the exported symbols used: the versions area starts 64 bytes; and the initial information is modified according to the verification information extracted from the reference driver
  • Corresponding information in the general-purpose kernel driver includes starting 64 bytes with the version of the reference-driven version of the region to cover 64 bytes of the initial generic kernel driver's versions.
  • the modifying the compiled initial generic kernel driver according to the information of the reference driving comprises: extracting relocation information of the load execution function and the uninstall execution function from the reference driver; according to the extracting from the reference driver Relocating information, modifying corresponding information in the initial generic kernel driver.
  • the relocation information refers to relocation information of this_module.init and this_mosule.exit; and modifying the corresponding information in the initial universal kernel driver according to the relocation information extracted from the reference driver includes: Copy the contents of the rel.gnu.linkonce.this_module area in the reference driver to the rel.gnu.linkonce.this_module area in the initial generic kernel driver.
  • the modifying the compiled initial generic kernel driver according to the information of the reference driver comprises: determining whether the reference driver includes a rel.gnu.linkonce.this_module region; If not, search the file system for the reference driver containing the rel.gnu.linkonce.this_module region; if so, first copy the vermagic information of the reference driver's modinfo region to the vermagic field of the modinfo region of the initial generic kernel driver, and then use the The reference driver's versions area starts with 64 bytes covering the initial generic kernel driver's .versions area starting with 64 bytes. Finally, it is determined whether the reference driver is the same size as the initial generic kernel driver's rel.gnu.linkonce.this_module area. If they are consistent, Copy the contents of the rel.gnu.linkonce.this_module area in the reference driver to the rel.gnu.linkonce.this_module area in the initial generic kernel driver.
  • loading the generated generic kernel driver into the kernel of the target system comprises: writing the generic kernel driver into the file, loading the generic kernel driver into the kernel of the target system through the insmod command; or using the general-purpose kernel in memory
  • the driver calls the init_module system call to load the generic kernel driver into the kernel of the target system.
  • the initial generic kernel driver is compiled based on standard Linux kernel source code.
  • the kernel source code of the android system is selected as the reference kernel code; if the target system is a ubuntu system, the kernel source code of the ubuntu system is selected as the reference kernel code. .
  • an apparatus for loading a Linux kernel driver comprising: a reference kernel code selection unit for selecting a kernel code consistent with a CPU platform of a target system as a reference kernel code for compiling an initial general kernel driver; An initial general-purpose kernel code compiling unit for populating a structure of a reference kernel code with a predetermined size of bytes and compiling the filled reference kernel code together with an initial generic kernel driver; a generic kernel driver generation unit for targeting The system finds the kernel driver that comes with the target system as the reference driver, and modifies the above-mentioned compiled initial general-purpose kernel driver according to the information of the reference driver to generate a general-purpose kernel driver; the general-purpose kernel driver loading unit is used to generate the generated general-purpose kernel driver. Loaded into the kernel of the target system.
  • the initial general-purpose kernel code compiling unit is specifically configured to: modify a struct module structure in the include/linux/module.h file of the reference kernel code, and fill a predetermined size byte at the end of the structure body.
  • the initial general-purpose kernel code compilation unit is filled with a predetermined size of bytes, and the struct module structure of the filled reference kernel code is larger than the struct of the target system. Module structure.
  • the universal kernel driver generating unit is specifically configured to: extract, from the reference driver, verification information that needs to be used for kernel verification; and modify the identifier according to the verification information extracted from the reference driver.
  • the corresponding information in the initial generic kernel driver is specifically configured to: extract, from the reference driver, verification information that needs to be used for kernel verification; and modify the identifier according to the verification information extracted from the reference driver. The corresponding information in the initial generic kernel driver.
  • the verification information refers to kernel version information: vermagic information; and the universal kernel driver generating unit is specifically configured to: copy vermagic information of the modinfo area of the reference driver to a vermagic field of the modinfo area of the initial universal kernel driver.
  • the verification information refers to kernel driver version information and version information of the exported symbols used: the versions area starts 64 bytes; the general kernel driver generation unit is specifically configured to: use the reference-driven .versions The region begins with 64 bytes covering the initial generic kernel driver's versions region starting with 64 bytes.
  • the universal kernel driver generating unit is specifically configured to: extract relocation information of the load execution function and the uninstall execution function from the reference driver; and modify the location according to the relocation information extracted from the reference driver The corresponding information in the initial generic kernel driver.
  • the relocation information refers to relocation information of this_module.init and this_mosule.exit;
  • the universal kernel driver generating unit is specifically configured to: content of the rel.gnu.linkonce.this_module area in the reference driver Copy to the rel.gnu.linkonce.this_module section of the initial generic kernel driver.
  • the universal kernel driver generating unit is specifically configured to: determine whether the reference driver includes a rel.gnu.linkonce.this_module region; if not, search the file system for a reference including a rel.gnu.linkonce.this_module region Driver; if so, first copy the vermagic information of the modinfo area of the reference driver to the vermagic field of the modinfo area of the initial generic kernel driver, and then start the 64 bytes of the initial generic kernel driver with the reference version of the .versions area of the reference driver. The area starts with 64 bytes, and finally determines whether the reference driver is the same size as the rel.gnu.linkonce.this_module area of the initial general-purpose kernel driver. If it is consistent, copy the contents of the rel.gnu.linkonce.this_module area in the reference driver to The rel.gnu.linkonce.this_module area in the initial generic kernel driver.
  • the universal kernel driver loading unit is specifically configured to: write a generic kernel driver into a text.
  • the generic kernel driver is loaded into the kernel of the target system by the insmod command; or the generic kernel driver is called by the init_module system call in the memory to load the generic kernel driver into the kernel of the target system.
  • the initial generic kernel driver is compiled based on standard Linux kernel source code.
  • the reference kernel code selection unit selects a kernel source code of the android system as the reference kernel code; if the target system is a ubuntu system, the reference kernel code selection The unit selects the kernel source code of the ubuntu system as the reference kernel code.
  • a computer program comprising computer readable code causing a computing device to perform the method of loading a Linux kernel driver as described above when the computer readable code is run on a computing device.
  • a computer readable medium storing the above computer program is provided.
  • the solution of the present invention avoids the out-of-bounds by avoiding the structure of the target system by adding some padding bytes in the reference kernel code structure to avoid the structure being larger than the structure of the general-purpose kernel driver; and modifying the initial general-purpose kernel driver according to the reference driver. So that the generated generic kernel driver can be verified by the target system and called normally.
  • a generic kernel driver can be loaded into a target system of a different kernel version; the same driver can be loaded into most Android phones.
  • FIG. 1 shows a flow chart of a method of loading a Linux kernel driver in accordance with one embodiment of the present invention
  • FIG. 2 illustrates a flow diagram for modifying an initial generic kernel driver based on reference driven information, in accordance with one embodiment of the present invention
  • FIG. 3 is a schematic structural diagram of an apparatus for loading a Linux kernel driver according to an embodiment of the present invention
  • FIG. 4 is a block diagram schematically showing a computing device for performing a method of loading a Linux kernel driver in accordance with the present invention
  • Fig. 5 schematically shows a storage unit for holding or carrying program code implementing a method of loading a Linux kernel driver according to the present invention.
  • the general way to load the kernel driver is to call the command insmod.
  • the insmod command first reads the kernel driver that needs to be loaded into memory, then calls the system call init_module to pass the address and length of the kernel driver in memory and the driver parameters to the kernel.
  • the kernel After the insmod command enters the kernel through the system call init_module, the kernel first copies the driver in the user space memory to the kernel space, and then checks whether the kernel driver conforms to the ELF format. If not, the kernel refuses to load the driver.
  • the kernel analyzes various information of the kernel driver according to the format of the ELF (Executable and Linkable Format), performs judgment and verification, and refuses to load the driver if the verification fails.
  • ELF Executable and Linkable Format
  • the kernel driver uses the ELF format, vermagic is in the .modinfo area, and vermagic is inside.
  • the kernel version information the kernel will verify that the vermagic of the driver being loaded is consistent with the kernel itself. If not, the driver's load is rejected.
  • the version information for module_layout and struct_module is contained in the __versions area. Kernels above version 3.0 will check if the version information of the module_layout of the kernel driver being loaded is consistent with the kernel itself. The kernel of 2.6 or higher and 3.0 or lower will check whether the version information of the struct_module of the kernel driver being loaded is consistent with the kernel itself. If not, the driver's load is rejected.
  • the kernel driver will refer to the function or variable (ie: symbol) exported in the kernel. If it is used, the version information of the function or variable will be saved in the __versions area of the kernel driver.
  • the kernel driver compares the version information of the function or variable in the __versions area with the version information saved in the kernel. If it is inconsistent, it refuses to load the driver.
  • the present invention is directed to the above problem, and provides a method and apparatus for loading a Linux kernel driver, which enables the same kernel driver to be loaded onto a Linux device running various versions of the kernel.
  • the problem to be solved by the present invention is to enable the same kernel driver to be loaded into different versions of the Linux kernel without being limited by the above three types of verification.
  • FIG. 1 a flow chart of a method for loading a Linux kernel driver according to an embodiment of the present invention is shown, including the following steps:
  • S101 Select a kernel code consistent with a CPU platform of the target system as a reference kernel code for compiling the initial general kernel driver;
  • S102 Fill a structure of a reference kernel code with a predetermined size of bytes, and fill the padded
  • the reference kernel code is compiled with the initial generic kernel driver
  • S103 searching the target system for the kernel driver that is included in the target system as a reference driver, and modifying the compiled initial general-purpose kernel driver according to the information of the reference driver to generate a general-purpose kernel driver;
  • S104 Load the generated generic kernel driver into the kernel of the target system.
  • the target system is a system running a Linux kernel, and the general kernel driver needs to be loaded into the system;
  • the reference kernel code is a complete kernel code, and the kernel driver needs to use the version information and symbols of the kernel code.
  • Information and header files, etc. are essential for compiling kernel drivers;
  • the initial generic kernel driver is compiled based on standard Linux kernel source code.
  • the initial generic kernel driver is a binary ELF file.
  • the initial generic kernel driver passes this After the processing of the inventive method, it is called a general-purpose kernel driver, and can be loaded into different versions of the Linux kernel;
  • the general-purpose kernel driver is generated by the initial general-purpose kernel driver after being modified according to the reference kernel driver, and can be loaded into different versions of Linux. In the kernel.
  • the basic idea of the solution provided by the present invention is as follows: in the target system, the kernel driver that is included in the system is used as a reference driver, and the initial general purpose is modified according to the information of the reference driver.
  • the kernel driver allows it to pass the three checks of the kernel and then load the modified kernel driver in the normal way.
  • Step 1 Select the kernel code that is consistent with the CPU platform of the target system as the reference kernel code for compiling the initial generic kernel driver.
  • the initial universal driver for device development on the ARM platform can be Choose the goldfish provided by Google (Goldfish is a virtual ARM processor, used in the android simulation environment) kernel source code as the reference kernel code.
  • the target system is Ubuntu (Ubuntu, a Linux operating system based on desktop applications), select the kernel source code of the Ubuntu system as the reference kernel code.
  • Step 2 Modify the struct module structure in the include/linux/module.h file of the reference kernel code, and add a predetermined size byte at the end, for example, adding 256 bytes of padding.
  • the size of the struct module structure may change.
  • different kernel versions can be used, and the struct module structure is increased by 256 bytes, so that the kernel is compiled using the present invention.
  • the generic kernel driver does not have a memory out of bounds behavior.
  • Step 3 Compile the reference kernel code with the initial generic kernel driver, copy the initial generic kernel driver to the target system, and find the kernel driver that comes with the system as a reference driver through the code.
  • Step 4 Extract the required information from the reference kernel driver and modify the initial generic kernel driver. The specific process is shown in Figure 2.
  • the kernel driver uses the ELF format, and the entire ELF format driver is read into the memory for easy modification.
  • S203 Determine whether the reference driver includes a .rel.gnu.linkonce.this_module area.
  • the usual driver will execute the driver's init function (loading the execution function) as soon as it is loaded into the kernel. Once it is unloaded, it will execute the driver's exit function (unloading the execution function).
  • the init and exit members in the this_module structure are stored.
  • the address of a function because the address loaded by the driver is undefined, the addresses of these two functions are unknown before loading. You need to reassign the members of the two structures after loading. This is relocation. What is stored in the .rel.gnu.linkonce.this_module area is the information that needs to be relocated in this_module, which is the relocation information of the two members init and exit.
  • Some kernel drivers do not have init and exit functions. It may just export some functions for other drivers to call. This driver cannot be used as a reference driver.
  • S205 Copy the vermagic information from the reference-driven .modinfo area to the vermagic field of the .modinfo area of the initial general-purpose kernel driver.
  • Each entry in the _version area occupies 64 bytes.
  • the first 4 bytes are version information, and the last 60 bytes are the names of functions or variables. Since the first items in the 2.6 and 3.0 kernels are struct_module and module_layout, respectively, What version of the target system is required to copy the first 64 bytes to the corresponding location in the initial generic kernel driver, and then pass the kernel check, including verification of the driver version and verification of the symbols that need to be used.
  • S207 Determine whether the reference driver is consistent with the size of the .rel.gnu.linkonce.this_module area of the initial universal kernel driver.
  • the initial generic kernel driver 's this_module structure is compiled at the time of adding a predetermined size byte (for example, 256 bytes), so it is definitely better than The structure of this_module in the target system is large, so the offset in the relocation information of init and exit must not exceed the this_module structure of the initial generic kernel driver.
  • the kernel assigns the addresses loaded by the init and exit functions to this_module.init and this_module.exit according to the relocation information, and then calls the function pointed to by this_module.init. This way the entire driver is loaded successfully.
  • Step 5 Load the modified generic kernel driver into the kernel of the target system through the traditional insmod command.
  • step 1 the selection of the reference kernel code can be various, as long as the system kernel source code is the same as the CPU architecture of the target system.
  • the module structure is filled with 256 bytes at the end, and other values can be used, as long as the size of the module structure in the modified reference kernel code is larger than the size of the module structure of the target system.
  • the initial generic kernel driver can be compiled together with the reference kernel code, or it can be compiled separately.
  • step 4 the behavior of the initial general-purpose kernel driver is modified according to the reference driver, and can be executed on the target system, or the reference driver on the target system can be copied to other machines for execution; the steps of modifying the initial general-purpose kernel driver can be performed in some order.
  • step five the last step does not need to write the file, directly use the general kernel driver in memory, call the init_module system call, load the modified driver into the kernel, so step five is not needed.
  • the present invention also provides an apparatus for loading a Linux kernel driver.
  • the device can be implemented by hardware, software or a combination of software and hardware.
  • the device may refer to a functional module of a Linux system, or may be a hardware device for installing a Linux system, as long as the function of the device can be implemented.
  • FIG. 3 illustrates an apparatus for loading a Linux kernel driver according to an embodiment of the present invention, including:
  • a reference kernel code selection unit 301 configured to select a kernel code consistent with a CPU platform of the target system as a reference kernel code for compiling the initial general kernel driver;
  • An initial general-purpose kernel code compiling unit 302 configured to fill a structure of a reference kernel code with a predetermined size of bytes, and compile the filled reference kernel code together with the initial general-purpose kernel driver;
  • the general-purpose kernel driver generating unit 303 is configured to search the target system for the kernel driver that is included in the target system as a reference driver, and modify the compiled initial universal kernel driver according to the information of the reference driver to generate a general-purpose kernel driver.
  • the generic kernel driver loading unit 304 is configured to load the generated generic kernel driver into the kernel of the target system.
  • the initial general-purpose kernel code compiling unit 302 is specifically configured to: modify a struct module structure in the include/linux/module.h file of the reference kernel code, and fill a predetermined size byte at the end of the structure body.
  • the initial general-purpose kernel code compiling unit 302 fills a byte of a predetermined size to ensure that the struct module structure of the filled reference kernel code is larger than the struct module structure of the target system.
  • the universal kernel driver generating unit 303 is specifically configured to: extract, from the reference driver, verification information that needs to be used for kernel verification; and, according to the verification information extracted from the reference driver, modify the location The corresponding information in the initial generic kernel driver.
  • the verification information refers to kernel version information: vermagic information;
  • the universal kernel driver generating unit 303 is specifically configured to: copy vermagic information of the modinfo area of the reference driver to a vermagic field of the modinfo area of the initial universal kernel driver. .
  • the verification information refers to kernel driver version information and version information of the exported symbols used: the versions area starts 64 bytes; the general kernel driver generation unit 303 is specifically configured to: drive with the reference.
  • the extent area begins with 64 bytes covering the initial generic kernel driver's versions area starting with 64 bytes.
  • the universal kernel driver generating unit 303 is specifically configured to: extract relocation information of the load execution function and the uninstall execution function from the reference driver; and modify according to the relocation information extracted from the reference driver. Corresponding information in the initial generic kernel driver.
  • the relocation information refers to relocation information of this_module.init and this_mosule.exit; the universal kernel driver generating unit 303 is specifically configured to: The contents of the rel.gnu.linkonce.this_module area are copied to the rel.gnu.linkonce.this_module area of the initial generic kernel driver.
  • the universal kernel driver generating unit 303 is specifically configured to: determine whether the reference driver includes a rel.gnu.linkonce.this_module region; if not, search for a rel.gnu.linkonce.this_module region in the file system. Reference drive; if so, first copy the vermagic information of the modinfo area of the reference driver to the vermagic field of the modinfo area of the initial general-purpose kernel driver, and then start the 64-byte start of the initial generic kernel driver with the .versions area of the reference driver The default area starts with 64 bytes. Finally, it is judged whether the reference driver is the same size as the rel.gnu.linkonce.this_module area of the initial general-purpose kernel driver. If it is consistent, the content of the rel.gnu.linkonce.this_module area in the reference driver is copied. Go to the rel.gnu.linkonce.this_module area in the initial generic kernel driver.
  • the universal kernel driver loading unit 304 is specifically configured to: write a generic kernel driver into a file, load the generic kernel driver into the kernel of the target system by using the insmod command; or call the init_module by using a general-purpose kernel driver in the memory.
  • the initial generic kernel driver is compiled based on standard Linux kernel source code.
  • the reference kernel code selecting unit 301 selects a kernel source code of the android system as the reference kernel code; if the target system is a ubuntu system, the reference kernel code The selection unit 301 selects the kernel source code of the ubuntu system as the reference kernel code.
  • modules in the devices of the embodiments can be adaptively changed and placed in one or more devices different from the embodiment.
  • the modules or units or components of the embodiments may be combined into one module or unit or component, and further they may be divided into a plurality of sub-modules or sub-units or sub-components.
  • any combination of the features disclosed in the specification, including the accompanying claims, the abstract and the drawings, and any methods so disclosed, or All processes or units of the device are combined.
  • Each feature disclosed in this specification (including the accompanying claims, the abstract and the drawings) may be replaced by alternative features that provide the same, equivalent or similar purpose.
  • the various component embodiments of the present invention may be implemented in hardware, or in a software module running on one or more processors, or in a combination thereof.
  • a microprocessor or digital signal processor may be used in practice to implement some or all of the functionality of some or all of the components of the Linux kernel-driven device in accordance with embodiments of the present invention.
  • the invention can also be implemented as a device or device program (e.g., a computer program and a computer program product) for performing some or all of the methods described herein.
  • a program implementing the invention may be stored on a computer readable medium or may be in the form of one or more signals. Such signals can be downloaded from the Internet website or in the carrier signal Provided on, or provided in any other form.
  • Figure 4 illustrates a computing device that can implement a method of loading a Linux kernel driver in accordance with the present invention.
  • the computing device conventionally includes a processor 410 and a computer program product or computer readable medium in the form of a memory 420.
  • the memory 420 may be an electronic memory such as a flash memory, an EEPROM (Electrically Erasable Programmable Read Only Memory), an EPROM, a hard disk, or a ROM.
  • the memory 420 has a storage space 430 that stores program code 431 for performing any of the method steps described above.
  • storage space 430 storing program code may include various program code 431 for implementing various steps in the above methods, respectively.
  • the program code can be read from or written to one or more computer program products.
  • These computer program products include program code carriers such as a hard disk, a compact disk (CD), a memory card, or a floppy disk.
  • Such computer program products are typically, for example, portable or fixed storage units as shown in FIG.
  • the storage unit may have storage segments, storage spaces, and the like that are similarly arranged to memory 420 in the computing device of FIG.
  • the program code can be compressed, for example, in an appropriate form.
  • the storage unit comprises computer readable code 431' for performing the steps of the method according to the invention, ie code that can be read by a processor such as 410, which when executed by the computing device causes the computing device Perform the various steps in the method described above.

Landscapes

  • Engineering & Computer Science (AREA)
  • Software Systems (AREA)
  • Theoretical Computer Science (AREA)
  • Physics & Mathematics (AREA)
  • General Engineering & Computer Science (AREA)
  • General Physics & Mathematics (AREA)
  • Stored Programmes (AREA)

Abstract

一种加载Linux内核驱动的方法及装置,其中的方法包括:选择与目标系统的CPU平台一致的内核代码作为编译初始通用内核驱动的参考内核代码(S101);在参考内核代码的结构体中填充预定大小的字节,并将填充后的参考内核代码与初始通用内核驱动一起编译(S102);在目标系统中查找目标系统自带的内核驱动作为参考驱动,并根据参考驱动的信息修改上述经过编译后的初始通用内核驱动,生成通用内核驱动(S103);将生成的通用内核驱动加载到目标系统的内核中(S104)。该技术方案可以把一个通用内核驱动加载到不同内核版本的目标系统中去;可以把同一个驱动加载到大部分的Android手机里。

Description

加载Linux内核驱动的方法及装置 技术领域
本发明涉及计算机技术领域,具体涉及一种加载Linux内核驱动的方法及装置。
背景技术
Linux系统中,加载内核驱动的方法是调用insmod命令。由于Linux的特性,加载的内核驱动的版本信息必须和内核的版本信息完全一致,才能够加载成功。并且由于内核版本升级频繁,并且众多厂商都有自己的定制,导致市场上Android手机上的Linux内核版本多种多样。为了开发一个内核驱动能够运行在某一款Android手机上,必须找到对应的手机的内核源码,把自己的内核驱动代码和内核代码一起编译。这种方式增加了巨大的开发工作量,需要收集海量的各种版本的内核源代码,针对各版本内核编译对应的内核驱动,甚至有些设备的内核源代码根本收集不到,这样就给内核驱动的通用性带来了致命的限制。
发明内容
鉴于上述问题,提出了本发明以便提供一种克服上述问题或者至少部分地解决上述问题的加载Linux内核驱动的方法及装置。
依据本发明的一个方面,提供一种加载Linux内核驱动的方法,包括:选择与目标系统的CPU平台一致的内核代码作为编译初始通用内核驱动的参考内核代码;在参考内核代码的结构体中填充预定大小的字节,并将填充后的参考内核代码与初始通用内核驱动一起编译;在目标系统中查找目标系统自带的内核驱动作为参考驱动,并根据参考驱动的信息修改上述经过编译后的初始通用内核驱动,生成通用内核驱动;将生成的通用内核驱动加载到目标系统的内核中。
优选的,所述在参考内核代码的结构体中填充预定大小的字节包括:修 改参考内核代码的include/linux/module.h文件中的struct module结构体,在结构体尾部填充预定大小的字节。
优选的,所述填充预定大小的字节,保证经过填充后的参考内核代码的struct module结构体大于目标系统的struct module结构体。
优选的,所述根据参考驱动的信息修改上述经过编译后的初始通用内核驱动包括:从所述参考驱动中提取内核校验需要使用到的校验信息;根据从参考驱动中提取的所述校验信息,修改所述初始通用内核驱动中对应的信息。
优选的,所述校验信息是指内核版本信息:vermagic信息;所述根据从参考驱动中提取的所述校验信息,修改所述初始通用内核驱动中对应的信息包括:将参考驱动的modinfo区的vermagic信息拷贝到初始通用内核驱动的modinfo区的vermagic字段。
优选的,所述校验信息是指内核驱动版本信息以及所使用的导出符号的版本信息:versions区开始64字节;所述根据从参考驱动中提取的所述校验信息,修改所述初始通用内核驱动中对应的信息包括:用所述参考驱动的versions区开始64字节覆盖所述初始通用内核驱动的versions区开始64字节。
优选的,所述根据参考驱动的信息修改上述经过编译后的初始通用内核驱动包括:从所述参考驱动中提取加载执行函数和卸载执行函数的重定位信息;根据从参考驱动中提取的所述重定位信息,修改所述初始通用内核驱动中对应的信息。
优选的,所述重定位信息是指this_module.init和this_mosule.exit的重定位信息;所述根据从参考驱动中提取的所述重定位信息,修改所述初始通用内核驱动中对应的信息包括:将所述参考驱动中的rel.gnu.linkonce.this_module区的内容拷贝到所述初始通用内核驱动中的rel.gnu.linkonce.this_module区。
优选的,所述根据参考驱动的信息修改上述经过编译后的初始通用内核驱动包括:判断所述参考驱动中是否包含rel.gnu.linkonce.this_module区; 若否,在文件系统中搜索包含rel.gnu.linkonce.this_module区的参考驱动;若是,首先将参考驱动的modinfo区的vermagic信息拷贝到初始通用内核驱动的modinfo区的vermagic字段,然后用所述参考驱动的versions区开始64字节覆盖所述初始通用内核驱动的.versions区开始64字节,最后判断参考驱动与初始通用内核驱动的rel.gnu.linkonce.this_module区大小是否一致,如果一致,将所述参考驱动中的rel.gnu.linkonce.this_module区的内容拷贝到所述初始通用内核驱动中的rel.gnu.linkonce.this_module区。
优选的,将生成的通用内核驱动加载到目标系统的内核中包括:将通用内核驱动写入文件中,通过insmod命令将通用内核驱动加载到目标系统的内核中;或者,利用内存中的通用内核驱动调用init_module系统调用,将所述通用内核驱动加载到目标系统的内核中。
优选的,所述初始通用内核驱动是基于标准Linux内核源代码编译生成的。
优选的,如果所述目标系统是android系统,则选择android系统的内核源代码作为所述参考内核代码;如果所述目标系统是ubuntu系统,则选择ubuntu系统的内核源代码作为所述参考内核代码。
依据本发明的另一个方面,提供一种加载Linux内核驱动的装置,包括:参考内核代码选择单元,用于选择与目标系统的CPU平台一致的内核代码作为编译初始通用内核驱动的参考内核代码;初始通用内核代码编译单元,用于在参考内核代码的结构体中填充预定大小的字节,并将填充后的参考内核代码与初始通用内核驱动一起编译;通用内核驱动生成单元,用于在目标系统中查找目标系统自带的内核驱动作为参考驱动,并根据参考驱动的信息修改上述经过编译后的初始通用内核驱动,生成通用内核驱动;通用内核驱动加载单元,用于将生成的通用内核驱动加载到目标系统的内核中。
优选的,所述初始通用内核代码编译单元具体用于:修改参考内核代码的include/linux/module.h文件中的struct module结构体,在结构体尾部填充预定大小的字节。
优选的,所述初始通用内核代码编译单元所填充预定大小的字节,保证经过填充后的参考内核代码的struct module结构体大于目标系统的struct  module结构体。
优选的,所述通用内核驱动生成单元具体用于:从所述参考驱动中提取内核校验需要使用到的校验信息;以及,根据从参考驱动中提取的所述校验信息,修改所述初始通用内核驱动中对应的信息。
优选的,所述校验信息是指内核版本信息:vermagic信息;所述通用内核驱动生成单元具体用于:将参考驱动的modinfo区的vermagic信息拷贝到初始通用内核驱动的modinfo区的vermagic字段。
优选的,所述校验信息是指内核驱动版本信息以及所使用的导出符号的版本信息:versions区开始64字节;所述通用内核驱动生成单元具体用于:用所述参考驱动的.versions区开始64字节覆盖所述初始通用内核驱动的versions区开始64字节。
优选的,所述通用内核驱动生成单元具体用于:从所述参考驱动中提取加载执行函数和卸载执行函数的重定位信息;以及,根据从参考驱动中提取的所述重定位信息,修改所述初始通用内核驱动中对应的信息。
优选的,所述重定位信息是指this_module.init和this_mosule.exit的重定位信息;所述通用内核驱动生成单元具体用于:将所述参考驱动中的rel.gnu.linkonce.this_module区的内容拷贝到所述初始通用内核驱动中的rel.gnu.linkonce.this_module区。
优选的,所述通用内核驱动生成单元具体用于:判断所述参考驱动中是否包含rel.gnu.linkonce.this_module区;若否,在文件系统中搜索包含rel.gnu.linkonce.this_module区的参考驱动;若是,首先将参考驱动的modinfo区的vermagic信息拷贝到初始通用内核驱动的modinfo区的vermagic字段,然后用所述参考驱动的.versions区开始64字节覆盖所述初始通用内核驱动的versions区开始64字节,最后判断参考驱动与初始通用内核驱动的rel.gnu.linkonce.this_module区大小是否一致,如果一致,将所述参考驱动中的rel.gnu.linkonce.this_module区的内容拷贝到所述初始通用内核驱动中的rel.gnu.linkonce.this_module区。
优选的,所述通用内核驱动加载单元具体用于:将通用内核驱动写入文 件中,通过insmod命令将通用内核驱动加载到目标系统的内核中;或者,利用内存中的通用内核驱动调用init_module系统调用,将所述通用内核驱动加载到目标系统的内核中。
优选的,所述初始通用内核驱动是基于标准Linux内核源代码编译生成的。
优选的,如果所述目标系统是android系统,则所述参考内核代码选择单元选择android系统的内核源代码作为所述参考内核代码;如果所述目标系统是ubuntu系统,则所述参考内核代码选择单元选择ubuntu系统的内核源代码作为所述参考内核代码。
依据本发明的又一个方面,提供一种计算机程序,其包括计算机可读代码,当计算机可读代码在计算设备上运行时,导致计算设备执行上述的加载Linux内核驱动的方法。
依据本发明的再一个方面,提供一种计算机可读介质,其中存储了上述计算机程序。
可见,本发明方案通过在参考内核代码结构体中增加一些填充字节,避免目标系统中结构体大于通用内核驱动中结构体,从而避免访问越界;并且,通过根据参考驱动修改初通用始内核驱动,使得生成的通用内核驱动可以通过目标系统的校验以及被正常调用。采用本发明的技术方案,可以把一个通用内核驱动加载到不同内核版本的目标系统中去;可以把同一个驱动加载到大部分的Android手机里。
上述说明仅是本发明技术方案的概述,为了能够更清楚了解本发明的技术手段,而可依照说明书的内容予以实施,并且为了让本发明的上述和其它目的、特征和优点能够更明显易懂,以下特举本发明的具体实施方式。
附图概述
通过阅读下文优选实施方式的详细描述,各种其他的优点和益处对于本领域普通技术人员将变得清楚明了。附图仅用于示出优选实施方式的目的,而并不认为是对本发明的限制。而且在整个附图中,用相同的参考符号表示 相同的部件。在附图中:
图1示出了根据本发明一个实施例的加载Linux内核驱动的方法流程图;
图2示出了根据本发明一个实施例的根据参考驱动的信息修改初始通用内核驱动的流程图;以及
图3示出了根据本发明一个实施例的加载Linux内核驱动的装置结构示意图;
图4示意性地示出了用于执行根据本发明的加载Linux内核驱动的方法的计算设备的框图;以及
图5示意性地示出了用于保持或者携带实现根据本发明的加载Linux内核驱动的方法的程序代码的存储单元。
本发明的较佳实施方式
下面将参照附图更详细地描述本公开的示例性实施例。虽然附图中显示了本公开的示例性实施例,然而应当理解,可以以各种形式实现本公开而不应被这里阐述的实施例所限制。相反,提供这些实施例是为了能够更透彻地理解本公开,并且能够将本公开的范围完整的传达给本领域的技术人员。
一般加载内核驱动的方法是调用命令insmod。insmod命令首先把需要加载的内核驱动读入内存,然后调用系统调用init_module,把内核驱动在内存中的地址和长度,以及驱动的参数传递给内核。insmod命令通过系统调用init_module进入内核后,内核首先把用户空间内存里的驱动拷贝到内核空间,然后检查内核驱动是否符合ELF格式,如果不符合,则内核拒绝加载该驱动。接下来内核会根据ELF(Executable and Linkable Format,可执行连接格式)的格式分析内核驱动的各种信息,进行判断、检验,如果校验失败则拒绝加载该驱动。
总体而言,需要校验的信息如下:
(1)vermagic
内核驱动采用的是ELF格式,vermagic在.modinfo区里,vermagic是内 核的版本信息,内核会校验正在加载的驱动的vermagic是否跟内核本身的一致。如果不一致则拒绝驱动的加载。
(2)module_layout(内核版本3.0以上)或者struct_module(内核版本2.6以上,3.0以下)的版本信息
module_layout和struct_module的版本信息包含在__versions区。3.0版本以上的内核会检查正在加载的内核驱动的module_layout的版本信息是否与内核本身的一致。2.6以上、3.0以下版本的内核会检查正在加载的内核驱动的struct_module的版本信息是否与内核本身的一致。如果不一致则拒绝驱动的加载。
(3)内核驱动引用到的symbol(符号)的版本信息
一般情况下,内核驱动都会引用到内核中导出的函数或者变量(即:symbol),如果用到了,则会在内核驱动的__versions区里面保存该函数或者变量的版本信息。在内核驱动加载的时候,内核会对函数或者变量在__versions区里面的版本信息与内核里面保存的版本信息做对比,如果不一致则拒绝驱动的加载。
由于Linux的特性,加载内核驱动时会进行上面描述的三种校验,所以很难用一个内核驱动来适应各种不同版本的Linux内核。通常情况下,需要找到对应版本的内核代码,然后把内核驱动与对应的内核代码一起编译,才能让编译出来的内核驱动能通过上面描述的三种校验。由于Linux内核的版本非常多,所以无法做到一个内核驱动能支持所有版本的Linux内核。
本发明针对上述问题,提供一种加载Linux内核驱动的方法及装置,能够使同一个内核驱动加载到运行着各种版本内核的Linux设备上。具体的,本发明所要解决的问题是让同一个内核驱动能加载到不同版本的Linux内核中,而不受上面三种校验的限制。
参见图1,示出了根据本发明一个实施例的加载Linux内核驱动的方法流程图,包括以下步骤:
S101:选择与目标系统的CPU平台一致的内核代码作为编译初始通用内核驱动的参考内核代码;
S102:在参考内核代码的结构体中填充预定大小的字节,并将填充后的 参考内核代码与初始通用内核驱动一起编译;
S103:在目标系统中查找目标系统自带的内核驱动作为参考驱动,并根据参考驱动的信息修改上述经过编译后的初始通用内核驱动,生成通用内核驱动;
S104:将生成的通用内核驱动加载到目标系统的内核中。
其中,目标系统是一种运行着Linux内核的系统,通用内核驱动需要加载到该系统中;参考内核代码是一份完整的内核代码,内核驱动的编译需要用到该内核代码的版本信息、符号信息和头文件等等,是编译内核驱动必不可少的基础;初始通用内核驱动是基于标准Linux内核源代码编译生成的,初始通用内核驱动是一种二进制的ELF文件,初始通用内核驱动经过本发明方法的处理后,称之为通用内核驱动,才能够加载到不同版本的Linux内核中;通用内核驱动是由初始通用内核驱动经过根据参考内核驱动修改之后生成的,可以加载到不同版本的Linux内核中。
为了解决上述问题,针对内核在驱动加载时所作的校验,本发明提供的方案的基本思路如下:在目标系统中寻找系统自带的内核驱动作为参考驱动,根据参考驱动的信息,修改初始通用内核驱动,使之可以通过内核的三种校验,然后再通过正常的方法加载修改后的内核驱动。
具体的步骤如下:
步骤一:选择与目标系统的CPU平台一致的内核代码,作为编译初始通用内核驱动的参考内核代码。
例如:如果是给Android(Android是一种基于Linux内核的自由及开放源代码的操作系统,主要使用于移动设备,如智能手机和平板电脑)的ARM平台的设备开发初始通用内核驱动,则可以选择google提供的goldfish(Goldfish是一种虚拟的ARM处理器,在android的仿真环境中使用)内核源代码作为参考内核代码。再如,如果目标系统是ubuntu(乌班图,是一个以桌面应用为主的Linux操作系统系统),则选择ubuntu系统的内核源代码作为参考内核代码。
步骤二:修改参考内核代码的include/linux/module.h文件中的struct module结构体,在最后面增加预定大小的字节,例如增加256字节的填充。
由于内核版本的不一致,struct module结构体的大小可能会有变化,为了编译出来的内核驱动可以使用不同的内核版本,把struct module结构体增大256字节,这样内核在使用本发明编译出来的通用内核驱动就不会发生内存越界的行为。
步骤三:把参考内核代码与初始通用内核驱动一起编译,把初始通用内核驱动拷贝到目标系统中,通过代码寻找系统自带的内核驱动作为参考驱动。
步骤四:从参考内核驱动中提取需要的信息,修改初始通用内核驱动,具体流程如图2所示。
对图2中的过程解释如下。
S201:读取初始通用内核驱动。
内核驱动采用的是ELF格式,为了方便修改,把整个ELF格式的驱动读入到内存。
S202:在文件系统中搜索参考驱动。
在目标系统的文件系统中搜索自带的原生的驱动,找到后可以从里面提取信息,以供修改初始通用内核驱动。
S203:判断参考驱动中是否包含.rel.gnu.linkonce.this_module区。
通常的驱动只要一旦加载进入内核就会执行驱动的init函数(加载执行函数),一旦被卸载就会执行驱动的exit函数(卸载执行函数),this_module结构体中的init和exit成员存着这两个函数的地址,由于驱动加载的地址不确定,所以这两个函数的地址在加载之前是未知的,需要在加载完后重新赋值这两个结构体的成员,这就是重定位。.rel.gnu.linkonce.this_module区中存着的就是this_module中需要重定位的信息,就是init和exit两个成员的重定位信息。有的内核驱动并没有init和exit函数,可能只是导出一些函数供其它驱动调用,这种驱动不能作为参考驱动。
S204:读取参考驱动。
把参考驱动的整个内容读入内存,方便信息的提取。
S205:从参考驱动的.modinfo区拷贝vermagic信息到初始通用内核驱动的.modinfo区的vermagic字段。
由于内核会在驱动加载的时候验证vermagic,而参考驱动的vermagic是正确的,所以把vermagic复制到初始通用内核驱动。
S206:用参考驱动的_versions区开始的64字节覆盖初始通用内核驱动_verions区开始64字节。
_version区的每一项占64字节,前面4个字节是版本信息,后面60个字节是函数或者变量的名字,由于2.6和3.0内核中的第一项分别是struct_module和module_layout,所以不管目标系统是什么版本,只需要把前64个字节拷贝到初始通用内核驱动中对应的位置,就可以通过内核的检验,包括对驱动版本的验证以及对需要使用到的符号的验证。
S207:判断参考驱动与初始通用内核驱动的.rel.gnu.linkonce.this_module区大小是否一致。
增加这个判断是防止参考驱动中的this_module中有更多的需要重定位的成员,这样可能会会导致init和exit成员的偏移不正确,导致内核加载出错,甚至内核崩溃。
S208:如果参考驱动与初始通用内核驱动的.rel.gnu.linkonce.this_module区大小一致,则拷贝参考驱动的.rel.gnu.linkonce.this_module到初始通用内核驱动的.rel.gnu.linkonce.this_module。
复制this_module.init和this_module.exit的重定位信息到初始通用内核驱动中,初始通用内核驱动的this_module结构体在编译的时候由于增加了预定大小字节(例如256字节)的填充,所以肯定比目标系统中的this_module的结构体要大,这样init和exit的重定位信息中的偏移量肯定不会超出初始通用内核驱动的this_module结构体。在驱动加载时,内核根据重定位信息把init和exit函数加载后的地址赋值到this_module.init和this_module.exit,然后再调用this_module.init指向的函数。这样整个驱动就算加载成功了。
S209:生成新的通用内核驱动。
把内存中的通用内核驱动写入到文件中,以供insmod加载。
上述是图2的流程,完成之后,就得到了通用内核驱动。
步骤五:通过传统的insmod命令将修改后的通用内核驱动加载进目标系统的内核。
上述技术方案仅仅是示例,一些方面可以做适当调整,比如:
步骤一中,参考内核代码的选择可以有很多种,只要选择与目标系统的CPU的架构是一样的系统内核源代码即可。
步骤二中,module结构体最后的填充256字节,可以用其它数值,只要确保修改后的参考内核代码中的module结构体大小,大于目标系统的module结构体大小。
步骤三中,编译初始通用内核驱动时可以放在参考内核代码内部一起编译,也可以放在外面单独编译。
步骤四中,根据参考驱动修改初始通用内核驱动的行为,可以放在目标系统上执行,也可以把目标系统上的参考驱动拷贝到其它机器上执行;修改初始通用内核驱动的步骤可以做一些顺序上的调整,甚至最后一步不需要写入文件,直接用内存中的通用内核驱动,调用init_module系统调用,把修改过的驱动加载到内核中,这样步骤五就不需要了。
可见,在上述详细过程中,拷贝参考驱动的vermagic信息到初始通用内核驱动,就可以通过内核对vermagic的校验;复制参考驱动__versions区的前64个字节到初始通用内核驱动的__verions区,就可以通过内核对struct_module或者module_layout的驱动版本信息的校验以及符号的校验;复制.rel.gnu.linkonce.this_module区,就可以让内核重定位this_module.ini和this_module.exit到正确的问题,让驱动init函数得到正确的调用。总之,采用本发明的技术方案,就可以把一个通用内核驱动加载到不同内核版本的目标系统中去。实际操作中,可以把同一个驱动加载到大部分的Android手机里。
与上述方法相对应,本发明还提供一种加载Linux内核驱动的装置。该装置可以通过硬件、软件或软硬件结合方式实现。该装置可以是指Linux系统的功能模块,也可以是指安装Linux系统的硬件设备,只要可实现该装置的功能即可。
图3示出了根据本发明一个实施例的加载Linux内核驱动的装置,包括:
参考内核代码选择单元301,用于选择与目标系统的CPU平台一致的内核代码作为编译初始通用内核驱动的参考内核代码;
初始通用内核代码编译单元302,用于在参考内核代码的结构体中填充预定大小的字节,并将填充后的参考内核代码与初始通用内核驱动一起编译;
通用内核驱动生成单元303,用于在目标系统中查找目标系统自带的内核驱动作为参考驱动,并根据参考驱动的信息修改上述经过编译后的初始通用内核驱动,生成通用内核驱动;
通用内核驱动加载单元304,用于将生成的通用内核驱动加载到目标系统的内核中。
优选的,所述初始通用内核代码编译单元302具体用于:修改参考内核代码的include/linux/module.h文件中的struct module结构体,在结构体尾部填充预定大小的字节。
优选的,所述初始通用内核代码编译单元302所填充预定大小的字节,保证经过填充后的参考内核代码的struct module结构体大于目标系统的struct module结构体。
优选的,所述通用内核驱动生成单元303具体用于:从所述参考驱动中提取内核校验需要使用到的校验信息;以及,根据从参考驱动中提取的所述校验信息,修改所述初始通用内核驱动中对应的信息。
优选的,所述校验信息是指内核版本信息:vermagic信息;所述通用内核驱动生成单元303具体用于:将参考驱动的modinfo区的vermagic信息拷贝到初始通用内核驱动的modinfo区的vermagic字段。
优选的,所述校验信息是指内核驱动版本信息以及所使用的导出符号的版本信息:versions区开始64字节;所述通用内核驱动生成单元303具体用于:用所述参考驱动的.versions区开始64字节覆盖所述初始通用内核驱动的versions区开始64字节。
优选的,所述通用内核驱动生成单元303具体用于:从所述参考驱动中提取加载执行函数和卸载执行函数的重定位信息;以及,根据从参考驱动中提取的所述重定位信息,修改所述初始通用内核驱动中对应的信息。
优选的,所述重定位信息是指this_module.init和this_mosule.exit的重定位信息;所述通用内核驱动生成单元303具体用于:将所述参考驱动中的 rel.gnu.linkonce.this_module区的内容拷贝到所述初始通用内核驱动中的rel.gnu.linkonce.this_module区。
优选的,所述通用内核驱动生成单元303具体用于:判断所述参考驱动中是否包含rel.gnu.linkonce.this_module区;若否,在文件系统中搜索包含rel.gnu.linkonce.this_module区的参考驱动;若是,首先将参考驱动的modinfo区的vermagic信息拷贝到初始通用内核驱动的modinfo区的vermagic字段,然后用所述参考驱动的.versions区开始64字节覆盖所述初始通用内核驱动的versions区开始64字节,最后判断参考驱动与初始通用内核驱动的rel.gnu.linkonce.this_module区大小是否一致,如果一致,将所述参考驱动中的rel.gnu.linkonce.this_module区的内容拷贝到所述初始通用内核驱动中的rel.gnu.linkonce.this_module区。
优选的,所述通用内核驱动加载单元304具体用于:将通用内核驱动写入文件中,通过insmod命令将通用内核驱动加载到目标系统的内核中;或者,利用内存中的通用内核驱动调用init_module系统调用,将所述通用内核驱动加载到目标系统的内核中。
优选的,所述初始通用内核驱动是基于标准Linux内核源代码编译生成的。
优选的,如果所述目标系统是android系统,则所述参考内核代码选择单元301选择android系统的内核源代码作为所述参考内核代码;如果所述目标系统是ubuntu系统,则所述参考内核代码选择单元301选择ubuntu系统的内核源代码作为所述参考内核代码。
在此提供的算法和显示不与任何特定计算机、虚拟系统或者其它设备固有相关。各种通用系统也可以与基于在此的示教一起使用。根据上面的描述,构造这类系统所要求的结构是显而易见的。此外,本发明也不针对任何特定编程语言。应当明白,可以利用各种编程语言实现在此描述的本发明的内容,并且上面对特定语言所做的描述是为了披露本发明的最佳实施方式。
在此处所提供的说明书中,说明了大量具体细节。然而,能够理解,本发明的实施例可以在没有这些具体细节的情况下实践。在一些实例中,并未详细示出公知的方法、结构和技术,以便不模糊对本说明书的理解。
类似地,应当理解,为了精简本公开并帮助理解各个发明方面中的一个或多个,在上面对本发明的示例性实施例的描述中,本发明的各个特征有时被一起分组到单个实施例、图、或者对其的描述中。然而,并不应将该公开的方法解释成反映如下意图:即所要求保护的本发明要求比在每个权利要求中所明确记载的特征更多的特征。更确切地说,如下面的权利要求书所反映的那样,发明方面在于少于前面公开的单个实施例的所有特征。因此,遵循具体实施方式的权利要求书由此明确地并入该具体实施方式,其中每个权利要求本身都作为本发明的单独实施例。
本领域那些技术人员可以理解,可以对实施例中的设备中的模块进行自适应性地改变并且把它们设置在与该实施例不同的一个或多个设备中。可以把实施例中的模块或单元或组件组合成一个模块或单元或组件,以及此外可以把它们分成多个子模块或子单元或子组件。除了这样的特征和/或过程或者单元中的至少一些是相互排斥之外,可以采用任何组合对本说明书(包括伴随的权利要求、摘要和附图)中公开的所有特征以及如此公开的任何方法或者设备的所有过程或单元进行组合。除非另外明确陈述,本说明书(包括伴随的权利要求、摘要和附图)中公开的每个特征可以由提供相同、等同或相似目的的替代特征来代替。
此外,本领域的技术人员能够理解,尽管在此所述的一些实施例包括其它实施例中所包括的某些特征而不是其它特征,但是不同实施例的特征的组合意味着处于本发明的范围之内并且形成不同的实施例。例如,在下面的权利要求书中,所要求保护的实施例的任意之一都可以以任意的组合方式来使用。
本发明的各个部件实施例可以以硬件实现,或者以在一个或者多个处理器上运行的软件模块实现,或者以它们的组合实现。本领域的技术人员应当理解,可以在实践中使用微处理器或者数字信号处理器(DSP)来实现根据本发明实施例的加载Linux内核驱动的装置中的一些或者全部部件的一些或者全部功能。本发明还可以实现为用于执行这里所描述的方法的一部分或者全部的设备或者装置程序(例如,计算机程序和计算机程序产品)。这样的实现本发明的程序可以存储在计算机可读介质上,或者可以具有一个或者多个信号的形式。这样的信号可以从因特网网站上下载得到,或者在载体信号 上提供,或者以任何其他形式提供。
例如,图4示出了可以实现根据本发明的加载Linux内核驱动的方法的计算设备。该计算设备传统上包括处理器410和以存储器420形式的计算机程序产品或者计算机可读介质。存储器420可以是诸如闪存、EEPROM(电可擦除可编程只读存储器)、EPROM、硬盘或者ROM之类的电子存储器。存储器420具有存储用于执行上述方法中的任何方法步骤的程序代码431的存储空间430。例如,存储程序代码的存储空间430可以包括分别用于实现上面的方法中的各种步骤的各个程序代码431。这些程序代码可以从一个或者多个计算机程序产品中读出或者写入到这一个或者多个计算机程序产品中。这些计算机程序产品包括诸如硬盘、紧致盘(CD)、存储卡或者软盘之类的程序代码载体。这样的计算机程序产品通常例如图5所示的便携式或者固定存储单元。该存储单元可以具有与图4的计算设备中的存储器420类似布置的存储段、存储空间等。程序代码可以例如以适当形式进行压缩。通常,存储单元包括用于执行根据本发明的方法步骤的计算机可读代码431',即可以由诸如410之类的处理器读取的代码,当这些代码由计算设备运行时,导致该计算设备执行上面所描述的方法中的各个步骤。
应该注意的是上述实施例对本发明进行说明而不是对本发明进行限制,并且本领域技术人员在不脱离所附权利要求的范围的情况下可设计出替换实施例。在权利要求中,不应将位于括号之间的任何参考符号构造成对权利要求的限制。单词“包含”不排除存在未列在权利要求中的元件或步骤。位于元件之前的单词“一”或“一个”不排除存在多个这样的元件。本发明可以借助于包括有若干不同元件的硬件以及借助于适当编程的计算机来实现。在列举了若干装置的单元权利要求中,这些装置中的若干个可以是通过同一个硬件项来具体体现。单词第一、第二、以及第三等的使用不表示任何顺序。可将这些单词解释为名称。

Claims (26)

  1. 一种加载Linux内核驱动的方法,包括:
    选择与目标系统的CPU平台一致的内核代码作为编译初始通用内核驱动的参考内核代码;
    在参考内核代码的结构体中填充预定大小的字节,并将填充后的参考内核代码与初始通用内核驱动一起编译;
    在目标系统中查找目标系统自带的内核驱动作为参考驱动,并根据参考驱动的信息修改上述经过编译后的初始通用内核驱动,生成通用内核驱动;
    将生成的通用内核驱动加载到目标系统的内核中。
  2. 如权利要求1所述的方法,其中,所述在参考内核代码的结构体中填充预定大小的字节包括:
    修改参考内核代码的include/linux/module.h文件中的struct module结构体,在结构体尾部填充预定大小的字节。
  3. 如权利要求2所述的方法,其中,所述填充预定大小的字节,保证经过填充后的参考内核代码的struct module结构体大于目标系统的struct module结构体。
  4. 如权利要求1所述的方法,其中,所述根据参考驱动的信息修改上述经过编译后的初始通用内核驱动包括:
    从所述参考驱动中提取内核校验需要使用到的校验信息;
    根据从参考驱动中提取的所述校验信息,修改所述初始通用内核驱动中对应的信息。
  5. 如权利要求4所述的方法,其中,所述校验信息是指内核版本信息:vermagic信息;
    所述根据从参考驱动中提取的所述校验信息,修改所述初始通用内核驱动中对应的信息包括:
    将参考驱动的modinfo区的vermagic信息拷贝到初始通用内核驱动的modinfo区的vermagic字段。
  6. 如权利要求4所述的方法,其中,所述校验信息是指内核驱动版本信息以及所使用的导出符号的版本信息:versions区开始64字节;
    所述根据从参考驱动中提取的所述校验信息,修改所述初始通用内核驱动中对应的信息包括:
    用所述参考驱动的versions区开始64字节覆盖所述初始通用内核驱动的versions区开始64字节。
  7. 如权利要求1所述的方法,其中,所述根据参考驱动的信息修改上述经过编译后的初始通用内核驱动包括:
    从所述参考驱动中提取加载执行函数和卸载执行函数的重定位信息;
    根据从参考驱动中提取的所述重定位信息,修改所述初始通用内核驱动中对应的信息。
  8. 如权利要求7所述的方法,其中,所述重定位信息是指this_module.init和this_mosule.exit的重定位信息;
    所述根据从参考驱动中提取的所述重定位信息,修改所述初始通用内核驱动中对应的信息包括:
    将所述参考驱动中的rel.gnu.linkonce.this_module区的内容拷贝到所述初始通用内核驱动中的rel.gnu.linkonce.this_module区。
  9. 如权利要求1所述的方法,其中,所述根据参考驱动的信息修改上述经过编译后的初始通用内核驱动包括:
    判断所述参考驱动中是否包含rel.gnu.linkonce.this_module区;
    若否,在文件系统中搜索包含rel.gnu.linkonce.this_module区的参考驱动;
    若是,首先将参考驱动的modinfo区的vermagic信息拷贝到初始通用内核驱动的modinfo区的vermagic字段,然后用所述参考驱动的versions区开始64字节覆盖所述初始通用内核驱动的.versions区开始64字节,最后判断参考驱动与初始通用内核驱动的rel.gnu.linkonce.this_module区大小是否一致,如果一致,将所述参考驱动中的rel.gnu.linkonce.this_module区的内容拷贝到所述初始通用内核驱动中的rel.gnu.linkonce.this_module区。
  10. 如权利要求1所述的方法,其中,将生成的通用内核驱动加载到目标系统的内核中包括:
    将通用内核驱动写入文件中,通过insmod命令将通用内核驱动加载到目标系统的内核中;或者,
    利用内存中的通用内核驱动调用init_module系统调用,将所述通用内核驱动加载到目标系统的内核中。
  11. 如权利要求1所述的方法,其中,所述初始通用内核驱动是基于标准Linux内核源代码编译生成的。
  12. 如权利要求1所述的方法,其中,如果所述目标系统是android系统,则选择android系统的内核源代码作为所述参考内核代码;如果所述目标系统是ubuntu系统,则选择ubuntu系统的内核源代码作为所述参考内核代码。
  13. 一种加载Linux内核驱动的装置,包括:
    参考内核代码选择单元,用于选择与目标系统的CPU平台一致的内核代码作为编译初始通用内核驱动的参考内核代码;
    初始通用内核代码编译单元,用于在参考内核代码的结构体中填充预定大小的字节,并将填充后的参考内核代码与初始通用内核驱动一起编译;
    通用内核驱动生成单元,用于在目标系统中查找目标系统自带的内核驱动作为参考驱动,并根据参考驱动的信息修改上述经过编译后的初始通用内核驱动,生成通用内核驱动;
    通用内核驱动加载单元,用于将生成的通用内核驱动加载到目标系统的内核中。
  14. 如权利要求3所述的装置,其中,所述初始通用内核代码编译单元具体用于:修改参考内核代码的include/linux/module.h文件中的struct module结构体,在结构体尾部填充预定大小的字节。
  15. 如权利要求14所述的装置,其中,所述初始通用内核代码编译单元所填充预定大小的字节,保证经过填充后的参考内核代码的struct module结构体大于目标系统的struct module结构体。
  16. 如权利要求13所述的装置,其中,所述通用内核驱动生成单元具体用于:从所述参考驱动中提取内核校验需要使用到的校验信息;以及,根据从参考驱动中提取的所述校验信息,修改所述初始通用内核驱动中对应的信息。
  17. 如权利要求16所述的装置,其中,所述校验信息是指内核版本信息:vermagic信息;所述通用内核驱动生成单元具体用于:将参考驱动的modinfo区的vermagic信息拷贝到初始通用内核驱动的modinfo区的vermagic字段。
  18. 如权利要求16所述的装置,其中,所述校验信息是指内核驱动版本信息以及所使用的导出符号的版本信息:versions区开始64字节;所述通用内核驱动生成单元具体用于:用所述参考驱动的.versions区开始64字节覆盖所述初始通用内核驱动的versions区开始64字节。
  19. 如权利要求13所述的装置,其中,所述通用内核驱动生成单元具体用于:从所述参考驱动中提取加载执行函数和卸载执行函数的重定位信息;以及,根据从参考驱动中提取的所述重定位信息,修改所述初始通用内核驱动中对应的信息。
  20. 如权利要求19所述的装置,其中,所述重定位信息是指this_module.init和this_mosule.exit的重定位信息;所述通用内核驱动生成单元具体用于:将所述参考驱动中的rel.gnu.linkonce.this_module区的内容拷贝到所述初始通用内核驱动中的rel.gnu.linkonce.this_module区。
  21. 如权利要求13所述的装置,其中,所述通用内核驱动生成单元具体用于:判断所述参考驱动中是否包含rel.gnu.linkonce.this_module区;若否,在文件系统中搜索包含rel.gnu.linkonce.this_module区的参考驱动;若是,首先将参考驱动的modinfo区的vermagic信息拷贝到初始通用内核驱动的modinfo区的vermagic字段,然后用所述参考驱动的.versions区开始64字节覆盖所述初始通用内核驱动的versions区开始64字节,最后判断参考驱动与初始通用内核驱动的rel.gnu.linkonce.this_module区大小是否一致,如果一致,将所述参考驱动中的rel.gnu.linkonce.this_module区的内容拷贝到所述初始通用内核驱动中的rel.gnu.linkonce.this_module区。
  22. 如权利要求13所述的装置,其中,所述通用内核驱动加载单元具 体用于:将通用内核驱动写入文件中,通过insmod命令将通用内核驱动加载到目标系统的内核中;或者,利用内存中的通用内核驱动调用init_module系统调用,将所述通用内核驱动加载到目标系统的内核中。
  23. 如权利要求13所述的装置,其中,所述初始通用内核驱动是基于标准Linux内核源代码编译生成的。
  24. 如权利要求13所述的装置,其中,如果所述目标系统是android系统,则所述参考内核代码选择单元选择android系统的内核源代码作为所述参考内核代码;如果所述目标系统是ubuntu系统,则所述参考内核代码选择单元选择ubuntu系统的内核源代码作为所述参考内核代码。
  25. 一种计算机程序,包括计算机可读代码,当所述计算机可读代码在计算设备上运行时,导致所述计算设备执行根据权利要求1-12中的任一项所述的加载Linux内核驱动的方法。
  26. 一种计算机可读介质,其中存储了如权利要求25所述的计算机程序。
PCT/CN2015/095577 2014-12-11 2015-11-25 加载Linux内核驱动的方法及装置 WO2016091071A1 (zh)

Applications Claiming Priority (2)

Application Number Priority Date Filing Date Title
CN201410766160.7A CN104375874B (zh) 2014-12-11 2014-12-11 加载Linux内核驱动的方法及装置
CN201410766160.7 2014-12-11

Publications (1)

Publication Number Publication Date
WO2016091071A1 true WO2016091071A1 (zh) 2016-06-16

Family

ID=52554814

Family Applications (1)

Application Number Title Priority Date Filing Date
PCT/CN2015/095577 WO2016091071A1 (zh) 2014-12-11 2015-11-25 加载Linux内核驱动的方法及装置

Country Status (2)

Country Link
CN (1) CN104375874B (zh)
WO (1) WO2016091071A1 (zh)

Cited By (5)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
CN110083363A (zh) * 2019-04-22 2019-08-02 珠海网博信息科技股份有限公司 一种Linux内核动态注入方式截取无线数据包的方法
CN110990072A (zh) * 2019-11-08 2020-04-10 杭州智控网络有限公司 价签屏幕多驱动动态加载方法
CN114281338A (zh) * 2021-11-25 2022-04-05 中国科学院信息工程研究所 一种获取Linux内核中数据结构偏移的方法和装置
CN114546500A (zh) * 2022-01-28 2022-05-27 郑州信大捷安信息技术股份有限公司 一种支持多设备的密码卡驱动实现方法和系统
CN114860324A (zh) * 2022-05-27 2022-08-05 裕太微电子股份有限公司 一种基于Linux的以太网phy内核驱动验证方法

Families Citing this family (6)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
CN104375874B (zh) * 2014-12-11 2017-05-17 北京奇虎科技有限公司 加载Linux内核驱动的方法及装置
CN105549965A (zh) * 2015-12-09 2016-05-04 浪潮电子信息产业股份有限公司 一种将驱动集成到不同Linux内核版本的方法
CN105893085A (zh) * 2016-03-30 2016-08-24 百度在线网络技术(北京)有限公司 内核模块加载方法和装置
CN106547706A (zh) * 2016-11-16 2017-03-29 公安部物证鉴定中心 一种基于源内核的手机动态内存提取方法
CN110569068A (zh) * 2018-06-06 2019-12-13 南通研祥智能科技有限公司 一种Linux驱动加载程序的方法及装置
CN111984334A (zh) * 2020-08-17 2020-11-24 上海睿赛德电子科技有限公司 一种轻量的操作系统内核与驱动分离方法

Citations (4)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US20020019972A1 (en) * 2000-04-24 2002-02-14 Grier Michael J. Isolating assembly versions for binding to application programs
CN1650264A (zh) * 2002-04-17 2005-08-03 计算机联合思想公司 用于修改一个内核模块以便在多个内核版本上运行的设备和方法
CN104021023A (zh) * 2014-06-24 2014-09-03 浪潮电子信息产业股份有限公司 一种突破内核模块版本控制解决方法
CN104375874A (zh) * 2014-12-11 2015-02-25 北京奇虎科技有限公司 加载Linux内核驱动的方法及装置

Family Cites Families (3)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US8505003B2 (en) * 2010-04-28 2013-08-06 Novell, Inc. System and method for upgrading kernels in cloud computing environments
CN102479097B (zh) * 2010-11-26 2014-06-11 中国科学院声学研究所 一种支持多级加载的安全嵌入式操作系统
CN102830983A (zh) * 2011-06-14 2012-12-19 上海未来宽带技术及应用工程研究中心有限公司 一种可动态加载不同终端交换芯片驱动的方法

Patent Citations (4)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US20020019972A1 (en) * 2000-04-24 2002-02-14 Grier Michael J. Isolating assembly versions for binding to application programs
CN1650264A (zh) * 2002-04-17 2005-08-03 计算机联合思想公司 用于修改一个内核模块以便在多个内核版本上运行的设备和方法
CN104021023A (zh) * 2014-06-24 2014-09-03 浪潮电子信息产业股份有限公司 一种突破内核模块版本控制解决方法
CN104375874A (zh) * 2014-12-11 2015-02-25 北京奇虎科技有限公司 加载Linux内核驱动的方法及装置

Cited By (8)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
CN110083363A (zh) * 2019-04-22 2019-08-02 珠海网博信息科技股份有限公司 一种Linux内核动态注入方式截取无线数据包的方法
CN110083363B (zh) * 2019-04-22 2022-04-01 珠海网博信息科技股份有限公司 一种Linux内核动态注入方式截取无线数据包的方法
CN110990072A (zh) * 2019-11-08 2020-04-10 杭州智控网络有限公司 价签屏幕多驱动动态加载方法
CN114281338A (zh) * 2021-11-25 2022-04-05 中国科学院信息工程研究所 一种获取Linux内核中数据结构偏移的方法和装置
CN114281338B (zh) * 2021-11-25 2024-05-28 中国科学院信息工程研究所 一种获取Linux内核中数据结构偏移的方法和装置
CN114546500A (zh) * 2022-01-28 2022-05-27 郑州信大捷安信息技术股份有限公司 一种支持多设备的密码卡驱动实现方法和系统
CN114860324A (zh) * 2022-05-27 2022-08-05 裕太微电子股份有限公司 一种基于Linux的以太网phy内核驱动验证方法
CN114860324B (zh) * 2022-05-27 2024-03-19 裕太微电子股份有限公司 一种基于Linux的以太网phy内核驱动验证方法

Also Published As

Publication number Publication date
CN104375874A (zh) 2015-02-25
CN104375874B (zh) 2017-05-17

Similar Documents

Publication Publication Date Title
WO2016091071A1 (zh) 加载Linux内核驱动的方法及装置
JP6198939B2 (ja) ドライバをロードする方法及び組み込みデバイス
US20060064576A1 (en) Boot systems and methods
CN1641583A (zh) 自描述软件映象更新组件
US20080072029A1 (en) Method for executing power on self test on a computer system and updating SMBIOS information partially
WO2018040270A1 (zh) 在Windows系统中加载Linux系统ELF文件的方法及装置
CN105760191A (zh) 嵌入式系统设备程序烧写量产方法
JP6157637B2 (ja) リードライトメモリデバイスのデータイメージ中の仮想境界コード
WO2023070823A1 (zh) 启动引导程序加载方法、装置、系统、电子设备及介质
TW201351274A (zh) 以機器指令取代編譯器內建輔助函數之方法及裝置
CN106951257A (zh) 一种用Uboot_CDROM启动WinCE的实现方法
WO2007070578A1 (en) Partitioning of non-volatile memories for vectorization
CN113377586B (zh) 一种服务器自动化检测方法、装置及存储介质
CN113485712B (zh) 一种内核裁剪方法及计算设备
CN110704113A (zh) 一种基于fpga平台的启动方法、系统及开发板装置
WO2016091078A1 (zh) 在Linux驱动中绑定内核符号的方法及装置
WO2018014687A1 (zh) 一种参数传递方法、装置及计算机存储介质
CN112698867A (zh) 注解信息的动态修改方法、装置、电子设备及介质
US10552135B1 (en) Reducing a size of an application package
CN106648788B (zh) 应用程序的安装方法及装置
US9063723B2 (en) Function-based software comparison method
CN111399926A (zh) 下载启动程序的方法和装置
CN105204896A (zh) 一种数字存储示波器的BootLoader设计方法
CN113010195B (zh) 一种系统升级方法、存储介质及终端设备
WO2017076034A1 (zh) 一种对移动终端的存储器进行格式化的方法和装置

Legal Events

Date Code Title Description
121 Ep: the epo has been informed by wipo that ep was designated in this application

Ref document number: 15868499

Country of ref document: EP

Kind code of ref document: A1

NENP Non-entry into the national phase

Ref country code: DE

122 Ep: pct application non-entry in european phase

Ref document number: 15868499

Country of ref document: EP

Kind code of ref document: A1