역할과 입력
- 입력 파일: arch/arm64/kernel/vdso/vdso.so
- 범위 심볼: vdso_start, vdso_end
원본 .S · 빌드 조건: Makefile · 명령·주소 표기 읽는 법
24줄 · SHA-256: 07ffaa3e2c7500bf769a72f280f68d0dd1f148770388057fa8f2a782ae05624b
구조와 흐름
섹션·정렬·범위 심볼
.incbin은 파일을 읽어 바이트를 붙이는 어셈블러 지시문입니다. vdso_end−vdso_start에는 끝 정렬 패딩도 포함됩니다. .previous는 이전 섹션으로 돌아갑니다. 마지막 emit_aarch64_feature_1_and는 설정에 맞는 GNU property note를 출력합니다.
vdso-wrap.S · L1–L24
1/* SPDX-License-Identifier: GPL-2.0-only */
2/*
3 * Copyright (C) 2012 ARM Limited
4 *
5 * Author: Will Deacon <will.deacon@arm.com>
6 */
7
8#include <linux/init.h>
9#include <linux/linkage.h>
10#include <linux/const.h>
11#include <asm/assembler.h>
12#include <asm/page.h>
13
14 .globl vdso_start, vdso_end
15 .section .rodata
16 .balign PAGE_SIZE
17vdso_start:
18 .incbin "arch/arm64/kernel/vdso/vdso.so"
19 .balign PAGE_SIZE
20vdso_end:
21
22 .previous
23
24emit_aarch64_feature_1_and
- L8
- 부팅 때만 사용할 코드·데이터의 섹션 표기를 가져옵니다. 초기화가 끝난 뒤 해제 가능한 영역과 계속 남겨야 하는 영역을 링커가 구분하게 합니다. #include는 전처리 단계에서 헤더 내용을 가져옵니다. CPU가 이 줄에서 함수를 호출하는 동작은 없습니다.
- L9
- SYM_FUNC_START·SYM_CODE_START·SYM_INNER_LABEL 등의 심볼 선언 규칙을 가져옵니다. 함수인지 코드 내부 라벨인지, 다른 오브젝트에 보일 이름인지와 정렬·크기 정보를 빌드 도구에 전달하는 데 필요합니다. #include는 전처리 단계에서 헤더 내용을 가져옵니다. CPU가 이 줄에서 함수를 호출하는 동작은 없습니다.
- L10
- C와 어셈블리 양쪽에서 쓸 정수 상수 표현을 가져옵니다. C용 형 접미사가 어셈블리 식에 그대로 들어가지 않게 하여 PAGE_SIZE 같은 공통 상수를 사용할 수 있게 합니다. #include는 전처리 단계에서 헤더 내용을 가져옵니다. CPU가 이 줄에서 함수를 호출하는 동작은 없습니다.
- L11
- ARM64의 큰 주소 구성, CPU별 값 조회, 시스템 레지스터 처리, 동기화 등에 쓰는 어셈블리 매크로를 가져옵니다. 각 사용 위치에서 일반 명령 여러 개로 펼쳐지는 작업입니다. #include는 전처리 단계에서 헤더 내용을 가져옵니다. CPU가 이 줄에서 함수를 호출하는 동작은 없습니다.
- L12
- 빌드가 선택한 페이지 크기와 정렬 단위를 가져옵니다. 4KiB를 항상 가정하지 않고 선택된 PAGE_SIZE로 표와 이미지 경계를 맞추는 데 사용합니다. #include는 전처리 단계에서 헤더 내용을 가져옵니다. CPU가 이 줄에서 함수를 호출하는 동작은 없습니다.
- L14
- AArch64 vDSO 원본의 시작·끝 기호를 다른 오브젝트에서 참조하도록 공개합니다. vdso.c가 이 기호로 원본 ELF를 찾고 페이지 수를 계산합니다.
- L15
- AArch64 vDSO 원본 바이트를 커널 읽기 전용 데이터 영역에 넣습니다. 사용자에게 실행 가능하게 연결하는 권한과 주소는 vdso.c의 별도 매핑 경로에서 정합니다. 이는 빌드 중 출력할 바이트의 섹션을 선택하는 지시문이며, 실행 중 PC나 SP를 옮기지 않습니다.
- L16
- vDSO 이미지의 경계를 PAGE_SIZE에 맞춥니다. 커널이 이 원본을 페이지 단위로 사용자 주소 공간에 연결할 수 있게 하려는 정렬이며, 명령어 한 개의 길이만 맞추는 작업이 아닙니다. .balign의 인자는 바이트 단위의 정렬 크기이며, 어셈블 단계에서 필요한 패딩을 넣습니다.
- L17
- AArch64 vDSO ELF 원본 바이트의 시작 주소입니다. 사용자 프로세스에 vDSO 페이지를 매핑할 코드가 이 시작과 끝 기호로 원본 범위를 구합니다. 레이블은 이 위치에 붙인 이름이며, 이름을 적는 것만으로 CPU 명령이 추가되지는 않습니다.
- L18
- 별도로 빌드한 AArch64 프로그램용 vDSO ELF의 바이트를 커널 읽기 전용 영역에 포함합니다. vDSO는 시각 조회 같은 일부 서비스를 매번 시스템 호출로 진입하지 않고 사용자 공간에서 수행하게 하는 작은 공유 라이브러리입니다. 이 줄은 실행이나 사용자 매핑 자체가 아니라, 뒤의 매핑 코드가 사용할 원본 이미지를 담는 단계입니다.
- L19
- vDSO 이미지의 경계를 PAGE_SIZE에 맞춥니다. 커널이 이 원본을 페이지 단위로 사용자 주소 공간에 연결할 수 있게 하려는 정렬이며, 명령어 한 개의 길이만 맞추는 작업이 아닙니다. .balign의 인자는 바이트 단위의 정렬 크기이며, 어셈블 단계에서 필요한 패딩을 넣습니다.
- L20
- 페이지 경계까지 정렬한 AArch64 vDSO 원본의 끝입니다. 시작 주소와의 차이로 매핑할 이미지 크기를 계산할 수 있습니다. 레이블은 이 위치에 붙인 이름이며, 이름을 적는 것만으로 CPU 명령이 추가되지는 않습니다.
- L22
- — 바로 이전에 사용하던 섹션으로 전환합니다.
- L24
- 이 어셈블리 오브젝트에 AArch64 GNU property note를 출력하여 BTI/PAC 등 빌드가 선언한 제어 흐름 보호 속성을 링커에 전달합니다. 방금 포함한 vDSO ELF를 실행하거나 그 내부 명령을 수정하는 작업은 아닙니다.
매크로 정의와 확장
각 정의는 v6.18.37 원문입니다. 역슬래시 인자는 사용 위치의 값으로 치환되며, 안쪽 매크로와 조건부 블록은 이후 단계에서 다시 처리됩니다.
상수·구조체 오프셋
S_*·THREAD_*·FREGS_* 등의 구조체 오프셋은 빌드한 C 구조체 배치에서 생성됩니다. 숫자를 고정하지 않고 원래 기호를 사용했습니다.