zoukankan      html  css  js  c++  java
  • linux内核源码中常见宏标志tag

    http://www.examda.com/linux/fudao/20100330/094653772.html

      这些宏包括 __init、__initdata、__initfunc()、asmlinkage、ENTRY()、FASTCALL()等等。它们的定义主要位于 Includelinuxlinkage.h和 includeasm-i386Init.h以及其他一些.h文件中。

      1) __init位置:includeasm-i386Init.h

      定义:#define __init __attribute__ ((__section__ (".text.init")))

      注释:这个标志符和函数声明放在一起,表示gcc编译器在编译的时候需要把这个函数放.text.init section中,而这个section在内核完成初始化之后,会被释放掉。

      举例:asmlinkage void __init start_kernel(void){...}

      2) __initdata

      位置:includeasm-i386Init.h

      定义:#define __initdata __attribute__ ((__section__ (".data.init")))

      注释:这个标志符和变量声明放在一起,表示gcc编译器在编译的时候需要把这个变量放在.data.init section中,而这个section在内核完成初始化之后,会被释放掉。

      举例:static struct kernel_param raw_params[] __initdata = {....}

      3) __initfunc()

      位置:includeasm-i386Init.h

      定义: #define __initfunc(__arginit)

      __arginit __init;

      __arginit

      注释: 这个宏用来定义一个 __init 函数。

      举例: __initfunc(void mem_init(unsigned long start_mem, unsigned long e

      nd_mem)) {....}

      4) asmlinkage

      位置:Includelinuxlinkage.h

      定义:#define asmlinkage CPP_ASMLINKAGE __attribute__((regparm(0)))

      注释:这个标志符和函数声明放在一起,告诉gcc编译器该函数不需要通过任何寄存器来传递参数,参数只是通过堆栈来传递。


      举例:asmlinkage void __init start_kernel(void){...}

      5) ENTRY()

      位置:Includelinuxlinkage.h

      定义: #define ENTRY(name)

      .globl SYMBOL_NAME(name);

      ALIGN;

      SYMBOL_NAME_LABEL(name)

      注释: 将name声明为全局,对齐,并定义为标号。

      举例: ENTRY(swapper_pg_dir)

      .long 0x00102007

      .fill __USER_PGD_PTRS-1,4,0

      /* default: 767 entries */

      .long 0x00102007

      /* default: 255 entries */

      .fill __KERNEL_PGD_PTRS-1,4,0

      等价于

      .globl swapper_pg_dir

      .align 16,0x90

      /* if i486 */

      swapper_pg_dir:

      .long 0x00102007

      .fill __USER_PGD_PTRS-1,4,0

      /* default: 767 entries */

      .long 0x00102007

      /* default: 255 entries */

      .fill __KERNEL_PGD_PTRS-1,4,0

      6) FASTCALL()

      位置:Includelinuxkernel.h

      定义:#define FASTCALL(x) x __attribute__((regparm(3)))

      注释:这个标志符和函数声明放在一起,带regparm(3)的属性声明告诉gcc编译器这个函数可以通过寄存器传递多达3个的参数,这3个寄存器依次为EAX、EDX 和 ECX。更多的参数才通过堆栈传递。这样可以减少一些入栈出栈操作,因此调用比较快。

      举例:extern void FASTCALL(__switch_to(struct task_struct *prev, struct t

      ask_struct *next));

      这个例子中,prev将通过eax,next通过edx传递

      7)_sched 存在于kernel/sched.h文件中

      Attach to any functions which should be ignored in wchan output

      #define _sched _attribute_ ((_section_(".sched.text")))

      Reference:



    http://blog.chinaunix.net/u2/60011/showart_1010485.html

    __init和__initdata

    Linux在arch/$(ARCH)/kernel/vmlinux.lds中定义了.init段。__init和__initdata属性的数据都在这个段中,当内核启动完毕后,这个段中的内存会被释放掉供其他使用。

    __init和__initdata宏定义如下:
    /* include/linux/init.c */
    #define __init  __attribute__ ((__section__ (".init.text")))
    #define __initdata __attribute__ ((__section__ (".init.data")))

    vmlinux.lds内容如下:
    /* arch/arm/kernel/vmlinux.lds */
    OUTPUT_ARCH(arm)
    ENTRY(stext)
    jiffies = jiffies_64;
    SECTIONS
    {
    . = (0xc0000000) + 0x00008000;
    .init : { /* Init code aand data  */
      _stext = .;
       _sinittext = .;
       *(.init.text)
       _einittext = .;
      __proc_info_begin = .;
       *(.proc.info.init)
      __proc_info_end = .;
      __arch_info_begin = .;
       *(.arch.info.init)
      __arch_info_end = .;
      __tagtable_begin = .;
       *(.taglist.init)
      __tagtable_end = .;
      . = ALIGN(16);
      __setup_start = .;
       *(.init.setup)
      __setup_end = .;
      __early_begin = .;
       *(.early_param.init)
      __early_end = .;
      __initcall_start = .;
       *(.initcall1.init)
       *(.initcall2.init)
       *(.initcall3.init)
       *(.initcall4.init)
       *(.initcall5.init)
       *(.initcall6.init)
       *(.initcall7.init)
      __initcall_end = .;
      __con_initcall_start = .;
       *(.con_initcall.init)
      __con_initcall_end = .;
      __security_initcall_start = .;
       *(.security_initcall.init)
      __security_initcall_end = .;
      . = ALIGN(32);
      __initramfs_start = .;
       usr/built-in.o(.init.ramfs)
      __initramfs_end = .;
      . = ALIGN(64);
      __per_cpu_start = .;
       *(.data.percpu)
      __per_cpu_end = .;
      __init_begin = _stext;
      *(.init.data)
      . = ALIGN(4096);
      __init_end = .;
    }
    ……
    }
    可以发现__init对应的section(.init.text)和__initdata对应的section(.init.data)都在.init 段中。同样,这里定义的其他一些section也都会在使用完后被释放,如.init.setup,.initcall1.init等。
    释放memory的大小会在系统启动过程中打印出来:
    eth0: link up
    IP-Config: Complete:
          device=eth0, addr=192.168.167.15, mask=255.255.255.0, gw=192.168.167.254,
         host=192.168.167.15, domain=, nis-domain=(none),
         bootserver=192.168.167.170, rootserver=192.168.167.170, rootpath=
    Looking up port of RPC 100003/2 on 192.168.167.170
    Looking up port of RPC 100005/1 on 192.168.167.170
    VFS: Mounted root (nfs filesystem).
    Freeing init memory: 128K
    <script>window._bd_share_config={"common":{"bdSnsKey":{},"bdText":"","bdMini":"2","bdMiniList":false,"bdPic":"","bdStyle":"0","bdSize":"16"},"share":{}};with(document)0[(getElementsByTagName('head')[0]||body).appendChild(createElement('script')).src='http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion='+~(-new Date()/36e5)];</script>
    阅读(651) | 评论(0) | 转发(1) |
    给主人留下些什么吧!~~
    评论热议
  • 相关阅读:
    Daily Scrum 10.31
    Daily Scrum 10.30
    Daily Scrum 10.29
    Daily Scrum 10.28
    扩展设置
    安装
    james+javamail入门
    解决ZF2_PATH environment
    Apache Httpd Server 2.2升级2.4
    缓存,spring
  • 原文地址:https://www.cnblogs.com/ztguang/p/12647789.html
Copyright © 2011-2022 走看看