Android 8.0에 도입된 모듈 커널 요구사항의 일부로 모든 SoC(단일 칩 시스템) 커널은 로드 가능한 커널 모듈을 지원해야 합니다.
커널 구성 옵션
로드 가능한 커널 모듈을 지원하기 위해 모든 일반 커널의 android-base.cfg에는 다음 커널 구성 옵션(또는 상응하는 커널 버전)이 포함됩니다.
CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y CONFIG_MODVERSIONS=y
모든 기기 커널에서 이러한 옵션을 사용 설정해야 합니다. 커널 모듈은 가능한 경우 항상 언로드 및 다시로드도 지원해야 합니다.
모듈 서명
GKI 공급업체 모듈에는 모듈 서명이 지원되지 않습니다. 자체 검사 부팅을 지원하는 데 필요한 기기에서는 커널 모듈이 dm-verity가 사용 설정된 파티션에 있어야 합니다. 이렇게 하면 개별 모듈의 신뢰성을 확인하기 위해 서명할 필요가 없습니다.
파일 위치
Android 7.x 이하에서는 커널 모듈에 요구하는 사항이 없고 insmod
및 rmmod
지원이 포함되지만 Android 8.x 이상에서는 생태계에서 커널 모듈을 사용하는 것이 좋습니다. 다음 표는 세 가지 Android 부팅 모드에 필요한 보드 관련 주변기기 지원 가능성을 보여줍니다.
부팅 모드 | 저장소 | 표시 | 키패드 | 배터리 | PMIC | 터치스크린 | NFC, Wi-Fi, 블루투스 |
센서 | 카메라 |
---|---|---|---|---|---|---|---|---|---|
복구 | |||||||||
충전기 | |||||||||
Android |
Android 부팅 모드에서의 가용성 외에도 커널 모듈은 소유자(SoC 공급업체 또는 ODM)에 따라 분류할 수 있습니다. 커널 모듈을 사용 중인 경우 파일 시스템에서의 배치 요구사항은 다음과 같습니다.
- 모든 커널에는 파티션을 부팅하고 마운트할 수있는 기본 지원 기능이 있어야 합니다.
- 커널 모듈은 읽기 전용 파티션에서 로드해야 합니다.
- 자체 검사 부팅이 필요한 기기의 경우 커널 모듈은 자체 검사 파티션에서 로드해야 합니다.
- 커널 모듈은
/system
에 없어야 합니다. - 전체 Android 또는 충전기 모드에 필요한 SoC 공급업체의 커널 모듈은
/vendor/lib/modules
에 있어야 합니다. - ODM 파티션이 있는 경우 전체 Android 또는 충전기 모드에 필요한 ODM의 커널 모듈은
/odm/lib/modules
에 있어야 합니다. 그렇지 않으면 이러한 모듈은/vendor/lib/modules
에 있어야 합니다. - 복구 모드(Recovery mode)에 필요한 SoC 공급업체 및 ODM의 커널 모듈은
/lib/modules
에서 복구ramfs
에 있어야 합니다. - 복구 모드(Recovery mode) 및 전체 Android 또는 충전기 모드에 모두 필요한 커널 모듈은 위에서 설명한 것처럼 복구
rootfs
및/vendor
또는/odm
파티션에 모두 있어야 합니다. - 복구 모드(Recovery mode)에서 사용되는 커널 모듈은
/vendor
나/odm
에만 있는 모듈에 의존하면 안 됩니다. 이러한 파티션이 복구 모드(Recovery mode)에서 마운트되지 않기 때문입니다. - SoC 공급업체 커널 모듈은 ODM 커널 모듈에 의존해서는 안 됩니다.
Android 7.x 이하에서는 /vendor
및 /odm
파티션이 초기에 마운트되지 않습니다. Android 8.x 이상에서는 이러한 파티션에서 모듈 로드가 가능하도록 A/B가 아닌 기기 및 A/B 기기에 모두 파티션을 초기에 마운트할 수 있도록 했습니다. 또한 파티션이 Android 및 충전기 모드 둘 다에서 마운트되도록 보장합니다.
Android 빌드 시스템 지원
BoardConfig.mk
에서 Android 빌드는 공급업체 이미지를 위해 설계된 커널 모듈의 전체 목록을 제공하는 BOARD_VENDOR_KERNEL_MODULES
변수를 정의합니다. 이 변수에 나열된 모듈은 /lib/modules/
에서 공급업체 이미지에 복사되며 Android에 마운트된 후에는 위 요구 사항에 따라 /vendor/lib/modules
에 표시됩니다.
공급업체 커널 모듈의 구성 예는 다음과 같습니다.
vendor_lkm_dir := device/$(vendor)/lkm-4.x BOARD_VENDOR_KERNEL_MODULES := \ $(vendor_lkm_dir)/vendor_module_a.ko \ $(vendor_lkm_dir)/vendor_module_b.ko \ $(vendor_lkm_dir)/vendor_module_c.ko
이 예에서 공급업체 커널 모듈의 사전 빌드 저장소는 위에 나열된 위치에서 Android 빌드에 매핑됩니다.
복구 이미지에는 공급업체 모듈의 하위 집합이 포함될 수 있습니다. Android 빌드는 이러한 모듈에 관해 BOARD_RECOVERY_KERNEL_MODULES
변수를 정의합니다. 예:
vendor_lkm_dir := device/$(vendor)/lkm-4.x BOARD_RECOVERY_KERNEL_MODULES := \ $(vendor_lkm_dir)/vendor_module_a.ko \ $(vendor_lkm_dir)/vendor_module_b.ko
Android 빌드는 depmod
실행을 처리하여 /vendor/lib/modules
및 /lib/modules
(recovery ramfs
)에 필수 modules.dep
를 생성합니다.
모듈 로드 및 버전 관리
modprobe -a
를 호출하여 init.rc*
에서 모든 커널 모듈을 한 번에 로드합니다. 이렇게 하면 modprobe
바이너리의 C 런타임 환경을 반복적으로 초기화하는 오버헤드가 방지됩니다. early-init
이벤트를 수정하여 modprobe
를 호출할 수 있습니다.
on early-init exec u:r:vendor_modprobe:s0 -- /vendor/bin/modprobe -a -d \ /vendor/lib/modules module_a module_b module_c ...
일반적으로 커널 모듈은 모듈이 함께 사용되는 커널로 컴파일되어야 합니다(그렇지 않으면 커널이 모듈 로드를 거부함).
CONFIG_MODVERSIONS
는 ABI(Application Binary Interface)에서 손상을 감지하여 해결 방법을 제공합니다. 이 기능은 커널에서 내보낸 각 기호의 프로토타입에 CRC(주기적 중복 검사) 값을 계산하고 이러한 값을 커널의 일부로 저장합니다. 커널 모듈에서 사용하는 기호의 경우 이러한 값은 커널 모듈에도 저장됩니다. 모듈이 로드될 때 모듈에서 사용되는 기호의 값은 커널의 기호 값와 비교됩니다. 이러한 값이 일치하면 모듈이 로드되고 그렇지 않으면 로드에 실패합니다.
공급업체 이미지와 별도로 커널 이미지를 업데이트하려면 CONFIG_MODVERSIONS
를 사용 설정합니다. 이렇게 하면 공급업체 이미지의 기존 커널 모듈과의 호환성을 유지하면서 커널의 소규모 업데이트(LTS의 버그 수정 등)가 이루어질 수 있습니다. 하지만 CONFIG_MODVERSIONS
자체로는 ABI 중단이 해결되지 않습니다. 소스 수정 또는 커널 구성 변경으로 인해 커널의 내보낸 기호 프로토타입이 변경되면 이 기호를 사용하는 커널 모듈과의 호환성이 손상됩니다. 이러한 경우 커널 모듈을 다시 컴파일해야 합니다.
예를 들어 커널의 task_struct
구조(include/linux/sched.h
에서 정의됨)에는 커널 구성에 따라 조건부로 포함된 많은 필드가 있습니다. sched_info
필드는 CONFIG_SCHED_INFO
가 사용 설정된 경우에만(CONFIG_SCHEDSTATS
또는 CONFIG_TASK_DELAY_ACCT
가 사용 설정된 경우 발생함) 존재합니다. 이러한 구성 옵션으로 상태가 변경되면 task_struct
구조의 레이아웃이 변경되고 task_struct
를 사용하는 커널에서 내보낸 인터페이스가 모두 변경됩니다(예: kernel/sched/core.c
의 set_cpus_allowed_ptr
). 이러한 인터페이스를 사용하는 이전에 컴파일된 커널 모듈과의 호환성이 손상되어 이러한 모듈을 새 커널 구성으로 다시 빌드해야 합니다.
CONFIG_MODVERSIONS
에 관한 자세한 내용은 Documentation/kbuild/modules.rst
에서 커널 트리 문서를 참조하세요.