-------------------------------------------
本文系作者原创, 欢迎大家转载!
转载请注明出处:netwalker.blog.chinaunix.net
-------------------------------------------

内核在某些应用中,为了实现某种机制,比如分页,或者提高访问效率需要保证数据或者指针地址对齐到某个特定的整数值,比如连接代码脚本。这个值必须是2N。数据对齐,可以看做向上圆整的一种运算。

  1. include/linux/kernel.h
  2. #define ALIGN(x, a) __ALIGN_MASK(x, (typeof(x))(a) - 1)
  3. #define __ALIGN_MASK(x, mask) (((x) + (mask))&~(mask))
  4. #define PTR_ALIGN(p, a) ((typeof(p))ALIGN((unsigned long)(p), (a)))
  5. #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宏用来判断当前值是否对齐与指定的值。内核中的分页对齐宏定义如下:

  1. arch/arm/include/asm/page.h
  2. /* PAGE_SHIFT determines the page size */
  3. #define PAGE_SHIFT 12
  4. #define PAGE_SIZE (1UL << PAGE_SHIFT)
  5. include/linux/mm.h
  6. /* to align the pointer to the (next) page boundary */
  7. #define PAGE_ALIGN(addr) ALIGN(addr, PAGE_SIZE)

PAGE_SIZE定义在体系架构相关的代码中,通常为4K。内核中提供的特性功能的对齐宏均是对ALIGN的扩展。下面提供一个代码示例,并给出结果:

  1. #include <stdio.h>
  2. ......
  3. int main()
  4. {
  5. int a = 0 ,i = 0;
  6. int *p = &a;
  7. for(; i < 6; i++)
  8. printf("ALIGN(%d, 4): %x\n", i, ALIGN(i, 4));
  9. printf("p:%p, PTR_ALIGN(p, 8): %p\n", p, PTR_ALIGN(p, 8));
  10. printf("IS_ALIGNED(7, 8): %d, IS_ALIGNED(16, 8): %d\n", IS_ALIGNED(7, 8), IS_ALIGNED(16, 8));
  11. return 0;
  12. }

对齐宏测试结果:

    1. ALIGN(0, 4): 0
    2. ALIGN(1, 4): 4
    3. ......
    4. ALIGN(4, 4): 4
    5. ALIGN(5, 4): 8
    6. p:0xbf96c01c, PTR_ALIGN(p, 8): 0xbf96c020
    7. 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解析.的更多相关文章

  1. linux device tree源代码解析--转

    //Based on Linux v3.14 source code Linux设备树机制(Device Tree) 一.描述 ARM Device Tree起源于OpenFirmware (OF), ...

  2. I.MX6 Linux U-boot 环境变量解析

    /********************************************************************************** * I.MX6 Linux U- ...

  3. linux网络配置完全解析

    概述:熟悉了windows下面的网络配置,对linux下的网络配置缺未必了解透彻.熟练掌握linux下的网络配置原理,能帮助我们更容易掌握网络传输原理:同时具备一些网络连接不通对应问题的排查能力.文本 ...

  4. linux ssh使用深度解析(key登录详解)

    linux ssh使用深度解析(key登录详解) SSH全称Secure SHell,顾名思义就是非常安全的shell的意思,SSH协议是IETF(Internet Engineering Task ...

  5. LINUX命令LS -AL 解析

    LINUX命令LS -AL 解析 linux命令ls -al 解析 ls是“list”的意思,与早期dos的命令dir功能类似.参数-al则表示列出所有的文件,包括隐藏文件,就是文件前面第一个字符为. ...

  6. Linux的DNS反向解析部署

    下面的部署是在Linux的DNS正向解析示例上进行修改的. 如果有什么问题或者错误,可以访问上篇帖子 下面开始有关DNS的服务部署.<DNS反向解析> 工具:虚拟机 centos7 配置: ...

  7. 【Linux开发】Linux V4L2驱动架构解析与开发导引

    Linux V4L2驱动架构解析与开发导引 Andrew按:众所周知,linux中可以采用灵活的多层次的驱动架构来对接口进行统一与抽象,最低层次的驱动总是直接面向硬件的,而最高层次的驱动在linux中 ...

  8. linux文件权限全面解析

    目录 linux文件权限全面解析 一:linux文件的权限有哪些? 1,权限分为3个部分 2,权限位 3,每一个权限拥有一个数字编号 4,在添加权限的时候,可以将权限加起来 5,linux添加权限命令 ...

  9. Arm Linux系统调用流程详细解析

    Linux系统通过向内核发出系统调用(system call)实现了用户态进程和硬件设备之间的大部分接口. 系统调用是操作系统提供的服务,用户程序通过各种系统调用,来引用内核提供的各种服务,系统调用的 ...

随机推荐

  1. TTTTTTTTTTTTT CF Good Bye 2015 C- New Year and Domino(CF611C) 二维前缀

    题目 题意:给你一个n*m由.和#组成的矩阵,.代表可以放,#代表不可以,问在左上角(px,py)到(右下角qx,qy)这样的一个矩阵中,放下一个长度为2宽度为1的牌有多少种放法: #include ...

  2. LA 3263 好看的一笔画 欧拉几何+计算几何模板

    题意:训练指南260 #include <cstdio> #include <cstring> #include <algorithm> #include < ...

  3. HGOI20190812 省常中互测5

    Task 1 辩论 有N 个参加辩论的候选人,每个人对这两个议题都有明确的态度,支持或反对.作为组织者,小D 认真研究了每个候选人,并给每个人评估了一个非负的活跃度,他想让活跃度之和尽可能大.选出的候 ...

  4. Net中Attribute特性的高级使用及自定义验证实现

    好久没写博客了,今天在百忙之中抽空来写篇文章,记录一下最近深入学习Attribute特性的笔记及心得.~~ 一.什么是特性? 特性(Attribute)是用于在运行时传递程序中各种元素(比如类.方法. ...

  5. gulp自动化构建工具安装使用(1)

    我用的是windows,所以以下操作针对于windows用户,其他系统有不一样的地方请自行查阅资料更正. 好了,废话少说,反正也就是随手捣腾.下雨了,天晴了,我们开始搞gulp了 安装:gulp是个构 ...

  6. Alpha发布--美工+文案

    此作业对应要求参见:https://edu.cnblogs.com/campus/nenu/2019fall/homework/8677 一.美工: 1.产品logo 2.原型页面展示 2.1 进入萌 ...

  7. Ajax学习--理解 Ajax 及其工作原理

    Ajax 是 Asynchronous JavaScript and XML(以及 DHTML 等)的缩写. 下面是 Ajax 应用程序所用到的基本技术:• HTML 用于建立 Web 表单并确定应用 ...

  8. axios的数据请求方式及跨域

    express 的三大功能:静态资源.路由.模板引擎 app.use(express.static('www')); 只要是创建这个静态的目录,这个 www 的静态目录里面的文件就可以被访问 数据的请 ...

  9. leetcode-easy-others-118 Pascal's Triangle

    mycode   16.47% class Solution(object): def generate(self, numRows): """ :type numRow ...

  10. JavaEE-实验一 Java常用工具类编程

    该博客仅专为我的小伙伴提供参考而附加,没空加上代码具体解析,望各位谅解 1.  使用类String类的分割split 将字符串  “Solutions to selected exercises ca ...