Linux内核中存储屏幕尺寸全局变量及开机全程复用方案咨询
针对Linux内核屏幕尺寸全局存储的实现方案
一、全局变量的合适声明位置
- 板级专属头文件:如果你的板卡代码属于特定BSP(比如
arch/arm/mach-xxx/board-xxx.h),可以在这里声明全局变量,示例:
然后在对应的板实现文件(extern struct screen_size g_screen_size;board-xxx.c)中定义并完成初始化:
其他需要调用的模块只需包含该头文件,即可直接使用struct screen_size { int width; int height; } g_screen_size; static void __init read_screen_size(void) { // 读取GPIO输入线的逻辑,填充尺寸数据 g_screen_size.width = gpio_get_value(GPIO_SCREEN_W_PIN); g_screen_size.height = gpio_get_value(GPIO_SCREEN_H_PIN); } core_initcall(read_screen_size); // 确保在开机早期执行g_screen_size。 - 通用内核头文件(谨慎使用):比如
include/linux/screen_info.h,但这种方式会污染全局命名空间,仅适合多板卡通用的场景,否则优先选择BSP专属头文件。
二、更优实现方案
1. 基于设备树的动态匹配
如果屏幕尺寸可通过GPIO状态匹配不同设备树节点,无需直接操作GPIO,开机阶段解析设备树即可获取尺寸:
- 设备树中定义不同屏幕节点:
screen_4inch: screen@0 { compatible = "vendor,panel"; width = <480>; height = <320>; detect-gpios = <&gpio 10 GPIO_ACTIVE_HIGH>, <&gpio 11 GPIO_ACTIVE_LOW>; }; screen_7inch: screen@1 { compatible = "vendor,panel"; width = <1024>; height = <600>; detect-gpios = <&gpio 10 GPIO_ACTIVE_LOW>, <&gpio 11 GPIO_ACTIVE_HIGH>; }; - 内核中编写匹配逻辑:根据GPIO状态筛选对应节点,读取width和height字段并存储,后续模块可直接从选中节点读取,或存入全局变量。
2. 暴露sysfs节点(多场景复用)
如果需要开机后内核模块或用户空间也能获取尺寸,可在初始化时读取数据并创建sysfs节点:
static struct screen_size g_screen_size; static ssize_t width_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { return sprintf(buf, "%d\n", g_screen_size.width); } static ssize_t height_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { return sprintf(buf, "%d\n", g_screen_size.height); } static struct kobj_attribute width_attr = __ATTR(width, 0444, width_show, NULL); static struct kobj_attribute height_attr = __ATTR(height, 0444, height_show, NULL); static struct attribute *screen_attrs[] = { &width_attr.attr, &height_attr.attr, NULL, }; static struct attribute_group screen_attr_group = { .attrs = screen_attrs, }; static struct kobject *screen_kobj; static int __init screen_info_init(void) { // 先读取屏幕尺寸 g_screen_size.width = gpio_get_value(GPIO_SCREEN_W_PIN); g_screen_size.height = gpio_get_value(GPIO_SCREEN_H_PIN); screen_kobj = kobject_create_and_add("screen_info", kernel_kobj); if (!screen_kobj) return -ENOMEM; return sysfs_create_group(screen_kobj, &screen_attr_group); } core_initcall(screen_info_init);
后续可通过/sys/kernel/screen_info/width和height路径,让内核模块或用户空间直接获取尺寸,避免重复读取GPIO。
3. 复用内核全局环境结构
部分内核存在专门存储板级环境信息的全局结构(比如struct system_device_environment),可以扩展该结构加入屏幕尺寸字段,这种方式更符合内核代码规范,避免新增独立全局变量。
注意事项
- 初始化时机:确保读取GPIO的代码在GPIO驱动初始化完成后执行,
core_initcall优先级高于多数设备驱动,适合该场景;若GPIO初始化更晚,可改用postcore_initcall。 - 变量访问安全:如果仅在BSP内部使用,建议将全局变量设为
static,通过函数接口暴露,示例:
头文件声明该函数,比直接暴露全局变量更安全,防止意外修改。static struct screen_size g_screen_size; struct screen_size get_screen_size(void) { return g_screen_size; }
内容的提问来源于stack exchange,提问作者Ravi A
相关产品推荐
相关产品推荐

