Albert Fayngold
[28/05/2010] Fedora 13 + kernel 2.6.34 + vga_switcheroo + switch scripts (0.a) Downloads: kernel 2.6.34 and untar it to: ~/linuxKernels/ R600_rlc.bin and copy it to: /lib/firmware/radeon/ R700_rlc.bin and copy it to /lib/firmware/radeon/ Or, if you prefer everything from command line: (0.b) Downloads: $ su -c 'yum update' $ su -c 'yum install wget' $ mkdir ~/linuxKernels $ wget -P ~/linuxKernels/ http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.34.tar.bz2 $ su -c 'wget -P /lib/firmware/radeon/ http://people.freedesktop.org/%7Eagd5f/radeon_ucode/R600_rlc.bin' $ su -c 'wget -P /lib/firmware/radeon/ http://people.freedesktop.org/%7Eagd5f/radeon_ucode/R700_rlc.bin' $ cd ~/linuxKernels/ $ tar -xvjf linux-2.6.34.tar.bz2 (1) Compile kernel with CONFIG_VGA_SWITCHEROO: $ su -c 'yum install patch qt3-devel gcc-c++ libXi-devel mkinitrd' # install development tools + mkinitrd $ cd ~/linuxKernels/linux-2.6.34/ $ make mrproper $ cp /boot/config-"kernel" .config # in my case: "kernel" = 2.6.33.4-95.fc13.x86_64 $ make xconfig # select (-> Device Drivers -> Graphics support ->) Laptop Hybrid Grapics - GPU switching support (VGA_SWITCHEROO) $ gedit Makefile # and change "EXTRAVERSION =" for "EXTRAVERSION = -vgaswitcheroo" $ make clean $ make -j4 bzImage # the -j specifies the number of jobs (commands) to run simultaneously; put your number of CPUs x 2 $ make -j4 modules $ su -c 'make -j4 modules_install' $ su -c 'make -j4 install' (2) Run the new kernel and test: $ su $ mount -t debugfs none /sys/kernel/debug $ cd /sys/kernel/debug/vgaswitcheroo $ cat switch # to see which card is active $ echo DDIS > switch # to go to discrete card (log off and then log in after this command) $ echo DIGD > switch # to go to integrated card (log off and then log in after this command) $ echo OFF > switch # to just power off the card you aren't using (3) Switch & logout scripts & launchers First of all, to use these new scripts & launchers you will need the following package:$ su -c 'yum install gxmessage'Also, the /etc/fstab should be changed so that it mounts automatically the /sys/kernel/debug/vgaswitcheroo/ so that we can use the switch file inside it. So we must:$ su -c 'gedit /etc/fstab'And add the following line:none /sys/kernel/debug debugfs defaults 0 0And then, we must change switch file permissions permanently every time the computer initiates:su -c 'gedit /etc/rc.d/rc.local'And add the following line:chown "username" /sys/kernel/debug/vgaswitcheroo/switch # change "username" with your user name Ok, so now we are ready to use the launchers and scripts. The first desktop launcher is used to switch between the graphic cards directly from your desktop, and the logout launcher is needed to turn off the computer (see below for details of why it is needed on my case). They work great on my laptop ASUS M51Ta. Each of the launchers calls a script that is detailled below. It would be a good idea to copy the scripts to /home/"username"/bin/ so that they are executable from any directory and copy the icons into /home/"username"/.local/share/icons/: $ wget -P /home/"$USER"/.local/share/icons/ http://lh4.ggpht.com/_Dw3SC8gD9Jk/S-MGVcEfaiI/AAAAAAAAAIA/Pguy_uSeqSk/s800/hardware_down.png $ wget -P /home/"$USER"/.local/share/icons/ http://lh5.ggpht.com/_Dw3SC8gD9Jk/S-MGVSO0JbI/AAAAAAAAAIE/_mdAnW7UiCQ/s800/hardware_up.png $ wget -P /home/"$USER"/.local/share/icons/ http://lh6.ggpht.com/_Dw3SC8gD9Jk/S36ugEZX1PI/AAAAAAAAACs/UQUdr5cow90/s800/hardware.png $ wget -P /home/"$USER"/.local/share/icons/ http://lh5.ggpht.com/_Dw3SC8gD9Jk/S41DjuMt_MI/AAAAAAAAAF4/5pQm2-dX6Sg/s800/switch_before_shutdown.png To switch between graphic cards the following launcher is used: switch_between_cards.desktop [Desktop Entry] Version=1.0 Encoding=UTF-8 Name=switch between cards Exec=/"location of script"/switch_between_cards.sh # change "location of script" with location of script described below Type=Application Categories=Other; Icon=/"location"/hardware.png # change "location" with the location of the icon Terminal=false switch_between_cards.sh #!/bin/bash # "switch_between_cards.sh" script by RM, with useful changes from LoLL # version 20100528 pci_integrated=$(lspci | grep VGA | sed -n '1p' | cut -f 1 -d " ") pci_discrete=$(lspci | grep VGA | sed -n '2p' | cut -f 1 -d " ") integrated=$(cat /sys/kernel/debug/vgaswitcheroo/switch | grep $pci_integrated | grep -o -P ':.:...:') discrete=$(cat /sys/kernel/debug/vgaswitcheroo/switch | grep $pci_discrete | grep -o -P ':.:...:') name_integrated=$(lspci | grep VGA | sed -n '1p' | sed -e "s/.* VGA compatible controller[ :]*//g" | sed -e "s/ Corporation//g" | sed -e "s/ Technologies Inc//g" | sed -e 's/\[[0-9]*\]: //g' | sed -e 's/\[[0-9:a-z]*\]//g' | sed -e 's/(rev [a-z0-9]*)//g' | sed -e "s/ Integrated Graphics Controller//g") name_discrete=$(lspci | grep VGA | sed -n '2p' | sed -e "s/.* VGA compatible controller[ :]*//g" | sed -e "s/ Corporation//g" | sed -e "s/ Technologies Inc//g" | sed -e 's/\[[0-9]*\]: //g' | sed -e 's/\[[0-9:a-z]*\]//g' | sed -e 's/(rev [a-z0-9]*)//g' | sed -e "s/ Integrated Graphics Controller//g") if [ "$integrated" = ":+:Pwr:" ] then integrated_condition="(*) - Power ON" elif [ "$integrated" = ": :Pwr:" ] then integrated_condition="( ) - Power ON" elif [ "$integrated" = ": :Off:" ] then integrated_condition="( ) - Power OFF" fi if [ "$discrete" = ":+:Pwr:" ] then discrete_condition="(*) - Power ON" elif [ "$discrete" = ": :Pwr:" ] then discrete_condition="( ) - Power ON" elif [ "$discrete" = ": :Off:" ] then discrete_condition="( ) - Power OFF" fi gxmessage -center \ -buttons "_Cancel":1,"switch to _Integrated":101,"switch to _Discrete":102 \ -wrap \ -title "Choose Hybrid Graphic Card" \ "Choose Hybrid Graphic Card ================= Integrated: $integrated_condition : $name_integrated Discrete: $discrete_condition : $name_discrete" whichCard=$? case "$whichCard" in 1) echo "Exit" ;; 101) if [ "$integrated" == ":+:Pwr:" ] && [ "$discrete" == ": :Pwr:" ] then notify-send -t 5000 --icon="/home/$USER/.local/share/icons/hardware_down.png" "switching to $name_integrated" echo OFF > /sys/kernel/debug/vgaswitcheroo/switch elif [ "$integrated" == ": :Pwr:" ] && [ "$discrete" == ":+:Pwr:" ] then notify-send -t 5000 --icon="/home/$USER/.local/share/icons/hardware_down.png" "switching to $name_integrated" echo DIGD > /sys/kernel/debug/vgaswitcheroo/switch killall -u "$USER" # or gnome-session-save --logout elif [ "$integrated" == ": :Off:" ] && [ "$discrete" == ":+:Pwr:" ] then notify-send -t 5000 --icon="/home/$USER/.local/share/icons/hardware_down.png" "switching to $name_integrated" echo ON > /sys/kernel/debug/vgaswitcheroo/switch echo DIGD > /sys/kernel/debug/vgaswitcheroo/switch killall -u "$USER" # or gnome-session-save --logout elif [ "$integrated" == ":+:Pwr:" ] && [ "$discrete" == ": :Off:" ] then notify-send -t 5000 --icon="/home/$USER/.local/share/icons/hardware_down.png" "already switched to $name_integrated" fi ;; 102) if [ "$integrated" == ":+:Pwr:" ] && [ "$discrete" == ": :Pwr:" ] then notify-send -t 5000 --icon="/home/$USER/.local/share/icons/hardware_up.png" "switching to $name_discrete" echo DDIS > /sys/kernel/debug/vgaswitcheroo/switch killall -u "$USER" # or gnome-session-save --logout elif [ "$integrated" == ": :Pwr:" ] && [ "$discrete" == ":+:Pwr:" ] then notify-send -t 5000 --icon="/home/$USER/.local/share/icons/hardware_up.png" "switching to $name_discrete" echo OFF > /sys/kernel/debug/vgaswitcheroo/switch elif [ "$integrated" == ":+:Pwr:" ] && [ "$discrete" == ": :Off:" ] then notify-send -t 5000 --icon="/home/$USER/.local/share/icons/hardware_up.png" "switching to $name_discrete" echo ON > /sys/kernel/debug/vgaswitcheroo/switch echo DDIS > /sys/kernel/debug/vgaswitcheroo/switch killall -u "$USER" # or gnome-session-save --logout elif [ "$integrated" == ": :Off:" ] && [ "$discrete" == ":+:Pwr:" ] then notify-send -t 5000 --icon="/home/$USER/.local/share/icons/hardware_up.png" "already switched to $name_discrete" fi ;; esac In this way, you can switch between graphic cards with just a couple of clicks. In this snapshot you can see the script showing the two hybrid graphic cards. The "(*)" symbol represents which card is currently being used and the Power ON/OFF indicates their power state. Have in mind that a graphic card can be ON but not currently being used... which of course we want to avoid. If you are using GNOME as graphical interface (instead of Openbox, like me), change al the instances of killall -u "$USER" by gnome-session-save --logout. So, if you want to switch to the discrete card (in this case the HD3650), you just click "switch to Discrete", and a message will appear: "switchig to (name of discrete card)". Then the system will log off, and after you log in again the cards have switched. Therefore, after loging out and login in, if you run again the script, it tells you which card is running "(*)": If you try to switch to the current card being used (in this case HD3650) a message will tell you "already switched to that card": And, of course, you can come back to the integrated card (running the script, choosing "switch to Integrated", and going through a log out and log in process): This next launcher is used to turn off the computer. Because, in my case, if I turn off the computer without switching on both cards (specially when the integrated card is on and the discrete card is off), the fan runs at full speed when I turn it on again, stoping only after rebooting. Hence, to avoid this, this other launcher can be used to turn off the computer: switch_before_shutdown.desktop [Desktop Entry] Version=1.0 Encoding=UTF-8 Name=switch before shutdown Exec=/"location of script"/switch_before_shutdown.sh # change "location of script" with the location of the script described below Type=Application Categories=Other; Icon=/"location"/switch_before_shutdown.png # change "location" with the location of the icon Terminal=false switch_before_shutdown.sh #!/bin/bash gxmessage "Are you sure you want to shut down your computer?" -center -title "Take action" -font "Sans bold 10" -default "Cancel" -buttons "_Cancel":1,"L_ock screen":101,"_Log out":102,"_Reboot":103,"_Shut down":104 case $? in 1) echo "Exit";; 101) xscreensaver-command -lock;; 102) killall -u "$USER";; 103) echo ON > /sys/kernel/debug/vgaswitcheroo/switch; gnome-terminal -e 'sudo shutdown -r now';; 104) echo ON > /sys/kernel/debug/vgaswitcheroo/switch gnome-terminal -e 'sudo shutdown -h now';; esac And finally, enjoy your hybrid graphics!! By the way, if you like my desktop, I use OpenBox with LXPanel and two conkys, one for the panel bar with a summary of CPUs, memory, network and hard disk functioning; and another one with more details in the desktop. Here are the conky files: .conkyrc_bar alignment top_right background yes border_margin 0 border_width 0 default_color grey double_buffer yes draw_borders no draw_outline yes draw_shades no gap_x 290 gap_y -5 maximum_width 286 minimum_size 286 no_buffers yes own_window yes own_window_colour green own_window_hints undecorated,below,sticky,skip_taskbar,skip_pager own_window_transparent yes own_window_type desktop stippled_borders 0 total_run_times 0 update_interval 1 uppercase no use_spacer yes TEXT ${cpugraph cpu1 18,29 0092e6 0092e6}${cpugraph cpu2 18,29 0092e6 0092e6} ${memgraph 18,29 00b35b 00b35b} ${downspeedgraph 18,29 fce94f fce94f}${upspeedgraph 18,29 c4a000 c4a000} ${diskiograph_read /dev/sda1 18,29 c65000 c65000}${diskiograph_write /dev/sda1 18,29 ff6700 ff6700} ${diskiograph_read /dev/sda5 18,29 c65000 c65000}${diskiograph_write /dev/sda5 18,29 ff6700 ff6700}$color .conkyrc_full alignment top_right background yes border_margin 0 border_width 0 default_color grey double_buffer yes draw_borders no draw_outline yes draw_shades no gap_x 0 gap_y 0 maximum_width 286 minimum_size 286 no_buffers yes override_utf8_locale yes own_window yes own_window_colour green own_window_hints undecorated,below,sticky,skip_taskbar,skip_pager own_window_transparent yes own_window_type desktop stippled_borders 0 total_run_times 0 update_interval 1 uppercase no use_spacer yes TEXT ${battery_bar 10,20 BAT0} ${battery_percent BAT0}% ${iconv_start UTF-8 ISO_8859-1}[$desktop/$desktop_number] CPU: ${color green}${acpitemp} C ${color}HDD: ${color green}${hddtemp /dev/sda 127.0.0.1 7634} C $alignr$color${time %H:%M:%S}${iconv_stop} ${color green}SYSTEM ${hr 2}$color $nodename $alignr$sysname $kernel $machine Uptime:$alignr$uptime ${color green}CPU 0 ${hr 2}$color ${freq 1}MHz $alignr Load: ${loadavg} ${cpubar cpu1} ${cpugraph cpu1 004973 0092e6} ${color green}CPU 1 ${hr 2}$color ${freq 2}MHz $alignr Load: ${loadavg} ${cpubar cpu2} ${cpugraph cpu2 004973 0092e6} ${top pid 1} ${top name 1} ${top cpu 1}% CPU ${top mem 1}% MEM ${top pid 2} ${top name 2} ${top cpu 2}% CPU ${top mem 2}% MEM ${top pid 3} ${top name 3} ${top cpu 3}% CPU ${top mem 3}% MEM ${top pid 4} ${top name 4} ${top cpu 4}% CPU ${top mem 4}% MEM ${top pid 5} ${top name 5} ${top cpu 5}% CPU ${top mem 5}% MEM ${top_mem pid 1} ${top_mem name 1} ${top_mem mem_res 1} MEM ${top_mem mem 1}% MEM ${top_mem pid 2} ${top_mem name 2} ${top_mem mem_res 2} MEM ${top_mem mem 2}% MEM ${top_mem pid 3} ${top_mem name 3} ${top_mem mem_res 3} MEM ${top_mem mem 3}% MEM ${top_mem pid 4} ${top_mem name 4} ${top_mem mem_res 4} MEM ${top_mem mem 4}% MEM ${top_mem pid 5} ${top_mem name 5} ${top_mem mem_res 5} MEM ${top_mem mem 5}% MEM Processes: $processes ${alignr}Running: $running_processes ${color green}MEMORY / DISK ${hr 2}$color RAM: $mem/$memmax - $memperc% ${membar 6}$color ${memgraph 006333 00b35b} swap: ${swap}/${swapmax} - $swapperc% ${swapbar 6}$color sda1: ${fs_used /}/${fs_size /} - ${fs_used_perc /}% ${color green}${hr 1}$color ${fs_bar 6 /}$color Read: ${diskio_read /dev/sda1} k/s ${alignr}Write: ${diskio_write /dev/sda1} k/s ${diskiograph_read /dev/sda1 25,140 5e2600 c65000} ${diskiograph_write /dev/sda1 25,140 823500 ff6700} sda5: ${fs_used /home/"username"/CONTAINER/}/${fs_size /home/"username"/CONTAINER/} - ${fs_used_perc /home/"username"/CONTAINER}% ${color green}${hr 1}$color ${fs_bar 6 /home/"username"/CONTAINER}$color Read: ${diskio_read /dev/sda5} k/s ${alignr}Write: ${diskio_write /dev/sda5} k/s ${diskiograph_read /dev/sda5 25,140 5e2600 c65000} ${diskiograph_write /dev/sda5 25,140 823500 ff6700} ${color green}NETWORK eth0 (${addr eth0}) ${hr 2}$color Down: $color${downspeed eth0} k/s ${alignr}Up: ${upspeed eth0} k/s ${downspeedgraph eth0 20,140 8c822c fce94f} ${upspeedgraph eth0 20,140 705b00 c4a000}$color Total: ${totaldown eth0} ${alignr}Total: ${totalup eth0} ${color green}NETWORK wlan0 (${addr wlan0}) ${hr 2}$color Down: $color${downspeed wlan0} k/s ${alignr}Up: ${upspeed wlan0} k/s ${downspeedgraph wlan0 20,140 8c822c fce94f} ${upspeedgraph wlan0 20,140 705b00 c4a000}$color Total: ${totaldown wlan0} ${alignr}Total: ${totalup wlan0} Inbound: ${tcp_portmon 1 32767 count} Outbound: ${tcp_portmon 32768 61000 count}${alignr}Total: ${tcp_portmon 1 65535 count} ${color green}${hr 2}$color