디바이스트리(Device Tree)

컴퓨터공부/리눅스 2017.01.04 19:07 Posted by 아는 개발자

운영체제(Operating System)가 하드웨어와 소프트웨어 사이의 중간자 역할을 하고 사용자의 애플리케이션이 하드웨어를 조작하기 쉬운 환경을 제공 한다는 것은 컴퓨터 전공자라면 운영체제 수업시간에 귀가 빠지도록 배웠을 것이다. 운영체제는 오드로이드, 아두이노, 주노보드처럼 다양한 보드 위에 있는 RAM, CPU, EMMC등 하드웨어들을 초기화 및 조작하는 역할을 한다. 지금 이 글을 쓰기 위해 타자를 치는 동안 운영체제는 타자 입력 인터럽트를 처리하고 소프트웨어에 전달하는 일을 계속 하고 있다.


어떤 메인 보드를 사용하더라도 운영체제의 기본 뼈대는 동일해야 한다. 하지만 메인 보드들마다 상세 하드웨어 스펙은 천지 차이다. 예를 들면 RAM의 크기나 USB의 물리 주소의 위치처럼 당연한 것 부터 이 인터럽트 핸들러는 몇번까지 등록하는지 등등 생각하면 한도 끝도 없다. 이런 하드웨어 정보들을 모두 운영체제 코드 내에 하드코딩 해버린다면... 아마 코드가 매우 지저분해지고 엉망이 될 것이다. 그렇다고 하드웨어 제조사들은 많고 또 저마다 자기들이 최고라고 자랑하는 보드를 내놓는데 안 쓰기는 아깝고. 


간단히 하드웨어 정보들만 정리해서 던져주면 운영체제가 전달받은 정보들을 활용해 하드웨어를 전달하면 어떨까? 하드코딩으로 잘 부분을 전달받은 정보들로만 치환해주면 될 것 같아 깔끔해보인다.


이런 구조를 리눅스 OS는 이미 구현 해뒀다. ARM기반의 보드를 사용하는 경우 리눅스를 부팅을 위해선 디바이스 정보들을 바이너리 형태로 싹 저장해둔 디바이스 트리라는 것이 필요하다. 부팅시 리눅스는 디바이스 트리 정보들을 쭉 훑어보고 하드웨어 초기화시 필요한 정보들을 파싱(parsing)해서 사용한다. 예를들어 빈 메모리 영역을 관리할 Buddy system을 만들고 싶다면 먼저 전체 메모리의 크기는 얼마인지도 알아야 하고 물리주소 몇 번부터 몇 번까지를 메모리 영역으로 사용 할 수 있는지도 알아야 한다. 디바이스 트리에 이런 정보들을 모두 담아 뒀으니 리눅스는 그냥 여기 있는 정보들을 가져다가 사용하면 된다.



Device Tree안의 메모리 정보가 있는 곳에서(노드라고 부른다) reg 값의 앞에 두 셀을 Address, 뒤의 두 셀을 Size로 정해서 시작 주소와 하드웨어의 사이즈를 읽어 올 수 있다.


운영체제가 사용하는 디바이스 트리 정보들은 모두 바이너리로 되어 있다. 이런 하드웨어 정보들은 제조사들이 dts파일인 스크립트 형태로 만들어 두고 커널 빌드시 디바이스트리도 같이 빌드돼어 dtb 형태의 바이너리 파일이 만들어진다. 리눅스 커널을 받아보면 arch/arm64/boot/dts 폴더 안에 보드에 따라 설정된 device tree 스크립트를 확인 할 수 있다. 



디바이스 트리 문법을 알고 싶다면 https://www.devicetree.org/ 요 사이트를 한번 참고해보길 바란다. 예전에 문법공부한다고 참고하던 사이트가 있었는데 어디갔는지 모르겠다. 어렵지 않으니 그냥 스크립트만 봐도 금방 따라 갈 수 있을 것이다.


만든 스크립트는 dtc라는 컴파일러를 이용해 바이너리로 만들 수 있다. 우분투에 패키지 형태로 제공되므로 다운받아서 사용하면 편하다.


x86에서는 ACPI를 사용한다.