Archlinux x86_64
KDE 4.6


Posted by 패스파인더

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 파일을 사용할 수는 있다.

[mj@mj-arch ~]$ cvt 1680 1050
# 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" 에

    SubSection "Display"
       Depth     24
       Modes     "1680x1050_60.00"
   EndSubSection

을 추가했으나 실패. /var/log/Xorg.0.log 를 확인해보니 No valid modes for "1680x1050_60.00"; removing. 이라며 무시되었다.

 이것저것 구글링을 하며 이옵션 저옵션을 넣고 빼고 하다가 다음 링크를 찾았다.

http://forums.opensuse.org/english/get-technical-help-here/hardware/443968-graphics-issue-w-11-2-nvidia-unable-get-full-resolution-1680x1050-2.html

그 안에 누가 LG의 L204WT 모니터 EDID 의 링크를 걸어줬고 CustomEDID 라는 옵션을 알게 되었다.

Section "Screen"  에 아래 옵션을 넣고 일단 d-sub 를 연결하고 X 를 띄워보았다.

Option        "CustomEDID" "CRT-0:/etc/X11/xorg.conf.d/edid.bin"

1680x1050 으로 화면이 나왔다!!! 옵션에서 CRT-0 대신에 DFP-0 을 넣고 dvi 포트를 연결했으나 이건 또 실패.....

다시 구글링중 http://www.ubuntu.or.kr/viewtopic.php?f=20&t=10180 에서 doodoo 님이 하신 설정을 따라해보다가

Section "Monitor" 에 아래 옵션을 넣자 마침내 dvi 로도 1680x1050 해상도를 볼 수 있었다!!!!!!!!!!!!!!!!!!! ㅠㅠ

HorizSync       30.0 - 81.0
VertRefresh     55.0 - 75.0

거기서 doodoo 님은 EDID 를 사용하지 않는 옵션을 주고 모니터에 맞는 Modelines 를 찾아서 넣었는데.. 나는 거기있는 설정으로는 작동하지 않았다.


내가 성공한 설정의 설정파일은 다음과 같다. # 으로 주석처리한 부분은 이것저것 바꿔봤던 설정들이다;;;

# /etc/X11/xorg.conf.d/10-monitor.conf
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

# /etc/X11/xorg.conf.d/20-nvidia.conf
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 은

을 풀면 그 안에 있습니다.


Posted by 패스파인더

리눅스 커널 모듈 안에서 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 파일을 보면 아래와 같은 코드가 있고

c->x86_max_cores = intel_num_cpu_cores(c);

arch/x86/kernel/cpu/amd.c 파일에는 다음과 같은 코드가 있었는데 이를 보면 x86_max_cores는 cpu 의 코어수가 맞는 것 같다.

c->x86_max_cores = (ecx & 0xff) + 1;

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 를 확인해 보기 위해 아래와 같은 코드로 테스트 해 보았다.

   for_each_possible_cpu( cpu ) {
       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).phys_proc_id : 0
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 디렉토리가 생성되고 아래와 같은 파일들이 생성된다.

affected_cpus     cpuinfo_transition_latency     scaling_driver
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 를 볼 수 있다.

echo userspace > scaling_governor

로 governor 를 설정하고 scaling_available_frequencies 에서 확인한 주파수로 클럭을 설정하면 된다.

echo 1000000 > scaling_setspeed

affected_cpus 파일에는 클럭 변경으로 영향을 받는 cpu들의 정보가 있다. 여기에 현재 cpu 만 있고 다른 cpu(core) 의 번호가 없다면 cpu(core)별로 클럭을 따로 설정할 수 있는 것이다.


이 글은 스프링노트에서 작성되었습니다.

Posted by 패스파인더
◀ PREV : [1] : [2] : [3] : [4] : [5] : ... [7] : NEXT ▶

BLOG main image
by 패스파인더

공지사항

카테고리

분류 전체보기 (19)
노트 (2)
라인트레이서 (0)
리눅스 (7)
아무거나 (2)
내 사랑하는.. (0)

최근에 받은 트랙백

글 보관함

달력

«   2012/01   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31        
Total : 12,003
Today : 0 Yesterday : 2