Linux v6.18.37 · 개념과 코드 읽기

Device Tree: compatible 목록에서 드라이버가 고르는 정보

이 코드는 어떤 문제를 푸나요?

Device Tree는 보드에 어떤 장치가 있고 어떤 주소·인터럽트·전원 자원을 사용하는지 설명합니다. 드라이버는 compatible 등으로 자신이 다룰 수 있는 장치를 찾습니다. __of_match_node 전체를 보면 단순히 이름이 같은 첫 항목을 반환하는 것이 아니라 호환성 점수를 비교해 가장 적합한 항목을 고릅니다.

읽을 범위: v6.18.37 · drivers/of/base.c · __of_match_node 1072–1092행입니다. 아래에 이 범위의 원문과 각 줄의 설명을 실었습니다. 주제 전체의 흐름과 다른 경로는 기존 분석에서 함께 읽으실 수 있습니다.

먼저 알아둘 개념

노드와 장치

device_node는 하드웨어 설명의 한 노드입니다. 모든 노드가 독립된 실행 중 드라이버 객체와 일대일로 대응하는 것은 아닙니다.

compatible

하드웨어 호환성을 나타내는 문자열 목록입니다. 더 구체적인 모델과 그보다 일반적인 호환 모델을 함께 표현할 수 있습니다.

매칭 표

드라이버의 of_device_id 배열은 지원하는 장치 정보를 담습니다. 끝은 name·type·compatible이 모두 비어 있는 항목으로 표시합니다.

match data

선택된 표 항목의 data 포인터에는 모델별 설정을 연결할 수 있습니다. 매칭 함수가 돌려주는 항목 자체를 보존하는 이유입니다.

처음 읽을 때

Device Tree를 실행 코드로 보지 말고 장치 설명으로 읽으십시오. compatible 매칭은 드라이버 후보를 정하는 과정이며 전원을 켜거나 레지스터를 설정하는 probe가 이미 실행됐다는 뜻은 아닙니다.

더 깊이 살펴볼 때

점수가 더 클 때만 best_match를 바꾸므로 동점에서 기존 선택이 유지됩니다. 이 내부 함수의 호출자는 트리 접근 보호 조건을 갖춰야 하며 공개 of_match_node의 잠금 처리와 나누어 읽는 것이 좋습니다.

그림으로 보는 변화

Device Tree: compatible 목록에서 드라이버가 고르는 정보의 단계별 개념 그림
각 단계에 화살표 의미와 생략 범위를 표시했습니다. 주소·숫자 예제는 실제 장치 값을 뜻하지 않습니다.
1단계 설명

1단계 고정

GIF 원본 열기

1. 장치 설명을 읽습니다

노드의 compatible 등과 드라이버의 매칭 표가 준비됩니다.

화살표는 노드의 설명을 매칭 함수가 읽는 참조 관계입니다.

2. 후보를 비교합니다

표의 끝 표시까지 각 항목의 호환성 점수를 계산합니다.

화살표는 배열 항목을 순회하는 순서이며 MMIO 접근 순서가 아닙니다.

3. 가장 적합한 항목을 반환합니다

점수가 가장 높은 항목을 반환하고, 호환 항목이 없으면 NULL입니다.

화살표는 선택한 설정 항목이 드라이버 매칭 경로에 전달되는 방향입니다.

__of_match_node를 한 줄씩 읽기

줄 번호는 v6.18.37 원문 기준입니다. 주석·빈 줄을 포함한 함수 전체를 먼저 보고, 그 아래에서 각 줄을 설명합니다.

static
const struct of_device_id *__of_match_node(const struct of_device_id *matches,
					   const struct device_node *node)
{
	const struct of_device_id *best_match = NULL;
	int score, best_score = 0;

	if (!matches)
		return NULL;

	for (; matches->name[0] || matches->type[0] || matches->compatible[0]; matches++) {
		score = __of_device_is_compatible(node, matches->compatible,
						  matches->type, matches->name);
		if (score > best_score) {
			best_match = matches;
			best_score = score;
		}
	}

	return best_match;
}
static

static은 이 내부 함수의 C 연결 범위를 현재 소스 파일로 제한합니다. 장치의 정적 주소나 메모리 고정을 뜻하지 않습니다.

const struct of_device_id *__of_match_node(const struct of_device_id *matches,

드라이버의 매칭 표를 받아 가장 적합한 항목의 포인터를 반환합니다.

					   const struct device_node *node)

비교할 Device Tree 노드를 함께 받습니다.

	const struct of_device_id *best_match = NULL;

아직 일치하는 항목을 찾지 못했으므로 최선 후보는 NULL입니다.

	int score, best_score = 0;

현재 항목의 점수와 지금까지 얻은 최고 점수를 준비합니다. 0은 아직 유효한 일치가 없다는 기준입니다.

	if (!matches)

매칭 표 자체를 제공하지 않았는지 확인합니다.

		return NULL;

비교 대상 표가 없으면 일치 결과도 없습니다.

	for (; matches->name[0] || matches->type[0] || matches->compatible[0]; matches++) {

name·type·compatible이 모두 빈 종료 항목 전까지 배열을 순회합니다.

		score = __of_device_is_compatible(node, matches->compatible,

노드와 현재 항목의 compatible을 기준으로 호환성 점수 계산을 시작합니다.

						  matches->type, matches->name);

항목의 type과 name 조건도 점수 계산 함수에 전달합니다.

		if (score > best_score) {

지금 후보가 이전 최고 점수보다 더 적합한지 비교합니다. 동점은 교체하지 않습니다.

			best_match = matches;

더 적합한 표 항목을 최선 후보로 기억합니다. 구조체 전체를 복사하는 것이 아닙니다.

			best_score = score;

새 최고 점수도 저장해 다음 항목과 비교합니다.

	return best_match;

선택한 항목을 반환합니다. 끝까지 유효한 일치가 없으면 NULL입니다.

함께 생각해 볼 질문

compatible이 맞으면 probe도 성공하나요?

매칭은 후보 선택입니다. probe에서 메모리·IRQ·전원 자원 준비가 실패할 수 있습니다.

표의 첫 항목이 언제나 이기나요?

아닙니다. 더 높은 호환성 점수의 항목이 나오면 그 항목으로 바뀝니다. 동점이면 앞의 선택이 유지됩니다.

device_node 주소가 장치 MMIO 주소인가요?

아닙니다. 커널 메모리의 설명 객체 포인터이며 실제 장치 주소는 노드 속성을 해석해 얻습니다.

출처와 읽은 범위

Linux stable v6.18.37 · drivers/of/base.c

해당 버전 원본 파일 · 기존 코드 분석 · 설명 원고

맨 위로 ↑