of_find_property追踪 OF

本文详细解析了Linux内核中的of_find_property函数,该函数用于查找设备节点的属性。从函数调用开始,经过spinlock的中断保存和恢复,到字符串比较和遍历设备节点属性链表,深入剖析了内核中锁机制和设备树操作的关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

prop = of_find_property(np, name, NULL);

跳转:base.c(driver/of/)

struct property *of_find_property(const struct device_node *np,
 const char *name,
 int *lenp)
{
struct property *pp;
unsigned long flags;


raw_spin_lock_irqsave(&devtree_lock, flags); // 1111111111111
pp = __of_find_property(np, name, lenp); // 22222222222222
raw_spin_unlock_irqrestore(&devtree_lock, flags); // 33333333333

return pp;
}
EXPORT_SYMBOL(of_find_property);

1111111111111111111111111111111111111111111111111111111

raw_spin_lock_irqsave(&devtree_lock, flags);

跳转:spinlock.h(include/linux/)

#define raw_spin_lock_irqsave(lock, flags) \
do { \
typecheck(unsigned long, flags); \
flags = _raw_spin_lock_irqsave(lock); \
} while (0)

###################################

spinlock.c(kernel/)

unsigned long __lockfunc _raw_spin_lock_irqsave(raw_spinlock_t *lock)
{
return __raw_spin_lock_irqsave(lock);
}
EXPORT_SYMBOL(_raw_spin_lock_irqsave);

###################################

 __raw_spin_lock_irqsave(lock) 

跳转:spinlock_api_amp.h(include/linux/)

static inline unsigned long __raw_spin_lock_irqsave(raw_spinlock_t *lock)
{
unsigned long flags;


local_irq_save(flags);
preempt_disable(); // #define preempt_disable() barrier()

// /* Copied from linux/compiler-gcc.h since we can't include it directly */
// #define barrier() __asm__ __volatile__("": : :"memory")
spin_acquire(&lock->dep_map, 0, 0, _RET_IP_);
/*
* On lockdep we dont want the hand-coded irq-enable of
* do_raw_spin_lock_flags() code, because lockdep assumes
* that interrupts are not re-enabled during lock-acquire:
*/
#ifdef CONFIG_LOCKDEP
LOCK_CONTENDED(lock, do_raw_spin_trylock, do_raw_spin_lock);
#else
do_raw_spin_lock_flags(lock, &flags);
#endif
return flags;
}

##################

#define local_irq_save(flags) \
do { \
raw_local_irq_save(flags); \
trace_hardirqs_off(); \
} while (0)

###################

static inline unsigned long arch_local_irq_save(void)
{
unsigned long flags;


asm volatile(
" mrs %0, cpsr @ arch_local_irq_save\n"
" cpsid i" // cpsid i 就是disable irq;  cpsid f 才disable fiq. fast irq硬件上已经自动保存了足够的上下文,这里的操作不会因fiq发生而受影响。
: "=r" (flags) : : "memory", "cc");
return flags;
}

###################

irqflags.h(include/linux/)

# define trace_hardirqs_off() do { } while (0)

22222222222222222222222222222222222222222222222222222222

 __of_find_property(np, name, lenp);

跳转:

static struct property *__of_find_property(const struct device_node *np,
  const char *name, int *lenp)
{
struct property *pp;


if (!np)
return NULL;


for (pp = np->properties; pp; pp = pp->next) {
if (of_prop_cmp(pp->name, name) == 0) {
if (lenp)
*lenp = pp->length;
break;
}
}


return pp;
}

##########################

of.h(include/linux/)

#define of_prop_cmp(s1, s2) strcmp((s1), (s2))

跳转:算了……

3333333333333333333333333333333333333333333333333333333

raw_spin_unlock_irqrestore

跳转:spinlock.h(include/linux/)

#define raw_spin_unlock_irqrestore(lock, flags) \
do { \
typecheck(unsigned long, flags); \
_raw_spin_unlock_irqrestore(lock, flags); \
} while (0)

##################

#define typecheck(type,x) \
({ type __dummy; \

typeof(x) __dummy2; \ // typeof是取变量的类型
(void)(&__dummy == &__dummy2); \
1; \ // (type一致)正常编译,然后最后的数据1,赋值给调用者
}) // 这个宏定义是一个表达式,不是函数,无所谓返回值,这个值是这个表达式的值,复合表达式,取最后一个表达式的值,作为复杂表达式的值。这里整个表达式的值就是最后一个表达式的值,也就是1

typecheck宏有两个参数,
第一个是一个类型,比如unsigned long,
第二个是一个变量,比如a。
它生成一个unsigned long类型的变量__dummy,
然后利用typeof生成和a同样类型的变量__dummy2,
比较__dummy和__dummy2的地址。
如果它们不是同样类型的指针比较,比如a不是unsigned long,
这时候编译器会有一个警告,让你注意到这个问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值