Linux内核源码结构

news2025/7/19 13:49:01

目录

Linux内核源码结构

Linux内核版本命名

Linux内核版本选择

内核源码结构

arch:与CPU架构相关的源代码

block:磁盘设备的支持

COPYING文件

CREDITS文件

crypto:加密相关

Documentation:

drivers:设备驱动

firmware:固件

fs:文件系统

include:头文件

init:内核初始化

ipc:进程间通信

1. 目录结构

2. IPC 机制的实现

2.1 共享内存(Shared Memory)

2.2 消息队列(Message Queue)

2.3 信号量(Semaphore)

3. IPC 命名空间

Kbuild文件

Kconfig文件

kernel:内核核心调度机制等

lib:库

MAINTAINERS文件

Makefile文件

mm:内存管理

net:网络协议

README文件

REPORTING-BUGS文件

samples

scripts:工具、脚本等

security:安全

sound

tools

usr:打包与压缩

virt:虚拟


Linux内核源码结构

内核源码可以在:Index of /pub/linux/kernel/中下载对应内核源码版本,这里下载的Linux3.14作为参考

Linux内核版本命名

主版本号.次版本号.修订版本

Linux内核版本选择

支持对应的硬件平台

相对成熟的版本(资料多)

稳定版本(次版本号为偶数的版本一般都是稳定版)

内核源码结构

所有目录:

arch:与CPU架构相关的源代码

它主要包含与架构相关的代码和配置

  1. 目录结构:

arch 目录下有多个子目录,每个子目录对应一种特定的硬件架构。常见的架构目录包括:

  • x86:用于 x86 架构的 CPU(32 位和 64 位),例如 Intel 和 AMD 的处理器。

  • arm:用于 ARM 架构的处理器,广泛应用于移动设备和嵌入式系统。

  • arm64:用于 ARMv8 架构的 64 位处理器。

  • powerpc:用于 PowerPC 架构的处理器。

  • mips:用于 MIPS 架构的处理器。

  • s390:用于 IBM 的 S/390 架构,主要用于大型机。

每个架构目录下又包含多个子目录和文件,用于实现该架构相关的功能。

arch/arm/为例子:

以下是 arch/arm 目录的主要内容和功能解析:

arch/arm 目录下包含多个子目录,每个子目录都有特定的功能:

  • boot:包含用于启动过程的代码和工具。例如,arch/arm/boot/compressed 目录包含压缩内核的启动代码,arch/arm/boot/dts 目录包含设备树源文件(.dts)和编译后的设备树二进制文件(.dtb)。

  • configs:包含各种开发板和芯片的默认配置文件(.config),这些文件用于指定内核的编译配置。

  • include:包含与 ARM 架构相关的头文件,这些头文件定义了硬件相关的数据结构、宏和函数原型。

  • kernel:包含 ARM 架构相关的内核初始化代码、中断处理代码、时钟管理代码等。

  • mm:包含 ARM 架构的内存管理代码,例如页表初始化、内存分配等。

  • mach-\*:每个以 mach- 开头的目录都对应一个特定的硬件平台或芯片系列,包含该平台的初始化代码、设备树支持代码等。

  • plat-\*:每个以 plat- 开头的目录包含多个硬件平台共享的代码。

主要文件和功能

  • arch/arm/Makefile:定义了 ARM 架构相关的编译规则和变量,例如如何生成内核镜像文件(如 zImage)。

  • arch/arm/kernel/head.S:内核启动时的第一个入口点,负责设置基本的硬件环境。

  • arch/arm/kernel/setup.c:负责初始化硬件和配置内核参数。

  • arch/arm/kernel/irq.c:中断管理代码,负责中断的注册、分发和处理。

  • arch/arm/mm/init.c:内存管理单元(MMU)和页表的初始化代码。

内核构建过程

在构建 ARM 架构的 Linux 内核时,通常会执行以下步骤:

  1. 配置内核:通过执行 make BOARDNAME_defconfig 或make menuconfig来选择适合特定硬件的配置文件。

  2. 编译内核:执行 make zImagemake Image 来生成内核镜像文件。

  3. 编译设备树:执行 make dtbs 来生成设备树二进制文件(.dtb)。

  4. 安装模块:执行 make modulesmake modules_install 来编译和安装内核模块。

