본문으로 건너뛰기

© 2026 Molayo

HN분석2026. 05. 28. 10:39

탈옥한 Kindle에서 Rust (및 Slint) 실행하기

요약

탈옥한 Kindle 기기에서 Rust 언어와 Slint UI 프레임워크를 실행하기 위한 크로스 컴파일 및 환경 구축 과정을 다룹니다. cargo-zigbuild를 활용한 ARMv7 타겟 빌드와 SSH를 통한 장치 제어 방법을 설명합니다.

핵심 포인트

  • cargo-zigbuild를 이용한 ARMv7 musl 타겟 크로스 컴파일
  • USBNetwork 도구를 활용한 Kindle SSH 액세스 설정
  • Slint 프레임워크를 이용한 임베디드 UI 구현 가능성
  • Linux의 '모든 것은 파일이다' 원칙을 이용한 터치 입력 처리

탈옥한 Kindle에서 Rust (및 Slint) 실행하기.

최근에 저는 7세대 Kindle Paperwhite를 탈옥(jailbreak)했습니다. 제 동기가 아마도 "Amazon의 끈적하고 조여오는 통제로부터 벗어나는 것"이어야 했겠지만, 사실 진실은 그것을 침대 옆 탁자 위의 시계로 사용하고 싶었기 때문입니다. 저는 이 프로젝트를 발견했고 코드를 약간만 수정하면 될 것이라고 생각했습니다. 그리고 그것은 작동했습니다. 하지만 이제 문을 열었으니, Kindle에서도 Rust를 작동시킬 수 있을지 고민하기 시작했습니다. 아마 더 유용한 일들을 할 수 있지 않을까요? 최근에 Home Assistant와 스마트 기기들을 다시 만지작거리기 시작했기 때문에, 몇몇 기능들을 위한 대시보드를 만드는 아이디어는 재미있는 프로젝트가 될 수 있을 것 같았습니다. 그리고 세상에는 아마도 충분히 괜찮은 프로젝트들이 많이 있겠지만, 는 그중 어떤 것도 만들어본 적이 없습니다.

프로그래머에게 X를 수행하는 라이브러리가 이미 있다고 말하는 것은, 작곡가에게 사랑에 관한 노래가 이미 있다고 말하는 것과 같습니다.

-Pete Cordell

Kindle을 위한 Rust 크로스 컴파일 (Cross compiling)

몇 가지 조사를 거친 후, 저는 ARMv7과 musl libc를 타겟으로 삼아야 한다는 것을 알게 되었습니다. 저는 이전에 ARM 머신에서 Rust를 다뤄본 적이 있으며, 그러한 저전력 기기에서 Rust 컴파일 툴체인 (compilation toolchain)을 작동시키는 것이 얼마나 어려운 일인지 고통스러운 경험을 통해 알고 있습니다. 다행히 크로스 컴파일 (cross compilation)을 위한 훌륭한 도구들이 있습니다. 제가 Rust 크로스 컴파일을 위해 즐겨 사용하는 도구는 다소 아이러니하게도 cargo-zigbuild입니다.

Zig 컴파일러는 지원되는 모든 아키텍처에 대해 musl libc 소스 및 헤더가 내장되어 제공됩니다. 또한 자체 링커 (linker)를 가지고 있어, zig cc는 어떤 호스트에서든 모든 musl 타겟에 대해 완전한 크로스 컴파일 툴체인 역할을 할 수 있습니다. Kindle을 위한 컴파일은 다음과 같이 간단해집니다:

* Zig 설치
* cargo-zigbuild 설치
* cargo zigbuild --release --target armv7-unknown-linux-musleabihf

Kindle에서 셸 (shell) 액세스 권한 얻기

