TECH 으로 돌아가기
TECH HACKER NEWS 오늘 8분 읽기 21 READS

512바이트 부트 섹터에 콘웨이의 생명 게임을 넣었다: OS 없이 돌아가는 코드 이야기

512바이트 부트 섹터에 콘웨이의 생명 게임을 넣었다: OS 없이 돌아가는 코드 이야기
SOURCE IMAGE · HACKER NEWS
512바이트 부트 섹터에 콘웨이의 생명 게임을 넣었다: OS 없이 돌아가는 코드 이야기

운영체제 없이 돌아가는 512바이트 프로그램

리눅스 커널 내부를 설명한 Linux Insides로 유명한 0xAX가 BootLife라는 작은 프로젝트를 공개했어요. 콘웨이의 생명 게임을 부트 섹터 안에 구현한 건데요, 운영체제가 아예 없는 상태에서 컴퓨터가 켜지자마자 바로 실행되는 프로그램이에요. 크기는 딱 512바이트. 요즘 웹 페이지 파비콘 하나보다 작아요.

왜 이런 걸 만드는지 궁금할 수 있는데요, 사실 이 장르는 저수준 프로그래밍을 배우는 사람들 사이에서 오래된 통과의례 같은 거예요. 컴파일러도, 라이브러리도, printf도 없는 상태에서 화면에 뭔가를 그려보면 컴퓨터가 정말 어떻게 시작되는지 몸으로 알게 되거든요.

이게 뭐냐면: 부트 섹터와 생명 게임

두 가지 개념만 알면 돼요.

부트 섹터부터요. 컴퓨터 전원을 켜면 메인보드에 있는 BIOS라는 작은 펌웨어가 먼저 깨어나요. BIOS는 디스크의 맨 첫 512바이트를 읽어서 메모리 주소 0x7C00에 복사하고, 그냥 거기로 점프해버려요. 그 512바이트가 뭐든 상관없이요. 다만 조건이 하나 있는데, 마지막 두 바이트가 0x55 0xAA여야 해요. 이걸 부트 시그니처라고 부르는데, '이 디스크는 부팅 가능해요'라는 도장 같은 거예요. 그래서 실제로 코드를 넣을 수 있는 공간은 510바이트예요. 보통은 여기에 '진짜 운영체제를 디스크에서 더 읽어오는 코드'가 들어가는데, BootLife는 그 자리에 게임 자체를 넣어버린 거죠.

생명 게임은 수학자 존 콘웨이가 만든 셀룰러 오토마톤이에요. 격자 위에 살아있는 칸과 죽은 칸이 있고, 세대마다 규칙에 따라 바뀌어요. 규칙은 딱 세 줄이에요. 살아있는 칸은 이웃이 2개나 3개면 살아남고, 아니면 죽어요. 죽은 칸은 이웃이 정확히 3개면 태어나요. 이 단순한 규칙에서 글라이더처럼 움직이는 패턴, 무한히 성장하는 패턴 같은 게 튀어나와서 지금까지도 사람들이 연구하는 주제예요. 플레이어가 조작하는 게임은 아니고, 초기 상태를 정해주면 알아서 돌아가는 시뮬레이션이에요.

510바이트 안에서 어떻게 돌아가나

BootLife는 x86 어셈블리로 작성돼 있고, BIOS가 점프한 직후의 환경인 16비트 리얼 모드에서 동작해요. 리얼 모드는 1980년대 8086 CPU와 호환되는 모드인데, 메모리 보호도 없고 주소도 1MB까지만 쓸 수 있지만 대신 BIOS가 제공하는 기능을 인터럽트로 바로 호출할 수 있어요. 예를 들어 int 0x10을 부르면 화면 모드를 바꾸거나 글자를 출력할 수 있고, int 0x16으로 키보드 입력을 받을 수 있어요.

이런 부트 섹터 프로그램에서 화면을 그리는 흔한 방법은 비디오 메모리에 직접 쓰는 거예요. 텍스트 모드라면 0xB8000 주소부터가 화면이라서, 거기에 글자 코드와 색상 바이트를 쓰면 바로 화면에 나타나요. 그래픽 모드라면 0xA0000부터 픽셀을 찍고요. OS가 그려주는 게 아니라 메모리에 값을 넣으면 하드웨어가 그걸 보여주는 방식이라, 개념적으로는 아주 원시적이지만 그래서 오히려 직관적이에요.

