Method and system for implementing loadable system module that dynamically determines running state
By adopting capability-based access control and symbol relocation technology in the operating system kernel, the operating state of the system module is dynamically determined, and a unified API and cross-module call mechanism is provided for the kernel state and user state, which solves the shortcomings in the running state of the kernel module in the existing technology, and achieves efficient inter-module communication and isolation.
Patent Information
- Application Number
- CN202210523188.2
- Authority / Receiving Office
- CN · China
- Patent Type
- Patents(China)
- Current Assignee / Owner
- Filing Date
- 2022-05-13
- Publication Date
- 2025-03-25
- Estimated Expiration
- 2042-05-13
AI Technical Summary
The prior art is difficult to achieve a dynamic trade-off between scalability and isolation of functional modules in operating system kernels, especially in the operational state decision of kernel modules.
Through access control and symbol relocation technology based on capability, a unified API is provided, and a cross-module call mechanism is provided in the kernel based on capability mechanism, which dynamically determines that the running state of the system module is kernel state or user state.
It realizes that the system module can optionally be loaded into the kernel state or user state during the operating system runtime, and conducts high-performance mutual communication, achieving a dynamic trade-off between performance and isolation.
Smart Images

Figure CN114969753B_ABST
Abstract
Description
Technical Field
[0001] The present invention relates to the field of kernel security technology, and in particular to a method and system for realizing a loadable system module for dynamically determining a running state. Background Art
[0002] In the field of operating system kernel research and engineering practice, there has always been a trade-off between kernel scalability, isolation of functional modules and performance.
[0003] In order to make the functions of the operating system kernel extensible, many common kernels often provide the function of dynamically loading optional kernel modules as needed during runtime, such as Linux's loadable kernel module (LKM) and macOS's kernel extension (Kext). Taking Linux's loadable kernel module as an example, this mechanism allows users to install official or third-party kernel modules into the kernel through configuration or manually through the insmod command to provide system functions. After the kernel module is loaded into the memory, it runs in the kernel state. In the kernel module, the code can arbitrarily access the symbols of the Linux kernel, including global variables and functions. Therefore, when the kernel loads the module, it needs to first load the ELF loadable segment of the kernel module into the kernel address space, and then perform symbol relocation on the kernel symbols accessed by the module according to the ELF symbol table, so that the module knows the memory address of these kernel symbols during runtime. In addition to accessing kernel symbols, kernel modules can also access any location in the kernel address space through pointers. This ability to access arbitrary kernel data makes the security of kernel modules particularly important. Loading a kernel module of unknown security may cause kernel data to be maliciously accessed or tampered with. There has been a lot of recent work in the research community that uses CPU hardware features such as Intel VT-x hardware virtualization technology to isolate kernel modules running in kernel state from the kernel to ensure that the kernel is not invaded.
[0004] The microkernel improves the isolation of the functional modules of the operating system from another perspective. It separates most of the functions of the operating system kernel from the kernel state and runs them as user-state system service processes. Similarly, third-party kernel modules that provide extended functions for the kernel in the macro kernel can also provide services in the form of user-state processes in the microkernel. The process-level address space isolation ensures that system services cannot arbitrarily access each other's data, but can only communicate with each other through the inter-process communication (IPC) mechanism with the assistance of the kernel. At the same time, the system service running in the user state ensures that the system service cannot arbitrarily access the kernel's data, nor can it directly call the CPU privileged instructions, but can only request the functions provided by the kernel through the system call mechanism. It can be seen that in the microkernel, the performance of IPC is the key indicator of the performance of the entire system, because in the macro kernel, all service processes after a system call are function calls, while in the microkernel, the same service may require multiple IPC calls between multiple system services, and one IPC call involves four CPU privilege level switches, which is twice as many as the two system calls, and the overhead is much higher than that of function calls.
[0005] In recent years, with the rise of Rust as a system programming language, some research works such as RedLeaf have begun to explore the use of Rust's compile-time memory safety checks and visibility checks of modules, functions, and fields to isolate functional modules in the kernel. Rust's memory safety feature is implemented through an ownership mechanism, which determines an owner for each variable at compile time and tracks the transfer of ownership, so that by default, the program cannot arbitrarily access memory space that does not belong to it, that is, without using unsafe statements; the visibility settings of modules, functions, and fields are implemented through keywords such as pub and pub(crate), which prevents the program from arbitrarily calling functions set to be invisible to the outside in other modules or accessing global variables or structure fields set to be invisible to the outside in other modules. At the same time, since these memory safety and visibility checks occur at compile time, the compiled program has almost no additional overhead at run time. Taking advantage of these features, some work has split the functions of the operating system kernel into logical modules. Similar to the Linux loadable kernel modules, these modules are run in kernel state, but similar to the microkernel, these modules cannot directly access kernel data and functions, but must go through a well-designed cross-module calling mechanism to pass data and request services. This makes the communication between kernel modules have performance close to that of function calls, while ensuring isolation between modules and between modules and the kernel.
[0006] In summary, the existing mechanisms either load the kernel module into the kernel state to run, exposing the kernel address space, or separate the kernel function into the user state to run, improving isolation while reducing cross-module call performance, or rely on the characteristics of new programming languages and cannot support modules written in other languages. These methods all have their own adaptive scenarios and limitations. The present invention hopes to provide a dynamic customizable solution that can comprehensively determine whether the system module runs in the kernel state or the user state according to the system module properties and actual needs during the operating period of the operating system.
[0007] Patent document CN104112098A (application number: CN201410340870.3) discloses a kernel module loading control method in an operating system, the steps are: 1) during the boot process of the operating system, the kernel module processing capabilities of all users are turned off by the kernel sealing module in the kernel state, and the kernel sealing module user verification function is enabled, so that the operating system kernel enters a sealed state; 2) during the operation of the operating system, the kernel module operation request is intercepted by the kernel sealing module, and the user or application that initiates the kernel module operation request is verified. If the verification is passed, the kernel module processing capability of the user or application is enabled, and the target kernel module requested by the user or application is loaded or unloaded through the operating system kernel. However, the invention cannot realize that the loadable system module can be optionally loaded into the kernel state or user state during the operation of the operating system and communicate with each other. Summary of the invention
[0008] In view of the defects in the prior art, the object of the present invention is to provide a method and system for realizing a loadable system module that dynamically determines the running state.
[0009] A method for implementing a loadable system module that dynamically determines a running state according to the present invention includes:
[0010] Step S1: The kernel provides a unified API to system modules running in kernel mode and user mode through capability-based access control;
[0011] Step S2: through symbol relocation technology, dynamically determine whether the kernel API called by the system module is implemented in kernel mode or user mode when loading the system module;
[0012] Step S3: providing a cross-module calling mechanism based on the capability mechanism in the kernel, and using shared memory pages to pass parameters and return values;
[0013] Step S4: By providing a preset interface, it is allowed to wait on multiple connections at one time in the kernel API called across modules.
[0014] Preferably, in step S1:
[0015] When the system module is loaded into the memory and runs, the capability mechanism is used to provide access control to the kernel object. The system module code does not directly access the memory data of the kernel object, but reads and writes it through method calls;
[0016] In order to make the direct call to the function that implements the system call in the kernel and the system call through the syscall instruction produce the same effect, and the system module can observe the same behavior, the capability mechanism is introduced to provide a unified kernel object abstraction for the system module. The system module running in the kernel state can access the kernel object indirectly through capability, just like the system module running in the user state. The capability mechanism isolates the access rights of different system modules to kernel objects from each other. The system module cannot access the kernel object to which it does not have permission by forging capability values. When the system module is written in a memory-safe language, the system module can be run in the kernel state through the encapsulation library provided by the capability and the system kernel without having to worry about the module arbitrarily accessing the kernel data by guessing the memory address and constructing a pointer. When the system module is written in a language that is not memory-safe, it is run in the user state to ensure the security of the kernel through process-level address space isolation.
[0017] Preferably, in step S2:
[0018] Through symbol relocation technology, different parameters of the special dynamic loader are used to control the redirection of undefined symbols of the system module in ELF format to kernel state implementation or user state implementation. Undefined symbols are APIs provided by the operating system kernel to the system module. Kernel state implementation is manifested as a direct call to the kernel function, and user state implementation is manifested as a system call to the kernel.
[0019] The specially designed dynamic loader decides whether to load the system module into kernel mode or user mode for execution based on the parameters specified by the user. The dynamic loader first loads each loadable segment of ELF into memory, and then relocates the undefined symbols according to their relocation type. The actual memory address of the symbol at runtime is filled into the relocation address after different operations are performed according to the different relocation types. According to the different parameters given by the user, the specially designed dynamic loader relocates the symbols required by ELF to different implementations. When the user loads the system module into kernel mode for execution, the loader's relocation implementation is to directly call the function that implements the system call in the kernel, so that it does not need to request kernel services through system calls like user mode programs when it runs; when the user loads the system module into user mode for execution, it falls into kernel processing through the syscall instruction, and the CPU privilege level switch will occur in this process.
[0020] Preferably, in step S3:
[0021] Based on the capability mechanism, the kernel provides a cross-module calling mechanism for system modules, so that system modules can provide services and call external services through a unified mechanism. The operation of this mechanism requires the participation of both the server and the client. The server first registers the service with the kernel, and then waits for the client to connect on the capability of the service. The client queries the kernel for the service, obtains the capability, and establishes a connection with the server. After the connection is successful, the server waits for the client's call request on the capability of the connection. After receiving the request, it provides the service and returns.
[0022] In the cross-module calling mechanism, the kernel provides an interface for the system module. The two parties of the cross-module calling are divided into the client and the server. The basic working method is as follows:
[0023] On the server side:
[0024] a. Register a Server kernel object with the kernel through the cmc_register_server interface. This interface uses a string as the key and the Server object as the value. A mapping table is maintained in the kernel for subsequent client queries and returns the capability used to access this kernel object.
[0025] b. Call the cmc_accept interface on the Server object to put the current thread into a waiting state, waiting for the client to initiate a connection request. After the connection is successful, the capability of the Connection kernel object is returned;
[0026] c. The server continuously calls the cmc_wait interface on the Connection object to wait for the client's cross-module call, so that the current thread enters the waiting state. When the interface returns, it indicates that the client's call request has been received and should be processed;
[0027] On the client side:
[0028] i. Use cmc_find_server interface to query the kernel for the Server kernel object with a specific name and obtain the capability that can be used to access it;
[0029] ii. Call cmc_connect interface on this Server object to initiate connection to the server. This interface checks whether the server has called cmc_accept interface to wait for connection. If so, a Connection kernel object is created in the kernel to represent the connection established between the two, and the capability for accessing the Connection kernel object is returned. At the same time, the cmc_accept interface call on the server also returns.
[0030] iii. The client calls the cmc_call interface on the Connection object multiple times to initiate cross-module calls.
[0031] Preferably, in step S4:
[0032] The API of the cross-module calling mechanism allows a thread of a system module to wait for call requests on multiple connections, so that the server can freely decide the number of threads to serve the client;
[0033] The kernel provides the system module with a cmc_select interface, which allows the cross-module call server to wait on multiple Connection objects at the same time. Any of them that receives a cross-module call will return. Through the cmc_select interface, the system module can decide how many threads to use to process the cross-module call based on the actual situation.
[0034] When cross-module parameters need to pass parameters and return values, both the client and the server obtain the shared PMO corresponding to the Connection object through the cmc_get_shared_pmo interface, also in the form of capability, and each is mapped to its own address space for access. The shared PMO is created when cmc_get_shared_pmo is called. The kernel ensures that the client and the server can obtain access rights to the same PMO. Before calling cmc_call to initiate a cross-module call, the client fills in the specific service and required parameters to be requested in a specific location in the shared PMO according to the ABI agreed upon by the server. Then, after cmc_wait returns, the server obtains the parameters from the shared PMO and performs corresponding processing. According to the agreed ABI, the return value is filled in a specific location in the shared PMO, and the execution flow is returned to the client at the next cmc_wait call.
[0035] In the cmc_wait and cmc_select interfaces, a capability of the Connection object to be returned is added, so that after the current server thread is switched to the waiting state, the execution flow is immediately migrated to the initiating side of the call request just processed.
[0036] A loadable system module implementation system for dynamically determining a running state according to the present invention includes:
[0037] Module M1: The kernel provides a unified API to system modules running in kernel mode and user mode through capability-based access control;
[0038] Module M2: Through symbol relocation technology, it dynamically determines whether the kernel API called by the system module is implemented in kernel mode or user mode when loading the system module;
[0039] Module M3: Provides a cross-module calling mechanism based on the capability mechanism in the kernel, using shared memory pages to pass parameters and return values;
[0040] Module M4: Allows waiting on multiple connections at once in kernel APIs called across modules by providing a preset interface.
[0041] Preferably, in the module M1:
[0042] When the system module is loaded into the memory and runs, the capability mechanism is used to provide access control to the kernel object. The system module code does not directly access the memory data of the kernel object, but reads and writes it through method calls;
[0043] In order to make the direct call to the function that implements the system call in the kernel and the system call through the syscall instruction produce the same effect, and the system module can observe the same behavior, the capability mechanism is introduced to provide a unified kernel object abstraction for the system module. The system module running in the kernel state can access the kernel object indirectly through capability, just like the system module running in the user state. The capability mechanism isolates the access rights of different system modules to kernel objects from each other. The system module cannot access the kernel object to which it does not have permission by forging capability values. When the system module is written in a memory-safe language, the system module can be run in the kernel state through the encapsulation library provided by the capability and the system kernel without having to worry about the module arbitrarily accessing the kernel data by guessing the memory address and constructing a pointer. When the system module is written in a language that is not memory-safe, it is run in the user state to ensure the security of the kernel through process-level address space isolation.
[0044] Preferably, in the module M2:
[0045] Through symbol relocation technology, different parameters of the special dynamic loader are used to control the redirection of undefined symbols of the system module in ELF format to kernel state implementation or user state implementation. Undefined symbols are APIs provided by the operating system kernel to the system module. Kernel state implementation is manifested as a direct call to the kernel function, and user state implementation is manifested as a system call to the kernel.
[0046] The specially designed dynamic loader decides whether to load the system module into kernel mode or user mode for execution based on the parameters specified by the user. The dynamic loader first loads each loadable segment of ELF into memory, and then relocates the undefined symbols according to their relocation type. The actual memory address of the symbol at runtime is filled into the relocation address after different operations are performed according to the different relocation types. According to the different parameters given by the user, the specially designed dynamic loader relocates the symbols required by ELF to different implementations. When the user loads the system module into kernel mode for execution, the loader's relocation implementation is to directly call the function that implements the system call in the kernel, so that it does not need to request kernel services through system calls like user mode programs when it runs; when the user loads the system module into user mode for execution, it falls into kernel processing through the syscall instruction, and the CPU privilege level switch will occur in this process.
[0047] Preferably, in the module M3:
[0048] Based on the capability mechanism, the kernel provides a cross-module calling mechanism for system modules, so that system modules can provide services and call external services through a unified mechanism. The operation of this mechanism requires the participation of both the server and the client. The server first registers the service with the kernel, and then waits for the client to connect on the capability of the service. The client queries the kernel for the service, obtains the capability, and establishes a connection with the server. After the connection is successful, the server waits for the client's call request on the capability of the connection. After receiving the request, it provides the service and returns.
[0049] In the cross-module calling mechanism, the kernel provides an interface for the system module. The two parties of the cross-module calling are divided into the client and the server. The basic working method is as follows:
[0050] On the server side:
[0051] a. Register a Server kernel object with the kernel through the cmc_register_server interface. This interface uses a string as the key and the Server object as the value. A mapping table is maintained in the kernel for subsequent client queries and returns the capability used to access this kernel object.
[0052] b. Call the cmc_accept interface on the Server object to put the current thread into a waiting state, waiting for the client to initiate a connection request. After the connection is successful, the capability of the Connection kernel object is returned;
[0053] c. The server continuously calls the cmc_wait interface on the Connection object to wait for the client's cross-module call, so that the current thread enters the waiting state. When the interface returns, it indicates that the client's call request has been received and should be processed;
[0054] On the client side:
[0055] i. Use cmc_find_server interface to query the kernel for the Server kernel object with a specific name and obtain the capability that can be used to access it;
[0056] ii. Call cmc_connect interface on this Server object to initiate connection to the server. This interface checks whether the server has called cmc_accept interface to wait for connection. If so, a Connection kernel object is created in the kernel to represent the connection established between the two, and the capability for accessing the Connection kernel object is returned. At the same time, the cmc_accept interface call on the server also returns.
[0057] iii. The client calls the cmc_call interface on the Connection object multiple times to initiate cross-module calls.
[0058] Preferably, in the module M4:
[0059] The API of the cross-module calling mechanism allows a thread of a system module to wait for call requests on multiple connections, so that the server can freely decide the number of threads to serve the client;
[0060] The kernel provides the system module with a cmc_select interface, which allows the cross-module call server to wait on multiple Connection objects at the same time. Any of them that receives a cross-module call will return. Through the cmc_select interface, the system module can decide how many threads to use to process the cross-module call based on the actual situation.
[0061] When cross-module parameters need to pass parameters and return values, both the client and the server obtain the shared PMO corresponding to the Connection object through the cmc_get_shared_pmo interface, also in the form of capability, and each is mapped to its own address space for access. The shared PMO is created when cmc_get_shared_pmo is called. The kernel ensures that the client and the server can obtain access rights to the same PMO. Before calling cmc_call to initiate a cross-module call, the client fills in the specific service and required parameters to be requested in a specific location in the shared PMO according to the ABI agreed upon by the server. Then, after cmc_wait returns, the server obtains the parameters from the shared PMO and performs corresponding processing. According to the agreed ABI, the return value is filled in a specific location in the shared PMO, and the execution flow is returned to the client at the next cmc_wait call.
[0062] In the cmc_wait and cmc_select interfaces, a capability of the Connection object to be returned is added, so that after the current server thread is switched to the waiting state, the execution flow is immediately migrated to the initiating side of the call request just processed.
[0063] Compared with the prior art, the present invention has the following beneficial effects:
[0064] 1. The present invention utilizes the existing symbol relocation technology and capability mechanism, proposes a new cross-module calling mechanism, and finally realizes a method in which a loadable system module can be selectively loaded into the kernel state or the user state during the operation period of the operating system and communicates with each other;
[0065] 2. The present invention uses symbol relocation to make the overhead of calling the kernel and other system modules almost equivalent to function calls when the system module runs in the kernel state, while allowing the system module to run in the user state to achieve process-level isolation;
[0066] 3. The present invention will allow operating system users to freely combine system modules according to actual needs and determine the privileged state in which they run to achieve a trade-off between performance and isolation. BRIEF DESCRIPTION OF THE DRAWINGS
[0067] Other features, objects and advantages of the present invention will become more apparent from the detailed description of non-limiting embodiments made with reference to the following drawings:
[0068] Figure 1 Schematic diagram of symbol relocation behavior loaded into kernel mode and user mode;
[0069] Figure 2A schematic diagram of kernel-mode and user-mode system modules accessing the kernel interface;
[0070] Figure 3 Create a basic workflow diagram for cross-module calls. DETAILED DESCRIPTION
[0071] The present invention is described in detail below in conjunction with specific embodiments. The following embodiments will help those skilled in the art to further understand the present invention, but are not intended to limit the present invention in any form. It should be noted that, for those of ordinary skill in the art, several changes and improvements can also be made without departing from the concept of the present invention. These all belong to the protection scope of the present invention.
[0072] Embodiment 1:
[0073] The main technical points of the present invention are:
[0074] 1. Through capability-based access control, the kernel provides a unified API to system modules running in kernel state and user state. Compared with the kernel modules of traditional macro kernels that can directly access kernel object pointers, the capability-based unified API makes it possible to replace different running state implementations during loading;
[0075] 2. Through symbol relocation technology, when loading a system module, it is dynamically determined whether the kernel API it calls is implemented in kernel state or user state, so that the same system module binary program can be dynamically loaded into different running states to meet different requirements for performance and isolation;
[0076] 3. Provide a well-abstracted cross-module calling mechanism in the kernel, so that two system modules loaded into any running state can request services from each other in the best way through a unified API. For example, two modules running in the kernel state request services in the form of function pointer calls, and two modules running in the user state request services in the form of microkernel IPC.
[0077] 4. Provide the function of waiting on multiple connections at a time in the kernel API called across modules, so that the system service can decide the number of threads to process the client call request according to the actual situation;
[0078] By providing the cmc_select interface, the cross-module call server is allowed to wait on multiple Connection objects at the same time, and any one of them will return a cross-module call.
[0079] 5. The parameters and return values of cross-module calls are passed through the technology of shared memory pages, thereby reducing memory copies and improving the performance of cross-module calls;
[0080] 6. Technical points 1 to 2 realize the dynamic loading of system modules into kernel mode or user mode, and technical points 3 to 5 realize the high-performance and low-memory inter-module communication mechanism;
[0081] According to the present invention, a method for implementing a loadable system module that dynamically determines the running state is provided, such as Figure 1-Figure 3 As shown, including:
[0082] Step S1: The kernel provides a unified API to system modules running in kernel mode and user mode through capability-based access control;
[0083] Specifically, in step S1:
[0084] When the system module is loaded into the memory and runs, the capability mechanism is used to provide access control to the kernel object. The system module code does not directly access the memory data of the kernel object, but reads and writes it through method calls;
[0085] In order to make the direct call to the function that implements the system call in the kernel and the system call through the syscall instruction produce the same effect, and the system module can observe the same behavior, the capability mechanism is introduced to provide a unified kernel object abstraction for the system module. The system module running in the kernel state can access the kernel object indirectly through capability, just like the system module running in the user state. The capability mechanism isolates the access rights of different system modules to kernel objects from each other. The system module cannot access the kernel object to which it does not have permission by forging capability values. When the system module is written in a memory-safe language, the system module can be run in the kernel state through the encapsulation library provided by the capability and the system kernel without having to worry about the module arbitrarily accessing the kernel data by guessing the memory address and constructing a pointer. When the system module is written in a language that is not memory-safe, it is run in the user state to ensure the security of the kernel through process-level address space isolation.
[0086] Step S2: through symbol relocation technology, dynamically determine whether the kernel API called by the system module is implemented in kernel mode or user mode when loading the system module;
[0087] Specifically, in step S2:
[0088] Through symbol relocation technology, different parameters of the special dynamic loader are used to control the redirection of undefined symbols of the system module in ELF format to kernel state implementation or user state implementation. Undefined symbols are APIs provided by the operating system kernel to the system module. Kernel state implementation is manifested as a direct call to the kernel function, and user state implementation is manifested as a system call to the kernel.
[0089] The specially designed dynamic loader decides whether to load the system module into kernel mode or user mode for execution based on the parameters specified by the user. The dynamic loader first loads each loadable segment of ELF into memory, and then relocates the undefined symbols according to their relocation type. The actual memory address of the symbol at runtime is filled into the relocation address after different operations are performed according to the different relocation types. According to the different parameters given by the user, the specially designed dynamic loader relocates the symbols required by ELF to different implementations. When the user loads the system module into kernel mode for execution, the loader's relocation implementation is to directly call the function that implements the system call in the kernel, so that it does not need to request kernel services through system calls like user mode programs when it runs; when the user loads the system module into user mode for execution, it falls into kernel processing through the syscall instruction, and the CPU privilege level switch will occur in this process.
[0090] Step S3: providing a cross-module calling mechanism based on the capability mechanism in the kernel, and using shared memory pages to pass parameters and return values;
[0091] Specifically, in step S3:
[0092] Based on the capability mechanism, the kernel provides a cross-module calling mechanism for system modules, so that system modules can provide services and call external services through a unified mechanism. The operation of this mechanism requires the participation of both the server and the client. The server first registers the service with the kernel, and then waits for the client to connect on the capability of the service. The client queries the kernel for the service, obtains the capability, and establishes a connection with the server. After the connection is successful, the server waits for the client's call request on the capability of the connection. After receiving the request, it provides the service and returns.
[0093] In the cross-module calling mechanism, the kernel provides an interface for the system module. The two parties of the cross-module calling are divided into the client and the server. The basic working method is as follows:
[0094] On the server side:
[0095] a. Register a Server kernel object with the kernel through the cmc_register_server interface. This interface uses a string as the key and the Server object as the value. A mapping table is maintained in the kernel for subsequent client queries and returns the capability used to access this kernel object.
[0096] b. Call the cmc_accept interface on the Server object to put the current thread into a waiting state, waiting for the client to initiate a connection request. After the connection is successful, the capability of the Connection kernel object is returned;
[0097] c. The server continuously calls the cmc_wait interface on the Connection object to wait for the client's cross-module call, so that the current thread enters the waiting state. When the interface returns, it indicates that the client's call request has been received and should be processed;
[0098] On the client side:
[0099] i. Use cmc_find_server interface to query the kernel for the Server kernel object with a specific name and obtain the capability that can be used to access it;
[0100] ii. Call cmc_connect interface on this Server object to initiate connection to the server. This interface checks whether the server has called cmc_accept interface to wait for connection. If so, a Connection kernel object is created in the kernel to represent the connection established between the two, and the capability for accessing the Connection kernel object is returned. At the same time, the cmc_accept interface call on the server also returns.
[0101] iii. The client calls the cmc_call interface on the Connection object multiple times to initiate cross-module calls.
[0102] Step S4: By providing a preset interface, it is allowed to wait on multiple connections at one time in the kernel API called across modules.
[0103] Specifically, in step S4:
[0104] The API of the cross-module calling mechanism allows a thread of a system module to wait for call requests on multiple connections, so that the server can freely decide the number of threads to serve the client;
[0105] The kernel provides the system module with a cmc_select interface, which allows the cross-module call server to wait on multiple Connection objects at the same time. Any of them that receives a cross-module call will return. Through the cmc_select interface, the system module can decide how many threads to use to process the cross-module call based on the actual situation.
[0106] When cross-module parameters need to pass parameters and return values, both the client and the server obtain the shared PMO corresponding to the Connection object through the cmc_get_shared_pmo interface, also in the form of capability, and each is mapped to its own address space for access. The shared PMO is created when cmc_get_shared_pmo is called. The kernel ensures that the client and the server can obtain access rights to the same PMO. Before calling cmc_call to initiate a cross-module call, the client fills in the specific service and required parameters to be requested in a specific location in the shared PMO according to the ABI agreed upon by the server. Then, after cmc_wait returns, the server obtains the parameters from the shared PMO and performs corresponding processing. According to the agreed ABI, the return value is filled in a specific location in the shared PMO, and the execution flow is returned to the client at the next cmc_wait call.
[0107] In the cmc_wait and cmc_select interfaces, a capability of the Connection object to be returned is added, so that after the current server thread is switched to the waiting state, the execution flow is immediately migrated to the initiating side of the call request just processed.
[0108] A loadable system module implementation system for dynamically determining a running state according to the present invention includes:
[0109] Module M1: The kernel provides a unified API to system modules running in kernel mode and user mode through capability-based access control;
[0110] Specifically, in the module M1:
[0111] When the system module is loaded into the memory and runs, the capability mechanism is used to provide access control to the kernel object. The system module code does not directly access the memory data of the kernel object, but reads and writes it through method calls;
[0112] In order to make the direct call to the function that implements the system call in the kernel and the system call through the syscall instruction produce the same effect, and the system module can observe the same behavior, the capability mechanism is introduced to provide a unified kernel object abstraction for the system module. The system module running in the kernel state can access the kernel object indirectly through capability, just like the system module running in the user state. The capability mechanism isolates the access rights of different system modules to kernel objects from each other. The system module cannot access the kernel object to which it does not have permission by forging capability values. When the system module is written in a memory-safe language, the system module can be run in the kernel state through the encapsulation library provided by the capability and the system kernel without having to worry about the module arbitrarily accessing the kernel data by guessing the memory address and constructing a pointer. When the system module is written in a language that is not memory-safe, it is run in the user state to ensure the security of the kernel through process-level address space isolation.
[0113] Module M2: Through symbol relocation technology, it dynamically determines whether the kernel API called by the system module is implemented in kernel mode or user mode when loading the system module;
[0114] Specifically, in the module M2:
[0115] Through symbol relocation technology, different parameters of the special dynamic loader are used to control the redirection of undefined symbols of the system module in ELF format to kernel state implementation or user state implementation. Undefined symbols are APIs provided by the operating system kernel to the system module. Kernel state implementation is manifested as a direct call to the kernel function, and user state implementation is manifested as a system call to the kernel.
[0116] The specially designed dynamic loader decides whether to load the system module into kernel mode or user mode for execution based on the parameters specified by the user. The dynamic loader first loads each loadable segment of ELF into memory, and then relocates the undefined symbols according to their relocation type. The actual memory address of the symbol at runtime is filled into the relocation address after different operations are performed according to the different relocation types. According to the different parameters given by the user, the specially designed dynamic loader relocates the symbols required by ELF to different implementations. When the user loads the system module into kernel mode for execution, the loader's relocation implementation is to directly call the function that implements the system call in the kernel, so that it does not need to request kernel services through system calls like user mode programs when it runs; when the user loads the system module into user mode for execution, it falls into kernel processing through the syscall instruction, and the CPU privilege level switch will occur in this process.
[0117] Module M3: Provides a cross-module calling mechanism based on the capability mechanism in the kernel, using shared memory pages to pass parameters and return values;
[0118] Specifically, in the module M3:
[0119] Based on the capability mechanism, the kernel provides a cross-module calling mechanism for system modules, so that system modules can provide services and call external services through a unified mechanism. The operation of this mechanism requires the participation of both the server and the client. The server first registers the service with the kernel, and then waits for the client to connect on the capability of the service. The client queries the kernel for the service, obtains the capability, and establishes a connection with the server. After the connection is successful, the server waits for the client's call request on the capability of the connection. After receiving the request, it provides the service and returns.
[0120] In the cross-module calling mechanism, the kernel provides an interface for the system module. The two parties of the cross-module calling are divided into the client and the server. The basic working method is as follows:
[0121] On the server side:
[0122] a. Register a Server kernel object with the kernel through the cmc_register_server interface. This interface uses a string as the key and the Server object as the value. A mapping table is maintained in the kernel for subsequent client queries and returns the capability used to access this kernel object.
[0123] b. Call the cmc_accept interface on the Server object to put the current thread into a waiting state, waiting for the client to initiate a connection request. After the connection is successful, the capability of the Connection kernel object is returned;
[0124] c. The server continuously calls the cmc_wait interface on the Connection object to wait for the client's cross-module call, so that the current thread enters the waiting state. When the interface returns, it indicates that the client's call request has been received and should be processed;
[0125] On the client side:
[0126] i. Use cmc_find_server interface to query the kernel for the Server kernel object with a specific name and obtain the capability that can be used to access it;
[0127] ii. Call cmc_connect interface on this Server object to initiate connection to the server. This interface checks whether the server has called cmc_accept interface to wait for connection. If so, a Connection kernel object is created in the kernel to represent the connection established between the two, and the capability for accessing the Connection kernel object is returned. At the same time, the cmc_accept interface call on the server also returns.
[0128] iii. The client calls the cmc_call interface on the Connection object multiple times to initiate cross-module calls.
[0129] Module M4: Allows waiting on multiple connections at once in kernel APIs called across modules by providing a preset interface.
[0130] Specifically, in the module M4:
[0131] The API of the cross-module calling mechanism allows a thread of a system module to wait for call requests on multiple connections, so that the server can freely decide the number of threads to serve the client;
[0132] The kernel provides the system module with a cmc_select interface, which allows the cross-module call server to wait on multiple Connection objects at the same time. Any of them that receives a cross-module call will return. Through the cmc_select interface, the system module can decide how many threads to use to process the cross-module call based on the actual situation.
[0133] When cross-module parameters need to pass parameters and return values, both the client and the server obtain the shared PMO corresponding to the Connection object through the cmc_get_shared_pmo interface, also in the form of capability, and each is mapped to its own address space for access. The shared PMO is created when cmc_get_shared_pmo is called. The kernel ensures that the client and the server can obtain access rights to the same PMO. Before calling cmc_call to initiate a cross-module call, the client fills in the specific service and required parameters to be requested in a specific location in the shared PMO according to the ABI agreed upon by the server. Then, after cmc_wait returns, the server obtains the parameters from the shared PMO and performs corresponding processing. According to the agreed ABI, the return value is filled in a specific location in the shared PMO, and the execution flow is returned to the client at the next cmc_wait call.
[0134] In the cmc_wait and cmc_select interfaces, a capability of the Connection object to be returned is added, so that after the current server thread is switched to the waiting state, the execution flow is immediately migrated to the initiating side of the call request just processed.
[0135] Embodiment 2:
[0136] Embodiment 2 is a preferred example of Embodiment 1, and is used to illustrate the present invention in more detail.
[0137] The method proposed by the present invention mainly solves the following problems:
[0138] 1. How to make a system module be loaded into kernel mode or user mode arbitrarily and selectively when the operating system is running?
[0139] 2. How to enable system modules running in different privileged states to make procedure calls to each other to request services?
[0140] The present invention proposes a method for implementing an operating system loadable system module that dynamically determines the running state, comprising:
[0141] 1. Through symbol relocation technology, when loading a system module, decide whether to use kernel state or user state implementation for the kernel API it depends on;
[0142] 2. Through the capability mechanism, the system module is provided with a way to access kernel objects without being aware of the privileged state in which it is currently running;
[0143] 3. Provide a cross-module calling mechanism based on the capability mechanism, so that any two system modules in kernel state or user state can make process calls to request services;
[0144] 4. The cross-module call mechanism provides an API that allows system modules to wait on multiple connections at a time, so that the system service can decide how many threads to use to handle client call requests based on actual conditions;
[0145] 5. When calling across modules, parameters and return values are passed by sharing memory pages, which reduces memory copies and improves the performance of cross-module calls;
[0146] 6. The present invention is applicable to any architecture that distinguishes between kernel mode and user mode.
[0147] The present invention includes the following technical points:
[0148] 1. Through symbol relocation technology, different parameters of the specially designed dynamic loader are used to control the redirection of undefined symbols of the system module in ELF format to kernel state implementation or user state implementation. The undefined symbols here are the APIs provided by the operating system kernel to the system module. The kernel state implementation is manifested as a direct call to the kernel function, and the user state implementation is manifested as a system call to the kernel;
[0149] 2. When system modules are loaded into memory and run, in order to enable them to access kernel objects in the same way in both kernel state and user state, the capability mechanism is used to provide access control to kernel objects. The system module code does not directly access the memory data of kernel objects, but reads and writes through method calls;
[0150] 3. Based on the capability mechanism, the kernel provides a cross-module calling mechanism for system modules, so that system modules can provide external services and call external services through a unified mechanism. The operation of this mechanism requires the participation of both the server and the client. The server first registers the service with the kernel, and then waits for the client to connect on the capability of the service. The client queries the kernel for the service, obtains the capability, and establishes a connection with the server. After the connection is successful, the server waits for the client's call request on the capability of the connection. After receiving the request, it provides the service and returns.
[0151] 4. The API of the cross-module calling mechanism allows a thread of the system module to wait for call requests on multiple connections, so that the server can freely decide the number of threads to serve the client, such as using one thread to serve all clients, or creating a service thread for each client;
[0152] 5. In order to improve the performance of cross-module calls and reduce memory copies, parameters and return values are passed using memory shared pages when calling across modules.
[0153] The following is a detailed description of the specific implementation of the present invention:
[0154] The specially designed dynamic loader can decide whether to load the system module into kernel mode or user mode according to the parameters specified by the user. The specific loading process is similar to the process of the Linux kernel loading loadable kernel modules and the process of ld.so loading dynamic link libraries. The dynamic loader first loads the loadable segments of ELF into the memory, and then relocates the undefined symbols (including global variables and functions) according to their relocation types. Specifically, the actual memory address of the symbol at runtime is filled into the relocation address, such as the GOT or PLT table, after performing different operations according to the different relocation types. Unlike the Linux kernel or ld.so, the specially designed dynamic loader here relocates the symbols required by ELF to different implementations according to the different parameters given by the user, such as Figure 1 As shown in the figure, when the user loads the system module into the kernel mode, the loader relocates it by directly calling the function that implements the system call in the kernel, so that it does not need to request kernel services through system calls like user mode programs when it runs; when the user loads the system module into the user mode, the loader relocates it by similarly implementing a traditional user program, which falls into kernel processing through the syscall instruction, and the CPU privilege level switching will occur in the process.
[0155] In order to make the direct call of the function that implements the system call in the kernel and the real system call through the syscall instruction produce the same effect, that is, for the system module, the same behavior can be observed, the capability mechanism is introduced to provide a unified kernel object abstraction for the system module. That is to say, in the traditional macro kernel, the kernel module can directly access the fields of the kernel object, while in the present invention, the system module running in the kernel state must indirectly access the kernel object through the capability like the system module running in the user state, such as Figure 2 As shown. The capability mechanism isolates the access rights of different system modules to kernel objects from each other. System modules cannot access kernel objects that they do not have access rights to by forging capability values. When using memory-safe languages such as Rust to write system modules, through capabilities and the encapsulation library provided by the system kernel, system modules can be safely run in kernel mode without worrying about modules arbitrarily accessing kernel data by guessing memory addresses or constructing pointers; when using non-memory-safe languages such as C to write system modules, they can be run in user mode to ensure kernel security through process-level address space isolation.
[0156] In the cross-module call mechanism, the kernel provides the system module with interfaces such as cmc_register_server, cmc_accept, cmc_wait, cmc_find_server, cmc_connect, and cmc_call. The two parties of the cross-module call are divided into the client and the server. The basic working method is as follows: Figure 3 shown.
[0157] On the server side:
[0158] 1. First, register a Server kernel object with the kernel through the cmc_register_server interface. This interface uses a string as the key and the Server object as the value. A mapping table is maintained in the kernel for subsequent client queries, and the capability that can be used to access this kernel object is returned.
[0159] 2. Then, the cmc_accept interface is called on the Server object to put the current thread into a waiting state, waiting for the client to initiate a connection request. After the connection is successful, the capability of the Connection kernel object is returned;
[0160] 3. After that, the server continuously calls the cmc_wait interface on the Connection object to wait for the client's cross-module call. Similar to the cmc_accept interface, it will put the current thread into a waiting state. When the interface returns, it indicates that the client's call request has been received and should be processed;
[0161] On the client side:
[0162] 1. First, query the kernel for a Server kernel object with a specific name through the cmc_find_server interface and obtain the capability that can be used to access it;
[0163] 2. Then call the cmc_connect interface on this Server object to initiate a connection to the server. The interface will check whether the server has called the cmc_accept interface to wait for the connection. If so, a Connection kernel object is created in the kernel to represent the connection established between the two, and the capability for accessing the Connection kernel object is returned. At the same time, the cmc_accept interface call on the server also returns;
[0164] 3. The client can then call the cmc_call interface on the Connection object multiple times to initiate cross-module calls.
[0165] In actual development, according to the type of system module, the importance of providing services and the difference in sensitivity of its function to delay, the server of different system modules may need to use different numbers of threads to process the cross-module call request of the client, so the kernel also provides cmc_select interface for the system module in the present invention, allowing the cross-module call server to wait on multiple Connection objects at the same time, and any one of them will return after receiving the cross-module call. Through this interface, the system module can decide how many threads to use to process the cross-module call according to the actual situation, and can choose one-to-one, that is, each client connects a thread, or can choose one-to-many, that is, one thread is responsible for processing all client connections, and can use a thread pool with dynamic resizing to process the cross-module calls on multiple connections. This feature provides a higher degree of freedom for the memory usage and performance trade-off of the system module.
[0166] When cross-module parameters need to pass parameters and return values, both the client and the server can obtain the shared PMO corresponding to the Connection object through the cmc_get_shared_pmo interface, also in the form of capability, and each is mapped to its own address space for access. The shared PMO does not need to be created when cmc_connect is used to establish a connection, but is lazily created when cmc_get_shared_pmo is called. The kernel ensures that the client and the server can obtain access rights to the same PMO. Before calling cmc_call to initiate a cross-module call, the client fills in the specific service to be requested and the required parameters in a specific location in the shared PMO according to the ABI agreed upon by the server. Then the server obtains the parameters from the shared PMO after cmc_wait returns, and performs corresponding processing. Finally, according to the agreed ABI, the return value is filled in a specific location in the shared PMO, and the execution flow is returned to the client at the next cmc_wait call.
[0167] In the implementation of cross-module calls, a trick is used to enable the above workflow to coexist with the thread migration model. Specifically, in the cmc_wait and cmc_select interfaces, a capability of the Connection object to be returned is added, so that after the current server thread is turned into a waiting state, the execution flow is immediately migrated to the initiating side of the call request just processed. On the contrary, if this trick is not used, the cmc_wait and cmc_return interfaces need to be split, and cmc_wait only waits for the call request, and cmc_return only marks the client as the end of the cross-module call, and thread migration cannot be performed directly.
[0168] Definitions of Abbreviations and Key Terms:
[0169] -ELF: Executable and Linkable Format, a file format commonly used for executable files and dynamic libraries
[0170] -Symbol relocation: A technique for specifying the runtime location of undefined symbols when loading an executable file or dynamic library.
[0171] -Capability: An access control mechanism commonly used in microkernel operating systems for user-mode programs to access kernel objects
[0172] -System module: a program loaded by the operating system during operation to provide system expansion functions.
[0173] -PMO: Physical Memory Object, a kernel object representing a block of available physical memory
[0174] Those skilled in the art know that, in addition to implementing the system, device and its various modules provided by the present invention in a purely computer-readable program code, it is entirely possible to implement the same program in the form of logic gates, switches, application-specific integrated circuits, programmable logic controllers and embedded microcontrollers by logically programming the method steps. Therefore, the system, device and its various modules provided by the present invention can be considered as a hardware component, and the modules included therein for implementing various programs can also be considered as structures within the hardware component; the modules for implementing various functions can also be considered as both software programs for implementing the method and structures within the hardware component.
[0175] The above describes the specific embodiments of the present invention. It should be understood that the present invention is not limited to the above specific embodiments, and those skilled in the art can make various changes or modifications within the scope of the claims, which does not affect the essence of the present invention. In the absence of conflict, the embodiments of the present application and the features in the embodiments can be combined with each other arbitrarily.
Claims
1. A method for implementing a loadable system module that dynamically determines the running state, characterized in that: include: Step S1: The kernel provides a unified API to system modules running in kernel mode and user mode through capability-based access control; Step S2: through symbol relocation technology, dynamically determine whether the kernel API called by the system module is implemented in kernel mode or user mode when loading the system module; Step S3: providing a cross-module calling mechanism based on the capability mechanism in the kernel, and using shared memory pages to pass parameters and return values; Step S4: By providing a preset interface, it is allowed to wait on multiple connections at one time in the kernel API called across modules.
2. The method for implementing a loadable system module for dynamically determining the running state according to claim 1, characterized in that: In step S1: When the system module is loaded into the memory and runs, the capability mechanism is used to provide access control to the kernel object. The system module code does not directly access the memory data of the kernel object, but reads and writes it through method calls; In order to make the direct call to the function that implements the system call in the kernel and the system call through the syscall instruction produce the same effect, and the system module can observe the same behavior, the capability mechanism is introduced to provide a unified kernel object abstraction for the system module. The system module running in the kernel state can access the kernel object indirectly through capability, just like the system module running in the user state. The capability mechanism isolates the access rights of different system modules to kernel objects from each other. The system module cannot access the kernel object to which it does not have permission by forging capability values. When the system module is written in a memory-safe language, the system module can be run in the kernel state through the encapsulation library provided by the capability and the system kernel without having to worry about the module arbitrarily accessing the kernel data by guessing the memory address and constructing a pointer. When the system module is written in a non-memory-safe language, it is run in the user state to ensure the security of the kernel through process-level address space isolation.
3. The method for implementing a loadable system module for dynamically determining the running state according to claim 1, characterized in that: In step S2: Through symbol relocation technology, different parameters of the special dynamic loader are used to control the redirection of undefined symbols of the system module in ELF format to kernel state implementation or user state implementation. Undefined symbols are APIs provided by the operating system kernel to the system module. Kernel state implementation is manifested as a direct call to the kernel function, and user state implementation is manifested as a system call to the kernel. The specially designed dynamic loader decides whether to load the system module into kernel mode or user mode for execution based on the parameters specified by the user. The dynamic loader first loads each loadable segment of ELF into memory, and then relocates the undefined symbols according to their relocation type. The actual memory address of the symbol at runtime is filled into the relocation address after different operations are performed according to the different relocation types. According to the different parameters given by the user, the specially designed dynamic loader relocates the symbols required by ELF to different implementations. When the user loads the system module into kernel mode for execution, the loader's relocation implementation is to directly call the function that implements the system call in the kernel, so that it does not need to request kernel services through system calls like user mode programs when it runs; when the user loads the system module into user mode for execution, it falls into kernel processing through the syscall instruction, and the CPU privilege level switch will occur in this process.
4. The method for implementing a loadable system module for dynamically determining a running state according to claim 1, characterized in that: In step S3: Based on the capability mechanism, the kernel provides a cross-module calling mechanism for system modules, so that system modules can provide services and call external services through a unified mechanism. The operation of this mechanism requires the participation of both the server and the client. The server first registers the service with the kernel, and then waits for the client to connect on the capability of the service. The client queries the kernel for the service, obtains the capability, and establishes a connection with the server. After the connection is successful, the server waits for the client's call request on the capability of the connection. After receiving the request, it provides the service and returns. In the cross-module calling mechanism, the kernel provides an interface for the system module. The two parties of the cross-module calling are divided into the client and the server. The basic working method is as follows: On the server side: Step A1: Register a Server kernel object with the kernel through the cmc_register_server interface. This interface uses a string as the key and the Server object as the value. A mapping table is maintained in the kernel for subsequent client queries, and the capability for accessing this kernel object is returned. Step A2: Call the cmc_accept interface on the Server object to put the current thread into a waiting state, waiting for the client to initiate a connection request. After the connection is successful, the capability of the Connection kernel object is returned; Step A3: The server continuously calls the cmc_wait interface on the Connection object to wait for the client's cross-module call, so that the current thread enters the waiting state. When the interface returns, it indicates that the client's call request has been received and should be processed; On the client side: Step B1: query the kernel for a Server kernel object with a specific name through the cmc_find_server interface, and obtain the capability that can be used to access it; Step B2: Call the cmc_connect interface on this Server object to initiate a connection to the server. The interface checks whether the server has called the cmc_accept interface to wait for a connection. If so, a Connection kernel object is created in the kernel to represent the connection established between the two, and the capability for accessing the Connection kernel object is returned. At the same time, the cmc_accept interface call on the server also returns. Step B3: The client calls the cmc_call interface on the Connection object multiple times to initiate a cross-module call.
5. The method for implementing a loadable system module for dynamically determining the running state according to claim 1, characterized in that: In step S4: The API of the cross-module calling mechanism allows a thread of a system module to wait for call requests on multiple connections, so that the server can freely decide the number of threads to serve the client; The kernel provides the system module with a cmc_select interface, which allows the cross-module call server to wait on multiple Connection objects at the same time. Any of them that receives a cross-module call will return. Through the cmc_select interface, the system module can decide how many threads to use to process the cross-module call based on the actual situation. When cross-module parameters need to pass parameters and return values, both the client and the server obtain the shared PMO corresponding to the Connection object through the cmc_get_shared_pmo interface, also in the form of capability, and each is mapped to its own address space for access. The shared PMO is created when cmc_get_shared_pmo is called. The kernel ensures that the client and the server can obtain access rights to the same PMO. Before calling cmc_call to initiate a cross-module call, the client fills in the specific service and required parameters to be requested in a specific location in the shared PMO according to the ABI agreed upon by the server. Then, after cmc_wait returns, the server obtains the parameters from the shared PMO and performs corresponding processing. According to the agreed ABI, the return value is filled in a specific location in the shared PMO, and the execution flow is returned to the client at the next cmc_wait call. In the cmc_wait and cmc_select interfaces, a capability of the Connection object to be returned is added, so that after the current server thread is switched to the waiting state, the execution flow is immediately migrated to the initiating side of the call request just processed.
6. A loadable system module implementation system for dynamically determining the running state, characterized in that: include: Module M1: The kernel provides a unified API to system modules running in kernel mode and user mode through capability-based access control. Module M2: Through symbol relocation technology, it dynamically determines whether the kernel API called by the system module is implemented in kernel mode or user mode when loading the system module; Module M3: Provides a cross-module calling mechanism based on the capability mechanism in the kernel, using shared memory pages to pass parameters and return values; Module M4: Allows waiting on multiple connections at once in kernel APIs called across modules by providing a preset interface.
7. The loadable system module implementation system for dynamically determining the running state according to claim 6, characterized in that: In the module M1: When the system module is loaded into the memory and runs, the capability mechanism is used to provide access control to the kernel object. The system module code does not directly access the memory data of the kernel object, but reads and writes it through method calls; In order to make the direct call to the function that implements the system call in the kernel and the system call through the syscall instruction produce the same effect, and the system module can observe the same behavior, the capability mechanism is introduced to provide a unified kernel object abstraction for the system module. The system module running in the kernel state can access the kernel object indirectly through capability, just like the system module running in the user state. The capability mechanism isolates the access rights of different system modules to kernel objects from each other. The system module cannot access the kernel object to which it does not have permission by forging capability values. When the system module is written in a memory-safe language, the system module can be run in the kernel state through the encapsulation library provided by the capability and the system kernel without having to worry about the module arbitrarily accessing the kernel data by guessing the memory address and constructing a pointer. When the system module is written in a language that is not memory-safe, it is run in the user state to ensure the security of the kernel through process-level address space isolation.
8. The loadable system module implementation system for dynamically determining the running state according to claim 6, characterized in that: In the module M2: Through symbol relocation technology, different parameters of the special dynamic loader are used to control the redirection of undefined symbols of the system module in ELF format to kernel state implementation or user state implementation. Undefined symbols are APIs provided by the operating system kernel to the system module. Kernel state implementation is manifested as a direct call to the kernel function, and user state implementation is manifested as a system call to the kernel. The specially designed dynamic loader decides whether to load the system module into kernel mode or user mode for execution based on the parameters specified by the user. The dynamic loader first loads each loadable segment of ELF into memory, and then relocates the undefined symbols according to their relocation type. The actual memory address of the symbol at runtime is filled into the relocation address after different operations are performed according to the different relocation types. According to the different parameters given by the user, the specially designed dynamic loader relocates the symbols required by ELF to different implementations. When the user loads the system module into kernel mode for execution, the loader's relocation implementation is to directly call the function that implements the system call in the kernel, so that it does not need to request kernel services through system calls like user mode programs when it runs; when the user loads the system module into user mode for execution, it falls into kernel processing through the syscall instruction, and the CPU privilege level switch will occur in this process.
9. The system for implementing a loadable system module for dynamically determining the running state according to claim 6, characterized in that: In the module M3: Based on the capability mechanism, the kernel provides a cross-module calling mechanism for system modules, so that system modules can provide services and call external services through a unified mechanism. The operation of this mechanism requires the participation of both the server and the client. The server first registers the service with the kernel, and then waits for the client to connect on the capability of the service. The client queries the kernel for the service, obtains the capability, and establishes a connection with the server. After the connection is successful, the server waits for the client's call request on the capability of the connection. After receiving the request, it provides the service and returns. In the cross-module calling mechanism, the kernel provides an interface for the system module. The two parties of the cross-module calling are divided into the client and the server. The basic working method is as follows: On the server side: a. Register a Server kernel object with the kernel through the cmc_register_server interface. This interface uses a string as the key and the Server object as the value. A mapping table is maintained in the kernel for subsequent client queries and returns the capability used to access this kernel object. b. Call the cmc_accept interface on the Server object to put the current thread into a waiting state, waiting for the client to initiate a connection request. After the connection is successful, the capability of the Connection kernel object is returned; c. The server continuously calls the cmc_wait interface on the Connection object to wait for the client's cross-module call, so that the current thread enters the waiting state. When the interface returns, it indicates that the client's call request has been received and should be processed; On the client side: i. Use cmc_find_server interface to query the kernel for the Server kernel object with a specific name and obtain the capability that can be used to access it; ii. Call cmc_connect interface on this Server object to initiate connection to the server. This interface checks whether the server has called cmc_accept interface to wait for connection. If so, a Connection kernel object is created in the kernel to represent the connection established between the two, and the capability for accessing the Connection kernel object is returned. At the same time, the cmc_accept interface call on the server also returns. iii. The client calls the cmc_call interface on the Connection object multiple times to initiate cross-module calls.
10. The system for implementing a loadable system module for dynamically determining the running state according to claim 6, characterized in that: In the module M4: The API of the cross-module calling mechanism allows a thread of a system module to wait for call requests on multiple connections, so that the server can freely decide the number of threads to serve the client; The kernel provides the system module with a cmc_select interface, which allows the cross-module call server to wait on multiple Connection objects at the same time. Any of them that receives a cross-module call will return. Through the cmc_select interface, the system module can decide how many threads to use to process the cross-module call based on the actual situation. When cross-module parameters need to pass parameters and return values, both the client and the server obtain the shared PMO corresponding to the Connection object through the cmc_get_shared_pmo interface, also in the form of capability, and each is mapped to its own address space for access. The shared PMO is created when cmc_get_shared_pmo is called. The kernel ensures that the client and the server can obtain access rights to the same PMO. Before calling cmc_call to initiate a cross-module call, the client fills in the specific service and required parameters to be requested in a specific location in the shared PMO according to the ABI agreed upon by the server. Then, after cmc_wait returns, the server obtains the parameters from the shared PMO and performs corresponding processing. According to the agreed ABI, the return value is filled in a specific location in the shared PMO, and the execution flow is returned to the client at the next cmc_wait call. In the cmc_wait and cmc_select interfaces, a capability of the Connection object to be returned is added, so that after the current server thread is switched to the waiting state, the execution flow is immediately migrated to the initiating side of the call request just processed.
Citation Information
Patent Citations
Loading control method for kernel module in operating system
CN104112098A
Kernel module loading control method in operating system
CN104112098B
Data message processing method from user mode to kernel mode
CN103312601A
Two-stage scheduling method of real-time extension of Windows system
CN103744726A