最终生成的内核镜像文件(如 zImage)位于 arch/arm/boot 目录下。

设备树支持

设备树(Device Tree)是一种描述硬件设备配置的机制,广泛用于 ARM 架构的嵌入式系统。arch/arm/boot/dts 目录下包含设备树源文件(.dts),这些文件在构建过程中会被编译为设备树二进制文件(.dtb),并与内核镜像一起加载。

总之,arch/arm 目录是 Linux 内核中针对 ARM 架构的核心部分,它为 ARM 架构的嵌入式设备提供了必要的硬件支持和内核初始化功能。

block:磁盘设备的支持

block 目录是与块设备(如硬盘、SSD 等)相关的代码存放位置。

作用:

block 目录主要包含块设备层(Block Layer)的核心代码。块设备层是 Linux 内核中用于处理块设备 I/O 请求的通用框架。它负责将来自文件系统层的 I/O 请求转换为硬件设备可以理解的指令,并管理这些请求的调度和执行。

主要功能:

  • 核心模块代码:从 Linux 内核 2.6.15 版本开始,块设备层的核心代码被提取出来,放置在顶层的 block 目录中。这些代码包括 I/O 调度算法、请求队列管理等。

  • I/O 调度器:块设备层提供了多种 I/O 调度器,如 Deadline、CFQ(完全公平队列)等。这些调度器负责优化 I/O 请求的顺序,以提高磁盘性能。

  • 请求队列管理:块设备层管理着请求队列,这些队列用于存储等待处理的 I/O 请求。

与其他目录的关系:

  • drivers 目录的关系:drivers 目录中包含各种硬件设备的驱动程序,其中块设备驱动程序(如硬盘驱动程序)会与 block 目录中的代码紧密协作。块设备驱动程序负责将来自块设备层的 I/O 请求转换为硬件设备可以理解的指令。

  • fs 目录的关系:文件系统层(fs 目录)负责管理文件和目录的逻辑结构,而块设备层则负责将文件系统层的 I/O 请求转换为硬件设备可以理解的指令。

块设备层是 Linux 内核中处理块设备 I/O 请求的核心部分,它对于提高磁盘性能和优化 I/O 操作至关重要。通过合理的 I/O 调度和请求管理,块设备层可以显著提高系统的整体性能。

COPYING文件

COPYING 文件是一个非常重要的文件,它定义了 Linux 内核的许可证条款。

文件内容:

COPYING 文件包含了 Linux 内核的许可证文本,即 GNU General Public License (GPL) 版本 2。这个文件明确指出了内核代码的使用、修改和分发的规则。

CREDITS文件

CREDITS 文件是一个记录对内核有重大贡献的开发者的文件。它详细列出了这些开发者的姓名、联系方式以及他们对内核的具体贡献

crypto:加密相关

crypto 目录包含了内核的加密子系统代码。这个子系统提供了各种加密算法的实现,以及用于管理和使用这些算法的框架。

Documentation:

提供了丰富的文档和指南,帮助开发者和用户更好地理解和使用 Linux 内核。无论是内核开发者还是普通用户,都可以从这些文档中获得宝贵的参考信息。

drivers:设备驱动

drivers 目录是内核中最大的部分之一,它包含了几乎所有硬件设备的驱动程序代码。这些驱动程序是内核与硬件设备之间通信的桥梁,负责管理和控制各种硬件设备。

目录结构:

drivers 目录下包含多个子目录,每个子目录对应一类硬件设备或设备类型。以下是一些常见的子目录及其功能:

base:

包含内核驱动程序框架的基础代码,例如设备模型、总线驱动等。

block:

包含块设备驱动程序,例如硬盘、SSD 等。

char:

包含字符设备驱动程序,例如串行端口、键盘、鼠标等。

net:

包含网络设备驱动程序,例如以太网卡、无线网卡等。

scsi:

包含 SCSI 设备驱动程序,例如 SCSI 磁盘、磁带等。

usb:

包含 USB 设备驱动程序,例如 USB 键盘、鼠标、存储设备等。

gpu:

包含图形处理单元(GPU)的驱动程序,例如 NVIDIA、AMD 等。

