记linux内核处理bootargs到内核并加载模块时传入参数(module_param_named()等)

2023-11-15

昨晚,一网友问我如何把LCD反转一下输出,顿时不会,只会去看之前的dm3730的linux2.6.32的内核。偶然发现直接设置bootargs的参数到内核也许就可以啦。

Linux以内核模块为核心,自动编译如系统后,所以的类似init_call等都会存放在Init的section中。类似的,一个模块中经过module_param()和module_param_named()设置的参数等也会有自己的一片section。这让我觉得这和dsp的内存段分配很类似。


1。下面我以 linux/drivers/video/omap2/omapfb-main.c这个驱动模块中的参数为列来做一个分析内核如何接收参数使得模块加载时,该参数已经初始化完毕。

在该文件下可以找到这组对应的模块参数:

module_param_named(mode, def_mode, charp, 0);
module_param_named(vram, def_vram, charp, 0);
module_param_named(rotate, def_rotate, int, 0);
module_param_named(vrfb, def_vrfb, bool, 0);
module_param_named(mirror, def_mirror, bool, 0);

从本质上来说module_param_named等其实就类似与dsp中的#pargam section()的功能,不信可以看下这些宏的实现,上述的在模块参数表中对应的名字都会加上当前模块名.name,MODULE_NAME.param参数:

#define MODULE_PARAM_PREFIX KBUILD_MODNAME "."

#define __module_param_call(prefix, name, set, get, arg, isbool, perm)	\
	/* Default value instead of permissions? */			\
	static int __param_perm_check_##name __attribute__((unused)) =	\
	BUILD_BUG_ON_ZERO((perm) < 0 || (perm) > 0777 || ((perm) & 2))	\
	+ BUILD_BUG_ON_ZERO(sizeof(""prefix) > MAX_PARAM_PREFIX_LEN);	\
	static const char __param_str_##name[] = prefix #name;		\
	static struct kernel_param __moduleparam_const __param_##name	\
	__used								\
    __attribute__ ((unused,__section__ ("__param"),aligned(sizeof(void *)))) \
	= { __param_str_##name, perm, isbool ? KPARAM_ISBOOL : 0,	\
	    set, get, { arg } }

#define module_param_call(name, set, get, arg, perm)			      \
	__module_param_call(MODULE_PARAM_PREFIX,			      \
			    name, set, get, arg,			      \
			    __same_type(*(arg), bool), perm)

/* Helper functions: type is byte, short, ushort, int, uint, long,
   ulong, charp, bool or invbool, or XXX if you define param_get_XXX,
   param_set_XXX and param_check_XXX. */
