안녕하세요. 오늘은 UART 통신으로 라즈베리파이의 부팅 로그를 확인하는 과정을 진행해
보도록 하겠습니다.
사실 교육을 진행할 당시에도 UART를 이용해 커널의 부팅 로그를 확인하는 과정을 진행했습니다. 하지만 그 당시에는 UART 선 연결하고 간단한 세팅을 해주면 볼 수 있는 통신 방법 정도로만 이해하고 넘어갔었는데, 생각보다도 UART는 중요한 통신 수단이었습니다.
UART는 임베디드 개발에서 가장 기본적이면서도 강력한 디버깅 도구이기 때문입니다. 특히 디바이스 트리나 커널 드라이버를 수정하다가 시스템이 부팅조차 되지 않는 위급 상황에서, 커널이 내뱉는 부팅 로그를 들을 수 있는 유일한 통로입니다.
따라서, 이번 시간에는 UART로 연결을 진행하고, 앞서 진행한 DT Overlay 과정에 오류가 발생한다면 어떤식으로 로그가 나타나는지를 확인해보고 해석하는 연습을 해보도록 하겠습니다.
UART는 별도의 클럭 신호(SCL) 없이, 데이터 선 2개(TX, RX)만으로 통신하는 방식.
우리가 평소에 쓰는 SSH나 모니터 화면은 운영체제(커널)가 어느 정도 부팅이 완료된 후에나 나타난다.
하지만,
probe() 함수에서 패닉(Kernel Panic)이 발생했다면?이런 상황에서는 네트워크나 모니터가 작동하지 않는다. 이때 UART는 커널이 태어나는 순간부터 죽는 순간까지의 모든 기록을 실시간으로 보여준다. 이를 통해 우리는 "어디서 에러가 났는지"를 정확히 파악할 수 있기 때문에, 커널 개발에서 UART를 사용하는 것이다.
라즈베리파이의 GPIO 14(TXD), 15(RXD)번 핀이 기본 UART 핀입니다. 이를 PC에서 확인하려면 USB to TTL (UART) 모듈이 필요합니다.

위 사진은 교육 당시 사용한 UART 모듈(시리얼 케이블)이다.
우측 끝은 USB로 연결할 수 있게 구성되어있고, 왼쪽 끝이 라즈베리파이의 핀에 연결할 수 있도록 되어있다. 각 케이블은 색상에 따라 의미를 가진다.
각 역할에 맞게,
검은색 (GND): 라즈베리파이의 GND 핀에 연결.
흰색 (RX): 라즈베리파이의 TXD (GPIO 14) 핀에 연결.
초록색 (TX): 라즈베리파이의 RXD (GPIO 15) 핀에 연결.
빨간색 (VCC/5V): 전원. 라즈베리파이는 이미 자체 전원을 쓰고 있으므로, USB 모듈의 전원까지 연결하면 보드에 무리가 가거나 쇼트가 날 수 있으니, 연결 X
- 연결 공식 (Cross Connection):
- 라즈베리파이 TX ↔ USB 모듈 RX
- 라즈베리파이 RX ↔ USB 모듈 TX
- 라즈베리파이 GND ↔ USB 모듈 GND

최종적으로 연결한 모습.
부팅 로그를 UART로 내보내려면 라즈베리파이 설정에서 UART를 활성화해야함.
1) /boot/firmware/config.txt 수정:
enable_uart=1
2) cmdline.txt 확인 (부팅 인자):
커널 로그를 어느 터미널로 쏠지 결정한다. 보통 아래와 같은 문구가 포함되어야함.
console=serial0,115200 console=tty1
console=serial0,115200: 부팅 로그를 UART(115200 BaudRate)로 보낸다는 뜻.저는 현재 맥북을 사용중인 관계로 iterm 창에 screen 명령어를 이용해서 UART 연결 로그를 확인해보도록 하겠습니다.

USB-TTL 연결 후 포트를 확인해보면, UART 선은 /dev/tty.usbserial-XXXX 로 나타난다. 즉 이 장치파일을 통해서 UART TX, RX 의 주고 받음을 확인할 수 있다.
따라서 해당 장치파일을 screen 명령어로 접속하고 사용하는 Baudrate를 명시해주면 UART 통신을 볼 수 있다.

이렇게 간단하게 끝내기는 아쉬우니, 커널 세팅에 문제가 발생했을 때, UART 로그에서 발생하는 문제들을 직접 확인하고 어떤식으로 디버깅하게 되는지를 손수 문제를 만들어가며(?) 테스트 해보고자 한다.
우선 지금 진행할 방식은 DT Overlay 하려는 파일명이 잘못되어 커널이 연결하지 못하고, 이에 대한 UART 로그를 확인할 것이다.
우선 준비 단계로 config.txt 설정이 필요하다.
라즈베리파이의 /boot/firmware/config.txt 파일을 열고 아래 내용을 추가/수정합니다.
// config.txt file
...
dtdebug=1 // 오버레이 상세 디버깅 활성화
uart_2ndstage=1 // 펌웨어 단계의 로그를 UART로 강제 출력 (핵심!)
dtoverlay=pcf8591_wrong_name // 의도적으로 틀린 파일명 기입 (실험용)
DT 오버레이는 커널이 동작하기 전 단계에서 적용이 되기에, uart_2ndstage=1 옵션을 넣어서 커널 동작 이전 부팅로그도 UART로 출력될 수 있게 하였다.
그 결과,

부팅 진행 상 문제가 되었던 부분을 UART 로그로 확인할 수 있었다.