sound:

包含音频设备驱动程序,例如声卡等。

misc:

包含一些不归类于其他目录的设备驱动程序。

  • eeprom:EEPROM 设备驱动程序。

  • i2c:I2C 设备驱动程序。

firmware:固件

firmware 目录主要用于存放各种硬件设备所需的固件文件。这些固件文件通常是二进制格式,用于初始化和运行硬件设备。

fs:文件系统

fs 目录是文件系统相关代码的核心部分,它包含了虚拟文件系统(VFS)的实现以及各种具体文件系统的驱动代码

include:头文件

include目录包含了内核编译过程中需要的各种头文件(.h 文件)。这些头文件定义了数据结构、宏、函数原型等,为内核代码的编写和编译提供了必要的接口和规范。

asm-generic

包含通用的架构相关头文件。这些头文件提供了一些通用的定义,可以在多种架构之间共享。例如,通用的内存管理宏、中断处理宏等。

linux

包含内核的核心头文件。这些头文件定义了内核的核心数据结构、函数原型和宏,是内核代码的基础。

uapi

包含用户空间和内核空间共享的头文件。这些头文件定义了用户空间程序与内核交互的接口,例如系统调用、设备驱动接口等。

scsi

包含 SCSI 设备相关的头文件。这些头文件定义了 SCSI 设备的驱动接口和数据结构。

net

包含网络协议栈相关的头文件。这些头文件定义了网络协议栈的数据结构和函数原型。

sound

包含音频设备相关的头文件。这些头文件定义了音频设备的驱动接口和数据结构。

对于内核开发者来说,include 目录是编写和调试内核代码的基础。开发者需要熟悉这些头文件的内容,以便正确地使用内核提供的接口和数据结构。例如:

  • 在编写设备驱动时,需要包含 linux/module.hlinux/fs.h 等文件。

  • 在优化内存管理时,需要参考 linux/mm.h 中的定义。

init:内核初始化

init 目录包含了内核初始化过程中的核心代码。这些代码负责在系统启动时完成内核的初始化工作,为后续的系统运行打下基础。

ipc:进程间通信

ipc 目录包含了内核中进程间通信(Inter-Process Communication, IPC)机制的核心代码。这些代码实现了 System V 和 POSIX 标准中定义的多种进程间通信方式,例如共享内存、消息队列和信号量等。以下是关于 ipc 目录的详细解析:

1. 目录结构

ipc 目录下包含多个文件,每个文件负责实现特定的 IPC 功能:

  • shm.c:实现共享内存(Shared Memory)的代码。

  • msg.c:实现消息队列(Message Queue)的代码。

  • sem.c:实现信号量(Semaphore)的代码。

  • util.c:提供 IPC 子系统中通用的工具函数,例如初始化 IPC 标识符、查找 IPC 对象等。

  • namespace.c:实现 IPC 命名空间(IPC Namespace)的代码,用于隔离不同进程组的 IPC 资源。

2. IPC 机制的实现

Linux 内核支持多种进程间通信机制,每种机制都有其特定的实现方式:

2.1 共享内存(Shared Memory)

共享内存允许多个进程共享同一块内存区域,从而实现高效的数据交换。共享内存的实现基于内核中的 shm 子系统:

  • shmget():创建或获取一个共享内存段。

  • shmat():将共享内存段映射到进程的地址空间。

  • shmctl():用于控制共享内存段的属性,例如删除共享内存段。

2.2 消息队列(Message Queue)

消息队列允许进程之间通过发送和接收消息进行通信。消息队列的实现基于内核中的 msg 子系统:

  • msgget():创建或获取一个消息队列。

  • msgsnd():向消息队列发送消息。

  • msgrcv():从消息队列接收消息。

2.3 信号量(Semaphore)

信号量是一种同步机制,用于控制对共享资源的访问。信号量的实现基于内核中的 sem 子系统:

  • semget():创建或获取一个信号量集。

  • semop():对信号量执行操作,例如 P(wait)或 V(signal)操作。

3. IPC 命名空间