#define module_param_named(name, value, type, perm)			   \
	param_check_##type(name, &(value));				   \
	module_param_call(name, param_set_##type, param_get_##type, &value, perm); \
	__MODULE_PARM_TYPE(name, #type)

#define module_param(name, type, perm)				\
	module_param_named(name, name, type, perm)
上述的宏调用过程,说明了最终哦会将模块参数的value取地址存放入_attribute__ ((unused,__section__ ("__param"),aligned(sizeof(void *))))这个section中去。可以猜想的是,最终都会访问这个模块参数指针列表,将uboot中的Bootargs等参数传入到内核时,对相关的模块参数区域进行初始化,其主要通过name来进行相对应的查找与匹配。


这个查找的过程在init/main.c函数下的start_kernel处:

	parse_early_param();
	parse_args("Booting kernel", static_command_line, __start___param,
		   __stop___param - __start___param,
		   &unknown_bootoption);

int parse_args(const char *name,
           char *args,
           struct kernel_param *params,
           unsigned num,
           int (*unknown)(char *param, char *val))
{
    while (*args) {
        int ret;
        int irq_was_disabled;

        args = next_arg(args, &param, &val);//提取一个参数的名字到param,如果该参数有=的就赋地址值给val
        irq_was_disabled = irqs_disabled();
        ret = parse_one(param, val, params, num, unknown);//提取一个参数到param,并对该参数进行解析,params是_param参数段的首地址
        if (irq_was_disabled && !irqs_disabled()) {
            printk(KERN_WARNING "parse_args(): option '%s' enabled "
                    "irq's!\n", param);
        }
...
}
。
。
。
static int parse_one(char *param,
             char *val,
             struct kernel_param *params, 
             unsigned num_params,
             int (*handle_unknown)(char *param, char *val))
{
    unsigned int i;

    /* Find parameter */
    for (i = 0; i < num_params; i++) {
        if (parameq(param, params[i].name)) {//论循传入的参数名字是否在模块参数表有匹配!
            DEBUGP("They are equal!  Calling %p\n",
                   params[i].set);
            return params[i].set(val, &params[i]);//将传入的value根据模块参数的数据类型,转化后赋值给参数表指针所指向的模块参数,而这些参赛在模块
                                                   //中往往是static的形似,故参数表存的是参数地址!
        }
    }
 通过以上各部分可以完全的将bootargs参数进行解析,而各模块在加载时也就可以使用到自己模块内部已经初始化的参数。

如本列中的framebuffer驱动,需要用到的omapfb.mode就是如此传入的。

bootargs 'console=ttyS2,115200n8 root=/dev/mmcblk0p2 rw ip=off mem=55M@0x80000000 mpurate=1000  omap_vout.vid1_static_vrfb_alloc=y omapfb.vram=0:8M mem=384M@0x88000000 omapfb.mode=lcd omapfb.rotate=2 omapfb.vrfb=y omapdss.def_disp=lcd rootwait vram=8M rootdelay=3'来实现旋转

此外补充一点是内核模块参数可以在insmod或者modprobe时,制定内核模块的参数值,如rotate = 2, vrfb = y即可。因为已经指定了模块名故不需要再参数前加前缀。bootargs中加入的前缀目的是区分不同模块的相同name的参数。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

记linux内核处理bootargs到内核并加载模块时传入参数(module_param_named()等) 的相关文章

  • 如何每周日运行 crontab 作业

    我想弄清楚如何每周周日运行 crontab 作业 我认为以下应该可行 但我不确定我是否理解正确 下面的说法正确吗 5 8 6 这是 crontab 格式的解释 1 Entry Minute when the process will be
  • 如何在 Linux 中制作一个将文件转换为大写的 x86 汇编程序?

    我找到了一个名为 ProgrammingGroundUp 1 0 booksize pdf 的 pdf 文件 其中一个项目是制作一个汇编程序 该程序接收文件并将其转换为大写 section data CONSTANTS system cal
  • 如何在Linux中获取带有图标的活动应用程序

    我想找到一种方法获取活动应用程序的列表及其名称和图标 实际上 我正在使用此命令来获取所有活动进程 wmctrl lp 示例输出 0x03800002 0 3293 user notebook XdndCollectionWindowImp
  • 如何让 VSCode 在当前工作区中打开?

    我在 Linux 上使用 VSCode 我有多个 Linux 工作区 当我在新工作区中的 VSCode 中打开新文件时 它会在原始工作区中的 VSCode 中打开一个新选项卡 而不是在当前工作区中打开 VSCode 的新实例 这确实是令人讨
  • 64位版本的adb和fastboot?

    我在 Debian 7 3 x64 已完全修补 上发现了以下错误 我很确定这是因为adb即使在其 SDK 工具的 64 位发行版中也是 32 位 which adb opt android sdk platform tools adb op
  • 是否可以为我的 Linux 函数复制命令的制表符补全?

    假设我有一个名为的 bash shell 函数magic 我想定义一个制表符补全功能 magic这将允许magic搭载任何给定命令的选项卡完成功能 如果可用 换句话说 我想要magic能够做这样的事情 magic git
  • 是否有一种异步信号安全的方式来读取 Linux 上的目录列表?

    SUSv4 http pubs opengroup org onlinepubs 9699919799 functions V2 chap02 html tag 15 04 03 03未在其异步信号安全函数列表中列出 opendir rea
  • 将任何当前目录“./”添加到Linux中的搜索路径[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 如何将任何当前目录 添加到 Linux 中可执行文件的搜索路径中 我知道这是一个旧答案 但如果其他人像我一样通过谷歌偶然发现这个问题 这里
  • 使用 SED 将单词的第一个字母大写

    如何将单词的第一个字母替换为大写字母 例如 Trouble me Gold rush brides into Trouble Me Gold Rush Brides 这一行应该做到这一点 sed e s b u 1 g
  • 使用 awk 处理多个文件

    我必须使用 awk 处理大量 txt 文件 每个文件 1600 万行 我必须阅读例如十个文件 File 1 en sample 1 200 en n sample 2 10 en sample 3 10 File 2 en sample 1
  • 为 Python 终端提供持久的历史记录

    有没有办法告诉交互式 Python shell 保留会话之间执行命令的历史记录 当会话运行时 在执行命令后 我可以向上箭头并访问所述命令 我只是想知道是否有某种方法可以保存一定数量的这些命令 直到下次使用 Python shell 时 这将
  • 如何在 Linux 中创建可通过 Screen 应用程序连接的 pty

    我想创建 C C 应用程序 它在 dev xxx 中创建新的 虚拟 设备 并且能够与 屏幕 应用程序连接 例如 循环运行的程序会创建新的 dev ttyABC 然后我将使用 屏幕 dev ttyABC 当我向那里发送一些字符时 应用程序将其
  • 使用 EOF 在未命名管道上发出信号

    我有一个测试程序 它使用使用 pipeline 创建的无名管道在 Linux 系统上使用 fork 创建的父进程和子进程之间进行通信 通常 当发送进程关闭管道的 write fd 时 接收进程从 read 返回值为 0 表示 EOF 然而
  • 在 bash 脚本中设置变量[重复]

    这个问题在这里已经有答案了 test sh 包含 A 1 B 2 我将 test sh 设置为 chmod 777 我用两个参数启动脚本 test sh first last 然后我通过输入以下内容对其进行了测试 echo FirstVar
  • 具有多个文件扩展名的查找命令

    我正在查看许多子目录 找到所有以 JPG jpg 和 png 结尾的文件 并将它们复制到一个单独的目录中 但是现在只找到 JPG 有人可以解释我做错了什么吗 find root TEST Images name png o name jpg
  • Tensorflow推荐的系统规格?

    我开始在我的 RHEL 6 5 机器上安装 Tensorflow 但事实证明 Tensorflow 需要 glibc gt 2 17 而 rhel 6 5 上默认的 glibc 是 2 12 我想知道是否有人可以帮助我了解张量流的最低 推荐
  • __NR_gettid 和 SYS_gettid 之间的区别

    我只是在寻找在 Linux 中获取唯一线程 ID 的方法 我发现的方法是将两个参数中的任何一个作为参数进行系统调用 NR gettid OR SYS gettid 有人能解释一下它们之间有何不同吗 Nothing in
  • linux + ksh + 向下舍入或向上舍入 - 浮点数

    在我的 ksh 脚本中 我只需要计算整数 有时我会得到浮点数 例如 3 49 或 4 8 等 所以我需要根据以下规则将浮点数转换为整数 示例 3 49 will be 3 2 9 will be 3 4 1 will be 4 23 51
  • 如何在Linux中诊断Python进程占用CPU

    我的 python 进程在自动化脚本中的某个时刻开始在基于 Linux 的系统 Ubuntu 上占用 CPU 我正在尝试在 GDB 中调试这个问题 我对 GDB 还很陌生 是否有任何 GDB 命令可以提供有关哪个线程正在使用大部分 cpu
  • 无法从 Windows GUI 工具连接到远程 Linux 服务器上的 MySql 数据库

    我已经在 Amazon EC2 上的 Linux 服务器上设置了 mysql 数据库 这在本地效果很好 我可以登录 linux 盒子并管理 mysql 数据库 我正在尝试将本地 GUI 客户端连接到远程 mysql 但连接失败 我更新了 e

随机推荐

  • Eclipse中配置Tomcat容器

    2019独角兽企业重金招聘Python工程师标准 gt gt gt 问题描述 独立启动tomcat后在浏览器输入http localhost 8080可以成功访问到tomcat主页 但是当在Eclipse中启动tomcat时 虽然启动成功
  • my97日期控件插件的开发与编写

    my97日期控件插件的开发与编写 扩展一个easyui 的my97 控件 function undefined function create target var state data target my97 opts state opt
  • ERROR: Could not build wheels for hdbscan, which is required to install pyproject.toml-based project

    pip安装hdbscan报错 ERROR Failed building wheel for hdbscan Failed to build hdbscan ERROR Could not build wheels for hdbscan
  • iOS开发中的网络请求

    转载自http www cocoachina com ios 20140919 9691 html 今天来说说关于iOS开发过程中的网络请求 关于网络请求的重要性我想不用多说了吧 对于移动客户端来说 网络的重要性不言而喻 常见的网络请求有同
  • N: 无法安全地用该源进行更新,所以默认禁用该源。

    解决方法 cd etc apt sources list d 进入该目录下 删除该目录下的文件 然后更换源 sudo apt get update
  • m计划-python

    题目描述 小明是个鹅卵石收藏者 从小到大他一共收藏了 n块鹅卵石 编号分别为 1 n 价值分别为 a1 a2 an 这天他乘船准备去往蓝桥王国 然而天有不测风云 小明所在的海域下起了暴雨 很快小明船上的积水越来越多 为了防止沉船 小明不得不
  • 有关 Rust 交叉编译的一些思路 (仅供参考)

    近来 使用 Rust 语言开发的应用程序渐渐融入了开发者以及普通用户的日常生活 它们不仅出现在我们常用的工作平台上 不少嵌入式设备或者云服务器上也多见它们的身影 Rust 是一种需要编译的语言 且一些 crate 仍需要 C C 的构建环境
  • 多个Makefile文件编译,Makefile多目标编译和多层次编译

    多个Makefile文件编译 Makefile多目标编译和多层次编译 README Makefile多目标编译 Makefile多层次编译 a文件夹 b文件夹 include文件夹 obj文件夹 多个Makefile文件编译 相关截图 ma
  • 论文集计算机,计算机学年论文集 计算机学年论文参考文献哪里找

    汇总了 100个 与计算机学年相关论文参考文献 为广大毕业生和职称者推荐计算机学年论文集 解决在校大学生不知个计算机学年论文参考文献哪里找等相关问题 一 计算机学年论文参考文献范文 1 试析西点军校计算机基础课程的改革 薛源 2006200
  • kudu clickhouse 添加字段删除字段

    impala 或hive 给指定kudu库中的表添加列 修改列并调整列位置 添加列 alter TABLE fact cpu supply category add columns supplier name string COMMENT
  • C语言—数据类型

    文章目录 1 基本数据类型 2 数组 字符数组和字符串 2 1 数组 2 2 字符数组与字符串 3 枚举类型 4 结构体和共用体 4 1 结构体 4 2 共用体 5 拓展 5 1 结构体内存分配 5 1 1 以结构体中占字节数最大的数据类型
  • IDEA和GIT关于文件中LF和CRLF问题

    问题描述 项目软件安装shell脚本上git仓库管理 但拉取后 上linux运行报错 问题思考 根据描述信息可以查看到 r字样 初步判别为换行符导致 1 将脚本文件移动至notepad 中 通过视图 gt 显示符号 gt 显示所有符号 一顿
  • 【Leetcode】111. 二叉树的最小深度

    题目描述 题解 递归遍历 记录深度 然后贪心地去更新结果 取min 考虑到这里还不够 需要加一层叶节点的判断 必须当前节点是叶子结点才能够做res的更新 否则可能会碰到这种情况 根结点左边没有子树 根结点右边有子树 结果递归下去发现深度是1
  • 轻量级网络:ResNeXt

    目录 insight Method Template Revisiting Simple Neurons Aggregated Transformations Model Capacity Experiments Experiments o
  • NVIDIA TensorRT简介

    一 NVIDIA TensorRT简介 二 NVIDIA TensorRT下载 根据自己硬件配置下载对应版本即可 本文以8 4 1为例 网址 https developer nvidia com nvidia tensorrt downlo
  • 分享一组开关按钮

    先看效果 再看代码
  • 网址备份

    1 搜索网站 http www google com 全球最强大的搜索网站 在语言学习中 它的功能至少包括 搜索新词可用之语境 确认某种搭配或用法是否准确 通过同时输入中文及 English 寻找可能存在的双语介绍 查询文学作品译本 了解某
  • Qt下QString与int 之间相互转换

    QString与int 之前相互转换 1 QString 转int QString str 100 int tmp str toInt 2 int 转QString int tmp 100 QString str QString numbe
  • python爬虫14:总结

    python爬虫14 总结 前言 python实现网络爬虫非常简单 只需要掌握一定的基础知识和一定的库使用技巧即可 本系列目标旨在梳理相关知识点 方便以后复习 申明 本系列所涉及的代码仅用于个人研究与讨论 并不会对网站产生不好影响 目录结构
  • 记linux内核处理bootargs到内核并加载模块时传入参数(module_param_named()等)

    昨晚 一网友问我如何把LCD反转一下输出 顿时不会 只会去看之前的dm3730的linux2 6 32的内核 偶然发现直接设置bootargs的参数到内核也许就可以啦 Linux以内核模块为核心 自动编译如系统后 所以的类似init cal