The 17th Chapter equipment and module one, equipment type
? In addition to the above 3 typical devices, in fact, there are some other types of equipment in Linux, which see more should be considered "pseudo-device." The so-called "pseudo-device", is actually some virtual device, only provides access to the kernel function, no physical device associated with it. Typical "pseudo-device" is/dev/random (kernel random number generator),/dev/null (empty device),/dev/zero (0 devices),/dev/full (full device) Two, kernel module? The Linux kernel is modular, the kernel module can be loaded on demand, so that the kernel boot without loading all the modules, that is, reduce the size of the kernel, but also improve efficiency. It is a good way to add functionality or interfaces to the kernel by writing kernel modules, without recompiling the kernel or debugging and deleting it. The kernel module can take parameters without parameters, and kernel modules without parameters are simpler. Kernel modules with parameters: The kernel has provided a simple framework to declare parameters to us. 1.module_param (name, type, perm): Defines a module parameter? Parameter name:: Is both the user-visible parameter name and the variable name that holds the module parameter in the module? parameters Type:: Types of parameters (byte, short, int, uint, long, ulong, CHARP, bool ...) The byte type is stored in the char variable, and the bool type is stored in the INT variable? parameter perm:: Specify module in SYSFS The corresponding file permissions in the system (about the contents of SYSFS)
static int stu_id = 0; // 默认idmodule_param(stu_id, int, 0644);
? 2.module_ Param_ named (name, variable, type, perm): Defines a module parameter, and the parameter is not the same as the external name? Parameters Name:: User-visible parameter name? parameter variable:: variable name for module parameter in module? parameter type and perm:: Type and perm in the same module_param
static char* stu_name_in = "default name"; // 默认名字module_param_named(stu_name_out, stu_name_in ,charp, 0644);/* stu_name_out 是对用户开放的名称 *stu_name_in 是内核模块内部使用的名称 */
? 3. Module_ PARAM_ String (name, string, Len, perm): Copies a string to a specified array of characters? Parameter name:: User-visible parameter name? parameter string:: The variable name that holds the module parameter in the module? Parameter len:: St The buffer length of the ring parameter? Parameter perm:: Perm in the same module_param
static char str_in[BUF_LEN];module_param_string(str_out, str_in, BUF_LEN, 0);/* perm=0 表示完全禁止 sysfs 项 */
? 4.module_ param_ Array (name, type, Nump, perm): Defines the module parameters of the array type? Parameter name:: Name in the same module_param? parameter type:: Same as Module_param The type of the parameter nump:: integer pointer, which holds the length of the array? parameter perm:: Perm in Module_param
#define MAX_ARR_LEN 5static int arr_len;static int arr_in[MAX_ARR_LEN];module_param_array(arr_in, int, &arr_len, 0644);
? 5.module_ param_ array_named (name, array, type, Nump, perm): Defines the module parameter of the array type, and the array parameter is not the same as the external name? Parameter name:: Array parameter external names? Parameter array: : Array parameter internal name? parameter Type,nump,perm:: Type,nump,perm in the same module_ PARAM_ array
#define MAX_ARR_LEN 5static int arr_len;static int arr_in[MAX_ARR_LEN];module_param_array_named(arr_out, arr_in, int, &arr_len, 0644);
? 6. Parameter description macro? You can add some descriptive information to the kernel module's parameters by Module_ parm_ DESC (). These descriptive information can be viewed through the modinfo command after the kernel module has been compiled.
static int stu_id = 0; // 默认idmodule_param(stu_id, int, 0644);MODULE_PARM_DESC(stu_id, "学生ID,默认为 0"); // 这句就是描述内核模块参数 stu_id 的语句
<font color==blue size=4> Kernel module related operations:? 1. Module installation
make modules_install <-- 把随内核编译出来的模块安装到合适的目录中( /lib/modules/version/kernel )
? 2. module dependencies? Commands for automatic Production module dependencies in Linux:
depmod <-- 产生内核依赖关系信息depmod -A <-- 只为新模块生成依赖信息(速度更快)
? 3. Module loading? Kernel module experiments have been used:
? 4. Module uninstall? Kernel module experiments have been used:
? 5. Module export symbol table? Once the kernel module is loaded, it loads dynamically into the kernel and needs to be exported in order for the other kernel modules to use their functionality. Methods for exporting functions in kernel modules:
EXPORT_SYMBOL(函数名) <-- 接在要导出的函数后面即可EXPORT_SYMBOL_GPL(函数名) <-- 和EXPORT_SYMBOL一样,区别在于只对标记为GPL协议的模块可见
Kernel object:? 2.6 The kernel adds a compelling new feature-the unified device model. The original motivation for the unified device model was to enable intelligent power management, and the Linux kernel You need to establish a tree structure that represents the topological relationships of all devices in the system, so that when power is turned off, it can be closed from the nodes of the tree. Once the unified device model is implemented, the following benefits are provided to the kernel: 1. Code duplication minimization (Unified processing of things more) 2. You can enumerate all the devices in the system, observe their status, and view the bus 3 they are connected to. All the devices in the system can be fully and effectively displayed in the form of a tree-including all bus and internal connections 4. The device can be connected to its corresponding driver, and vice versa 5. Devices can be categorized by type without having to understand the topology of the physical device 6. It is possible to traverse the leaves of the plant tree to its root in order to ensure that the device power is turned off in the correct sequence. 19th portability? The Linux kernel is very portable, and the current kernel supports very many architectures (more than 20). But at first, Linux only supported Intel i386 Architecture, supported by Digital Alpha, Intel x86, MIPS, and SPARC (although not well supported) from version v1.2. Since the v2.0 release, the official support for Motorala 68K and PowerPC has been added, and the v2.2 version has started to add AR MS, IBM S390 and UltraSPARC support. The v2.4 version supports up to 15 architectures, and the v2.6 version supports an increased number of architectures to 21. Given that the kernel supports so many architectures, it is necessary to consider the portability of the code when the kernel is developed. Data alignment is also an important aspect of enhancing portability (some architectures are very strict with data alignment requirements, and loading unaligned data can result in performance degradation or even errors). Data alignment means that the memory address of the data can be divisible by 4. For structs, make sure that each element in the struct is aligned correctly. If the elements in the struct are not aligned, the compiler automatically populates the structure to ensure that it is aligned. For example, the following code is expected to output 12, but the actual output of 24.
#include <stdio.h>struct animal_struct { char dog; /* 1个字节 */ unsigned long cat; /* 8个字节 */ unsigned short pig; /* 2个字节 */ char fox; /* 1个字节 */ }; int main(int argc, char *argv[]) { /* 在我的64bit 系统中是按8位对齐, 下面的代码输出 24 */ printf ("sizeof(animal_struct)=%d\n", sizeof(struct animal_struct)); return 0; }
The structure should be filled in the following form:
struct animal_struct{ char dog; /* 1个字节 */ /* 此处填充了7个字节 */ unsigned long cat; /* 8个字节 */ unsigned short pig; /* 2个字节 */ char fox; /* 1个字节 */ /* 此处填充了5个字节 */ };
? By adjusting the order of elements in the structure, you can reduce the number of bytes that are filled, such as if the above structure is defined in the following order:
struct animal_struct{unsigned long cat; /* 8 bytes */unsigned short pig; /* 2 bytes */char dog; /* 1 bytes */char Fox; /* 1 Bytes */* This is populated with 4 bytes */};
Note: Although the order of the elements in the structure can be adjusted to reduce the number of bytes that are filled, the memory consumption is reduced. However, for those structures that are already in the kernel, you must not arbitrarily adjust the order of their elements, because many of the existing methods in the kernel get elements by positioning them in the structure. 20th Patch, Development and Community 1. Join the community? If you want to contribute code to Linux, then it is necessary to join the Linux community, not only in time for the latest kernel updates, but also in time to exchange experiences with experienced kernel developers in the community. and the place to commit code and discuss code, to understand the rules of the community, In the Community environment, we can learn the kernel better and realize the fun and accomplishment of the kernel development. The kernel community is just plain the kernel mailing list (LKML Linux kernel mail list)? Subscribe to Mailing lists: http://vger.kernel.org/ Vger-lists.html is there a variety of Linux-related mailing lists? The message list for the kernel is: Http://vger.kernel.org/vger-lists.html#linux-kernel2. Coding style? The community gives us a place to learn and contribute to the kernel, but in order to avoid unnecessary hassles (being blamed or ignored), you must first understand some of the coding styles of the kernel code. Linux coding styles are documented in Documentation/codingstyle Read the following before the kernel development, and then I'll put it in the blog after a while. 3. Submit a patch? After the preparation is complete, you can start the kernel development journey:) As long as the continuous learning and try, one day will be the kernel to contribute their own code, this time, you need to understand how to submit code, that is, kernel patches. If you find bugs or improvements, You can send a description of the bug or improve the code to the corresponding maintainer. (The maintainer information for each subsystem of the kernel is in the maintainers file under the root of the kernel code) there are 2 ways to generate bugs or improve code patches: (1), create patches with the diff command
生成patchdiff -urN linux-old/ linux-new/ > my-patch # 比对整个内核代码文件夹ORdiff -u linux-old/some/file linux-new/some/file > my-patch # 比对某个文件
After applying patches, the code in Linux-old and Linux-new is the same.
cd linux-oldpatch -p1 < ../my-patch # 这个命令是进入linux内核代码根目录内执行的
PS. There's a very useful tool, Diffstat.
diffstat -p1 my-patch # 列出补丁所引起的变更的统计(加入或移去的代码行)
(2), create patches with GIT commands? Submit modified or new code
git commit -a # 提交所有修改的代码ORgit commit linux-src/some/file.c # 提交某个修改的代码ORgit add linux-src/some/new-file.c # 把新增的文件加入版本库git commit -a # 提交新增的文件# 生成patchgit format-patch -N # N 是正整数, 这条命令生成最后N次提交产生的补丁ORgit format-patch -1 # 最后1次提交产生的补丁
2017-2018-1 20179215 "Linux kernel Fundamentals and Analysis" Tenth week assignment