IPC 命名空间允许将 IPC 资源隔离到不同的命名空间中,从而避免不同进程组之间的冲突。命名空间的实现基于内核中的 ipc_namespace 结构:

  • struct ipc_namespace:表示一个 IPC 命名空间,包含该命名空间中所有 IPC 资源的管理信息。

  • clone():通过设置 CLONE_NEWIPC 标志,可以在创建新进程时创建一个新的 IPC 命名空间。

Kbuild文件

Kbuild 文件是内核构建系统(Kbuild)的一部分,用于定义如何编译内核及其模块。它们的主要功能包括:

  • 指定哪些文件需要编译。

  • 定义编译目标(如内核模块或内核镜像)。

  • 设置编译选项和依赖关系

Kconfig文件

Kconfig 文件是内核配置系统的核心组成部分。这些文件定义了内核的配置选项(也称为配置符号或 Kconfig 符号),并指定了它们之间的依赖关系。Kconfig 文件使得用户可以通过配置工具(如 make menuconfig)选择性地启用或禁用内核功能,从而定制内核的构建。

Kconfig 文件的主要作用是:

  • 定义配置选项:列出内核中所有可配置的功能和选项。

  • 指定依赖关系:定义配置选项之间的依赖关系,确保某些功能启用时,其依赖的其他功能也会被启用。

  • 生成配置文件:根据用户的配置选择生成 .config 文件,该文件用于指导内核的编译过程。

Kconfig 文件被内核的配置工具(如 make menuconfigmake xconfig 等)使用,这些工具提供了一个图形化的界面,让用户可以方便地选择和配置内核功能。

当用户完成配置并保存时,配置工具会根据用户的选择生成一个 .config 文件。这个文件包含了所有配置选项的状态,用于指导内核的编译过程。

kernel:内核核心调度机制等

kernel 目录是内核的核心部分,包含了操作系统的基本功能和机制。这些代码负责管理系统的资源、调度进程、处理中断以及提供系统调用接口等

kernel 目录下包含多个子目录和文件,每个部分都有特定的功能:

1.1 子目录:

  • sched:包含进程调度器的代码,负责管理进程的运行时间和优先级。

  • fork:包含进程创建和销毁的代码,例如 fork()exit() 系统调用的实现。

  • exit:包含进程退出时的清理代码。

  • signal:包含信号处理机制的代码,负责发送和接收信号。

  • panic:包含内核崩溃时的处理代码,例如 panic() 函数。

  • power:包含电源管理相关的代码,例如系统休眠和唤醒。

  • time:包含时间管理相关的代码,例如时钟中断处理和时间同步。

  • sys:包含系统调用的实现代码,例如 sys_open()sys_read() 等。

  • irq:包含中断处理机制的代码,负责管理硬件中断和软件中断。

  • softirq:包含软中断(软件中断)的处理代码,用于处理内核中的异步任务。

  • timer:包含定时器管理的代码,负责管理内核中的定时器。

  • kthread:包含内核线程的管理代码,例如创建和销毁内核线程。

  • module:包含内核模块的加载和卸载代码。

  • uidgid:包含用户和组 ID 管理的代码。

  • cred:包含凭证管理的代码,例如用户权限和安全上下文。

lib:库

lib 目录包含了内核使用的各种通用库函数。这些函数提供了内核代码中广泛使用的工具和算法,例如字符串处理、内存拷贝、排序等。

MAINTAINERS文件

MAINTAINERS 文件是一个纯文本文件,包含了多个字段,用于描述内核各个子系统的维护信息

Makefile文件

Makefile 是内核构建系统的核心文件。它定义了如何编译内核及其模块,包括编译目标、编译选项、依赖关系等。

mm:内存管理

mm 目录是内存管理(Memory Management)相关代码的核心部分。它包含了内核用于管理物理内存、虚拟内存以及页面管理的代码。

net:网络协议

net 目录是网络协议栈相关代码的核心部分。它包含了网络协议栈的核心代码。这些代码负责实现各种网络协议、套接字管理、网络设备管理以及网络过滤等功能。

README文件

README 文件是内核源码的主说明文件,它为开发者和用户提供了一个快速了解内核的基本信息和编译指南的入口。

文件内容

