envia

From Power Up To Bash Prompt

Greg O'Keefe, gcokeefe@postoffice.utas.edu.au

v0.9a, November 2000

그레그 찰스 오키프(Greg Charles O'Keefe)님의 사이트에서 원문을 읽을 수 있고, From Power Up To Bash Prompt 홈 페이지에서 다양한 형식으로 구할 수 있습니다.

이 문서는 KLDP 위키 페이지에서 수정된 내용을 반영하고 있으며, 번역을 하면서 센다 유지(千旦 裕司)님의 일본어 번역판을 참고하였습니다. 이 문서의 내용은 꽤 오래 되었으며 제가 시험해 보지 않았기 때문에 동작하지 않는 것도 있을 수 있습니다.

이 번역은 원문과 마찬가지로 그누 일반 공중 사용 허가서(GNU General Public License)의 규정에 따라 이용할 수 있습니다.


이 문서는 전원을 켤 때부터 로그인하고 배시 프롬프트가 뜰 때까지 리눅스 시스템에서 무슨 일이 일어나는지를 간략히 설명합니다. 이것을 이해하는 것은 여러분이 문제를 해결하거나 시스템을 설정할 때 도움이 될 것입니다.

소개

저는 제 리눅스 머신에서 제가 이해하지 못한 많은 일들이 일어난다는 것을 불만스러워 합니다. 여러분도 저와 같이 그저 시스템의 사용법을 알고 싶으실 뿐만이 아니라 진짜로 시스템을 이해하고 싶어하신다면, 이 문서는 좋은 출발점이 될 것입니다. 여러분이 최고 수준의 리눅스 문제 해결사가 되고 싶을 때에도 이러한 종류의 배경 지식이 필요할 것입니다.

저는 여러분이 동작하는 리눅스 박스를 가지고 있고, 유닉스와 PC 하드웨어에 대한 기본적인 것들을 이해하고 있다고 가정하겠습니다. 만약 그렇지 않다면, Eric S. Raymond의 The Unix and Internet Fundamentals HOWTO부터 배우시는 것이 것이 매우 바람직합니다. 이 글은 짧고, 매우 읽기 쉬우며, 모든 기초를 다루고 있습니다.

리눅스 시스템이 시작되는 과정이 이 문서의 주제입니다. 그렇지만 좀 더 포괄적인 학습 자료로도 쓰일 수 있도록 노력하였습니다. 각 절(section)마다 연습 문제들을 포함하였습니다. 만약 여러분들이 그것들을 실제로 해 본다면, 단순히 읽으셨을 때 배울 수 있는 것보다 많은 것을 배우실 수 있을 것입니다.

제가 아는 한 리눅스를 배울 때 할 수 있는 가장 좋은 연습은 소스 코드로부터 리눅스 시스템을 구축하는 것이며, 저는 독자분들이 그것을 해 보셨으면 합니다. 이탈리아의 철학자인 Giambattista Vico(1668-1744)는 이해는 만듦에서 기원한다(understanding arises through making)는 뜻인 verum ipsum factum이라는 말을 남겼습니다. 이 구절을 가르쳐준 Alex(감사를 보십시오.)에게 감사합니다.

만약 여러분이 소스 코드로부터 리눅스 시스템을 설치하여 여러분의 것을 돌리고자(roll your own) 한다면, Gerard Beekmans의 Linux From Scratch HOWTO(LFS)를 보아야 할 것입니다. LFS에는 소스 코드로부터 완전히 사용가능한 시스템을 구축하는 것에 관한 자세한 지시사항들이 있습니다. 여러분은 LFS 웹사이트에서 시스템을 이러한 방법으로 구축하고자 하는 사람들을 위한 메일링 리스트도 찾을 수 있을 것입니다. LFS의 일부 지시 사항들은 지금 독립된 문서인 Building a Minimal Linux System from Source Code가 되었으며, 여러분은 이것을 From Power Up to Bash Prompt 홈 페이지에서 찾을 수 있습니다. 그것들은 순수하게 배우기 위한 연습으로서 장난감(toy) 시스템을 구축하는 방법을 설명하고 있습니다.

꾸러미(package)들은 시스템이 시작하는 과정에서 나타나는 순서대로 소개되어 있습니다. 이것은 여러분이 꾸러미들을 문서에 나온 순서대로 설치하면, 각각의 설치가 끝날 때마다 재부팅을 할 수 있고, 그 때마다 시스템은 배시 프롬프트를 보여주는 상태에 좀 더 가까워진다는 것을 뜻합니다. 이러한 면을 통해서 상황이 진전되고 있다는 확신을 받을 수 있습니다.

저는 여러분이 처음 읽을 때에는 연습 문제나 참고 자료들을 건너뛰면서 각 절(section)의 본문을 읽기를 권합니다. 그 다음에 얼마나 깊게 이해하고 싶은지, 얼마나 많이 노력할 준비가 되었는지 결정하십시오. 그 다음에 다시 처음으로 돌아와서, 연습 문제를 푸시고, 참고 자료들도 읽으시면서 다시 시작하십시오.

하드웨어

여러분이 처음으로 컴퓨터를 켜게 되면 컴퓨터는 자기 자신을 테스트해서 모든 것들이 잘 작동하는지 확인합니다. 이 과정은 Power on self test라고 불립니다. 그 다음에 ROM BIOS에 있는 부트스트랩 로더(bootstrap loader)라는 프로그램이 호출되어 부트 섹터를 찾습니다. 부트 섹터는 디스크의 첫번째 섹터로서 운영체제를 읽을 수 있는 작은 프로그램이 저장되어 있습니다. 부트 섹터는 0x1FE = 510 바이트 위치에 매직 넘버(magic number) 0xAA55 = 43603 이 있는 것으로 구분됩니다. 이것은 섹터의 마지막 두 바이트 입니다. 이를 통해서 하드웨어는 어떤 섹터가 부트 섹터인지 아닌지를 알 수 있습니다.

부트스트랩 로더는 부트 섹터를 찾을 장소들의 목록을 가지고 있습니다. 제 오래된 기계는 첫번째(primary) 플로피 드라이브와 첫번째(primary) 하드 디스크를 찾았습니다. 최근의 기계들은 CD ROM에서도 부트 섹터를 찾을 수 있습니다. 부트스트랩 로더가 부트 섹터를 찾으면, 부트 섹터를 메모리로 읽은 뒤 운영체제를 읽는 프로그램에게 제어권을 넘깁니다. 일반적인 리눅스 시스템에서 이 프로그램은 LILO의 일단계(first stage) 부트 로더(boot loader)일 것입니다. 사실 여러분의 시스템이 부팅하는 과정은 다양하게 설정될 수 있습니다. 자세한 내용은 LILO User's Guide를 보십시오. URL은 LILO 섹션에서 찾으십시오.

PC 하드웨어가 무슨 일을 하는 지에 대해 언급할 것은 당연히 많이 남아 있지만, 이 문서는 그것을 다루지 않습니다. PC 하드웨어를 다룬 많은 좋은 책들이 있으니 참고하십시오.

설정

컴퓨터는 자기 자신에 대한 정보를 CMOS에 저장합니다. 시스템에 어떤 디스크와 램이 있는가와 같은 정보도 저장되어 있습니다. 컴퓨터의 BIOS는 여러분이 이러한 설정들을 고칠 수 있도록 하는 프로그램을 포함하고 있습니다. 컴퓨터가 켜질 때 화면에 나오는 메시지들을 확인하여 어떻게 그 프로그램을 실행할 수 있는지 보십시오. 제 컴퓨터에서는 운영체제가 읽히기 전에 딜리트(delete)키를 누르면 되었습니다.

연습 문제

PC 하드웨어에 대해 배울 수 있는 좋은 방법은 중고 부품들을 모아서 새로운 컴퓨터를 조립해 보는 것입니다. 리눅스를 쉽게 실행시킬 수 있도록 적어도 386을 만들도록 하십시오. 주변에 물어보면, 당신이 필요한 부분을 누군가가 줄 수도 있습니다.

Unios에 대해 확인하고, 다운로드한 뒤 컴파일 하여 부트 디스크를 만들어보십시오. (그들의 홈페이지가 http://www.unios.org에 있었지만, 사라졌습니다.) 이것은 100줄 정도의 어셈블러 코드로 구성된 단순한 부팅할 수 있는 Hello World! 프로그램입니다. 어셈블러 코드를 GNU 어셈블러 as가 이해할 수 있는 형태로 변환하여 읽어 보시는 것도 좋을 것입니다.

여러분의 운영체제를 만들어 여러분의 것을 돌리는(roll your own) 것에 대한 지시 사항이 Roll Your Own에 있습니다. 여러분이 진정한 도전을 찾고 있으시다면 읽어 보시기 바랍니다.

헥스 에디터(hex editor)로 부트 디스크 이미지를 열어 보십시오. 이 이미지의 길이는 정확히 한 섹터가 되는 512바이트입니다. 매직 넘버(magic number) 0xAA55를 찾아 보십시오. 다른 부팅 가능한 플로피 디스크나 여러분의 컴퓨터의 부트 섹터에 대해서도 같은 일을 해 보십시오. 여러분은 dd if=/dev/fd0 of=boot.sector와 같이 dd명령을 사용해서 그것을 파일로 복사할 수 있습니다. if (input file, 입력 파일)와 of (out file, 출력 파일)를 정확히 입력하였는지 매우 조심스럽게 확인하십시오.

리로의 부트 로더의 소스 코드를 읽어 보십시오.

추가 정보

리로(Lilo)

컴퓨터가 보통 리눅스 시스템의 부트 섹터를 읽을 때, 실제로 읽는 것은 lilo의 일부분인 일단계 부트 로더(first stage boot loader)입니다. 이것은 이단계 부트 로더(first stage boot loader)를 불러들이는 일만을 하는 작은 프로그램입니다.

이단계 부트 로더는 (그렇게 하도록 설치하였다면) 프롬프트를 표시하고 여러분이 선택한 운영 체제를 읽어들입니다.

여러분의 시스템이 시작되고 동작하는 상태에서 여러분이 lilo를 실행한다면, 여러분이 실제로 실행하는 것은 map installer입니다. 이것은 설정 파일인 /etc/lilo.conf를 읽고 부트 로더와 부트로더가 읽을 수 있는 운영 체제에 대한 정보를 하드 디스크에 씁니다.

여러분의 시스템을 부트하는 데에는 매우 다양한 방법들이 있습니다. 제가 설명할 것은 적어도 주 운영 체제가 리눅스인 시스템에서는 가장 단순하고 일반적인 방법입니다. Lilo 사용자 가이드(Lilo Users' Guide)는 부트 개념(boot concept)의 몇몇 예들을 설명합니다. 이것은 읽어볼만한 글이며, 그 중의 일부를 소개하겠습니다.

설정

Lilo의 설정파일은 /etc/lilo.conf입니다. 그것을 위한 맨 페이지가 있습니다. 셸에서 man lilo.conf라고 치시면 보실 수 있습니다. lilo.conf의 핵심은 리로가 부트하도록 되어 있는 것들마다 하나씩 있는 설정 항목입니다. 리눅스 항목에는 커널이 어디에 있는지와 루트 파일시스템으로 어느 디스크 파티션을 마운트할지를 포함하고 있습니다. 다른 운영 체제에 대한 항목에는 주로 어느 파티션으로부터 부트할 것인지에 대한 정보가 있습니다.

연습 문제

위험: 이 연습 문제를 해결 하실 때 주의하십시오. 무언가 잘못하여 여러분의 마스터 부트 레코드(your master boot record)를 날리게 되어 여러분의 시스템을 사용할 수 없게 만들기 쉽습니다. 여러분은 응급 디스크(rescue disk)를 가지고 있어야 하고, 어떻게 다시 복구할 수 있는지를 알아야 합니다. 제가 사용했고 권장하는 응급 디스크인 tomsrtbt의 링크는 아래에 있습니다. 가장 좋은 방법은 사용할 수 없게 되어도 괜찮은 컴퓨터를 사용하는 것입니다.

리로를 플로피 디스크에 설치하십시오. 플로피에 커널밖에 없어도 됩니다. 여러분은 커널이 init를 부르려고 할 때 커널 패닉(kernel panic)을 경험하시겠지만, 최소한 lilo가 동작한다는 것은 아실 수 있을 것입니다.

여러분이 바라신다면 플로피 위에서 시스템이 어디까지 진행될 수 있는지 실험해 보실 수도 있을 것입니다. 이것은 아마도 두번째로 좋은 리눅스를 배우는 활동일 것입니다. 단서를 위해서 Bootdisk HOWTO(URL은 아래에 있습니다.)와 tomsrtbt(URL은 아래에 있습니다.)를 보실 수 있을 것입니다.

리로로 unios(하드웨어 연습에서 URL을 찾으십시오)를 부팅해 보십시오. 추가로, 이것을 플로피 디스크에서 하실 수 있는지 확인해 보십시오.

부트 루프(boot-loop)를 만들어 보십시오. 리로를 마스터 부트 레코드에 설치하여 프라이머리 파티션 부트 섹터중의 하나에 있는 리로를 부팅하고, 그 리로가 마스터 부트 레코드의 리로를 부트하고, 이것이 반복되게 하십시오. 여러분은 마스터 부트 레코드와 네개의 프라이머리 파티션 모두를 사용하여 5단계 루프를 만들 수도 있을 것입니다. 즐기세요!

추가 정보

리눅스 커널

리눅스 커널은 정말로 많은 일을 합니다. 잘 정리하면, 리눅스 커널은 하드웨어들이 공정하고 능률적으로 프로그램이 바라는 일을 하도록 합니다.

프로세서는 동시에 한가지 명령밖에 수행하지 못하지만, 리눅스 시스템은 동시에 많은 일을 수행하는 것 처럼 보입니다. (역주 — 최신 프로세서들은 동시에 여러 명령을 수행할 수 있지만, 여전히 모든 일을 동시에 처리하지는 못합니다.) 커널은 작업과 작업 사이를 매우 빠르게 전환함으로서 이것을 가능하게 합니다. 커널은 어떤 프로레스가 실행될 준비가 되었고, 어떤 프로세스가 하드디스크 파일의 레코드나 키보드 입력과 같은 것을 기다리고 있는지를 추적하여 프로세서를 가장 효율적으로 사용되게 합니다. 이것이 스케쥴링(scheduling)이라고 불리는 작업입니다.

어떤 프로그램이 아무 일도 하지 않는다면, 그것은 RAM에 있을 필요가 없습니다. 무언가를 하고 있는 프로그램이라고 할지라도, 그 프로그램의 일부분은 아무것도 하지 않을 수 있습니다. 각 프로세스의 주소 공간은 페이지로 나뉘어집니다. 커널은 어느 프로세스의 어느 페이지가 가장 많이 쓰이는지를 추적합니다. 그다지 많이 쓰이지 않는 페이지들은 스왑 파티션으로 옮겨집니다. 그들이 다시 필요해지면, 다른 쓰이지 않는 페이지들이 페이지 아웃(paged out)되어 공간을 만듭니다. 이것이 가상 메모리 관리입니다.

여러분이 커널을 컴파일해 보신 적이 있으시다면, 특정한 장치들에 대해서 많고 많은 옵션들이 있다는 것을 느끼셨을 것입니다. 커널은 다양한 종류의 하드웨어들과 대화하기 위한 많은 특별 코드들을 가지고 있어서, 어플리케이션 프로그램들이 모든 하드웨어들을 단일하고 좋은 방법으로 접근할 수 있도록 합니다.

커널은 파일시스템, 프로세스간 통신, 네트워킹과 관련된 많은 것들도 관리합니다.

일단 커널이 불려지면, 가장 먼저 하는 일은 실행할 init 프로그램을 찾는 것입니다.

설정

여러분이 /usr/src/linux/(나 여러분의 커널 소스가 있는 곳)에서 make menuconfigmake xconfig를 사용하여 설정하고 커널을 만들 때 대부분의 커널 설정이 이루어집니다. 여러분은 기본 비디오 모드, 루트 파일시스템, 스왑 디바이스, 램 디스크 사이즈 등을 rdev를 통해 다시 설정할 수 있습니다. 이러한 파라메터들과 다른 것들은 리로로부터 커널로 전달될 수 있습니다. 여러분은 lilo.conf 안에서나 리로 프롬프트에서 커널에게 넘겨질 리로 파라메터들을 정할 수 있습니다. 예를 들어 여러분이 hda3을 hda2대신에 루트 파일시스템으로 이용하려고 하신다면 아래와 같이 입력하실 것입니다.

	LILO: linux root=/dev/hda3

여러분이 소스로부터 시스템을 만들고 계신다면, 여러분은 모놀리틱(monolithic) 커널을 만들어서 일을 단순하게 하실 수 있습니다. 모놀리틱 커널은 모듈이 없는 커널입니다. 여러분은 커널 모듈을 대상 시스템으로 복사할 필요가 없을 것입니다. (역주 — 이 글에서 모놀리틱 커널은 모듈이 없는 커널이라는 의미로 쓰였지만, 다른 글에서는 마이크로 커널에 반대되는 의미로 자주 쓰입니다.)

주의: System.map 파일은 메시지를 만들어내는 모듈들의 이름을 정하기 위해서 커널 로거(kernel logger)에 의해 사용됩니다. top 프로그램도 이 정보를 사용합니다. 여러분이 커널을 대상 시스템에 복사할 때, System.map도 복사하세요.

연습 문제

/dev/hda3은 하드 디스크 파티션을 설명하는 특별한 종류의 파일입니다. 하지만 이것은 다른 파일들과 같이 파일 시스템 안에 있습니다. 커널은 어느 파티션을 루트 파티션으로 마운트할지를 알고자 합니다. 하지만, 파일 시스템은 아직 없는 상태입니다. 커널이 어떻게 /dev/hda3을 읽어서 어느 파티션을 마운트 할지를 알까요? 생각해 보십시오.

여러분이 아직 해보지 않으셨다면, 여러분만의 커널을 만들어 보십시오. 각 옵션마다 있는 도움말을 모두 읽어 보십시오.

작동하는 커널을 얼마나 작게 만들 수 있는지 보십시오. 꼭 필요한 것을 뺐을 때 여러분은 많은 것을 배울 수 있습니다.

The Linux Kernel(URL은 아래에 있습니다.)을 읽어보고 참조하는 소스 코드들을 찾아 보십시오. (제가 이 글을 쓸 때) 이 책은 커널 2.0.33을 참조하고 있었으며, 이것은 꽤 지난 배포판입니다. 여러분이 이 옛 커널을 다운로드 받아 참고하는 것이 더 편할지도 모르겠습니다. 프로세스페이지라고 불리는 C 코드를 찾는 것은 놀라운 일입니다.

해킹하십시오! 여러분이 추가적인 메시지나 다른 것들을 출력하게 만들수 있는지 시험해 보십시오.

추가 정보

그누 C 라이브러리(The GNU C Library)

여러분의 컴퓨터가 시작될 때 다음으로 일어날 일은 init가 불려져서 실행되는 것입니다. 하지만, 다른 거의 모든 프로그램들과 같이 init도 라이브러리 함수들을 사용합니다.

여러분은 아마도 아래와 같은 예제 C 코드를 보신 적이 있을 것입니다.

	main() {
		printf("Hello World!\n");
	}

이 프로그램에는 printf의 정의가 없는데, 그렇다면 printf는 어디에서 나타난 것일까요? 그누/리눅스 시스템의 표준 C 라이브러리인 glibc에서 온 것입니다. 여러분이 이것을 Visual C++에서 컴파일을 하신다면, printf는 같은 표준 함수를 마이크로소프트에서 구현한 것에서 오게 될 것입니다. 수학이나 문자열, 날짜/시간, 메모리 할당과 같은 일들을 위한 수많은 표준 함수들이 있습니다. (리눅스를 포함한) 유닉스의 모든 것들은 C로 썼거나 C로 써진 것처럼 보이려고 노력하기 때문에, 모든 것들이 이러한 함수를 사용합니다.

여러분이 시스템의 /lib 아래를 본다면 libsomething.solibsomething.a와 같은 많은 파일들을 볼 수 있을 것입니다. 이들은 위와같은 함수들의 라이브러리 파일입니다. Glibc는 단순히 GNU에서 그러한 함수를 구현해 놓은 것입다.

프로그램이 이러한 라이브러리 함수들을 사용하는 데에는 두 가지 방법이 있습니다. 만약 여러분이 프로그램을 정적으로(statically) 링크한다면, 이 라이브러리 함수들은 만들어지는 실행 가능한 파일에 복사될 것입니다. libsomething.a와 같은 파일은 이러한 일을 위한 것입니다. 여러분이 동적으로(dynamically) 프로그램을 링크한다면(이것은 기본값입니다.), 프로그램이 실행되어 라이브러리 코드가 필요할 때 libsomething.so에서 부르게 될 것입니다.

여러분이 특정한 프로그램에서 어떠한 라이브러리가 필요한지 알려고 하신다면 ldd명령을 쓰실 수 있습니다. 예를 들어 bash가 어떠한 라이브러리들을 쓰는지 아시려면 아래와 같이 입력하십시오.

	[greg@Curry power2bash]$ ldd /bin/bash
		libtermcap.so.2 => /lib/libtermcap.so.2 (0x40019000)
		libc.so.6 => /lib/libc.so.6 (0x4001d000)
		/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)

설정

라이브러리의 몇몇 함수들은 여러분이 어디에 사시는지에 따라 다른 일을 합니다. 예를 들어, 호주에서는 날자를 일/월/년과 같이 쓰지만, 미국에서는 월/일/년과 같이 씁니다. glibc 배포판에 함께 있는 localedef라는 프로그램은 여러분이 이것을 설정할 수 있도록 합니다.

연습 문제

여러분이 가장 좋아하는 어플리케이션이 어떠한 라이브러리를 사용하는지 ldd로 알아보십시오.

lddinit가 어떤 라리브러리를 사용하는지 알아보십시오.

한개나 두개의 함수만을 포함하는 장난감 라이브러리를 만들어 보십시오. 그러한 라이브러리는 ar 프로그램으로 만들 수 있으며, ar의 맨 페이지는 어떻게 이것이 이루어지는지 조사하기 위해 먼저 보아야 할 자료입니다. 이 라이브러리를 쓰는 프로그램을 쓰고 컴파일 한 뒤 링크해 보십시오.

추가 정보

Init

저는 리눅스 시스템들이 가장 많이 사용하는 System V 스타일의 init만을 언급하겠습니다. 다른 대안들도 있습니다. 사실, 여러분은 어떤 프로그램이라도 /sbin/init에 넣을 수 있고, 커널은 자신이 완전히 불린 다음에 그것을 실행할 것입니다.

init이 하는 일은 모든 것들이 바라는 대로 실행되게 하는 것입니다. 파일 시스템이 괜찮은지 확인하고 마운트합니다. 데몬들이 시작해서 시스템 메시지들을 로그하게 하고, 네트워킹을 하고, 웹 페이지를 보내고, 마우스가 무슨 일을 하는지 보는 것과 같은 일을 합니다. 이것은 여러분의 가상 터미널에 로그인 프롬프트를 출력하는 getty 프로세스를 시작합니다.

런레벨(run-levels)을 전환하는 것에 대해 다 이야기 하려면 복잡하겠지만, 여기서는 대부분을 건너뛰고 시스템 시작에 관련된 부분만 이야기할 것입니다.

Init는 무엇을 할지 기록되어 있는 /etc/inittab이라는 파일을 읽습니다. 전형적으로 제일 먼저 하는 일은 초기화 스크립트를 실행하는 것입니다. 이 스크립트를 실행(또는 해석)하는 것은 여러분에게 명령 프롬프트를 주는 프로그램이기도 한 bash입니다. 데비안 시스템에서 시작 스크립트는 /etc/init.d/rcS이고, 레드햇에서는 /etc/rc.d/rc.sysinit입니다. 여기서 파일시스템이 체크되며 마운트되고, 시계가 설정되고, 스왑 공간이 켜지고, 호스트 이름이 설정되는 것과 같은 일이 일어납니다.

다음으로, 또 다른 스크립트가 불려져서 우리를 기본 런레벨로 데려갑니다. 기본 런레벨은 실행할 수 있는 서브시스템들의 모임입니다. 각각의 런레벨들에 대하여 레드햇에서는 /etc/rc.d/rc0.d, /etc/rc.d/rc1.d, ..., /etc/rc.d/rc6.d와 같은 디렉토리가 있고, 데비안에는 /etc/rc0.d, /etc/rc1.d, ..., /etc/rc6.d와 같은 디렉토리들이 있습니다. 데비안에서 우리는 런레벨 3으로 가서 /etc/rc3.d안에 있는 ‘S’(시작, start를 의미)로 시작하는 스크립트들을 실행합니다. 사실 이 스크립트들은 init.d라는 다른 디렉토리에 있는 스크립트에 대한 링크입니다.

그래서 우리의 런레벨 스크립트는 init에 의해 불려지고, 디렉토리 안에서 ‘S’로 시작하는 스크립트들을 찾습니다. S10syslog를 먼저 찾을 수도 있습니다. 숫자는 스크립트들을 실행시키는 순서를 알려줍니다. 그래서 이 경우 S00 ... S09로 시작하는 스크립트들이 없었기 때문에 S10syslog가 먼저 실행됩니다. S10syslog는 시스템 로거를 시작하고 끝내는 스크립트인 /etc/init.d/syslog로의 링크입니다. 링크가 ‘S’로 시작하기 때문에, 런레벨 스크립트는 syslog 스크립트를 start 파라메터로 실행합니다. 여기에 대응되는 런레벨을 떠날 때 무엇을 무슨 순서로 꺼야 하는지를 지시하는 링크는 ‘K’(죽이기, kill을 의미)로 시작합니다.

기본으로 시작되는 서브시스템들을 바꾸려면, 여러분은 rcN.d 디렉토리 안에 있는 이러한 링크들을 설정해야 할 것입니다. 여기서 N은 inittab에 설정된 기본 런레벨입니다.

Init가 마지막으로 하는 중요한 일은 getty들을 시작하는 것입니다. 그들은 몇 번이라도 소생하는(respawned) 특징을 가지고 있습니다. 이는 그들이 정지되었을 때, init가 그들을 다시 시작하게 한다는 것을 의미합니다. 대부분의 배포판들은 여섯개의 가상 터미널이 있습니다. 여러분은 메모리를 절약하기 위해서 수를 줄일 수도 있고, 많은 것들을 동시에 실행하면서 필요할 때마다 전환할 수 있도록 늘릴 수도 있을 것입니다. 여러분은 getty를 텍스트 터미널이나 모뎀 연결을 위해 실행하고 싶으실 수도 있습니다. 이런 경우에는 여러분이 inittab 파일을 편집할 필요가 있을 것입니다.

설정

/etc/inittab은 init를 위한 최고 수준의 설정 파일입니다.

N = 0, 1, ..., 6인 rcN.d 디렉토리들은 어떤 서브시스템이 시작되는지를 결정합니다.

init에 의해 불려지는 스크립트 중의 하나의 어디에선가 mount -a 명령이 실행될 것입니다. 이것은 마운트하기로 예정된 모든 파일시스템들이 마운트한다는 것을 의미합니다. 파일 /etc/fstab이 무엇이 마운트될 예정인지를 정의합니다. 여러분이 시스템이 시작될 때 무엇이 어디에 마운트 되는지를 바꾸고 싶으시다면 이 파일을 편집하십시오. fstab에 대한 맨 페이지가 있습니다.

연습 문제

여러분의 시스템의 기본 런레벨을 위한 rcN.d디렉토리를 찾아 파일들이 어디로 링크되어 있는지 ls -l로 보십시오.

여러분의 시스템에서 실행되는 getty들의 수를 바꾸어 보십시오.

여러분의 기본 런레벨에서 필요로 하지 않는 서브시스템을 없애십시오.

얼마나 적은 프로그램을 실행하며 시스템을 시작할 수 있는지 보십시오.

여러분의 플로피 디스크에 리로와 커널, 그리고 정적으로 링크된 hello world 프로그램인 /sbin/init를 넣고 부트한 뒤 인사하는 것을 보십시오.

여러분의 시스템이 시작되는 것을 주의깊게 보시면서 무엇이 일어나고 있다고 말하는지 기록하십시오. 또는 /var/log/messages의 시작할 때부터 일부분을 출력해 보십시오. 그 다음에 inittab에서부터 모든 스크립트를 보시면서 무슨 코드가 무엇을 하는지 보십시오. 여러분은 아래와 같은 시작 메시지를 추가할 수 있을 것입니다.

	echo "Hello, I am rc.sysinit"

배시 셸 스크립트를 배우는 것도 아주 좋은 연습입니다. 몇몇은 아주 복잡합니다. 좋은 배시 참고서와 함께 하십시오.

추가 정보

파일 시스템

이 절에서 저는 파일시스템이라는 단어를 두 가지의 다른 의미로 사용할 것입니다. 디스크 파티션이나 다른 디바이스에 있는 파일시스템이 있고, 동작하는 리눅스 시스템에 의해 여러분에게는 있는 것처럼 보이는 파일시스템이 있습니다.

전 절에서 저는 init 스크립트가 파일시스템을 체크하고 마운트 한다는 사실을 언급하였습니다. 그것을 하는 명령어는 각각 fsckmount입니다.

하드디스크는 단지 여러분이 0과 1을 쓸 수 있는 큰 공간에 불과합니다. 파일시스템은 그것에 구조를 주어 디렉토리 안의 디렉토리 안의 ... 파일처럼 보이게 합니다. 각각의 파일은 그 파일이 누구의 것이며 언제 만들어졌고 내용은 어디서 볼 수 있는지를 저장한 inode에 의해 나타내집니다. 디렉토리들도 inode들에 의해 나타내어지게 되는데, 이 inode는 디렉토리의 파일의 inode들을 어디에서 찾을 수 있는지 알려줍니다. 만약 시스템이 /home/greg/bigboobs.jpeg를 읽으려고 한다면, 먼저 superblock(슈퍼블록)의 루트 디렉토리 /의 inode를 찾고, /의 내용 중에서 디렉토리 home의 inode를 찾은 뒤, /home의 내용 중에서 디렉토리 greg의 inode를 찾습니다. 같은 방법으로 bigboobs.jpeg의 inode를 찾아서 어느 디스크 블록을 읽어야 할지를 알게 됩니다.

우리가 파일의 끝에 데이터를 추가하고자 할 때, inode가 업데이트되어 새로운 블록이 파일에 속하게 되었다는 것을 반영하기 전에 데이터가 씌여질 수 있고, 그 반대의 경우도 가능합니다. 만약 전원 공급이 중단되어 이러한 것이 끊긴다면, 파일시스템이 고장날 수도 있습니다. fsck는 이러한것을 찾아서 고치려고 합니다.

마운트 명령어는 장치에 있는 파일시스템을 가져와서 여러분이 시스템을 사용할 때 볼 수 있는 계층에 추가합니다. 보통 커널은 루트 파일시스템을 읽기 전용으로 마운트합니다. fsck가 루트 파일시스템이 정상인지 확인한 뒤 마운트 명령어로 다시 마운트합니다.

리눅스는 msdos, vfat, minix와 같은 다른 종류의 파일시스템도 지원합니다. 특정한 종류의 파일시스템에 대한 상세한 정보는 가상 파일 시스템(virtual file system, VFS)에 의해 추상화되어 가려집니다. 지금은 더 이상 깊이 들어가지는 않겠습니다. 이것에 대한 논의는 The Linux Kernel에 있습니다. (리눅스 커널에서 URL을 보십시오.)

완전히 다른 종류의 파일시스템이 /proc에 마운트됩니다. 사실 이것은 커널 안에 있는 것들을 표현한 것에 불과합니다. 여기에는 시스템에서 돌아가고 있는 각 프로세스마다 디렉토리가 있으며, 디렉토리의 이름은 프로세스 번호입니다. 또한 interrupts, meminfo와 같이 어떻게 하드웨어가 사용되고 있는지를 알려주는 것들도 있습니다. 여러분은 /proc을 둘러봄으로써 많은 것을 배울 수 있을 것입니다.

설정

Ext2 파일시스템을 만드는 mke2fs 명령어에는 파라메터들이 있습니다. 파라메터들은 블록들의 크기, inode들의 수와 같은 것을 조절합니다. 자세한 내용은 mke2fs의 맨 페이지를 보십시오.

여러분의 파일시스템에 무엇이 어디에 마운트되는지는 /etc/fstab 파일에 의해 조절됩니다. 이 파일에 대한 맨 페이지가 있습니다.

연습 문제

매우 작은 파일시스템을 만들고 헥스 뷰어(hex viewer)로 보십시오. inode들, 슈퍼블록들(superblocks)과 파일 내용들을 구분해 보십시오.

저는 파일 시스템을 그래픽으로 보여주는 도구들이 있을 것이라고 믿습니다. 찾아서 써 보신 뒤 URL과 리뷰를 저에게 메일보내 주십시오!

커널의 ext2 파일시스템 코드를 보십시오.

추가 정보

커널 데몬들

여러분이 ps aux 명령을 입력하면 아래와 같은 것을 볼 것입니다.

USER       PID %CPU %MEM  SIZE   RSS TTY STAT START   TIME COMMAND
root         1  0.1  8.0  1284   536   ? S    07:37   0:04 init [2] 
root         2  0.0  0.0     0     0   ? SW   07:37   0:00 (kflushd)
root         3  0.0  0.0     0     0   ? SW   07:37   0:00 (kupdate)
root         4  0.0  0.0     0     0   ? SW   07:37   0:00 (kpiod)
root         5  0.0  0.0     0     0   ? SW   07:37   0:00 (kswapd)
root        52  0.0 10.7  1552   716   ? S    07:38   0:01 syslogd -m 0 
root        54  0.0  7.1  1276   480   ? S    07:38   0:00 klogd 
root        56  0.3 17.3  2232  1156   1 S    07:38   0:13 -bash 
root        57  0.0  7.1  1272   480   2 S    07:38   0:01 /sbin/agetty 38400 tt
root        64  0.1  7.2  1272   484  S1 S    08:16   0:01 /sbin/agetty -L ttyS1
root        70  0.0 10.6  1472   708   1 R   Sep 11   0:01 ps aux 

이것은 시스템에서 실행되고 있는 프로세스들의 목록입니다. 이 정보는 제가 전 절에서 언급했던 /proc 파일시스템에서 온 것입니다. init이 프로세스 번호 1번이라는 점에 주의하십시오. 프로세스 2, 3, 4, 5는 kflushd, kupdate, kpiod, kswapd입니다. 여기서 무엇인가 이상한 것이 있습니다. 가상 저장 크기(virtual storage size, SIZE)와 실제 저장 크기(Real Storage Size, RSS)를 살펴보면, 이 프로세스들은 모두 0을 나타내고 있습니다. 어떻게 프로세스가 메모리를 쓰지 않을 수 있을까요?

이 프로세스들은 커널 데몬들입니다. 대부분의 커널은 프로세스 목록을 전혀 보여주지 않기 때문에, 얼마나 많은 메모리가 사용되는지를 계산하는 방법은 시스템의 사용 가능한 메모리의 양을 빼는 방법밖에 없습니다. 커널 데몬들은 init 뒤에 시작하기 때문에, 일반적인 프로세스들과 같은 프로세스 번호를 받습니다. 하지만 그들의 코드와 데이터는 메모리의 커널 부분에 있습니다.

이 명령어들은 COMMAND를 살펴보면 괄호가 쳐져 있는데, 이는 /proc 파일시스템에 이 프로세스들의 정보가 없기 때문입니다.

그러면 이러한 커널 데몬들은 무엇을 위해 있는 것일까요? 이 문서의 이전 버전에서 저는 커널 데몬에 대해 잘 몰랐기 때문에 도움을 요청했습니다. 아래의 이야기의 일부는 이 요청에 대한 고마운 답장들을 모아서 만든 것입니다. 더 많은 단서나 참고 자료나 수정에 대한 조언은 언제나 환영합니다!

입출력은 메모리의 버퍼를 통해서 이루어집니다. 이를 통해 속도를 높일 수 있습니다. 프로그램이 무엇인가를 쓰는 것을 메모리 안의 버퍼에 모았다가 더 크고 효율적인 묶음으로 씁니다. kflushdkupdate 데몬들은 이러한 일들을 관리합니다. kupdate는 (5 초 정도의?) 간격을 두고 정기적으로 버퍼에 무엇인가가 많이 있는지를 확인합니다. 무엇인가가 있다면, kflushd를 불러서 그들을 디스크에 쓰게(flush) 합니다.

프로세스들은 아무 일도 하지 않을 때가 종종 있으며, 실행중인 것도 그들의 코드와 데이터 모두가 메모리에 있을 필요는 없습니다. 이것은 실행중인 프로그램의 사용하지 않는 부분들을 하드디스크의 스왑 파티션으로 복사함으로써 메모리를 더 잘 쓸 수 있다는 것을 의미합니다. 이 데이터를 의도한 대로 메모리 안팎으로 움직이는 것은 kpiodkswapd에 의해 이루어집니다. 몇 초 정도의 간격을 두고, kswapd가 일어나서 메모리 상황을 확인한 뒤, 디스크에 있는 것이 메모리에 필요하거나, 충분한 메모리가 없어서 디스크로 옮겨야 할 때 kpiod를 부릅니다.

여러분이 자동 전원 관리(automatic power management)를 커널에 포함하도록 설정했다면 kapmd 데몬이 여러분의 시스템에 있을 것입니다.

설정

update프로그램은 여러분이 kflushdkswapd를 설정하도록 합니다. 정보를 보시려면 update -h 를 해 보십시오.

스왑 공간은 swapon에 의해 켜지고 swapoff에 의해 꺼집니다. init 스크립트(/etc/rc.sysinit/etc/rc.d/rc.sysinit)는 시스템이 시작될 때 대개 swapon을 부릅니다. 저는 swapoff가 노트북에서 전력을 절약하는 간단한 방법이라고 들었습니다.

연습 문제

update -d 해 보시고, 버퍼 내분에 대한 문턱값(threshold for buffer fratricide)에 관한 마지막 줄을 보십시오. 재미있는 개념이니 조사해 보십시오!

/proc/sys/vm로 디렉토리를 옮겨서 그곳의 파일들을 cat 해 보십시오. 여러분이 무엇을 할 수 있는지 보십시오.

추가 정보

리눅스 문서화 프로젝트(The Linux Documentation Project)의 The Linux Kernel (리눅스 커널에서 URL을 보십시오.)

여러분이 충분히 용감하다면, 리눅스 커널 소스 코드를 보십시오! kswapd 코드는 linux/mm/vmscan.c에, kflushdkupdatelinux/fs/buffer.c에 있습니다.

시스템 로거(System Logger)

Init은 syslogdklogd 데몬들을 시작합니다. 이들은 메시지들을 로그에 기록합니다. 커널의 메시지들은 klogd이 관리하며, syslogd는 다른 프로세스들의 로그 메시지들을 관리합니다. 중심 로그는 /var/log/messages입니다. 여러분의 시스템이 이상해졌다면 여기서부터 시작하는 것이 좋을 것입니다.

설정

/etc/syslog.conf는 로거에게 무슨 메시지를 어디에 쓸지를 알려줍니다. 메시지들은 그들이 어느 서비스에서 왔는지, 그들의 중요도(priority)가 어느 정도인지에 따라 구별됩니다. 설정 파일은 서비스 x의 중요도 y인 메시지는 z로 가야 한다는 것을 나타내는 줄들로 이루어져 있습니다. 여기서 z는 파일이거나 tty이거나, 프린터이거나, 리모트 호스트거나, 무엇이든 될 수 있습니다.

주의: Syslog는 /etc/services 파일이 있기를 요구합니다. 이 services 파일은 포트들을 할당합니다. 저는 아직 syslog가 리모트 로깅(remote logging)을 할 때만 포트를 할당하기를 바라는지, 아니면 단지 여러분이 /etc/syslog.conf에 입력한 서비스 이름들을 포트 번호로 바꾸기 위해서 /etc/services을 이용하는지 잘 모릅니다.

연습 문제

여러분의 시스템 로그를 보십시오. 여러분이 이해하지 못한 메시지를 찾고, 무슨 의미를 가졌는지 알아내 보십시오.

여러분의 모든 로그 메시지들을 tty로 보내 보십시오. (해 보신 뒤에는 시스템을 정상으로 돌려 놓으십시오.)

추가 정보

sysklogd 홈 페이지

Getty와 Login

Getty는 여러분이 가상 터미널이나 텍스트 터미널 또는 모뎀과 같은 직렬 장치(serial device)를 통해서 로그인 할 수 있도록 도와줍니다. 이것은 로그인 프롬프트를 표시합니다. 여러분이 사용자 이름을 입력하면, getty는 login에게 넘깁니다. login은 여러분에게 비밀번호를 물어보고 확인한 뒤 셸을 줍니다.

많은 getty들이 사용 가능합니다. 래드햇을 비롯한 몇몇 배포판들은 가상 터미널로만 동작하는 아주 작은 getty인 mingetty를 사용합니다.

login 프로그램은 util-linux 꾸러미의 일부분입니다. 이 꾸러미는 또 다른 잘 동작하는 getty인 agetty를 포함하고 있습니다. 이 꾸러미는 mkswap, fdisk, passwd, kill, setterm, mount, swapon, rdev, renice, more(프로그램)와 더 많은 프로그램(more)을 포함하고 있습니다.

설정

로그인 프롬프트와 함께 화면 위에 나타나는 메시지들은 /etc/issue에 있습니다. Gettys들은 /etc/inittab에서 시작됩니다. Login은 사용자의 상세한 정보를 /etc/passwd에서 찾고, 여러분이 패스워드 셰도잉(password shadowing)을 한다면, /etc/shadow에서 찾습니다.

연습 문제

/etc/passwd를 직접 만드십시오. 패스워드는 없을 수도 있고, 일단 여러분이 로그인 하면 passwd 프로그램으로 바꿀 수도 있습니다. man 5 passwd를 사용하여 프로그램에 대한 도움말 대신 이 파일에 대한 도움말을 보십시오.

배시(Bash)

여러분이 login에 맞는 사용자 이름과 패스워드의 조합을 입력했다면, login은 어떠한 셸을 여러분에게 줄지 /etc/passwd에서 찾을 것입니다. 대부분의 리눅스 시스템에서는 bash를 줄 것입니다. bash는 여러분의 명령들을 읽고 무슨일을 하려고 하는지 알아냅니다. 동시에 이것은 사용자 인터페이스이며, 프로그래밍 언어 인터프린터입니다.

사용자 인터페이스로서 배시는 여러분의 명령들을 읽어서 cd와 같은 내부 명령어들은 스스로 실행하고, cpstartx와 같은 외부 명령어들은 프로그램을 찾아서 실행합니다. 사용된 명령어들의 목록을 유지하며, 파일 네임을 자동으로 완성하는 것과 같은 매혹적인 일들도 합니다.

우리는 bash의 프로그래밍 언어로서의 기능을 이미 보았습니다. init가 시스템을 시작하기 위해 실행하는 스크립트들은 대개 셸 스크립트 들이며 bash에 의해 실행됩니다. 여러분이 무엇을 하고자 하는지 안다면, 적절한 프로그래밍 언어와 커맨드 라인(command line)에서 쓸 수 있는 일상적인 시스템 유틸리티들은 강력한 조합을 만듭니다. 저는 어느 날 무더기의 패치들(patches)을 소스 코드의 디렉토리에 적용할 필요가 있었습니다. 저는 아래와 같은 한 줄의 명령으로 이것을 할 수 있었습니다.

for f in /home/greg/sh-utils-1.16*.patch; do patch -p0 < $f; done;

이것은 저의 홈 디렉토리의 sh-utils-1.16로 시작하고 .patch로 끝나는 모든 파일들을 찾아봅니다. 그들을 하나씩 차례대로 가져와서, 변수 f를 설정하고 dodone사이의 명령을 수행합니다. 이 경우에 저는 11개의 패치 파일들이 있었지만, 3000개였더라도 똑같이 쉽게 할 수 있습니다.

설정

/etc/profile은 시스템 전체에서 배시가 어떻게 동작하는지 조정합니다. 여러분이 여기에 집어넣는 것은 여러분의 시스템에서 배시를 쓰는 사람 모두에게 영향을 미칠 것입니다. 이것은 PATH에 디렉토리를 추가하고 MAIL 디렉토리 변수를 설정하는 것과 같은 일을 할 것입니다.

키보드의 기본적인 동작은 사람들이 일반적으로 바라는 것과 거리가 멉니다. 이것을 우리가 바라는 대로 실제로 관리하는 것은 readline입니다. Readline은 커맨드 라인 인터페이스(command line interfaces)를 관리하고, 사용한 명령어들을 제공하고 파일 이름을 자동으로 완성하며, 고급 행 단위 편집(advanced line editing)을 할 수 있게 하는 독립된 꾸러미입니다. 이것은 배시 안으로 컴파일됩니다. Readline은 기본으로 여러분의 홈 디렉토리에 있는 .inputrc을 사용하도록 설정되었습니다. 배시 변수 INPUTRC를 써서 이것을 바꿀 수 있습니다. 예를 들어 래드햇 6에서는, INPUTRC/etc/profile에서 /etc/inputrc로 설정되어 있습니다. 이렇게 해서 모두가 백스페이스, 딜리트, 홈, 엔드 키를 잘 쓸 수 있도록 합니다.

배시가 시스템 전체에 영향을 미치는 설정 파일들을 읽은 뒤에는 개인적인 설정 파일들을 읽습니다. 여러분의 홈 디렉토리에 .bash_profile, .bash_login.profile이 있는지 확인합니다. 이들 중에 가장 먼저 찾은 것을 실행합니다. 여러분이 다른 사람들에게는 영향이 없이 여러분을 위해서 배시가 동작하는 방식을 바꾸고자 한다면, 이 파일들을 고치십시오. 예를 들어서, 많은 어플리케이션들은 그들이 어떻게 동작할지 조절하는 환경 변수들을 사용합니다. 저는 EDITOR 변수를 vi로 설정하여 제가 미드나잇 커멘더(Midnight Commander, 아주 좋은 콘솔에 기반한 파일 관리자) 에서 vi를 쓸 수 있도록 하였습니다.

연습 문제

배시의 기본은 배우기 쉽습니다. 하지만 거기서 멈추지 마십시오. 배시는 믿기 어려울 만큼 깊습니다. 무언가를 할 때 더 나은 방법을 찾는 버릇을 들이십시오.

셸 스크립트들을 읽고, 여러분이 이해하지 못한 부분에 대해서 찾아 보십시오.

추가 정보

명령어들

여러분은 배시에서 cp와 같은 명령어를 입력해서 대부분의 일을 하게 될 것입니다. cd와 같이 몇몇 명령어는 셸에 붙어 있지만, 대부분의 명령들은 작은 프로그램입니다.

명령들은 꾸러미에 포함되어 있으며, 그들의 대부분은 자유 소프트웨어 재단(또는 그누)에서 개발된 것입니다. 이들을 열거하는 대신, 저는 여러분에게 Linux From Scratch HOWTO에 가 보기를 권합니다. 리눅스에 들어갈 수 있는 패키지들의 완전한 최신 목록이 있으며, 그들을 설치하는 방법도 있습니다.

결론

제 부족한 의견으로는, 리눅스의 가장 좋은 점 중의 하나는 여러분이 안으로 들어와 모든 것들이 어떻게 움직이는지 진정으로 알 수 있다는 것입니다. 저는 여러분이 이 일을 저만큼 즐기셨으면 합니다. 또한 이 짧은 기록이 여러분께서 그것을 하시는 데 도움이 되었기를 바랍니다.

이 문서에 대해서

저작권

This document is copyright (c) 1999, 2000 Greg O'Keefe. You are welcome to use, copy, distribute or modify it, without charge, under the terms of the GNU General Public Licence. Please acknowledge me if you use all or part of this in another document.

홈페이지

이 문서의 최신판은 From Power Up To Bash Prompt에 있으며, 보조 문서인 Building a Minimal Linux System from Source Code도 함께 있습니다.

From Powerup To Bash Prompt에 불어 번역판이 있습니다. Dominique van den Broeck 님께 감사드립니다. Yuji Senda 님께서 작업하신 일본어판은 Japanese Documentation and FAQ Project에 있을 예정이며, 이미 있을 수도 있습니다. (역주 — 일본어 번역도 완료되었습니다.)

피드백

저는 여러분의 어떠한 조언이나 비평, 개선을 위한 제안도 듣고 싶습니다. 그것들을 저, Greg O'Keefe에게 보내십시오.

감사

제품 이름들은 각각의 소유자의 상표이며, 여기에서 감사를 드립니다.

이 문서를 쓸 수 있도록 도와주신 데 대해 아래의 분들께 감사를 드리고 싶습니다.

Michael Emery
Unios를 알려 주셨습니다.
Tim Little
/etc/passwd에 대해 도움을 주셨습니다.
efnet의 #linux에 계신 sPaKr
syslogd는 /etc/services를 필요로 한다는 것을 알려주셨고, 시스템을 소스 코드로 설치하는 것을 묘사하기 위한 여러분의 것을 돌린다(rolling your own)는 표현을 소개해 주셨습니다.
Alex Aitkin
저에게 Vico와 그의 verum ipsum factum(understanding arises through making, 이해는 만듦에서 기원한다)을 저에게 소개해 주셨습니다.
Dennis Scott
저의 16진수 계산을 고쳐 주셨습니다.
jdd
오자들을 지적해 주셨습니다.
David Leadbeater
커널 데몬에 관한 복잡한(ramblings) 내용들을 제공해 주셨습니다.
Dominique van den Broeck
이 문서를 불어로 번역해 주셨습니다.
Matthieu Peeters
커널 데몬에 관한 좋은 정보를 주셨습니다.
John Fremlin
커널 데몬에 관한 좋은 정보를 주셨습니다.
Yuji Senda
이 문서를 일어로 번역해 주셨습니다.
Antonius de Rozari
UNIOS의 GNU 어셈블러 판으로 기여해 주셨습니다. (홈 페이지의 리소스(resources) 절(section)을 보십시오.)
Botp Peña
여러분만의 OS 돌리기(roll your own os) 링크를 운영하십니다.
Kees J. Bot
미닉스 맨 페이지의 저자십니다. 특히, boot - from power on to the login prompt라는 부제가 붙은 boot 맨 페이지를 쓰셨습니다. 저는 이 문서를 LDP에 제출한 다음에서야 이 작은 보석을 찾아냈습니다.
Scott Hankin
오자를 알려 주셨습니다.

변경 기록

0.9 → 0.9a (2000년 11월)

0.8 → 0.9 (2000년 11월)

0.7 → 0.8 (2000년 9월)

0.6 → 0.7

0.5 → 0.6

할 일