见Linux5.4/arch/riscv/kernel/head.S,"…"表示省略部分代码。
...
__HEAD
ENTRY(_start)
/*
* Image header expected by Linux boot-loaders. The image header data
* structure is described in asm/image.h.
* Do not modify it without modifying the structure and all bootloaders
* that expects this header format!!
*/
/* jump to start kernel */
j _start_kernel
/* reserved */
.word 0
.balign 8
#ifdef CONFIG_RISCV_M_MODE
/* Image load offset (0MB) from start of RAM for M-mode */
.dword 0
#else
#if __riscv_xlen == 64
/* Image load offset(2MB) from start of RAM */
.dword 0x200000
#else
/* Image load offset(4MB) from start of RAM */
.dword 0x400000
...
END(_start)
...
查看arch/riscv/kernel/vmlinux.lds链接脚本,第二行就是ENTRY(_start),故_start本是Linux内核入口函数,ENTRY(_start)常见于链接脚本文件,何故出现在此.S文件中,查找以后发现,本质一样只是在封了一层。见include/linux/linkage.h文件:
...
11 #ifndef ASM_NL
12 #define ASM_NL ;
13 #endif
...
97 /* SYM_L_* -- linkage of symbols */
98 #define SYM_L_GLOBAL(name) .globl name
...
115 #ifndef ENTRY
116 /* deprecated, use SYM_FUNC_START */
117 #define ENTRY(name) \
118 SYM_FUNC_START(name)
119 #endif
...
146 /* SYM_ENTRY -- use only if you have to for non-paired symbols */
147 #ifndef SYM_ENTRY
148 #define SYM_ENTRY(name, linkage, align...) \
149 linkage(name) ASM_NL \
150 align ASM_NL \
151 name:
152 #endif
...
154 /* SYM_START -- use only if you have to */
155 #ifndef SYM_START
156 #define SYM_START(name, linkage, align...) \
157 SYM_ENTRY(name, linkage, align)
158 #endif
...
218 #define SYM_FUNC_START(name) \
219 SYM_START(name, SYM_L_GLOBAL, SYM_A_ALIGN)
220 #endif
...
分析上述代码可知,一环套一环,ENTRY(_start)最终展开就是:
.globl _start;
align;
_start:
END(_start)分析和上面一样,可在include/linux/linkage.h文件中找到。