README 文件通常包含以下内容:

  • 内核版本信息:当前内核的版本号。

  • 获取源码:如何获取最新的内核源码。

  • 编译指南:如何编译内核的基本步骤。

  • 安装指南:如何安装编译后的内核。

  • 运行指南:如何启动和运行新编译的内核。

  • 支持平台:内核支持的硬件平台和架构。

  • 常见问题:一些常见问题的解答和调试建议。

REPORTING-BUGS文件

它为用户和开发者提供了关于如何报告内核问题的详细指南。

samples

samples 目录是一个非常有用的资源,它包含了各种示例代码和演示程序。这些示例代码主要用于展示内核编程的各个方面,帮助开发者学习和理解内核的实现细节。

scripts:工具、脚本等

它包含了各种脚本和工具,用于辅助内核的开发、构建和维护。这些脚本和工具在内核的编译、配置、测试和调试过程中发挥着重要作用。

security:安全

它包含了内核安全功能的核心代码。这些代码负责实现访问控制、密钥管理、完整性检查和审计功能等安全机制。

sound

sound 目录是与音频相关的驱动程序和代码的核心部分。它主要包含音频硬件的驱动程序,例如声卡驱动程序,以及与音频处理相关的内核代码。

tools

它包含了各种工具和脚本,用于辅助内核的开发、调试、测试和性能分析。

usr:打包与压缩

usr 目录是 Linux 内核源码中与用户空间初始化相关的部分,它提供了用户空间初始化程序、初始 RAM 文件系统和轻量级 C 标准库。

virt:虚拟

virt 目录是 Linux 内核源码中与虚拟化相关的部分,它提供了虚拟化技术的核心代码,包括 KVM、Virtio、虚拟机迁移和内存管理等功能。

参考资源:https://download.csdn.net/download/2403_82436914/90678232

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2343955.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

72.评论日记

【巫师】中美关税战02:应给人民爆装备,以及普通人如何应对(7条建议)_哔哩哔哩_bilibili 2025年4月26日11:03:31

Websocket自动发送消息客户端工具

点击下载《Websocket自动发送消息客户端工具》 1. 前言 在现代网络应用中,实时通信和即时数据传输变得越来越重要。WebSocket作为一种全双工通信协议,因其高效、实时的特点,被广泛应用于聊天应用、实时数据监控、在线游戏等领域。然而&…

STM32的开发环境介绍

目录 STM32软件环境 Keil软件在线安装 其他软件环境安装 STM32开发的几种方式 STM32寄存器版本和库函数版本 标准外设库的作用: STM32软件环境 STM32 的集成开发环境(IDE):编辑编译软件 常见的环境: (1)KEIL&a…

数据库系统概论(四)关系操作,关系完整性与关系代数

数据库系统概论(四)详细讲解关系操作,关系完整性与关系代数 前言一、什么是关系操作1.1 基本的关系操作1.2 关系数据语言的分类有哪些 二、关系的完整性2.1 实体完整性2.2 参照完整性2.3 用户的定义完整性 三、关系代数是什么3.1 传统的集合运…

基于 IPMI + Kickstart + Jenkins 的 OS 自动化安装

Author:Arsen Date:2025/04/26 目录 环境要求实现步骤自定义 ISO安装 ipmitool安装 NFS定义 ks.cfg安装 HTTP编写 Pipeline 功能验证 环境要求 目标服务器支持 IPMI / Redfish 远程管理(如 DELL iDRAC、HPE iLO、华为 iBMC)&…

使用 Node、Express 和 MongoDB 构建一个项目工程

本文将详细介绍如何使用 Node.js Express MongoDB 构建一个完整的 RESTful API 后端项目,涵盖: 项目初始化 Express 服务器搭建 MongoDB 数据库连接 REST API 设计(CRUD 操作) 错误处理与中间件 源码结构与完整代码 部署建…

【C++11】右值引用和移动语义:万字总结

📝前言: 这篇文章我们来讲讲右值引用和移动语义 🎬个人简介:努力学习ing 📋个人专栏:C学习笔记 🎀CSDN主页 愚润求学 🌄其他专栏:C语言入门基础,python入门基…

Python基于Django的全国二手房可视化分析系统【附源码】

博主介绍:✌Java老徐、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专栏推荐订阅👇&…

VulnHub-DC-2靶机渗透教程

