새해에 무언가를 시작하는 것은 그다지 익숙하지 않다. 하지만 코로나 바이러스가 한창 유행하던 2021년의 첫머리에 캔콜라를 마시면서 (지금 생각해 보면 모리 히로시의 S&M 시리즈에 무의식적으로 영향을 받은 게 분명하다) Racket Scheme의 실습을 하고 있더랬다. 그때의 감각을 되살려서 해보기로 한 Writing an OS in Rust 시리즈의 실습이다. 이미 블로그 포스트가 있으니 실습이라 해도 쓸 말이 있을지 모르겠지만, 그렇다고 갑자기 유튜브를 시작하기에는 너무도 나태한 나의 정신이다.
우선 그래도 혹시 모르니 내일부터는 동영상을 녹화해두기로 했다. (/etc/nixos/configuration.nix
에 넣어두고 지금껏 써본 적이 없는 OBS Studio를 써먹을 때다.)
첫날이니 셋업 이야기가 대부분이다. Rust를 많이 사용하지 않는 관계로 이제사 rustup
을 설치했다. NixOS에 rustup
을 추가해서 리빌드한 뒤, rustup default stable
로 툴체인을 내려받는다.
Emacs의 rust-mode는 기본적으로 rust-analyzer를 요구하는데, 이것도 rustup으로 구성 가능하다.
rustup component add rust-analyzer
cargo new blog_os --bin --edition 2018
이제부터는 튜토리얼대로. 막혔던 부분이나 인상 깊은 부분만 서술한다. 아무래도 강독회 같이 되어 버릴지도 모른다. 오히려 그렇게 되어서 좋은 점은, 텍스트북의 내용을 자신의 말로 언어화하는 과정에서 얻을 수 있는, 코드 실행 이상의 어떤 가치가 있다는 것이다. 물론 해보다가 탈언어화 -> 재언어화할 말들이 없어지면 영상 녹화만으로 끝날 수도 있는 일이다.
우선 가이드북의 각 코드 스니핏이 즉시 컴파일 가능한 것이 아니란 점을 말해 둬야겠다. 아무래도 일일이 실행하면서 나아가는 실습이 아닌, 하나의 완성된 코드를 위한 텍스트다.
알 만한 내용들도 많지만, 런타임 시스템을 보다 직접적으로 생각해볼 수 있어서 새롭다.
main
이전에 호출되는 런타임 시스템이 존재하며, Rust는 이를 위해 crt0라는 C 런타임 라이브러리를 사용한다는 것.- 그 다음,
start
language item으로써 Rust 런타임의 실행 시작 함수를 호출. 이것은 맥락상으로 보다 Rust 자체의 실행 시작 함수인 것 같다.
그렇다면 start가 main
을 가리키고 있다는 것 같은데, 그 start를 호출해주는 것이 crt0이기 때문에 start를 구현하고 지정하는 것만으로는 안 된다고 한다. 이 부분이 좀 까다롭다. 요는 지정하는 주체가 Rust인 이상 이것이 crt0으로 전달될 수 없다는 뜻인가? 아무래도 맞는 것 같다. crt0이 가리키는 start는 Rust 체계 안에서는 수정할 수 없도록 되어 있는 게 아닐까?
후반의 코드를 보니 조금 더 확신이 생겼다.
#[no_mangle]
pub extern "C" fn _start() -> ! {
loop {}
}
여기서 no_mangle
은 함수명이 Rust 컴파일러로 하여금 메모리 속에서 모종의 해시화 과정 비슷한 것 (UUID 라 할 수도 있겠다) 을 통과하지 않고, 직접적으로 함수명 (여기서는 _start
) 자체를 사용하게 하는 강제성을 부여한다. 그렇다면 crt0 속에 (아마도) 하드코딩된 _start
함수가 가리키는 함수 정의를 위의 정의로 메모리에 덮어쓸 수 있게 될 것이다. 이러한 – C의 요소에 직접적으로 관여하는 – 행위를 위해, 함수 정의 앞에는 pub extern "C"
를 붙여서 C의 함수 호출 규약을 적용시킬 수 있다고 한다.
이 다음에 발생하는 링커 오류를 해결하기 위해, 가이드북대로 C 런타임을 사용하지 않도록 링커를 설정해줘야 한다는데, 두어 가지 의문이 생긴다. 바로 전에 _start
의 재정의를 내린 것은 crt0를 위한 것이 아니었나? 이제 와서 C 런타임을 사용하지 않는다면 무엇 하러? _start
의 네이밍 컨벤션은 C뿐만이 아닌 다른 시스템에서도 보편적으로 적용되는 것이라고 한다면 아귀가 맞는다.
어찌되었건 rustup으로 컴파일 타깃을 추가하고, cargo로 빌드하니 문제는 없었다. 운영 체제가 없는 시스템을 타깃으로 컴파일하니 어째선지 기분이 좋다. 크로스 컴파일 만세다. 하지만 생각해 볼 거리들은 상술했다시피 남아 있다.
이럴 때는 각자의 특색과 사상이 너무 짙은 인터넷 포럼의 답변들보다 보편적인 시점을 제공하는 LLM의 힘을 빌리는 것이 낫다. 질문만 확실히 준비되어 있다면 말이다.