linux tricks 之 ALIGN解析.
内核在某些应用中,为了实现某种机制,比如分页,或者提高访问效率需要保证数据或者指针地址对齐到某个特定的整数值,比如连接代码脚本。这个值必须是2N。数据对齐,可以看做向上圆整的一种运算。
- include/linux/kernel.h
- #define ALIGN(x, a) __ALIGN_MASK(x, (typeof(x))(a) - 1)
- #define __ALIGN_MASK(x, mask) (((x) + (mask))&~(mask))
- #define PTR_ALIGN(p, a) ((typeof(p))ALIGN((unsigned long)(p), (a)))
- #define IS_ALIGNED(x, a) (((x) & ((typeof(x))(a) - 1)) == 0)
内核提供了两个用来对齐的宏ALIGN和PTR_ALIGN,一个实现数据对齐,而另一个实现指针的对齐。它们实现的核心都是__ALIGN_MASK,其中mask参数为低N位全为1,其余位全为0的掩码,它从圆整目标值2N - 1得到。__ALIGN_MASK得到对齐值,对于数据来说直接返回即可,而对于指针则需要进行强制转换。IS_ALIGNED宏用来判断当前值是否对齐与指定的值。内核中的分页对齐宏定义如下:
- arch/arm/include/asm/page.h
- /* PAGE_SHIFT determines the page size */
- #define PAGE_SHIFT 12
- #define PAGE_SIZE (1UL << PAGE_SHIFT)
- include/linux/mm.h
- /* to align the pointer to the (next) page boundary */
- #define PAGE_ALIGN(addr) ALIGN(addr, PAGE_SIZE)
PAGE_SIZE定义在体系架构相关的代码中,通常为4K。内核中提供的特性功能的对齐宏均是对ALIGN的扩展。下面提供一个代码示例,并给出结果:
- #include <stdio.h>
- ......
- int main()
- {
- int a = 0 ,i = 0;
- int *p = &a;
- for(; i < 6; i++)
- printf("ALIGN(%d, 4): %x\n", i, ALIGN(i, 4));
- printf("p:%p, PTR_ALIGN(p, 8): %p\n", p, PTR_ALIGN(p, 8));
- printf("IS_ALIGNED(7, 8): %d, IS_ALIGNED(16, 8): %d\n", IS_ALIGNED(7, 8), IS_ALIGNED(16, 8));
- return 0;
- }
对齐宏测试结果:
- ALIGN(0, 4): 0
- ALIGN(1, 4): 4
- ......
- ALIGN(4, 4): 4
- ALIGN(5, 4): 8
- p:0xbf96c01c, PTR_ALIGN(p, 8): 0xbf96c020
- IS_ALIGNED(7, 8): 0, IS_ALIGNED(16, 8): 1
1. 在linux内核中,经产会看到对齐ALIGN的调用,常见的如内存管理中page对齐,net_device中私有数据的获取等,本文是对ALIGN宏的一个简单分析。
1.1. 内核调用:在e100.c中,网卡irq处理函数 irqreturn_t e100_intr(int irq, void *dev_id) 调用netdev_priv(netdev)处理函数获取net_device的私有数据。
2105 static irqreturn_t e100_intr(int irq, void *dev_id)
2106 {
2107 struct net_device *netdev = dev_id;
2108 struct nic *nic = netdev_priv(netdev);
netdev_priv函数和ALIGN宏定义分别如下:
991 static inline void *netdev_priv(const struct net_device *dev)
992 {
993 return (char *)dev + ALIGN(sizeof(struct net_device), NETDEV_ALIGN);
994 }
41 #define ALIGN(x,a) __ALIGN_MASK(x,(typeof(x))(a)-1)
42 #define __ALIGN_MASK(x,mask) (((x)+(mask))&~(mask))
1.2 用法解析:
先说ALIGN的用法,ALIGN(x,a) 是为了使x以a为边界对齐,实现原理是给x加上一个最小的数,使x以a为边界对齐。举个例子,a = 8, x=0, ALIGN(x,a) 运算结果为0; a = 8, x = 3, 运算结果为8; a = 8, x = 11, 运算结果为16。
1.3原理分析:
为了便于分析,假设所用到的数字都是16bit,typeof是类型定义分析的时候可以忽略,假设为了使x以8位界对齐。
a = 8, 则上面mask= 7,那么 __ALIGN_MASK(x,mask) (((x)+(mask))&~(mask)) 用二进制表示为:
X xxxx xxxx
MASK + 0000 0111
进一步,以上公式可以分为x低 三位全为0(加mask后无进位)和低三位不全为0(加mask后有进位)两种情况。
1.3.1. x低三位全为0(加mask无进位)
即 x = xxxx x000,这种情况下,__ALIGN_MASK(x,mask)运算结果仍为x,而x本身就为8的倍数,因此x以8为界对齐。
1.3.2 x低三位不全为0 (加mask有进位)
x + mask 可理解为给x加7使得x向第四低位进位,同时低三位清零,运算后x = xxxx x000,同样为8的倍数,因此x以8为界对齐。
linux tricks 之 ALIGN解析.的更多相关文章
- linux device tree源代码解析--转
//Based on Linux v3.14 source code Linux设备树机制(Device Tree) 一.描述 ARM Device Tree起源于OpenFirmware (OF), ...
- I.MX6 Linux U-boot 环境变量解析
/********************************************************************************** * I.MX6 Linux U- ...
- linux网络配置完全解析
概述:熟悉了windows下面的网络配置,对linux下的网络配置缺未必了解透彻.熟练掌握linux下的网络配置原理,能帮助我们更容易掌握网络传输原理:同时具备一些网络连接不通对应问题的排查能力.文本 ...
- linux ssh使用深度解析(key登录详解)
linux ssh使用深度解析(key登录详解) SSH全称Secure SHell,顾名思义就是非常安全的shell的意思,SSH协议是IETF(Internet Engineering Task ...
- LINUX命令LS -AL 解析
LINUX命令LS -AL 解析 linux命令ls -al 解析 ls是“list”的意思,与早期dos的命令dir功能类似.参数-al则表示列出所有的文件,包括隐藏文件,就是文件前面第一个字符为. ...
- Linux的DNS反向解析部署
下面的部署是在Linux的DNS正向解析示例上进行修改的. 如果有什么问题或者错误,可以访问上篇帖子 下面开始有关DNS的服务部署.<DNS反向解析> 工具:虚拟机 centos7 配置: ...
- 【Linux开发】Linux V4L2驱动架构解析与开发导引
Linux V4L2驱动架构解析与开发导引 Andrew按:众所周知,linux中可以采用灵活的多层次的驱动架构来对接口进行统一与抽象,最低层次的驱动总是直接面向硬件的,而最高层次的驱动在linux中 ...
- linux文件权限全面解析
目录 linux文件权限全面解析 一:linux文件的权限有哪些? 1,权限分为3个部分 2,权限位 3,每一个权限拥有一个数字编号 4,在添加权限的时候,可以将权限加起来 5,linux添加权限命令 ...
- Arm Linux系统调用流程详细解析
Linux系统通过向内核发出系统调用(system call)实现了用户态进程和硬件设备之间的大部分接口. 系统调用是操作系统提供的服务,用户程序通过各种系统调用,来引用内核提供的各种服务,系统调用的 ...
随机推荐
- Confluence 6 上传文件
当你上传一个文件的时候,例如上传一个图片或者文档,上传的文件将会附加到当前页面上. 你可以选择在页面中将文件显示为一个链接,一个图片或者嵌入到页面中(使用宏). 上传一个文件到页面中你需要具有空间的权 ...
- EL表达式无效问题
引起原因web.xml中: <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3// ...
- java从ldap中导出数据到ldif文件中
原创:http://www.cnblogs.com/dqcer/p/7814034.html 导入ldap.jar包,笔者已对下面两个文件测试并通过.若有疑问欢迎留言 LDAPExport.java ...
- (LeetCode)1114. 按序打印
题目来源:https://leetcode-cn.com/problems/print-in-order/ 我们提供了一个类: public class Foo { public void one( ...
- Unity3D_(网格导航)简单物体自动寻路
NavMesh(导航网络)是3D游戏世界中用于实现动态物体自动寻路的一种技术,它将游戏场景中复杂的结构组织关系简化为带有一定信息的网格,进而在这些网格的基础上通过一系列的计算来实现自动寻路. 实现Ca ...
- 【学习】mysql 时间戳与日期格式的相互转换
1.UNIX时间戳转换为日期用函数: FROM_UNIXTIME() ); 输出:2006-08-22 12:11:10 2.日期转换为UNIX时间戳用函数: UNIX_TIMESTAMP() Sel ...
- centos 系统时间设置
在我们使用CentOS系统的时候,也许时区经常会出现问题,有时候改完之后还是会出错,下面我们就来学习一种方法来改变这个状况.如果没有安装,而你使用的是 CentOS系统 那使用命令 yum insta ...
- TCP定时器 之 保活定时器
在用户进程启用了保活定时器的情况下,如果连接超过空闲时间没有数据交互,则保活定时器超时,向对端发送保活探测包,若(1)收到回复则说明对端工作正常,重置定时器等下下次达到空闲时间:(2) 收到其他回复, ...
- java期末总结
java期末总结: java语言特点:1.简洁有效 2.可移植性 3.面向对象 4.解释型 5.适合分布式计算 6.拥有较好的性能 7.健壮.防患于未然 8.具有多线程处理能力 9.具有较高的安全性 ...
- ad2014注册出现:注册 - 激活错误 (0015.111)
将安装包内的(adlmact.dll & adlmact_libFNP.dll)这两个文件取出并覆盖即可.安装包内文件具体位置:在安装包内搜索“adlmact”出现的两个文件“adlmact_ ...