리눅스에서 램디스크 블럭 디바이스 사용하기 ------------------------------------------ Paul Gortmaker 95년 12월 옮긴이: 차현진(xunil@linuxfan.com) 99년 6월 28일 순서: 1) 개요 2) 커널 명령어 라인 파라미터 3) 새로운 커널에 "rdev -r" 명령어 사용하기 4) 압축 램디스크 만드는 예제 1) 개요 ------- 커널 버전 1.3.48이후로 램디스크 드라이버는 많은 부분이 바뀌었다. 예전 버전은 부팅시 커널이 메모리를 관리하기 전에 메모리를 떼어내 사용했기 때문에 "ramdisk=1440 이나 rdev -r /dev/fd0 1440"같은 크기 파라미터를 지정해서 얼마만큼의 메모리를 잡을 것인지를 커널에게 알려줘야 했다. 하지만 지금의 램디스크는 공간이 필요할 때마다 동적으로 자라나게 된다. 이는 램을 버퍼 캐쉬를 이용해서 쓰기 때문이다. 드라이버는 자신이 쓰는 버퍼를 커널이 나중에 사용하지 못하게 하려고 "BH_Protected" 플래그를 표시해 놓는다. 따라서 예전에 쓰던 크기 파라미터는 더 이상 필요가 없게 됐고 새로운 명령어 라인 파라미터가 생겼다. 또한 "rdev -r" 이나 "ramsize"(보통 rdev로 심볼릭 링크가 되어 있다.) 명령어도 바뀌었다. 새로운 램디스크는 16개의 램디스크까지 지원을 하지만 rd.c를 약간 고쳐주면 255개까지 지원할 수가 있다. 1개 이상의 램디스크를 쓰려면 'mknod /dev/ramX b 1 X'(X=숫자)를 하고 'chmod'를 써서 퍼미션을 바꿔줘라. 기본 /dev/ram(disk)는 마이너 넘버 1을 쓰니까 ram2부터 시작해서 필요한 만큼 만들면 된다. 좀 더 확실히 하기 위해서 예전의 "ramdisk="는 "ramdisk_size="로 바뀌었다. 원래의 "ramdisk="는 호환성을 위해 아직 남아 있지만 커널 버전 2.1.X 정도 쯤에서 없어질 것이다. 새로운 램디스크는 압축된 램디스크 이미지를 로드할 수가 있다. 이로써 설치 디스켓나 복구 디스켓에 좀 더 많은 프로그램이 압축되어 들어갈 수가 있다. 주의: 당신의 시스템에 "/dev/ram"이나 "/dev/ramdisk", 혹은 둘 다 있을 수 있다. 이 문서에서는 이들을 똑같이 취급한다. 또, 새로운 램디스크는 config 옵션이 되었다. "make config"를 할 때 램디스크를 넣을지 뺄지를 결정할 수가 있다. 2) 커널 명령어 라인 파라미터 ---------------------------- ramdisk_start=NNN ================= 플로피 디스켓에 커널이 압축된 램디스크 이미지와 같이 있을 경우를 위해 "ramdisk_start=" 명령어가 추가되었다. 하지만 커널은 압축된 램디스크 파일 시스템 이미지에 포함될 수가 없다. 왜냐하면 커널이 0번째 블럭부터 있어야 바이오스가 부트 섹터를 읽을 수 있고 그 다음에 커널이 자기 자신을 계속해서 부팅해 나가기 때문이다. 주의: 만약 압축되지 않은 램디스크 이미지를 쓴다면 커널은 램디스크로 로드될 파일 시스템의 일부분이 될 수가 있고, 리로로 디스켓을 부팅 시킬 수 있다. 혹은 이 두가지는 압축 이미지에서처럼 두 장으로 나누어 질 수가 있다. 디스켓 두 장으로 부트/루트 시스템(커널은 1번 디스켓, 램디스크 이미지는 2번 디스켓)을 쓴다면 램디스크는 0번 블럭에서 시작할 것이고 옵셋은 당연히 0이 될 것이다. 이 때의 0은 기본값이기 때문에 "ramdisk_start" 옵션은 주지 않아도 된다. 디스켓 한 장에 350 kb 정도의 "zImage"(커널)와 1 Mb 정도의 "fs_image.gz"(압축된 파일 시스템)을 넣는다면 이 때는 옵셋을 정해 줘야 한다. 예를 들어 "fs_image.gz" 를 디스켓의 400 kb 위치에 저장했다면, "ramdisk_start=400" 이라고 써야 될 것이다. load_ramdisk=N ============== 이 파라미터는 램디스크 이미지를 읽을 것인지 아닌지를 지정한다. "load_ramdisk=1"이라고 하면 플로피에서 램디스크로 읽을 것이다. 기본값은 0이다. prompt_ramdisk=N ================ 이 파라미터는 램디스크 이미지를 갖고 있는 디스켓을 넣을 수 있게 잠시 멈출 수 있는지 없는지를 결정한다. 디스켓 한 장에 커널과 램디스크 이미지가 같이 들어 있다면 잠시 멈출 필요가 없으므로 "prompt_ramdisk=0"이라고 하면 된다. 하지만 두 장으로 나눠져 있다면 디스켓을 바꿀 시간이 필요하므로 "prompt_ramdisk=1"이라고 하면 된다. 기본값은 1이다. ramdisk_size=N ============== 램디스크 드라이버가 램디스크를 N k 크기로 잡게 한다. 기본값은 4096 (4 MB)이다. 3) 새로운 커널에 "rdev -r" 명령어 사용하기 ------------------------------------------ "rdev -r" 명령어가 세트하는 커널 이미지에 있는 워드(2 바이트)의 사용법이 바뀌었다. 하위 11비트(0-10)는 램디스크를 2 Mb(2^11)까지중 어디서 찾을 것인지를 지정해준다(에전엔 크기를 나타냈다.). 14 비트는 램디스크가 로드될지 안 될지를 나타내고, 15 비트는 램디스크를 읽기전에 멈출지 안 멈출지를 나타낸다. 램디스크가 동적으로 자랄 수 있기 때문에 크기 필드는 필요가 없어졌다. 11 비트부터 13 비트 까지는 현재 쓰이지 않고 0으로 채워져 있다. 아래 숫자들은 보기와는 다르게 무슨 신비스러운 비밀이 아니다. ./arch/i386/kernel/setup.c:#define RAMDISK_IMAGE_START_MASK 0x07FF ./arch/i386/kernel/setup.c:#define RAMDISK_PROMPT_FLAG 0x8000 ./arch/i386/kernel/setup.c:#define RAMDISK_LOAD_FLAG 0x4000 전형적인 디스켓 두 장짜리 상황을 생각해 보자. 첫 번째 디스켓에는 커널이 들어 있을 것이고, 두 번째 디스켓에는 램디스크 이미지가 있을 것이다. 램디스크는 디스켓의 처음에서 0 kb 떨어진 곳에서 시작을 하므로 0번 비트에서 13번 비트는 0으로 세트를 해야 할 것이다. "ramdisk_start=0" 램디스크가 로드될 것이므로 14번 비트는 세트가 되어야 할 것이다. "load_ramdisk=1" 디스켓을 갈아 끼워야 하므로 15번 비트 역시 세트가 되어야 한다. "prompt_ramdisk=1" 이것들을 다 합치면 rdev 워드에 들어갈 값은 2^15 + 2^14 + 0 = 49152가 된다. 커널이 들어갈 디스켓은 다음과 같이 만들면 되겠다. /usr/src/linux# cat arch/i386/boot/zImage > /dev/fd0 /usr/src/linux# rdev /dev/fd0 /dev/fd0 /usr/src/linux# rdev -r /dev/fd0 49152 부트 디스켓이 리로로 부팅이 된다면 위의 작업은 다음처럼 간단해진다. append = "ramdisk_start=0 load_ramdisk=1 prompt_ramdisk=1" ramdisk_start = 0 과 prompt_ramdisk = 1 이 기본값이므로 이렇게 쓸 수도 있다. append = "load_ramdisk=1" 4) 압축 램디스크 만드는 예제 램디스크 이미지를 만들려면 여분의 블럭 디바이스가 있어야 한다. 램디스크 자체 에서 만들수도 있고 사용하지 않는 디스크 파티션(언마운트된 스왑 파티션 같은)에서 할 수도 있다. 이 예제에서는 램디스크 디바이스, "/dev/ram"를 사용할 것이다. 주의: 이 방법은 8 Mb이하의 램을 가진 시스템에서 해서는 안 된다. /dev/ram 대신에 여분의 디스크 파티션을 쓴다면 이 제한 사항은 적용되지 않는다. 가) 얼마만큼을 램디스크로 쓸 것인지 결정하라. 여기서는 2 Mb 를 쓰겠다. 램디스크 디바이스를 2 Mb 로 만들어라.(이 단계는 지금은 불필요하지만 나중에 쓰일지도 모른다.) 여기를 0으로 채우는 것이 좋다.(일반 디스크 같은 경우는 특별히 더 그렇다.) 왜냐하면 당신이 만든 이미지가 차지하고 남은 공간은 이 때 최고로 압축되기 때문이다. dd if=/dev/zero of=/dev/ram bs=1k count=2048 나) 거기다가 파일 시스템을 만들어라. 우리는 ext2fs를 만들자. mke2fs -vm0 /dev/ram 2048 다) 마운트를 하고 필요한 파일들(/etc/* /dev/* ...)을 복사한 뒤, 언마운트를 해라. 라) 램디스크를 압축해라. 파일이 차지하고 있는 공간의 50%정도가 압축이 될 것이다. 안 쓰고 남은 부분은 압축에서 제외될 것이다. dd if=/dev/ram bs=1k count=2048 | gzip -v9 > /tmp/ram_image.gz 마) 커널을 디스켓에다 집어넣어라. dd if=zImage of=/dev/fd0 bs=1k 바) 램디스크 이미지를 커널 뒤쪽에 집어넣어라. 이 때 실제 커널보다 약간 큰 값을 옵셋으로 쓰면 나중에 (더 큰) 다른 커널을 넣을 때, 램디스크 이미지를 덮어 쓰지 않는다. 350 kb 짜리 커널이라면 옵셋을 400 kb 정도 주는 것이 적당할 것이다. 주의할 점은 옵셋 + ram_image.gz 의 크기가 디스켓 용량보다 크면 안 된다는 것이다.(보통 1440 kb) dd if=/tmp/ram_image.gz of=/dev/fd0 bs=1k seek=400 사) "rdev" 명령어를 써서 부트 디바이스나 램디스크 옵셋, 프롬프트 플래그 등을 세트해라. 이 예제에서 쓸 값은 prompt_ramdisk=1, load_ramdisk=1, ramdisk_start=400 이므로 2^15 + 2^14 + 400 = 49552 가 될 것이다. rdev /dev/fd0 /dev/fd0 rdev -r /dev/fd0 49552 여기까지! 이제 압축된 부트/루트 램디스크 디스켓이 생겼다. 라)에서 바)까지는 파이프를 써서 할 수도 있을 것이다. ----------------------------------------------------------------------------- Paul Gortmaker 95년 12월 ----------------------------------------------------------------------------- 해석: 차현진(xunil@linuxfan.com) 99년 6월 28일