KDE 4.6
2011-02-18 컴퓨터를 대대적으로 업그레이드 하고 운영체제도 새로 깔았다. WindowsXP 에서 Windows7 64bit 로 다시 설치하고 리눅스도 64bit 로 설치했다.
최신 운영체제라서 설치하고 설정하는 것에 아무 문제가 없을줄 알았다. 예전에는 그래픽카드 설정에 신경을 써야했지만 요새는 dvi 포트에 모니터 꽂으면 별다른 설정 없이 알아서 해상도 잡고 잘 보여줬기 때문에...
그런데 이번에는 다시 엄청난 삽질을 하고 나서야 제대로된 화면을 볼 수 있었다 ㅠㅠ
리눅스만 그런것이 아니고 윈도우7도 같은 문제인데 아직 dvi 로는 제대로된 해상도를 쓸수가 없다.. 좀더 찾아봐야 할듯 ㅠㅠ
문제는 요새 nvidia 그래픽카드(amd 카드도 그런지는 안찾아봐서 모르겠음) 드라이버에서는 모니터의 EDID 를 참조하는데 옛날 모니터의 경우(중소기업 모니터라 그런건지..) 이것이 잘못되어 있는지 아니면 제대로 가져올 수 없는지 매우 낮은 해상도로만 화면이 표시된다.
내 그래픽 카드는 NVIDIA Geforce GTS450이다. 모니터는 MOTV CNC 에서 만든 20.1" 모니터로 최적 해상도는 1680x1050 이다. 그런데 dvi 포트를 사용하면 윈도우7 에서는 1024x768, 리눅스에서는 640x480 밖에 사용을 못한다. d-sub 포트로 연결하면 윈도우7 에선 1680x1050 을 쓸수 있지만(이것도 자동으로 설정되진 않고 잡아줘야 한다...) 리눅스는 이것도 1024x768 밖에 설정이 안된다.
문제를 해결하기 위해 먼저 Modeline 을 지정해주고 Modes 를 설정했다.
Tip. 예전에는 /etc/X11/xorg.conf 파일 하나에 X의 모든 설정이 있었지만 xorg 버전이 올라가면서(1.8부터) 지금은 /etc/X11/xorg.conf.d 디렉토리에 설정파일이 나뉘어 존재한다. 그렇지만 지금도 xorg.conf 파일을 사용할 수는 있다.
# 1680x1050 59.95 Hz (CVT 1.76MA) hsync: 65.29 kHz; pclk: 146.25 MHz
Modeline "1680x1050_60.00" 146.25 1680 1784 1960 2240 1050 1053 1059 1089 -hsync +vsync
cvt 로 구한 Modeline 을 /etc/X11/xorg.conf.d/10-monitor.conf 의 Section "Monitor" 에 추가 하고 Section "Screen" 에
Depth 24
Modes "1680x1050_60.00"
EndSubSection
을 추가했으나 실패. /var/log/Xorg.0.log 를 확인해보니 No valid modes for "1680x1050_60.00"; removing. 이라며 무시되었다.
이것저것 구글링을 하며 이옵션 저옵션을 넣고 빼고 하다가 다음 링크를 찾았다.
그 안에 누가 LG의 L204WT 모니터 EDID 의 링크를 걸어줬고 CustomEDID 라는 옵션을 알게 되었다.
Section "Screen" 에 아래 옵션을 넣고 일단 d-sub 를 연결하고 X 를 띄워보았다.
1680x1050 으로 화면이 나왔다!!! 옵션에서 CRT-0 대신에 DFP-0 을 넣고 dvi 포트를 연결했으나 이건 또 실패.....
다시 구글링중 http://www.ubuntu.or.kr/viewtopic.php?f=20&t=10180 에서 doodoo 님이 하신 설정을 따라해보다가
Section "Monitor" 에 아래 옵션을 넣자 마침내 dvi 로도 1680x1050 해상도를 볼 수 있었다!!!!!!!!!!!!!!!!!!! ㅠㅠ
VertRefresh 55.0 - 75.0
거기서 doodoo 님은 EDID 를 사용하지 않는 옵션을 주고 모니터에 맞는 Modelines 를 찾아서 넣었는데.. 나는 거기있는 설정으로는 작동하지 않았다.
내가 성공한 설정의 설정파일은 다음과 같다. # 으로 주석처리한 부분은 이것저것 바꿔봤던 설정들이다;;;
Section "Monitor"
Identifier "Monitor0"
HorizSync 30.0 - 81.0
VertRefresh 55.0 - 75.0
# 1680x1050 59.95 Hz (CVT 1.76MA) hsync: 65.29 kHz; pclk: 146.25 MHz
Modeline "1680x1050_60.00" 146.25 1680 1784 1960 2240 1050 1053 1059 1089 -hsync +vsync
# 1680x1050 @ 60.00 Hz (GTF) hsync: 65.22 kHz; pclk: 147.14 MHz
#Modeline "1680x1050_60.00" 147.14 1680 1784 1968 2256 1050 1051 1054 1087 -HSync +Vsync
#ModeLine "1680x1050rb" 119.0 1680 1728 1760 1840 1050 1053 1059 1080 +Hsync -VSync
#Option "DPMS"
EndSection
Section "Screen"
Identifier "Screen0" #Collapse Monitor and Device section to Screen section
Device "Default nvidia Device"
Monitor "Monitor0"
DefaultDepth 24 #Choose the depth (16||24)
Option "CustomEDID" "CRT-0:/etc/X11/xorg.conf.d/edid.bin;DFP-0:/etc/X11/xorg.conf.d/edid.bin"
SubSection "Display"
Depth 24
Modes "1680x1050_60.00"
EndSubSection
EndSection
Section "Device"
Identifier "Default nvidia Device"
Driver "nvidia"
Option "NoLogo" "True"
#Option "UseEDID" "FALSE"
#Option "UseEDIDFreqs" "false"
#Option "ModeValidation" "DFP-0: NoMaxPClkCheck, NoEdidMaxPClkCheck"
#Option "ModeValidation" "NoDFPNativeResolutionCheck"
Option "DPI" "96 x 96"
EndSection
/etc/X11/xorg.conf.d/edid.bin 은
을 풀면 그 안에 있습니다.
리눅스 커널 모듈 안에서 cpu 와 코어의 수를 얻어와야 할 일이 생겼다. 그리고 코어별로 클럭을 조절해서 테스트 해야 할 일이 생겨 찾아본 것을 정리해 보았다.
확인해 본 커널 버전은 2.6.30 , 2.6.34 였다. (2010년 8월 8일 현재 최신 커널버전은 2.6.35)
CPU info
http://www.hanb.co.kr/network/view.html?bi_id=1446
위 의 링크에서 친절히 잘 설명된 정보를 얻을 수 있었다.
리눅스 커널에서는 cpu 의 정보를 담은 구조체가 전역변수로 선언되어 있고 그것을 통해 cpu 정보를 가져올 수 있는 것이다.
다만 커널 버전이 올라가면서 전에는 cpu_data[] 배열에서 직접 데이터를 얻을 수 있던 것이 이제는 안된다. (정확히 언제 바뀌었는지 모르겠는데 2.6.30 이후 부터는 안됨.)
현재 실행중인 cpu 정보를 얻기위한 current_cpu_data 매크로는 여전히 존재하며 cpu_data() 매크로를 통해 특정 cpu 의 정보를 얻어올 수 있으니 이를 이용해보자.
두 매크로는 <asm/processor.h> 에 선언되어 있다.
struct cpuinfo_x86
pc 에서 아까의 매크로로 얻어온 데이터는 struct cpuinfo_x86 구조체로 되어있는데 여기서 내가 관심있는 물리적 코어수 관련 정보는 x86_max_cores 로 보인다.
arch/x86/kernel/cpu/intel.c 파일을 보면 아래와 같은 코드가 있고
arch/x86/kernel/cpu/amd.c 파일에는 다음과 같은 코드가 있었는데 이를 보면 x86_max_cores는 cpu 의 코어수가 맞는 것 같다.
booted_cores 도 같은 값을 가지고 있는데.. OS에서 보는 코어의 수라고 하니 하이퍼쓰레딩 같은 것에 따라 달라질 수 있는 것 같다. 이것은 테스트를 한번 해 볼 필요가 있다. 아래와 같은 코드로 값을 확인해 볼 수 있다.
printk("current_cpu_data.x86_max_cores : %hu\n",
current_cpu_data.x86_max_cores);
printk("current_cpu_data.booted_cores : %hu\n",
current_cpu_data.booted_cores);
각 cpu의 core id 와 physical processor id 를 확인해 보기 위해 아래와 같은 코드로 테스트 해 보았다.
printk("cpu_data(%d).phys_proc_id : %hu\n",
cpu, cpu_data(cpu).phys_proc_id);
printk("cpu_data(%d).cpu_core_id : %hu\n",
cpu, cpu_data(cpu).cpu_core_id);
}
내 pc 는 1cpu 2 core 이기 때문에 결과는 다음과 같다.
cpu_data(0).cpu_core_id : 0
cpu_data(1).phys_proc_id : 0
cpu_data(1).cpu_core_id : 1
CPU Frequency scaling
참조 : http://www.thinkwiki.org/wiki/How_to_make_use_of_Dynamic_Frequency_Scaling
리눅스에서 cpu 클럭을 동적으로 바꾸기 위해서는 먼저 cpu 에서 이를 지원해 주어야 하고( intel speed step, amd power now 등) 커널에서
CPU Frequency scaling
이 설정되어 있어야 한다. 자세한 설정은 위의 링크에 잘 나와있다.
그 다음. cpu frequency driver 를 로드해야 한다. 사용 가능한 드라이버는
/lib/modules/*/kernel/arch/*/kernel/cpu/cpufreq
에 있다. cpu 에 맞는 드라이버가 올라갔다면
/sys/devices/system/cpu/cpuN 밑에 cpufreq 디렉토리가 생성되고 아래와 같은 파일들이 생성된다.
bios_limit related_cpus scaling_governor
cpuinfo_cur_freq scaling_available_frequencies scaling_max_freq
cpuinfo_max_freq scaling_available_governors scaling_min_freq
cpuinfo_min_freq scaling_cur_freq scaling_setspeed
유저가 클럭을 변경하려면 scaling_setspeed 파일에 값을 설정하면 된다. 그런데 이때 governor 가 userspace 로 되어있지 않으면 값을 변경할 수 없다.
scaling_available_governors에서 사용 가능한 governor 를 확인할 수 있고 scaling_governor 에서 현재 설정된 governor 를 볼 수 있다.
로 governor 를 설정하고 scaling_available_frequencies 에서 확인한 주파수로 클럭을 설정하면 된다.
affected_cpus 파일에는 클럭 변경으로 영향을 받는 cpu들의 정보가 있다. 여기에 현재 cpu 만 있고 다른 cpu(core) 의 번호가 없다면 cpu(core)별로 클럭을 따로 설정할 수 있는 것이다.
이 글은 스프링노트에서 작성되었습니다.
L204WT.zip
