Linux Kernel Stuffs

tags: OS

Atomic

  1. atomic_read、atomic_set、atomic_add、atomic_sub
  2. WRITE_ONCE(x,val)
tatic __always_inline void __write_once_size(volatile void *p, void *res, int size)
{
        //簡單變數之Atomic由MESI協定來確保
        switch (size) {
        case 1: *(volatile __u8 *)p = *(__u8 *)res; break;
        case 2: *(volatile __u16 *)p = *(__u16 *)res; break;
        case 4: *(volatile __u32 *)p = *(__u32 *)res; break;
        case 8: *(volatile __u64 *)p = *(__u64 *)res; break;
        /*複雜變數之Atomic由barrier();來確保*/
        default:
                barrier();
                __builtin_memcpy((void *)p, (const void *)res, size);
                barrier();
        }
}
  1. 常見誤會:
  • ​​​​​​volatile: 他不保證Atomic,只保證程式碼的執行順序不會因為compiler優化而改變順序(對Programmer來說比較好debug)
    

Module Init

  1. 平常寫程式的進入點是main,kernel的module進入點則是由module_init所定義。
    module_init(我的起始函數)
  2. 在built-in module中(不含loadable module),還有不同先後順序的initcall可以選擇,當你有多個modules,而他們的初始化必須符合先後關係時可以使用:
//由此可知module_init事實上是一個順位6的初始函數
#define module_init(x)  __initcall(x);
#define __initcall(fn) device_initcall(fn)


//其他初始函數可以參考如下,數字越小的會越先被執行:
#define pure_initcall(fn)		__define_initcall(fn, 0)

#define core_initcall(fn)		__define_initcall(fn, 1)
#define core_initcall_sync(fn)		__define_initcall(fn, 1s)
#define postcore_initcall(fn)		__define_initcall(fn, 2)
#define postcore_initcall_sync(fn)	__define_initcall(fn, 2s)
#define arch_initcall(fn)		__define_initcall(fn, 3)
#define arch_initcall_sync(fn)		__define_initcall(fn, 3s)
#define subsys_initcall(fn)		__define_initcall(fn, 4)
#define subsys_initcall_sync(fn)	__define_initcall(fn, 4s)
#define fs_initcall(fn)			__define_initcall(fn, 5)
#define fs_initcall_sync(fn)		__define_initcall(fn, 5s)
#define rootfs_initcall(fn)		__define_initcall(fn, rootfs)
#define device_initcall(fn)		__define_initcall(fn, 6)
#define device_initcall_sync(fn)	__define_initcall(fn, 6s)
#define late_initcall(fn)		__define_initcall(fn, 7)
#define late_initcall_sync(fn)		__define_initcall(fn, 7s)