TECH 으로 돌아가기
TECH HACKER NEWS 1주 전 6분 읽기 23 READS

RAM 256KB짜리 1994년 게임기에서 리눅스 부팅하기 — 세가 32X 포팅기가 알려주는 동시성의 밑바닥

1994년에 나온 세가 32X는 메가드라이브 위에 얹어서 성능을 끌어올리는 확장 기기였어요. 상업적으로는 처참하게 실패해서 게임기 역사의 '흑역사'로 꼽히는 물건인데요, 30년이 지난 지금 한 개발자가 이 기기에서 리눅스를 부팅시키는 데 성공했어요. 단순히 '됐다'로 끝나는 게 아니라, 그 과정에서 마주친 문제들이 운영체제와 동시성 프로그래밍의 교과서 같은 내용이라 포팅기 자체가 훌륭한 읽을거리예요.

32X는 어떤 기계였나

스펙부터 볼게요. 32X에는 히타치의 SH-2라는 32비트 RISC CPU가 두 개 들어 있고, 클럭은 각각 약 23MHz예요. RAM은 256KB고요. 요즘 스마트워치보다도 한참 모자란 사양이죠. 그리고 결정적으로 MMU가 없어요. MMU가 뭐냐면 메모리 관리 장치(Memory Management Unit)인데, 각 프로세스에게 '너만의 독립된 메모리 공간'이라는 환상을 만들어주는 하드웨어예요. 리눅스의 가상 메모리와 프로세스 격리가 전부 이 장치에 기대고 있거든요.

MMU가 없으니 일반 리눅스는 못 올리고, no-MMU 리눅스라고 부르는 특수한 구성을 써야 해요. 예전에 uClinux라는 이름으로 발전하다가 지금은 커널 본체에 흡수된 기능인데, 가상 메모리 없이 모든 프로세스가 실제 메모리 주소를 그대로 쓰는 방식이에요. 프로세스 격리가 없어서 프로그램 하나가 실수하면 시스템 전체가 무너질 수 있지만, MMU 없는 소형 임베디드 칩에서는 지금도 현역으로 쓰이는 방식이죠. 256KB라는 메모리에 맞추려면 커널에서 뺄 수 있는 건 다 빼는 다이어트도 필수였고요.

진짜 문제: 원자적 연산이 없다

이 포팅기의 백미는 제목에도 나오는 '하드웨어 동기화 프리미티브' 이야기예요. CPU가 두 개니까 SMP, 그러니까 두 CPU가 하나의 커널을 같이 돌리는 구성을 시도했는데, 여기서 근본적인 벽을 만나요.

멀티코어 시스템에서는 두 CPU가 같은 데이터를 동시에 건드리지 못하게 막는 락(lock)이 필요해요. 그리고 락을 만들려면 원자적 연산이 필요하고요. 원자적 연산이 뭐냐면, '값을 읽고, 확인하고, 바꾸는' 과정이 중간에 절대 끼어들 수 없는 한 덩어리로 실행되는 연산이에요. 이게 보장되지 않으면 두 CPU가 동시에 '락이 비었네? 내가 잡아야지' 하고 둘 다 락을 잡아버리는 참사가 나거든요. SH-2에는 TAS(test-and-set)라는 원자적 명령이 있긴 한데, 문제는 32X의 버스 설계상 두 CPU 사이에서는 이 명령의 원자성이 제대로 보장되지 않는다는 거예요. 하드웨어가 락을 만들 재료 자체를 안 주는 상황인 거죠.

그럼 어떻게 했을까요? 하드웨어의 도움 없이 일반적인 메모리 읽기/쓰기만으로 상호 배제를 구현하는, 데커(Dekker)나 피터슨(Peterson) 알고리즘 같은 고전적인 소프트웨어 기법으로 돌아가는 거예요. 운영체제 수업에서 '역사적으로 이런 방법이 있었다'며 스쳐 지나가는 바로 그 알고리즘들이요. 각 CPU가 깃발 변수로 진입 의사를 표시하고 양보 순서를 정하는 규칙만으로, 원자적 명령 없이도 두 CPU가 절대 동시에 임계 구역에 들어가지 못하게 만드는 방식이죠. 교과서 속 유물인 줄 알았던 알고리즘이 2020년대에 실전 투입된 셈이에요.

왜 이런 일을 하는 걸까요

레트로 하드웨어에 리눅스나 둠(Doom)을 이식하는 건 해커 문화의 오랜 전통이에요. 실용성은 없지만, 극단적인 제약 속에서 시스템의 밑바닥을 다시 이해하게 되는 최고의 공부거든요. 평소에 당연하게 쓰는 뮤텍스가 사실은 하드웨어 원자 명령이라는 기반 위에 서 있다는 것, 그리고 그 기반이 사라지면 어떤 일이 벌어지는지를 이렇게 생생하게 보여주는 사례는 드물어요.

한국 개발자에게도 시사점이 분명해요. 우리가 매일 쓰는 락, 세마포어, 동시성 자료구조가 어떤 하드웨어 계약 위에 만들어졌는지 이해하면 동시성 버그를 보는 눈이 달라지거든요. 커널이나 임베디드 쪽으로 커리어를 넓히고 싶은 분에게는 이런 포팅기가 살아 있는 교재고, 당장 그쪽 일을 안 하더라도 멀티스레드 코드를 짤 때의 감각이 한층 깊어져요.

정리하면, 실패한 1994년 게임기에서 리눅스를 돌리기 위해 교과서 속 동기화 알고리즘을 부활시킨 이야기예요. 여러분은 '당연히 있는 줄 알았던 기반'이 없어서 고생해본 경험, 있으신가요?


🔗 출처: Hacker News

SOURCE · HACKER NEWS
원문 전체 보기 → https://cakehonolulu.github.io/linux-on-32x/
SHARE
처리 중...