생명 게임 자체의 구현은 두 개의 격자 버퍼를 번갈아 쓰는 게 기본이에요. 현재 세대를 읽으면서 다음 세대를 다른 버퍼에 쓰고, 다 끝나면 두 버퍼의 역할을 바꾸는 거죠. 각 칸마다 주변 8칸을 세어야 하니까 이중 루프 안에 또 루프가 있는 구조인데, 510바이트에 맞추려면 이 부분을 얼마나 압축하느냐가 관건이에요. 이런 사이즈코딩에서 자주 쓰는 기법이 몇 가지 있는데요, x86의 문자열 명령어인 lodsb나 stosb를 쓰면 '읽고 포인터 증가'가 한 바이트 명령어로 끝나고, 레지스터를 0으로 만들 때 mov 대신 xor을 쓰면 더 짧고, 격자 크기를 2의 거듭제곱으로 잡으면 경계 처리를 나눗셈 없이 AND 연산으로 끝낼 수 있어요. 한 바이트가 아쉬운 세계라서 이런 잔기술이 쌓여야 들어가요.

직접 돌려보는 건 어렵지 않아요. nasm -f bin boot.asm -o boot.bin으로 어셈블해서 바이너리를 만든 다음, qemu-system-x86_64 -drive format=raw,file=boot.bin처럼 QEMU에 디스크 이미지로 넘기면 돼요. 진짜 USB에 dd로 구워서 실제 PC를 부팅시켜볼 수도 있어요. 다만 요즘 PC는 UEFI 부팅이 기본이라 BIOS 호환 모드(CSM)를 켜야 하는 경우가 많아요.

업계 맥락: 부트 섹터 프로그래밍이라는 작은 장르

부트 섹터에 뭔가를 욱여넣는 건 하나의 취미 장르예요. 512바이트 테트리스인 Tetranglix, 부트 섹터 스네이크 게임, 심지어 BASIC 인터프리터를 넣은 bootBASIC과 작은 OS인 bootOS 같은 프로젝트도 있어요. 데모씬에서는 이걸 사이즈코딩이라고 부르고 256바이트, 128바이트 단위로 경쟁하기도 해요. 이 흐름의 공통점은 '제약이 창의력을 만든다'는 거예요. 제한이 극단적이니까 CPU와 하드웨어를 정말 깊이 이해해야 하고, 그 과정에서 배우는 게 많아요.

한국 개발자에게 주는 시사점

실무에서 부트 섹터를 짤 일은 거의 없어요. 하지만 이 프로젝트가 주는 학습 가치는 커요. 컴퓨터 구조 수업에서 배운 '부팅 과정'을 실제 코드로 만져볼 수 있고, 어셈블리를 처음 배우는 사람에게는 결과가 화면에 바로 보이니까 동기부여가 되거든요. 커널이나 임베디드, 펌웨어 쪽에 관심 있다면 주말 프로젝트로 딱이에요. BootLife 코드를 읽으면서 한 줄씩 무슨 일을 하는지 따라가보고, 그다음에 규칙을 바꾸거나 색을 바꾸는 식으로 손대보면 돼요. 0xAX가 쓴 Linux Insides와 같이 보면 부트 섹터 다음 단계, 그러니까 리눅스 커널이 어떻게 이어받는지까지 자연스럽게 연결돼요.

정리

한 줄 정리: 운영체제 없이 BIOS가 읽는 512바이트만으로 생명 게임이 돌아가고, 그걸 이해하면 컴퓨터가 켜지는 과정이 머릿속에 그려져요.

여러분은 어셈블리를 처음 배울 때 어떤 프로그램으로 시작했나요? 아니면 이런 극단적인 제약 속 코딩이 실무 능력에 도움이 된다고 생각하시나요?


🔗 출처: Hacker News

SOURCE · HACKER NEWS
원문 전체 보기 → https://github.com/0xAX/BootLife
SHARE
NEXT · CHOOSE

변화를 읽었다면,
내가 만들 수익 구조를 고릅니다.

정보를 더 모으는 데서 멈추지 않고, 광고·외주·판매·중개·구독 중 내 상황에 맞는 출발점을 정해보세요.

21가지 수익 구조 살펴보기
처리 중...