VulnHub-DC-2靶机渗透教程 1.靶机部署 [Onepanda] Mik1ysomething 靶机下载:https://download.vulnhub.com/dc/DC-2.zip 直接使用VMware导入打开就行 2.信息收集 2.1 获取靶机ip(arp-scan/nmap) arp-scan -l ​ nmap 192.168.135.0/24 2.2 详细信息扫描(nmap)…

n8n 中文系列教程_10. 解析n8n中的AI节点:从基础使用到高级Agent开发

在自动化工作流中集成AI能力已成为提升效率的关键。n8n通过内置的LangChain节点,让开发者无需复杂代码即可快速接入GPT-4、Claude等大模型,实现文本处理、智能决策等高级功能。本文将深入解析n8n的AI节点体系,从基础的Basic LLM Chain到强大的…

计算机网络 | 应用层(1)--应用层协议原理

💓个人主页:mooridy 💓专栏地址:《计算机网络:自定向下方法》 大纲式阅读笔记 关注我🌹,和我一起学习更多计算机的知识 🔝🔝🔝 目录 1. 应用层协议原理 1.1 …

MuJoCo 关节角速度记录与可视化,监控机械臂运动状态

视频讲解: MuJoCo 关节角速度记录与可视化,监控机械臂运动状态 代码仓库:GitHub - LitchiCheng/mujoco-learning 关节空间的轨迹优化,实际上是对于角速度起到加减速规划的控制,故一般来说具有该效果的速度变化会显得丝…

LVGL模拟器:NXP GUIDER+VSCODE

1. 下载安装包 NXP GUIDER:GUI Guider | NXP 半导体 CMAKE:Download CMake MINGW:https://github.com/niXman/mingw-builds-binaries/releases SDL2:https://github.com/libsdl-org/SDL/releases/tag/release-2.30.8 VSCODE&…

《USB技术应用与开发》第四讲:实现USB鼠标

一、标准鼠标分析 1.1简介 1.2页面显示 其中页面显示的“”不用管它,因为鼠标作为物理抓包,里面有时候会抓到一些错误,不一定是真正的通讯错误,很可能是本身线路接触质量不好等原因才打印出来的“”。 1.3按下鼠标左键 &#x…

一、鸿蒙编译篇

一、下载源码和编译 https://blog.csdn.net/xusiwei1236/article/details/142675221 https://blog.csdn.net/xiaolizibie/article/details/146375750 https://forums.openharmony.cn/forum.php?modviewthread&tid897 repo init -u https://gitee.com/openharmony/mani…

得物业务参数配置中心架构综述

一、背景 现状与痛点 在目前互联网飞速发展的今天,企业对用人的要求越来越高,尤其是后端的开发同学大部分精力都要投入在对复杂需求的处理,以及代码架构,稳定性的工作中,在对比下,简单且重复的CRUD就显得…

【算法】单词搜索、最短距离

单词搜索 这道题主要考察了深度优先遍历(DFS)算法。 我们通过几个简单例子来分析一些细节问题: 1. 要搜索的单词串:abc 搜索的过程中必须按照字母顺序,首先从矩阵中的第一个元素开始搜索,遇到字母a则开始深度优先遍历&#xff0…

Python函数基础:简介,函数的定义,函数的调用和传入参数,函数的返回值

目录 函数简介 函数定义,调用,传入参数,返回值 函数的定义 函数的调用和传入参数 函数的返回值 函数简介 函数简介:函数是组织好,可重复使用,用来实现特定功能(特定需求)的代码…

基于FFmpeg命令行的实时图像处理与RTSP推流解决方案

前言 在一些项目开发过程中需要将实时处理的图像再实时的将结果展示出来,此时如果再使用一张一张图片显示的方式展示给开发者,那么图像窗口的反复开关将会出现窗口闪烁的问题,实际上无法体现出动态画面的效果。因此,需要使用码流…

【随笔】地理探测器原理与运用

文章目录 一、作者与下载1.1 软件作者1.2 软件下载 二、原理简述2.1 空间分异性与地理探测器的提出2.2 地理探测器的数学模型2.21 分异及因子探测2.22 交互作用探测2.23 风险区与生态探测 三、使用:excel 一、作者与下载 1.1 软件作者 作者: DOI: 10.…