linux常用巨集解析

2021-08-30 15:55:28 字數 4452 閱讀 8055

前言

linux核心原始碼裡有很多巨集,為了能更好地理解核心和驅動原始碼,有必要對一些常用巨集做乙個梳理和解析,在此專門做一篇博文來幫助學習,並在以後的學習中逐步新增和完善。

正文1._ior(type,nr,size)

用法:

#define gpio_ioc_magic					'g'

#define ioctl_gpio_getvalue _ior(gpio_ioc_magic, 3, int)

巨集解析:

#define _ior(type,nr,size) _ioc(_ioc_read,(type),(nr),(_ioc_typecheck(size)))

->>

#define _ioc(dir,type,nr,size) \

(((dir) << _ioc_dirshift) | \

((type) << _ioc_typeshift) |

((nr) << _ioc_nrshift) |

((size) << _ioc_sizeshift))

#ifndef _ioc_read

#define _ioc_read 2u

#endif

->>

#define _ioc(dir,type,nr,size) \

(((dir) << 30) | \

((type) << 8) |

((nr) << 0) |

((size) << 16))

由上分析可知_ioc巨集把四個引數拼成了乙個32位的數字,該數字的組成如下

所以#define ioctl_gpio_getvalue _ior(gpio_ioc_magic, 3, int)語句設定ioctl_gpio_getvalue的值為

定義:

#define minorbits	20

#define minormask ((1u << minorbits) - 1)

#define major(dev) ((unsigned int) ((dev) >> minorbits))

#define minor(dev) ((unsigned int) ((dev) & minormask))

#define mkdev(ma,mi) (((ma) << minorbits) | (mi))

所以dev裝置號的結構

用法:

static define_spinlock(gpio_lock);
巨集解析:

#define __arch_spin_lock_unlocked	

#define __raw_spin_lock_initializer(lockname) \

#define __spin_lock_initializer(lockname) \

}#define __spin_lock_unlocked(lockname) \

(spinlock_t ) __spin_lock_initializer(lockname)

#define define_spinlock(x) spinlock_t x = __spin_lock_unlocked(x)

static define_spinlock(gpio_lock);->>

spinlock_t gpio_lock=(spinlock_t )}}}

該巨集定義乙個自旋鎖,並初始化自旋鎖不可用

4.list_head(name)

用法:

static list_head(omap_hwmod_list);
定義:

struct list_head ;

#define list_head_init(name)

#define list_head(name) \

struct list_head name = list_head_init(name)

所以static list_head(omap_hwmod_list);等效於

struct list_head omap_hwmod_list = ;

5.syscall_define3

用法:

syscall_define3(init_module, void __user *, umod,

unsigned long, len, const char __user *, uargs)

定義:

#define __sc_decl1(t1, a1)	t1 a1

#define __sc_decl2(t2, a2, ...) t2 a2, __sc_decl1(__va_args__)

#define __sc_decl3(t3, a3, ...) t3 a3, __sc_decl2(__va_args__)

#define __sc_decl4(t4, a4, ...) t4 a4, __sc_decl3(__va_args__)

#define __sc_decl5(t5, a5, ...) t5 a5, __sc_decl4(__va_args__)

#define __sc_decl6(t6, a6, ...) t6 a6, __sc_decl5(__va_args__)

#define syscall_define3(name, ...) syscall_definex(3, _##name, __va_args__)

#define syscall_definex(x, sname, ...) \

__syscall_definex(x, sname, __va_args__)

#define __syscall_definex(x, name, ...) \

asmlinkage long sys##name(__sc_decl##x(__va_args__))

所以syscall_define3(init_module, void __user *, umod,

unsigned long, len, const char __user *, uargs);等效於

asmlinkage long sys_init_module(void __user * umod,

unsigned long len, const char __user * uargs))

6.asmlinkage

用法:

asmlinkage long sys_init_module(void __user * umod,

unsigned long len, const char __user * uargs))

定義:

#ifdef __cplusplus

#define cpp_asmlinkage extern "c"

#else

#define cpp_asmlinkage

#endif

#ifndef asmlinkage

#define asmlinkage cpp_asmlinkage

#endif

所以asmlinkage long sys_init_module(void __user * umod,

unsigned long len, const char __user * uargs))

等效於extern 「c」 long sys_init_module(void __user * umod,

unsigned long len, const char __user * uargs))

或long sys_init_module(void __user * umod,

unsigned long len, const char __user * uargs))

使用extern "c"關鍵字,它的作用是告訴編譯器這段**是以c編譯器來編譯,它的底層函式簽名是就是函式名稱,而不是c++那樣的函式名+引數,不支援過載的

關於extern "c"的用法參考

c和c++混合編譯

Linux setup巨集解析

setup 這條巨集在linux kernel 中使用最多的地方就是定義處理kernel的啟動引數的函式及資料結構,巨集定義如下 define setup str,fn setup param str,fn,fn,0 define setup param str,unique id,fn,early...

DECLARE HANDLE巨集解析

在mfc原始碼中,經常看到這樣的語句 declare handle hdrvr declare handle hdtrcv 檢視declare handle定義如下 ifdef strict typedef void handle define declare handle name struct ...

linux常用名稱解析

shell 殼,區別於核 指提供使用者使用介面的軟體 命令解析器 類似doc中的cmd.exe red hat package manager rpm軟體包管理器 yum yellow dog updater,modified 極好的,妙的 黃狗更新 安裝軟體 yum install 刪除軟體 yu...