CentOS-4.4에서 VT8237A IDE DMA 켜기

아래와 같이 부품 몇 개를 싼 맛에 사서 64비트 컴퓨터를 마련했다.

- ASRock K8VM890 (VIA 8M890CE + VT8237A)
- AMD Sempron Palermo 2600+ 64bit
- TwinMOS DDR PC3200 512MB 2.5-3-3-8

여기에 CentOS-4.4 64비트 버전을 설치해 봤다.
그런데 2.6.9-42.0.2.EL 커널은 VIA VT8237A 사우스브리지의 P-ATA 콘트롤러에서
아래와 같이 DMA가 활성화되지 못하는 문제가 있었다.

# hdparm /dev/hda

/dev/hda:
 multcount    = 16 (on)
 IO_support   =  0 (default 16-bit)
 unmaskirq    =  0 (off)
 using_dma    =  0 (off)
 keepsettings =  0 (off)
 readonly     =  0 (off)
 readahead    = 256 (on)
 geometry     = 65535/16/63, sectors = 80026361856, start = 0

# hdparm -d1 /dev/hda


/dev/hda:
 setting using_dma to 1 (on)
 HDIO_SET_DMA failed: Operation not permitted
 using_dma    =  0 (off)


dmesg로 시스템의 로그를 살펴보면, IDE 드라이버가 로드되는 부분에서
아래와 같이 칩셋이 정확히 규명되지 않아 DMA를 끈다는 식의 말도 나왔다.

Uniform Multi-Platform E-IDE driver Revision: 7.00alpha2
ide: Assuming 33MHz system bus speed for PIO modes; override with idebus=xx
VP_IDE: IDE controller at PCI slot 0000:00:0f.1
VP_IDE: chipset revision 7
VP_IDE: not 100% native mode: will probe irqs later
VP_IDE: Unknown VIA SouthBridge, disabling DMA.
Probing IDE interface ide0…
hda: ST380021A, ATA DISK drive
Probing IDE interface ide1…
hdc: LITE-ON LTR-12101B, ATAPI CD/DVD-ROM drive
Probing IDE interface ide2…
Probing IDE interface ide3…
Probing IDE interface ide4…
Probing IDE interface ide5…
Using cfq io scheduler
ide0 at 0x1f0-0x1f7,0x3f6 on irq 14
ide1 at 0x170-0x177,0x376 on irq 15
hda: max request size: 128KiB
hda: 156301488 sectors (80026 MB) w/2048KiB Cache, CHS=65535/16/63
hda: cache flushes not supported
 hda: hda1 hda2 hda3 < hda5 hda6 hda7 hda8 hda9 > hda4
hdc: ATAPI 32X CD-ROM CD-R/RW drive, 2048kB Cache
Uniform CD-ROM driver Revision: 3.20


알고보니, VT82C586부터 VT8237 등에 이르기까지 VIA의 사우스브리지 IDE 구동을 담당하는
드라이버인 via82cxxx에 VT8237A의 장치 ID가 등록되지 않았기 때문에 생긴 문제였다.
구동에 필요한 코드는 이미 구현되어 있었다.

커널 소스를 살펴보면 VT8237(0x3227)은 등록되어 있으나 VT8237A(0x3337)는 없다.
아래와 같이 두 개의 파일을 수정하고 커널을 다시 컴파일하면 해결된다.

