Linux内核程序入口地址

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux内核程序入口地址相关的知识,希望对你有一定的参考价值。

参考技术A

在Linux内核中,使用 vmlinux.lds.S 文件(路径: arch/arm64/kernel/ )布局内核映像中相关段(例: .text、.data )的位置。

在Linux内核编译时, vmlinux.lds.S 文件最终会被构建成链接脚本 vmlinux.lds 文件(路径: arch/arm64/kernel/ )。

本文主要介绍Linux内核程序运行的起始位置 _text ,在 vmlinux.lds.S 文件中定义如下:

从上面可以看出: _text = KIMAGE_VADDR + TEXT_OFFSET 。

1、KIMAGE_VADDR定义

文件: arch/arm64/include/asm/memory.h ,定义如下:

文件: include/linux/sizes.h ,定义如下:

宏 KIMAGE_VADDR 展开如下:

上面是按照无符号计算, KIMAGE_VADDR 为: 0xFFFFFF8008000000 。

2、TEXT_OFFSET定义

文件: arch/arm64/Makefile ,定义如下:

通过计算, _text 值为: 0xFFFFFF8008080000 。

在Linux内核启动时,从 log 信息中也可以找到对应的地址:

_text 对应的是虚拟地址 在内核中可以直接通过访问该地址获取其保存的值 ,其对应 Image 映像中的第一个字 0x14424000 。

Image 映像查看方法如下:

本文基于 RockPI 4A 单板Linux 4.4内核。

心得

编写Linux驱动程序的步骤:

第1步:建立Linux驱动骨架(装载和卸载Linux驱动)

任何类型的程序都有一个基本的结构,例如,C语言需要有一个入口函数main。Linux驱动程序也不例外。Linux内核在使用驱动时首先需要装载驱 动。 在装载过程中需要进行一些初始化工作,例如,建立设备文件,分配内存地址空间等。当Linux系统退出时需要卸载Linux驱动,在卸载的过程中需要释放 由Linux驱动占用的资源,例如,删除设备文件、释放内存地址空间等。在Linux驱动程序中需要提供两个函数来分别处理驱动初始化和退出的工作。这两 个函数分别用module_init和module_exit宏指定。Linux驱动程序一般都都需要指定这两个函数,因此包含这两个函数以及指定这两个 函数的两个宏的C程序文件也可看作是Linux驱动的骨架。

第2步:注册和注销设备文件

任何一个Linux驱动都需要有一个设备文件。否则应用程序将无法与驱动程序交互。建立设备文件的工作一般在第1步编写的处理Linux初始化工作的函数 中 完成。删除设备文件一般在第1步编写的处理Linux退出工作的函数中完成。可以分别使用misc_register和misc_deregister函 数创建和移除设备文件。

第3步:指定与驱动相关的信息

驱动程序是自描述的。例 如,可以通过modinfo命令获取驱动程序的作者姓名、使用的开源协议、别名、驱动描述等信息。这些信息都需要在驱动源代码中指定。通过 MODULE_AUTHOR、MODULE_LICENSE 、MODULE_ALIAS 、MODULE_DESCRIPTION等宏可以指定与驱动相关的信息。

第4步:指定回调函数

Linux 驱动包含了多种动作,也可称为事件。例如,向设备文件写入数据时会触发“写”事件,Linux系统会调用对应驱动程序的write回调函数,从设备文件读 数据时会触发“读”事件,Linux系统会调用对应驱动程序的read回调函数。一个驱动程序并不一定要指定所有的回调函数。回调函数会通过相关机制进行 注册。例如,与设备文件相关的回调函数会通过misc_register函数进行注册。

第5步:编写业务逻辑

这一步是Linux驱动的核心部分。光有骨架和回调函数的Linux驱动是没有任何意义的。任何一个完整的Linux驱动都会做一些与其功能相关的工作,如 打印机驱动会向打印机发送打印指令。COM驱动会根据传输数率进行数据交互。具体的业务逻辑与驱动的功能有关。业务逻辑可能有多个函数、多个文件甚至是多 个Linux驱动模块组成。具体的实现读者可以根据实际情况而定。

第6步:编写Makefile文件

Linux内核源代码的编译规则是通过Makefile文件定义的。因此编写一个新的Linux驱动程序必须要有一个Makefile文件。

第7步:编译Linux驱动程序

Linux驱动程序可以直接编译进内核,也可以作为模块单独编译。

第8步:安装和卸载Linux驱动

如果将Linux驱动编译进内核,只要Linux使用该内核,驱动程序就会自动装载。如果Linux驱动程序以模块单独存在,需要使用insmod或modprobe命令装载Linux驱动模块,使用rmmod命令卸载Linux驱动模块。

以上是关于Linux内核程序入口地址的主要内容,如果未能解决你的问题,请参考以下文章

Tiny4412 Linux 内核启动流程

求 Linux 内核中断 INT 80H 详细资料

main函数由哪个进程创建?

2017-2018-1 20179219 《Linux内核原理与分析》第三周作业

Linux内核(12) - 子系统的初始化之那些入口函数

linux内核空间能正常显示mac地址,到了用户空间就显示有问题