ARM64 Linux Kernel/head.S

head.S의 시작

ukjin 2025. 5. 18. 20:39
반응형

head.S의 시작은 __HEAD 매크로로 시작한다.

/*
 * Kernel startup entry point.
 * ---------------------------
 *
 * The requirements are:
 *   MMU = off, D-cache = off, I-cache = on or off,
 *   x0 = physical address to the FDT blob.
 *
 * Note that the callee-saved registers are used for storing variables
 * that are useful before the MMU is enabled. The allocations are described
 * in the entry routines.
 */
	__HEAD

 

#define __HEAD		.section	".head.text","ax"

__HEAD는 .head.text 섹션으로 되어 있으며, 해당 섹션은 vmlinux.lds.S에 정의되어 있다. 

SECTIONS
{
	/*
	 * XXX: The linker does not define how output sections are
	 * assigned to input sections when there are multiple statements
	 * matching the same input section name.  There is no documented
	 * order of matching.
	 */
	DISCARDS
	/DISCARD/ : {
		*(.interp .dynamic)
		*(.dynsym .dynstr .hash .gnu.hash)
		*(.ARM.attributes)
	}

	. = KIMAGE_VADDR;

	.head.text : {
		_text = .;
		HEAD_TEXT
	}
    ...

따라서 커널의 부팅은 이 head.text 세션부터 시작한다.

	__HEAD
	/*
	 * DO NOT MODIFY. Image header expected by Linux boot-loaders.
	 */
	efi_signature_nop			// special NOP to identity as PE/COFF executable
	b	primary_entry			// branch to kernel start, magic

이후 efi_signature_nop 매크로 실행 후, primary_entry 함수로 분기한다.

	.macro	efi_signature_nop
#ifdef CONFIG_EFI
.L_head:
	/*
	 * This ccmp instruction has no meaningful effect except that
	 * its opcode forms the magic "MZ" signature required by UEFI.
	 */
	ccmp	x18, #0, #0xd, pl
#else
	/*
	 * Bootloaders may inspect the opcode at the start of the kernel
	 * image to decide if the kernel is capable of booting via UEFI.
	 * So put an ordinary NOP here, not the "MZ.." pseudo-nop above.
	 */
	nop
#endif
	.endm

해당 매크로는 EFI 호환성을 위해 커널 이미지 앞에 MZ(magic number)를 붙이는 명령어이다. MZ는 아스키 넘버로 0x4d, 0x5A인데, ccmp 0x18, 0x0, 0xd, pl 은 opcode 변경하게 되면 0xfa405a4d이다. 첫번째 바이트와 두 번째 바이트가 0x4d, 0x5a 이므

로 해당 명령어를 통해 이미지 첫번째와 두번째 바이트에 MZ 값을 써주게 된다.

(https://developer.arm.com/documentation/ddi0602/2021-12/Base-Instructions/CCMP--immediate---Conditional-Compare--immediate--)
sf 값은 64 bit일 경우 1이며, imm5는 0, cond는 pl이므로 5이며, Rn은 r18이므로 18이다. 이후 그림에는 생략되었지만
nzcv 항목은 0xd를 써줬다. 그러면 바이너리 코드로 환산해보면,
1111 1010 0100 0000 0101 1010 0100 1101 = 0xfa405a4d
이 된다.
반응형

'ARM64 Linux Kernel > head.S' 카테고리의 다른 글

preserve_boot_args  (0) 2025.05.18
record_mmu_state  (0) 2025.05.18
head.S  (0) 2025.04.27