Linux虚拟总线platform驱动框架之地址对齐省内存
来源:互联网 发布:无锡知原药业有限公司 编辑:程序博客网 时间:2024/05/21 12:39
文章原始出处:http://blog.csdn.net/gqb666/article/details/8351080,作者:gqb666
最近在学习Linux虚拟总线platform驱动框架,对其中为一字符串申请内存使用strlen时未加1有点疑惑,于是通过写几个demo把研究发现的心得,记录了下来,分享给大家,有理解不够准确的地方还请大家多多拍砖。
注:本文代码实例在ubuntu10.04下使用gcc-4.4.3编译测试,使用其他编译器可能会造成对齐与本文结果不致的现象,特别说明一下。
Linux内核2.6.37源码目录driver/base/platform.c下分配platform_device内存空间,实现如下:
platform_device定义:
- struct platform_device {
- const char * name;
- int id;
- struct device dev;
- u32 num_resources;
- struct resource * resource;
- const struct platform_device_id *id_entry;
- /* arch specific additions */
- struct pdev_archdata archdata;
- };
定义一个platform_device的结构体变量omap3evm_snd_device:
- static struct platform_device *omap3evm_snd_device;
为omap3evm_snd_device分配内存空间并命名为"soc-audio":
- omap3evm_snd_device = platform_device_alloc("soc-audio", -1);
platform_device_alloc定义:
- struct platform_device *platform_device_alloc(const char *name, int id)
- {
- struct platform_object *pa;
- pa = kzalloc(sizeof(struct platform_object) + strlen(name), GFP_KERNEL);
- if (pa) {
- strcpy(pa->name, name);
- pa->pdev.name = pa->name;
- pa->pdev.id = id;
- device_initialize(&pa->pdev.dev);
- pa->pdev.dev.release = platform_device_release;
- }
- return pa ? &pa->pdev : NULL;
- }
熟悉C语言的TX应该要问第5行在使用strlen时,后面为什么没有加1,也就是为什么没有用
pa = kzalloc(sizeof(struct platform_object) + strlen(name) + 1, GFP_KERNEL);
如果字符串“soc-audio”后面地址的内容可能不是'\0"(空间只有名字的位置,没有分配结束符)
时不会造成内存访问越界吗?
看一下结构体platform_object的定义:
- struct platform_object {
- struct platform_device pdev;
- char name[1];
- };
定义中的char name[1]有什么特别的呢?看下面几段代码:
仅有一个元素的char型数组情况:
- #include <stdio.h>
- struct test {
- char name[1];
- };
- int main()
- {
- printf("sizeof struct test=%d\n",sizeof(struct test));
- return 0;
- }
仅有一个元素的int型数组情况:
- #include <stdio.h>
- struct test {
- int name[1];
- };
- int main()
- {
- printf("sizeof struct test=%d\n",sizeof(struct test));
- return 0;
- }
两个元素的int型数组情况:
- #include <stdio.h>
- struct test {
- int name[2];
- };
- int main()
- {
- printf("sizeof struct test=%d\n",sizeof(struct test));
- return 0;
- }
上面3个例子很好理解:编译器再给数组分配空间时会以数组实际空间分配内存。但如果结构体包含数组和其他数据类型的情况呢?
- #include <stdio.h>
- struct test {
- char a;
- char name[1];
- };
- int main()
- {
- printf("sizeof struct test=%d\n", sizeof(struct test));
- return 0;
- }
举例来说明:
- #include <stdio.h>
- struct test {
- int a;
- char name[1];
- };
- int main()
- {
- printf("sizeof struct test=%d\n", sizeof(struct test));
- return 0;
- }
而如果定义为指针的话:
- #include <stdio.h>
- struct test {
- char a;
- char *name;
- };
- int main()
- {
- printf("sizeof struct test=%d\n", sizeof(struct test));
- return 0;
- }
pa = kzalloc(sizeof(struct platform_object) + strlen(name) + 1, GFP_KERNEL);
下面用内存分配图来形象说明使用数组与指针两种情况的内存分配图(为了作图方便将struct platform_device的空间当成4个字节,实际不然):
所以总体上内核实现方法很巧妙,不仅避免了分配置内存时使用strlen+1,而且还有3个字节的内存空间可以扩展使用,对linux内核高手来说这并不是什么难事,严格的来说内核方法巧妙地节省char *name指针所用的4字节内存空间。
Linux kernel作为一个强大成熟稳定的操作系统核心,为了做到节省系统资源,开发Linux内核的黑客大牛们将C语言的特性发挥到极致,死扣每一个字节。有太多值到我们学习的地方了!
- Linux虚拟总线platform驱动框架之地址对齐省内存
- Linux虚拟总线platform驱动框架之地址对齐省内存
- Linux虚拟总线platform设备和驱动
- Linux设备驱动--------platform虚拟总线
- linux驱动之platform总线
- linux驱动下platform总线框架
- linux platform 虚拟总线
- linux设备总线驱动模型 之 platform总线驱动
- linux设备总线驱动模型 之 platform总线驱动
- linux设备总线驱动模型 之 platform总线驱动
- Linux设备驱动模型之platform总线
- LINUX设备驱动之platform总线
- Linux设备驱动模型之platform总线
- LINUX设备驱动之platform总线
- LINUX设备驱动之platform总线
- LINUX设备驱动之platform总线
- Linux设备驱动模型之platform总线
- LINUX设备驱动之platform总线
- The C Programming Language 读书总结
- gcc -E 产生预编译后的文件
- 题目1108:堆栈的使用
- 用特化来实现多态--外部多态
- 怎样调试OpenStack Unit Test
- Linux虚拟总线platform驱动框架之地址对齐省内存
- Android资源目录assets及raw
- cookie保存user数据及cookie实现自动登录
- 网页嵌入 播放器
- ldap命令初试
- 10个职场故事,让人不得不看
- hdu1049-Climbing Worm
- Java Unsigned数据类型解决方案
- 学习小记--android静态注册广播接收器之惑--6.6