[1] include/linux/pci_ids.h에 적당한 곳에 아래의 한 줄을 넣고
   ( http://marc.theaimsgroup.com/?l=linux-kernel&m=115758568527950&w=2 )

#define PCI_DEVICE_ID_VIA_8237A         0x3337

[2] drivers/ide/pci/via82cxxx.c에 적당한 곳에 아래의 한 줄을 넣으면 된다.
   ( http://marc.theaimsgroup.com/?l=linux-kernel&m=115428666607564&w=2 )

        { "vt8237a",    PCI_DEVICE_ID_VIA_8237A,    0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },


조치 후에는 dmesg를 통해 아래와 같이 VT8237A를 정확히 인식한 로그를 확인할 수 있다.

Uniform Multi-Platform E-IDE driver Revision: 7.00alpha2
ide: Assuming 33MHz system bus speed for PIO modes; override with idebus=xx
VP_IDE: IDE controller at PCI slot 0000:00:0f.1
VP_IDE: chipset revision 7
VP_IDE: not 100% native mode: will probe irqs later
VP_IDE: VIA vt8237a (rev 00) IDE UDMA133 controller on pci0000:00:0f.1
    ide0: BM-DMA at 0xfc00-0xfc07, BIOS settings: hda:DMA, hdb:pio
    ide1: BM-DMA at 0xfc08-0xfc0f, BIOS settings: hdc:pio, hdd:pio
Probing IDE interface ide0…
hda: ST380021A, ATA DISK drive
Using cfq io scheduler
ide0 at 0x1f0-0x1f7,0x3f6 on irq 14
Probing IDE interface ide1…
hdc: LITE-ON LTR-12101B, ATAPI CD/DVD-ROM drive
ide1 at 0x170-0x177,0x376 on irq 15
Probing IDE interface ide2…
Probing IDE interface ide3…
Probing IDE interface ide4…
Probing IDE interface ide5…
hda: max request size: 128KiB
hda: 156301488 sectors (80026 MB) w/2048KiB Cache, CHS=65535/16/63, UDMA(100)
hda: cache flushes not supported
 hda: hda1 hda2 hda3 < hda5 hda6 hda7 hda8 hda9 > hda4
hdc: ATAPI 32X CD-ROM CD-R/RW drive, 2048kB Cache, DMA
Uniform CD-ROM driver Revision: 3.20

그리고 아래와 같이 /dev/hda에 대해 DMA가 활성화되어 잘 동작하는 것도 확인할 수 있다.

# hdparm /dev/hda

/dev/hda:
 multcount    = 16 (on)
 IO_support   =  1 (32-bit)
 unmaskirq    =  1 (on)
 using_dma    =  1 (on)
 keepsettings =  0 (off)
 readonly     =  0 (off)
 readahead    = 256 (on)
 geometry     = 65535/16/63, sectors = 80026361856, start = 0

시험삼아 dd if=/dev/hda of=/dev/null 명령을 돌리고 vmstat 1 명령으로 속도를 재보면
약 40MB/s 가 나온다. DMA를 켜기 전에는 3~4MB/s 정도였다.

----

작업의 기록

위의 작업은 커널 SRPM으로부터 커널 소스 RPM을 만들고, 만들어진 RPM을 설치하여
커널소스를 설치한 다음, 소스를 수정하고 빌드하는 식으로 했다.

과정을 간단히 적으면 아래와 같다.

커널 SRPM인 kernel-2.6.9-42.0.2.EL.src.rpm 을 받아서 설치하고
/usr/src/redhat/SPECS/kernel-2.6.spec 을 열어 아래와 같이 buildsource를 0 에서 1로 바꾼다.

%define buildup 1
%define buildsmp 1
%define buildsource 1
%define buildhugemem 1
%define buildlargesmp 1
%define builddoc 0
%define kabi 1

아래 명령을 통해 커널 소스 RPM을 만든다.

# rpmbuild -bb --target=x86_64 /usr/src/redhat/SPECS/kernel-2.6.spec

만들어진 RPM은 /usr/src/redhat/RPM/kernel-sourcecode-2.6.9-42.0.2.EL.x86_64.rpm 이다.
이것을 설치하면 /usr/src/linux-2.6.9-42.0.2.EL 디렉토리 아래에 소스가 설치된다.

# cd /usr/src
# ln -s linux-2.6.9-42.0.2.EL linux
# cd linux

이제 위 [1], [2]처럼 파일 두 개를 편집하고 다음과 같이 빌드/설치했다.

# make oldconfig
# make all modules modules_install install

커널 소스 RPM을 따로 만들 것 없이 커널 SRPM이 설치된 상태에서
/usr/src/redhat 디렉토리 밑에서 바로 작업해도 되는 것 같기는 한데,
그런 식의 과정에는 익숙하지 못해서 그냥 구식으로 했다.
( SRPM에서 바로 작업하려면 http://chanik.egloos.com/1430938

CentOS-4.4에서 VT8237A IDE DMA 켜기

댓글 남기기

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다