NOT indexed

include <asm/xxx.h> 先找arch/xxx/include/xxx.h,没有的话就找/include/asm-generic/xxx.h

从dts中获取regs地址并映射到virtual address:

linux5.10: void __iomem *devm_platform_get_and_ioremap_resource(struct platform_device *pdev, unsigned int index, struct resource **res)

linux5.4: void __iomem *devm_platform_ioremap_resource(struct platform_device *pdev, unsigned int index)

相当于platform_get_resource + devm_request_mem_region + devm_ioremap

linux链表相关操作:

#define list_entry(ptr, type, member) \ /// list_entry作用和container_of相同
	container_of(ptr, type, member)

container_of(ptr, type, member)

// ptr:表示结构体中member的地址h(已知的)
// type:表示结构体类型 struct xxx
// member:表示结构体中的成员 yyy
// 返回结构体的首地址

/**
 * list_for_each_entry	-	iterate over list of given type
 * @pos:	the type * to use as a loop cursor. pos中的list_head被加入了第二个成员head中
 * @head:	the head for your list. 要循环的链表
 * @member:	the name of the list_head within the struct. pos中的list_head链表对象
 */
list_for_each_entry(pos, head, member)

Initcalls

  • 图中initcalls优先级从上到下。这些都是只能用于builtin的modules。loadable的modules使用module_init()。

  • 使用initcalls会在目标文件object file中创建ELF sections。

module_init()

本质是device_initcall。

#define module_init(x)	__initcall(x);
#define __initcall(fn) device_initcall(fn)

kernel的System.map可以查看符号文件,其中__initcall6_start后的顺序就对应device_initcall的驱动加载顺序。

#define pure_initcall(fn)		__define_initcall(fn, 0)

#define core_initcall(fn)		__define_initcall(fn, 1)
#define postcore_initcall(fn)		__define_initcall(fn, 2)
#define arch_initcall(fn)		__define_initcall(fn, 3)
#define subsys_initcall(fn)		__define_initcall(fn, 4)
#define fs_initcall(fn)			__define_initcall(fn, 5)
#define rootfs_initcall(fn)		__define_initcall(fn, rootfs)
#define device_initcall(fn)		__define_initcall(fn, 6)
#define late_initcall(fn)		__define_initcall(fn, 7)