UEFI 베어메탈 프로그래밍 5부작 연재, 리눅스에서 직접 컴파일해 부팅 디스크 만들기
- 리눅스 워크스테이션에서 UEFI 펌웨어 PC용 베어메탈 애플리케이션을 만드는 5부작 연재로, 컴파일과 링크부터 EFI 시스템 파티션, DVD/USB 이미지 제작, Simple File Protocol 파일 처리까지 다루며 순서대로 읽어야 이해됨
- 저자는 UEFI 사전 지식이 없는 숙련 리눅스 개발자를 대상으로 한다고 밝혔고, 다루는 범위는 필요한 소프트웨어 도구, 컴파일과 링크, 부팅 가능 디스크 생성, 기본 파일 관리임
- 댓글에서 부족한 C 표준 라이브러리 대안으로 edk2-libc, LLVM libc의 UEFI 지원, Rust uefi-rs 라이브러리가 언급됨
- UEFI의 UTF-16 문자열, VFAT, PE32+ 같은 Windows 계열 설계를 두고 댓글에서 과하게 설계된 DOS라는 평부터 독성 폐기물에 비유하는 비판까지 나옴
- 링크 후 남은 외부 심볼을 nm -D --undefined-only로 확인해 빌드 스크립트에 넣는 검증 팁이 댓글에 있음
Hacker News 의견들
이거 딱 찾고 있던 내용인데, 고맙다.
UEFI에 C 표준 라이브러리 없는 게 힘들면 edk2-libc 쓰면 된다. EFI가 Windows 코딩 스타일처럼 보이는 건 우연이 아니고, 원래 Intel Boot Initiative부터 EFI, UEFI 스펙까지 그 방식을 그대로 가져왔다.
'그 방식을 가져왔다'는 너무 긍정적인 표현이다. 병을 퍼뜨렸다고 해야 맞지. UTF-16에 VFAT라니. 1998년에도 UTF-16이 정상적인 문자열 포맷이 아니라는 건 명백했고 2005년 EFI에서 UEFI로 넘어갈 때도 그대로 갔다. UEFI는 호수에 독성 폐기물 버리는 방식을 '활용'한 것과 같다. 편하긴 한데 뒤처리는 남이 훨씬 큰 비용으로 한다.
참고로 EDK II에 최근 심각한 CVE가 있으니 조심해라.
LLVM libc에도 UEFI 지원이 있다. 아직 업데이트하는지는 모르겠지만.
이 가이드 진짜 좋다. Zig로 부트로더 만들 때 참고자료 중 하나로 썼다. 16비트 문자 문제 같은 삐걱거리는 부분이 좀 있는데, EFI 환경 자체가 리눅스 개발에 비해 너무 이질적이라 그런 것 같다.
GRUB 대체품을 만드는 게 아니면 Multiboot2도 괜찮은 선택이고 UEFI 서비스도 그대로 호출할 수 있다. 나는 gnu-efi 같은 감사 불가능한 의존성 없이 UEFI 앱을 만들었는데, UEFI 인터페이스 부분을 289줄 헤더 파일로 정리해서 키보드와 마우스 이벤트를 프레임버퍼에 띄우는 inputmon을 만들었다. QEMU에 OVMF 올려서 부팅하는 run 타깃도 Makefile에 넣었다.
LLVM이랑 Clang이 의존성이라고? 그건 빌드 타임 얘기지 런타임은 아니다. 싫으면 TinyCC나 Portable C Compiler 같은 더 작은 컴파일러를 쓰거나, 아예 어셈블리로 내려가면 된다.
'링커가 없는 함수를 호출해도 external로만 표시한다'는 부분, nm -D --undefined-only로 링크 후 남은 외부 심볼이 없는지 확인해서 빌드 스크립트에 넣으면 된다.
초보자용 책이 있었으면 좋겠다. C랑 어셈블리로 이걸 하는 방법을 PDF나 epub로.
UEFI 아직도 쓰나? Qualcomm Nuvia ARM 윈도우 노트북도 UEFI를 쓰나, 아니면 그냥 BIOS인가?
UEFI 엄청 흔하다. 그 ARM 노트북도 UEFI 쓰고, 요즘 널리 생산되는 것 중에 옛날 BIOS 쓰는 건 거의 없다. 레거시 BIOS처럼 보이는 것도 대부분 UEFI가 흉내내는 거고, 애플 맥북은 EFI도 아닌 자체 펌웨어를 쓴다.
BIOS는 원래 IBM PC에서 리버스 엔지니어링된 x86 사실상 표준이었다. ARM은 임베디드에서 시작해서 제조사가 한 가지 작업용 펌웨어만 넣었고, UEFI가 x86 표준이 된 뒤에야 ARM에서도 자기 OS를 올릴 만한 범용 기기가 나왔다.
UEFI 쓰면 그게 진짜 베어메탈인가?
베어메탈은 제어가 내 코드로 넘어온 뒤 하드웨어를 얼마나 직접 만질 수 있나의 문제다. 부트로더가 CPU 좀 썼다고 자격이 사라지진 않고, OS가 하드웨어 접근을 막을 때 사라진다.
이런 글과 프로젝트가 더 많았으면 좋겠다.
과하게 설계된 DOS를 프로그래밍하는 기분이다.
UEFI가 생각보다 훨씬 별로구나. 그냥 부트로더로만 취급하고 더 정상적인 걸 쓰는 게 낫겠다. 다음 리비전에서 8비트 UTF를 쓰면 좋겠다.
coreboot나 DeviceTree, Open Firmware 같은 게 낫지 않나? UEFI나 BIOS는 호환 레이어일 뿐이고 장점이라곤 값싸고 빠른 하드웨어에 이미 설치돼 있다는 것뿐인데, 그것도 28년 전보다 장점이 줄었다.
다른 UEFI 자료도 있다. uefirc는 UEFI용 IRC 클라이언트고 uefi-rs를 라이브러리로 쓴다. GRUB이나 별도 부트로더 코드 경로 없이 UEFI에서 리눅스 커널을 직접 로드해 부팅하는 방법도 있다.