linux中__weak關鍵字

在linux的驅動代碼中常常能夠看到__weak去修飾一個函數或者變量,大可能是用來修飾函數。它的做用有兩個:html

1.weak 顧名思義是「弱」的意思,因此若是函數名稱前面加上__weak 修飾符,咱們通常稱這個函數爲「弱函數」。加上了__weak 修飾符的函數,用戶能夠在用戶文件中從新定義一個同名函數,最終編譯器編譯的時候,會選擇用戶定義的函數,若是用戶沒有從新定義這個函數,那麼編譯器就會執行__weak 聲明的函數,而且編譯器不會報錯。linux

2.__weak 在回調函數的時候常常用到。這樣的好處是,系統默認定義了一個空的回調函數,保證編譯器不會報錯。同時,若是用戶本身要定義用戶回調函數,那麼只須要從新定義便可,不須要考慮函數重複定義的問題,使用很是方便ubuntu

在linux/init/main.c中有函數smp_setup_processor_idide

void __init __weak smp_setup_processor_id(void)
{
}

2.6.30內核中ARM結構沒有額外定義smp_setup_processor_id(),因此ARM結構不執行任何操做。函數

n-ubuntu05@nubuntu05:linux-2.6.30.4$ grep -rn smp_setup_processor_id ./*
./arch/sparc/kernel/smp_64.c:1182:void __init smp_setup_processor_id(void)
./include/linux/smp.h:188:void smp_setup_processor_id(void);
./init/main.c:528:void __init __weak smp_setup_processor_id(void)
./init/main.c:541:  smp_setup_processor_id();

v4.9內核在./arch/arm/kernel/setup.c中定義了smp_setup_processor_id()ui

584 void __init smp_setup_processor_id(void)                                        
 585 {                                                                               
 586         int i;                                                                  
 587         u32 mpidr = is_smp() ? read_cpuid_mpidr() & MPIDR_HWID_BITMASK : 0;     
 588         u32 cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0);                               
 589                                                                                 
 590         cpu_logical_map(0) = cpu;                                               
 591         for (i = 1; i < nr_cpu_ids; ++i)                                        
 592                 cpu_logical_map(i) = i == cpu ? 0 : i;                          
 593                                                                                 
 594         /*                                                                      
 595          * clear __my_cpu_offset on boot CPU to avoid hang caused by            
 596          * using percpu variable early, for example, lockdep will               
 597          * access percpu variable inside lock_release                           
 598          */                                                                     
 599         set_my_cpu_offset(0);                                                   
 600                                                                                 
 601         pr_info("Booting Linux on physical CPU 0x%x\n", mpidr);                 
 602 }

因爲linux/init/main.c中定義的函數有__weak屬性,因此ARM使用的是./arch/arm/kernel/setup.c中定義的smp_setup_processor_idspa

v4.9其餘結構中相關定義:code

n-ubuntu05@nubuntu05:v4.9$ grep -rn smp_setup_processor_id ./*
./arch/arm64/kernel/setup.c:95:void __init smp_setup_processor_id(void)
./arch/s390/kernel/smp.c:930:void __init smp_setup_processor_id(void)
./arch/sparc/kernel/smp_64.c:1238:void __init smp_setup_processor_id(void)
./arch/arm/kernel/devtree.c:147:         * to override the map created in smp_setup_processor_id().
./arch/arm/kernel/devtree.c:185:     * logical map created in smp_setup_processor_id() can be overridden
./arch/arm/kernel/setup.c:584:void __init smp_setup_processor_id(void)
./include/linux/smp.h:197:void smp_setup_processor_id(void);
./init/main.c:452:void __init __weak smp_setup_processor_id(void)
./init/main.c:487:  smp_setup_processor_id();

[參考] linux中__weak關鍵字的做用解析
https://www.2cto.com/kf/201810/784218.htmlhtm

相關文章
相關標籤/搜索