hello-world-app이 준비되고 빌드되었으므로, 이를 Kindle에 넣고 실행할 방법이 필요했습니다. 탈옥 (jailbreaking) 과정에서 설치한 KUAL을 사용할 수도 있었겠지만, 애플리케이션이 실제로 작동하는지 확인하기 위해 표준 출력 (stdout)을 볼 수 있는 방법이 필요했습니다. 조사를 좀 해본 결과, USB 또는 Wi-Fi를 통해 장치에 SSH 액세스를 설정할 수 있게 해주는 USBNetwork 도구를 찾았습니다. 편의를 위해 제 sshconfig에 항목을 추가하고 공개 키 (public key)를 복사했습니다. 참고: 저에게는 ssh-copy-id가 작동하지 않았기에, Kindle의 /mnt/us/usbnet/etc/authorized_keys에 직접 .pub 파일을 추가해야 했습니다.

Hello, World! 그다음은?

셸 (shell) 액세스가 확보되자 제 교차 컴파일 (cross compilation) 툴체인이 실제로 잘 작동한다는 것을 확인할 수 있었고,

여기를 터치하세요, 저기를 터치하세요

화면에 픽셀을 띄우는 데 성공했다면, 퍼즐의 나머지 절반은 터치 패널이 Slint와 통신하도록 만드는 것입니다. 여기서 다시 한번 "모든 것은 파일이다 (everything is a file)"라는 격언이 구원투수로 등장합니다. 터치 컨트롤러는 /dev/input/event1로 나타나며, 우리는 단순히 거기서 read()를 수행할 수 있습니다. 매번 읽을 때마다 커널이 우리의 버퍼에 직접 기록한 구조체(struct)가 반환됩니다. 여기에는 타임스탬프(timestamp), 이벤트 유형(event type), 코드(code), 그리고 값(value)이 포함되어 있습니다. 파싱(parsing)도, 프로토콜(protocol)도 필요 없이, 우리가 맞춰야 할 메모리 레이아웃(memory layout)만 있을 뿐입니다.

Kindle은 Linux 커널의 멀티터치 프로토콜 타입 B (multi-touch protocol type B)를 사용합니다. 이는 이벤트가 "현재 X 좌표는 이것이다", "현재 Y 좌표는 저것이다", "트래킹 ID (tracking ID)는 이것이다"와 같은 스트림 형태로 전달되다가, "좋아, 해당 배치가 완료되었으니 이제 처리해도 좋다"라고 말하는 SYNC_REPORT 이벤트가 뒤따라온다는 것을 의미합니다. 따라서 우리는 이벤트가 들어올 때마다 최신 X, Y 및 트래킹 ID를 축적하고, 각 SYNC_REPORT가 발생할 때마다 Slint로 무엇을 전달할지 결정합니다. 트래킹 ID가 -1이라는 것은 손가락이 떨어졌음을 의미하며, 이는 PointerReleased가 됩니다. 그렇지 않은 경우, 터치 다운 (touch-down) 이후의 첫 번째 싱크(sync)는 PointerPressed가 되고, 그 이후의 모든 싱크는 PointerMoved가 됩니다. 나머지는 Slint가 처리합니다.

실제로 작동합니다!

출력이 보이지 않음, 화면이 새로고침되지 않음, 이중 새로고침 깜빡임, 터치 입력이 등록되지 않음, 터치 입력이 두 번 등록됨 등 수많은 버그를 디버깅한 끝에, 저는 카운터와 증가 버튼을 만들었습니다.

Our dog, Luna

Our dog, Luna

겉보기에 작동하는 (적어도 제 특정 기기에서는 작동하며, 다른 Kindle 버전에서는 조정이 필요할 것입니다) Slint용 kindle-backend를 완성한 후, 관련 코드를 별도의 크레이트 (crate)로 추출하여 crates.io에 게시했습니다.

이제 준비가 되었으니, 남은 부분(대시보드)을 그리기만 하면 됩니다. 그것은 다음 기회에 하겠습니다.

AI 자동 생성 콘텐츠

본 콘텐츠는 HN AI Posts의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0