内核有 main() 函数吗?

som*_*one 54 drivers linux-kernel

我正在学习设备驱动程序和内核编程。根据 Jonathan Corbet 的书,main()设备驱动程序中没有功能。

所以我有两个问题:

  • 为什么我们不需要main()设备驱动程序中的函数?
  • 内核本身有main()功能吗?

谁可以给我解释一下这个?

Tho*_*man 85

在用户空间程序中,是执行二进制文件时由 libc 初始化代码调用main()的程序的入口点。内核代码不能过度依赖 libc,因为 libc 本身依赖内核系统调用接口进行内存分配、I/O、进程管理等。

也就是说,相当于main()内核代码中的start_kernel()引导加载程序在加载内核映像后调用它,将其解压缩到内存中并设置必要的硬件和内存分页。start_kernel()执行大部分系统设置并最终产生 init 进程。

Linux 内核模块的入口点是一个通过调用module_init()宏向内核注册的 init 函数。然后在内核启动期间,内核代码通过该do_initcalls()函数调用注册的模块 init 函数。

  • 感谢您认识到 C 中 `main` 方法的真正用途。(这是一种普遍存在的误解,即操作系统直接调用 `main`,事实并非如此,在例如 C++。)如果可以的话,我会再给你一个赞成票。 (11认同)

Edw*_*hen 18

内核没有main函数。 main是C语言的一个概念。内核是用 C 和汇编语言编写的。内核的入口代码是用汇编写的。

启动顺序组织如下:

  1. BIOS 通常从引导块设备加载引导加载程序。现在流行的引导加载程序是 grub。
  2. Grub 将内核映像加载到 ram 中,可以使用初始根设备 ( initrd)。然后执行某个地址处的代码。
  3. 内核映像有一些内核模块,例如:文件系统模块、设备驱动程序。内核映像使用文件系统模块来挂载根文件系统。现在内核可以从磁盘加载和运行所有内核模块。
  4. 内核运行初始化任务。例如:遍历PCI总线,找到所有的PCI设备,初始化所有的设备驱动。
  5. 最后内核创建进程0和进程1(init进程),将CPU的上下文从ring 0切换到ring 3,并启动init进程(进程id为1)。现在内核启动完成!
  6. init程序运行所有初始化脚本。启动所有服务。壳被称为。用户可以登录。

main函数是一个 C 函数。实际上 main 方法并不是 C 程序的入口点。C 运行时在main. GCC 有一个扩展特性:构造函数。声明为“构造函数”的函数在main.

例如:

/* This should not be used directly. Use block_init etc. instead. */ 
#define module_init(function, type) \
    static void _attribute__((constructor)) do_qemu_init ## function(void) { \
    register_module_init(function, type); \
} 
Run Code Online (Sandbox Code Playgroud)

这个宏来自 qemu 项目。

  • 这个答案充满了“一切都是 PC/Linux/i86”,它以这种方式启动,内核也是如此……为什么每个人都认为这是世界上唯一可能的方式? (3认同)

小智 10

例如在arch/x86/boot/main.c 中有一个 main() 函数,用于准备系统从真实模式切换到保护模式,但其他体系结构没有这样的代码。有一个很好的概述如何在 x86 平台上启动 Linux 内核 2.6.x。真的很值得一读。

根据文档HOWTO do Linux kernel development,Linux内核是

独立的 C 环境,不依赖于标准 C 库,因此不支持 C 标准的某些部分。

根据 C 标准 BTW 意味着什么

独立环境中的程序是否需要定义“main”函数是实现定义的。