- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
我正在学习Device Driver
和Kernel
编程。根据Jonathan Corbet 的书,我们在设备驱动程序中没有main()
函数。
#include <linux/init.h>
#include <linux/module.h>
static int my_init(void)
{
return 0;
}
static void my_exit(void)
{
return;
}
module_init(my_init);
module_exit(my_exit);
这里我有两个问题:
main()
函数?main()
函数吗?最佳答案
启动内核
关于 4.2,start_kernel
from init/main.c
是一个相当大的初始化过程,可以与 main
函数进行比较。
它是第一个运行的 arch 独立代码,并设置了内核的很大一部分。与 main
非常相似,start_kernel
之前是一些较低级别的设置代码(在用户空间 main
crt*
对象中完成)),之后运行“主要”通用 C 代码。
如何在 x86_64 中调用 start_kernel
arch/x86/kernel/vmlinux.lds.S
,一个链接描述文件,设置:
ENTRY(phys_startup_64)
和
phys_startup_64 = startup_64 - LOAD_OFFSET;
和:
#define LOAD_OFFSET __START_KERNEL_map
arch/x86/include/asm/page_64_types.h
将 __START_KERNEL_map
定义为:
#define __START_KERNEL_map _AC(0xffffffff80000000, UL)
这是内核入口地址。 TODO 该地址是如何准确到达的?我必须了解 Linux 向引导加载程序公开的接口(interface)。
arch/x86/kernel/vmlinux.lds.S
将第一个引导加载程序部分设置为:
.text : AT(ADDR(.text) - LOAD_OFFSET) {
_text = .;
/* bootstrapping code */
HEAD_TEXT
include/asm-generic/vmlinux.lds.h
定义HEAD_TEXT
:
#define HEAD_TEXT *(.head.text)
arch/x86/kernel/head_64.S
定义了 startup_64
。这是第一个运行的 x86 内核代码。它执行大量低级设置,包括分段和分页。
那是第一个运行的东西,因为文件以:
.text
__HEAD
.code64
.globl startup_64
和include/linux/init.h
将__HEAD
定义为:
#define __HEAD .section ".head.text","ax"
因此与链接描述文件的第一件事相同。
最后它调用 x86_64_start_kernel
和 lretq
有点笨拙:
movq initial_code(%rip),%rax
pushq $0 # fake return address to stop unwinder
pushq $__KERNEL_CS # set correct cs
pushq %rax # target address in negative space
lretq
和:
.balign 8
GLOBAL(initial_code)
.quad x86_64_start_kernel
arch/x86/kernel/head64.c
定义 x86_64_start_kernel
调用 x86_64_start_reservations
调用 start_kernel
。
arm64 入口点
在 v5.7 未压缩内核上运行的第一个 arm64 定义在 https://github.com/cirosantilli/linux/blob/v5.7/arch/arm64/kernel/head.S#L72所以 add x13, x18, #0x16
或 b stext
取决于 CONFIG_EFI
:
__HEAD
_head:
/*
* DO NOT MODIFY. Image header expected by Linux boot-loaders.
*/
#ifdef CONFIG_EFI
/*
* This add instruction has no meaningful effect except that
* its opcode forms the magic "MZ" signature required by UEFI.
*/
add x13, x18, #0x16
b stext
#else
b stext // branch to kernel start, magic
.long 0 // reserved
#endif
le64sym _kernel_offset_le // Image load offset from start of RAM, little-endian
le64sym _kernel_size_le // Effective size of kernel image, little-endian
le64sym _kernel_flags_le // Informative flags, little-endian
.quad 0 // reserved
.quad 0 // reserved
.quad 0 // reserved
.ascii ARM64_IMAGE_MAGIC // Magic number
#ifdef CONFIG_EFI
.long pe_header - _head // Offset to the PE header.
这也是未压缩内核镜像的第一个字节。
这两种情况都跳转到 stext
开始“真正的” Action 。
如评论中所述,这两条指令是记录在案的 header 的前 64 个字节,描述于:https://github.com/cirosantilli/linux/blob/v5.7/Documentation/arm64/booting.rst#4-call-the-kernel-image
arm64 第一个启用 MMU 的指令:__primary_switched
我认为是__primary_switched
in head.S :
/*
* The following fragment of code is executed with the MMU enabled.
*
* x0 = __PHYS_OFFSET
*/
__primary_switched:
此时,内核似乎正在创建页表 + 可能会重新定位自身,以便 PC 地址与 vmlinux ELF 文件的符号相匹配。因此,此时您应该能够在 GDB 中看到有意义的函数名称,而无需额外的魔法。
arm64 辅助 CPU 入口点
secondary_holding_pen
定义于:https://github.com/cirosantilli/linux/blob/v5.7/arch/arm64/kernel/head.S#L691
进入程序进一步描述:https://github.com/cirosantilli/linux/blob/v5.7/arch/arm64/kernel/head.S#L691
关于c - Linux内核有main函数吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18266063/
总的来说,我对 Linux 内核和操作系统非常感兴趣。我想知道的是,内核的文件类型或扩展名是什么?它显然没有 .exe 或 .out 扩展名,因为它们用于安装在操作系统上的应用程序。 内核只是一个二进
我需要为 Raspbian Linux 内核添加一个自己的系统调用。现在我在搜索了大约 2 天以找到解决方案后陷入困境。 要加一个系统调用,我基本上是按照大纲来的( http://elinux.org
对于一个学术项目,我希望将源文件 (myfile.c) 添加到 kernel/目录,与exit.c相同的目录和 fork.c .构建系统似乎不会自动获取新文件,因为我在 myfile.c 中定义的函数
浏览器排行榜 浏览器市占率排行榜全球榜 。 浏览器市占率排行榜中国榜 -快科技 。 如果按照浏览器内核来看, Chromium 内核的市场占有率无疑是最大的,一家独大
给定一个进程或线程的任务结构,迭代属于同一进程的所有其他线程的习惯用法是什么? 最佳答案 Linux 不区分进程(任务)和线程。库调用 fork() 和 pthread_create() 使用相同的系
我正在用c(不是linux。完全从头开始)从头开始制作一个内核,但我遇到了一些问题。我有这个代码: #include "timer.h" int ms = 0; void timer_handler(
我正在从头开始制作一个 C 内核,我实际上只是从网站上复制了这段代码,因为我的代码无法工作,所以我很困惑。 void kmain(void) { const char *str = "my f
我不确定,如果我完全理解上述差异,所以我想自己解释一下,你可以打断我,只要我有错:“内核是创建内核线程的初始代码段。内核线程是由内核管理的进程。用户线程是进程的一部分。如果你有一个单线程进程,那么整个
看一下struct file 定义from this code Linux 内核版本 2.6.18。 我正在尝试比较代码中的两个 struct file 变量,并确定它们是否指的是同一个文件。该结构中
我试图在 Linux 启动时使嵌入式设备中的 LED 闪烁。基本上,LED 闪烁表明 Linux 正在启动。为了使 LED 闪烁,我正在做以下事情 在 init/main.c 中创建了一个全局定时器(
我有一些在 FreeBSD 和 Linux 上运行的特定硬件。 我必须做一个用户空间应用程序,它将使用内核/用户空间应用程序之间的共享内存与驱动程序一起工作。我的应用程序对来自用户空间的共享内存进行忙
我在哪里可以找到 linux 内核中相应函数的解释,特别是对于 ICMPv4? 例如:icmp_reply、icmp_send等 感谢您的帮助。 最好的,阿里木 最佳答案 探索 Linux 内核中的
我在 Linux Kernel 3.4 上工作,我有以下代码: /* Proximity sensor calibration values */ unsigned int als_kadc;
我正在阅读“罗伯特·洛夫 (Robert Love) 撰写的 Linux 内核开发第 3 版”,以大致了解 Linux 内核的工作原理..(2.6.2.3) 我对等待队列的工作方式感到困惑,例如这段代
我之前也问过同样的问题,但是我的帖子不知为何被删除了。 无论如何,我正在尝试使用 C++ 并编写一个允许我直接访问内存并向其中写入内容的程序。我听说我需要对内核做一些事情,因为它是连接操作系统和应用程
在尝试了解 Ruby 执行方法时,我找到了这篇关于在 Ruby 中运行命令的五种方法的博文 http://mentalized.net/journal/2010/03/08/5_ways_to_run
是否有 Linux 发行版(Minix 除外)包含良好的源代码文档?或者,是否有一些好的文档来描述一般的 Linux 源代码? 我已经下载了内核源代码,但是(不出所料)我有点不知所措,我想知道是否有一
有谁知道 linux 中的哪个函数或文件包含查找用于 bind() 系统调用的随机端口的算法?我到处寻找,在 Linux 源代码中找不到包含此算法的方法。 谢谢! 最佳答案 这是一段又长又复杂的代码,
前言 首先,对于有科班背景的读者,可以跳过本系列文章。这些文章的主要目的是通过简单易懂的汇总,帮助非科班出身的读者理解底层知识,进一步了解为什么在面试中会涉及这些底层问题。否则,某些概念将始终
CentOS7.2与CentOS6区别及特点 Linux 操作系统的启动首先从 BIOS 开始,接下来进入 boot loader,由 bootloader 载入内核,进行内核初始化。内核初始化的
我是一名优秀的程序员,十分优秀!