在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