최근의 비디오카드는 엄청난 양의 비디오램(보통 256~512MB)을 가지고 있다. 하지만 그 중 대부분은 최신 3D 게임같은것을 하지 않는다면 사용되지 않는다. 리눅스에서 이 비디오램을 스왑 파티션 또는 램디스크로 사용할 수 있다. 리눅스에서 놀고 있는 비디오카드의 메모리를 램디스크 또는 스왑으로 사용하면 엄청난 성능 향상이 가능해진다.
커널 준비하기
그래팩카드의 메모리를 사용하려면 그 메모리 영역이 커널에 매핑되어야만 한다. 기본적으로 시스템 메모리만 사용할 수 있는 램으로 인식되기 때문에 PCI 주소 영역(address space)의 메모리를 사용하려면 사용하고자 하는 메모리를 커널에 등록해 줄 수 있는 드라이버가 필요하다. 2.6 커널에 이 역할을 수행해주는 MTD(Memory Technology Device) 지원 드라이버가 포함되었다. 리눅스의 menuconfig를 실행해서 MTD 기능을 활성화 시켜줘야 한다. 커널에 포함된 (built-in) 드라이버로 하건 모듈로 컴파일하건 관계 없이 동작한다.
비디오 메모리 주소 확인
커널을 다시 만들어 준 다음에는 PCI 영역에서 비디오 메모리 주소를 찾아내야 한다. 가장 쉬운 방법은 lspci를 사용하는 것이다.
$ lspci -vvv
0000:02:00.0 VGA compatible controller: ATI Technologies Inc R300 AD [Radeon 9500 Pro] (prog-if 00 [VGA])
Subsystem: PC Partner Limited: Unknown device 7c07
Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping+ SERR- FastB2B-
Status: Cap+ 66Mhz+ UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR-
Latency: 32 (2000ns min), cache line size 08
Interrupt: pin A routed to IRQ 255
Region 0: Memory at d8000000 (32-bit, prefetchable) [size=128M]
Region 1: I/O ports at b000 [size=256]
Region 2: Memory at e9000000 (32-bit, non-prefetchable) [size=64K]
Expansion ROM at e8000000 [disabled] [size=128K]
Capabilities: [58] AGP version 3.0
Status: RQ=256 Iso- ArqSz=0 Cal=0 SBA+ ITACoh- GART64- HTrans- 64bit- FW+ AGP3+ Rate=x4,x8
Command: RQ=1 ArqSz=0 Cal=0 SBA+ AGP- GART64- 64bit- FW- Rate=<none>
Capabilities: [50] Power Management version 2
Flags: PMEClk- DSI- D1+ D2+ AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-)
Status: D0 PME-Enable- DSel=0 DScale=0 PME-
이 중에 필요한 정보는 prefetchable memory region인 Region 0이다. 이 영역의 시작 주소는 0xd8000000 이다.
* 위의 화면은 예제이다. 실제로 컴퓨터의 메모리 영역의 시작번지는 다를 수 있기 때문에 꼭 확인해 줘야 한다.
메모리 매핑하기
실제로 PCI 영역의 메모리를 억세스하려면 MTD드라이버에게 해당 영역의 시작과 끝 주소를 알려줘야만 한다. 끝 주소를 계산하는 법은 간단하다. 단순히 어느정도의 메모리를 사용할지 결정하면 된다. 하지만 비디오카드가 원래 목적의 기본동작을 위해 얼마간의 메모리 영역은 남겨둬야 한다.
만일 SLRAM 드라이버를 모듈로 컴파일 했다고 하면 다음 명령을 실행해주면 된다.
# Region 0 starts at 0xd8000000, leave 4 MB ram for the VGA, so add 4*1024*1024 to it
# which is 0x00400000 in hex, 32 bit. This means: 0xd8400000 will be the starting position.
# Now, to use the other 124 MB, the easiest way is to tell the offset value.
# The third parameter's leading + means that we are telling the offset,
# not the actual region's ending address. 124 MB is 0x7c00000 in hex, 32 bit.
modprobe slram map=VRAM,0xd8400000,+0x7c00000
PHRAM 드라이버를 모듈로 컴파일 한 경우는 다음의 명령을 사용한다.
# Loading with PHRAM module is very similar to SLRAM module, except that it uses a "length"
# parameter by default rather than an "end offset".
# This does the same thing as the SLRAM module above
modprobe phram phram=VRAM,0xd8400000,0x7c00000
# This is also the same (and easier to read)
modprobe phram phram=VRAM,0xd8400000,124Mi
커널에 포함된 드라이버로 컴파일 한 경우 커널 커맨드 라인에 아래를 추가해주면 된다.
# Now the first parameter is the device which will be mapped.
# Other parameters share the same meaning shown above, in the module version.
# Please reboot your computer, to take it effect.
slram=mtd0,0xd8400000,+0x7c00000
제대로 설정이 되었는지 dmesg를 사용해서 확인할 수 있다.
slram: devname = mtd0
slram: devstart = 0xd8400000
slram: devlength = +0x7c00000
slram: devname=mtd0, devstart=0xd8400000, devlength=0x7c00000
slram: Registered device mtd0 from 3543040KiB to 3670016KiB
slram: Mapped from 0xe0880000 to 0xe8480000
또는 좀 더 확실히 하고 싶으면 /proc/mtd 파일을 보면 된다.
dev: size erasesize name
mtd0: 07c00000 00004000 "mtd0"
MTD 디바이스 만들기
커널이 MTD를 지원하도록 설정하고 나면 메모리를 억세스 할 방법이 있어야 한다. 즉 디바이스를 만들어 줘야 할 차례이다. 다음의 명령을 사용하면 된다.
$ modprobe mtdchar ("Direct char device access to MTD devices" 가 모듈로 컴파일 된 경우만 필요, 커널 built-in인 경우 사용하면 안된다.)
$ mknod /dev/mtd0 c 90 0
$ modprobe mtdblock ("Caching block device access to MTD devices" 가 모듈로 컴파일 된 경우만 필요, 커널 built-in인 경우 사용하면 안된다.)
$ mknod /dev/mtdblock0 b 31 0
사용하기
이제 비디오카드의 메모리를 램디스크나 스왑파티션으로 사용할 수 있다. 어느 경우로 사용하건 비디오램에 파일 시스템을 만들어 줘야 한다.
* 스왑 파티션으로 사용하기
스왑파티션으로 사용하려면 다음의 명령을 사용하면 된다.
$ mkswap /dev/mtdblock0
$ swapon /dev/mtdblock0
위의 명령을 실행하면 비디오카드의 메모리에 스왑 파일 시스템을 만들고 그 파티션을 활성화 시키게 된다. 스왑 파티션을 여러개 지정한 경우 어느 스왑 파티션을 먼저 사용할 지 우선권(priority) 지정하려면 swapon에 '-p X' 스위치를 사용하면 된다. 여기서 X는 0부터 32767 사이의 정수로 숫자가 클수록 우선권이 높다.
$ swapon /dev/mtdblock0 -p 10
우선권을 지정하지 않으면 현재 사용되는 스왑파티션의 우선권보다 낮은 값이 할당되게 된다. 또한 이 명령을 사용하면 fstab에도 반영되기 때문에 매번 부팅할 때 마다 다시 수동으로 추가해 줄 필요는 없다.
위의 명령을 실행한 후의 /etc/fstab의 내용이다.
$ <fs> <mountpoint> <type> <opts> <dump/pass>
/dev/mtdblock0 none swap sw,pri=10
* 램디스크로 사용하기
램디스크로 사용하려면 비디오램에 다음의 명령으로 파일시스템을 만들어 주면 된다.
$ mkfs.ext2 /dev/mtdblock0
이렇게 만들어 준 다음 리눅스 파일 시스템의 원하는 위치에 마운트 시켜 주면 된다.
* Michał Schulz와 Gentoo Wiki의 문서를 정리, 번역한 글이다. 원문은 각각의 링크를 누르면 볼 수 있다.