Skip to content

Monthly Archives: March 2014

Preparing a new Rig (Gentoo + SGMiner)

bios-z77a-g45This page is used with a MSI Z77A-G45 Motherboard UEFI, a SSD hard drive SATA partionned with GPT,

1. Update the motherboard firmware (aka BIOS even if UEFI based)

2.Configure the motherboard

  1. Settings > Advanced > Power Management Setup > Restore after AC power loss : [Power On]
  2. Settings > Boot > Full screen logo display : [Disabled]
  3. Settings > Boot > Boot mode select : [legacy+uefi]
  4. Settings > Boot > Forced boot order :
    1. UEFI USB Key
    2. USB Key
    3. UEFI USB CD/DVD
    4. USB CD/DVD
    5. UEFI Hard Disk
    6. powerHard Disk

3.  Configure your modem/router :

  1. Set a static DHCP entry for the mac address of the motherboard, ie 192.168.0.100
  2. Set a port forwarding from 22100/tcp to 22100/tcp

4. Boot on a Gentoo Install Minimal USB Key :

  1. Set a temporary root password (“passwd”)
  2. Set “Port 22100” in /etc/ssh/sshd_config
  3. Launch sshd : “/etc/init.d/sshd start”
  4. Check with “ip a” that eth0 have the good ip address (may be enp2s0, enp3s0 or other)

5. Prepare playbook execution

  1. Connect with ssh : “ssh -p 22100 root@192.168.0.100”
  2. Add your ssh public key to /root/.ssh/authorized_keys
  3. Retry the connection with the ssh key
  4. disable or change the root passwd with a huge one
  5. load the kernel module for efi : “modprobe efivars”
  6. Partition, format and mount the harddrive :
# partition
parted --script --align optimal /dev/sda mklabel gpt
parted --script --align optimal /dev/sda mklabel msdos
parted --script --align optimal /dev/sda mklabel gpt
parted --script --align optimal /dev/sda mkpart primary fat32 0% 256MiB
parted --script --align optimal /dev/sda mkpart primary ext2 256MiB 512MiB
parted --script --align optimal /dev/sda mkpart primary linux-swap 512MiB 768MiB
parted --script --align optimal /dev/sda mkpart primary ext3 768MiB 100%
parted --script --align optimal /dev/sda set 1 boot on
parted --script --align optimal /dev/sda print

# format
mkfs.vfat -F32 -s 2 -n efi-boot /dev/sda1
mkfs.ext2 /dev/sda2
mkfs.ext3 /dev/sda4
mkswap /dev/sda3

# mount
swapon /dev/sda3
mount /dev/sda4 /mnt/gentoo
mkdir /mnt/gentoo/boot
mount /dev/sda2 /mnt/gentoo/boot
mkdir /mnt/gentoo/boot/efi
mount /dev/sda1 /mnt/gentoo/boot/efi

6. Execute the playbook to install Gentoo stage3 (amd64), portage, base configuration, grub, programs, x, drivers, kernel

many shell / emerge commands in this playbook waiting for me to finish the emerge module for ansible :

- hosts: gentoo_stage3_chroot_and_mining_base

  vars:
    chroot_basedir: "/mnt/gentoo"

  vars_files:
    - ../global_vars.yml

  user: root

  tasks:

    - copy: backup=no src=${basedir}/files/gentoo/${gentoo_stage3_latest} dest=${chroot_basedir}/${gentoo_stage3_latest} owner=root group=root mode=0644
    - copy: backup=no src=${basedir}/files/gentoo/${gentoo_portage_latest} dest=${chroot_basedir}/${gentoo_portage_latest} owner=root group=root mode=0644
    - file: path=${chroot_basedir} owner=root group=root mode=0755 state=directory
    - shell: test -d ${chroot_basedir}/usr || tar xf ${chroot_basedir}/${gentoo_stage3_latest} -C ${chroot_basedir}
    - shell: test -d ${chroot_basedir}/usr/portage || tar xf ${chroot_basedir}/${gentoo_portage_latest} -C ${chroot_basedir}/usr

    - shell: chroot ${chroot_basedir} /bin/bash -c "env-update && source /etc/profile && cd /tmp && exec /etc/init.d/sshd checkconfig" &>/dev/null
    - file: path=${chroot_basedir}/root/.ssh owner=root group=root mode=0700 state=directory
    - shell: test -e ${chroot_basedir}/root/.ssh/authorized_keys || touch ${chroot_basedir}/root/.ssh/authorized_keys
    - file: path=${chroot_basedir}/root/.ssh/authorized_keys owner=root group=root mode=0600 state=file
    - lineinfile: dest=${chroot_basedir}/root/.ssh/authorized_keys regexp='w8TbqlGQqcs0WcvHGkTuI58fUTX50QPqz54YVBYK1m6zj3sLM2uJPPPr2' line='from="176.123.63.0/24,192.168.0.0/24,192.168.1.0/24" ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCpJ+UQL3U7jeEJmJFmtfEz69sfFiqXaX/9z2EGx1ZFDxgyUVZ5Kyn5wrVbEufExQ1D3N8PINLRg7tL0JArofiJCVcBqEWk/w8TbqlGQqcs0WcvHGkTuI58fUTX50QPqz54YVBYK1m6zj3sLM2uJPPPr2r/6FZm8S1kxfMhtO6n/8q47M4YzXp5cHwzgejcLNjez5RS5Vc+EA+QVynOgNFrCSGhPEI5P1tSXTLFmD9kqBvbMTKdTQC4ao+yu2xkyudzg2SBFcnvDzfvKkfDEqy15gjI9fCfd+Glvg4BHpvx0re7Gx4E+wGAv6ZxWHclGNPgGhj4o+hPOwlcV+E6PcVT davixx@madness.davixx.net'

    - shell: cp -L /etc/resolv.conf ${chroot_basedir}/etc/resolv.conf
    - shell: mount | grep "${chroot_basedir}/proc" &>/dev/null || mount -t proc none ${chroot_basedir}/proc
    - shell: mount | grep "${chroot_basedir}/dev" &>/dev/null || mount --rbind /dev ${chroot_basedir}/dev
    - shell: mount | grep "${chroot_basedir}/sys" &>/dev/null || mount --rbind /sys ${chroot_basedir}/sys
    - shell: test -e ${chroot_basedir}/usr/bin/python2.7 || chroot ${chroot_basedir} /bin/bash -c "env-update && source /etc/profile && cd /tmp && exec /usr/bin/emerge --quiet dev-lang/python:2.7" &>/dev/null
    - shell: ${chroot_basedir}/usr/bin/python -V | grep 'Python 2.7.' &>/dev/null || chroot ${chroot_basedir} /bin/bash -c "env-update && source /etc/profile && cd /tmp && exec eselect python set python2.7" &>/dev/null

    - shell: cp -L /etc/resolv.conf ${chroot_basedir}/etc/resolv.conf

    - shell: chroot ${chroot_basedir} /bin/bash -c "env-update && source /etc/profile && cd /tmp && exec /usr/bin/emerge --sync" &>/dev/null

    - shell: chroot ${chroot_basedir} /bin/bash -c "cp /usr/share/zoneinfo/Europe/Paris /etc/localtime" &>/dev/null
    - shell: chroot ${chroot_basedir} /bin/bash -c "echo 'Europe/Paris' > /etc/timezone" &>/dev/null

    # todo hour / date 012514422014 # MMJJhhmmAAAA

    - shell: chroot ${chroot_basedir} /bin/bash -c "env-update && source /etc/profile && exec eselect profile set default/linux/amd64/13.0" &>/dev/null
    - shell: chroot ${chroot_basedir} /bin/bash -c "echo '127.0.0.1 ${host}.davixx.net ${host} localhost' > /etc/hosts" &>/dev/null
    - shell: chroot ${chroot_basedir} /bin/bash -c "echo 'hostname=${host}' > /etc/conf.d/hostname" &>/dev/null
    - shell: chroot ${chroot_basedir} /bin/bash -c "env-update && source /etc/profile && exec hostname ${host}" &>/dev/null

    - template: src=${basedir}/templates/net_eth0 dest=${chroot_basedir}/etc/conf.d/net owner=root group=root mode=0644
    - shell: chroot ${chroot_basedir} /bin/bash -c "cd /etc/init.d && exec ln -snf net.lo net.eth0" &>/dev/null
    - shell: chroot ${chroot_basedir} /bin/bash -c "env-update && source /etc/profile && exec rc-update add net.eth0 default" &>/dev/null

    - shell: chroot ${chroot_basedir} /bin/bash -c "env-update && source /etc/profile && exec rc-update add sshd default" &>/dev/null

    - lineinfile: dest=${chroot_basedir}/etc/conf.d/keymaps regexp='^keymap=' line='keymap="fr"'

    - lineinfile: dest=${chroot_basedir}/etc/portage/make.conf regexp='^USE=' line='USE="-bindist mmx sse sse2"'
    - lineinfile: dest=${chroot_basedir}/etc/portage/make.conf regexp='^GRUB_PLATFORMS=' line='GRUB_PLATFORMS="efi-64"'
    - lineinfile: dest=${chroot_basedir}/etc/portage/make.conf regexp='^VIDEO_CARDS=' line='VIDEO_CARDS="fglrx vesa"'
    - lineinfile: dest=${chroot_basedir}/etc/portage/make.conf regexp='^INPUT_DEVICES=' line='INPUT_DEVICES="evdev"'

    - lineinfile: dest=${chroot_basedir}/etc/portage/package.use regexp='^x11-wm/fluxbox\s' line='x11-wm/fluxbox -gnome -kde truetype vim-syntax' create=yes
    - lineinfile: dest=${chroot_basedir}/etc/portage/package.use regexp='^x11-libs/cairo\s' line='x11-libs/cairo X'
    - lineinfile: dest=${chroot_basedir}/etc/portage/package.use regexp='^media-libs/imlib2\s' line='media-libs/imlib2 X'
    - lineinfile: dest=${chroot_basedir}/etc/portage/package.use regexp='^x11-libs/libdrm\s' line='x11-libs/libdrm libkms'
    - lineinfile: dest=${chroot_basedir}/etc/portage/package.use regexp='^media-libs/mesa\s' line='media-libs/mesa xa'
    - lineinfile: dest=${chroot_basedir}/etc/portage/package.use regexp='^dev-libs/libxml2\s' line='dev-libs/libxml2 python'
    - lineinfile: dest=${chroot_basedir}/etc/portage/package.use regexp='^x11-base/xorg-server\s' line='x11-base/xorg-server udev'
    - lineinfile: dest=${chroot_basedir}/etc/portage/package.use regexp='^x11-libs/pango\s' line='x11-libs/pango X'

    - lineinfile: dest=${chroot_basedir}/etc/portage/package.keywords regexp='^=x11-drivers/ati-drivers-' line='=x11-drivers/ati-drivers-13.9' create=yes

    - template: src=${basedir}/templates/fstab_gentoo_efi_grub2 dest=${chroot_basedir}/etc/fstab owner=root group=root mode=0644

    - shell: chroot ${chroot_basedir} /bin/bash -c "env-update && source /etc/profile && exec /usr/bin/emerge -qn --newuse dev-libs/openssl net-misc/openssh" &>/dev/null

    - shell: chroot ${chroot_basedir} /bin/bash -c "env-update && source /etc/profile && exec /usr/bin/emerge -qn =sys-kernel/gentoo-sources-3.10.25 sys-kernel/linux-firmware sys-fs/dosfstools sys-block/parted net-analyzer/tcpdump" &>/dev/null

    - copy: backup=no src=${basedir}/files/kernel/${kernel_image_latest} dest=${chroot_basedir}/boot/${kernel_image_latest} owner=root group=root mode=0644
    - copy: backup=no src=${basedir}/files/kernel/${kernel_config_latest} dest=${chroot_basedir}/boot/${kernel_config_latest} owner=root group=root mode=0644
    - copy: backup=no src=${basedir}/files/kernel/${kernel_config_latest} dest=${chroot_basedir}/usr/src/linux-${kernel_version_latest}/.config owner=root group=root mode=0644
    - shell: chroot ${chroot_basedir} /bin/bash -c "env-update && source /etc/profile && cd /usr/src/linux-${kernel_version_latest} && exec make -j3" &>/dev/null
    - shell: chroot ${chroot_basedir} /bin/bash -c "env-update && source /etc/profile && cd /usr/src/linux-${kernel_version_latest} && exec make -j3 modules modules_install" &>/dev/null
    - copy: backup=no src=${basedir}/files/drivers/${driver_r8168_tarball} dest=${chroot_basedir}/usr/portage/distfiles/${driver_r8168_tarball} owner=root group=root mode=0644
    - shell: chroot ${chroot_basedir} /bin/bash -c "env-update && source /etc/profile && cd /tmp && rm -rf ./${driver_r8168_dirname} && tar xf /usr/portage/distfiles/${driver_r8168_tarball} && cd ./${driver_r8168_dirname} && make clean modules && exec make install" &>/dev/null
    - lineinfile: dest=${chroot_basedir}/etc/conf.d/modules regexp='^modules=' line='modules="${modules} r8168"'

    - shell: chroot ${chroot_basedir} /bin/bash -c "env-update && source /etc/profile && exec /usr/bin/emerge -qn app-editors/vim app-admin/metalog sys-process/fcron net-misc/openvpn dev-vcs/git dev-vcs/subversion app-admin/pwgen" &>/dev/null
    - shell: chroot ${chroot_basedir} /bin/bash -c "env-update && source /etc/profile && exec /usr/bin/emerge -qn net-misc/dhcpcd sys-boot/grub app-portage/gentoolkit dev-util/strace sys-apps/iproute2 app-misc/screen app-portage/eix" &>/dev/null
    - shell: chroot ${chroot_basedir} /bin/bash -c "env-update && source /etc/profile && exec /usr/bin/emerge -qn x11-base/xorg-server fluxbox xlockmore eterm x11-misc/slim x11-apps/xdm" &>/dev/null
    - shell: chroot ${chroot_basedir} /bin/bash -c "env-update && source /etc/profile && exec /usr/bin/emerge -qn commonbox-styles commonbox-styles-extra fluxbox-styles-fluxmod gentoo-artwork xf86-input-evdev xf86-video-fbdev app-admin/conky" &>/dev/null
    - shell: chroot ${chroot_basedir} /bin/bash -c "env-update && source /etc/profile && exec /usr/bin/emerge -qn dev-python/pip dev-python/setuptools sys-process/daemontools sys-process/supervise-scripts sys-apps/lm_sensors" &>/dev/null
    - shell: chroot ${chroot_basedir} /bin/bash -c "env-update && source /etc/profile && exec /usr/bin/emerge -qn net-libs/nodejs net-dns/unbound www-client/links net-misc/openntpd app-arch/rpm2targz x11-libs/wxGTK app-admin/sudo x11-terms/xterm net-misc/telnet-bsd" &>/dev/null

    - shell: chroot ${chroot_basedir} /bin/bash -c "env-update && source /etc/profile && exec eselect news read all" &>/dev/null

    - shell: chroot ${chroot_basedir} /bin/bash -c "env-update && source /etc/profile && exec svscan-add-to-inittab" &>/dev/null
    - shell: chroot ${chroot_basedir} /bin/bash -c "env-update && source /etc/profile && exec emerge --config sys-process/fcron" &>/dev/null
    - shell: chroot ${chroot_basedir} /bin/bash -c "env-update && source /etc/profile && exec emerge --config mail-mta/nullmailer" &>/dev/null

    - shell: chroot ${chroot_basedir} /bin/bash -c "env-update && source /etc/profile && exec rc-update add metalog default" &>/dev/null
    - shell: chroot ${chroot_basedir} /bin/bash -c "env-update && source /etc/profile && exec rc-update add fcron default" &>/dev/null

    - shell: chroot ${chroot_basedir} /bin/bash -c "env-update && source /etc/profile && exec eix-update" &>/dev/null

    - lineinfile: dest=${chroot_basedir}/etc/ssh/sshd_config regexp='^Port\s+' line="Port ${ansible_ssh_port}"

    - lineinfile: dest=${chroot_basedir}/etc/default/grub regexp='^GRUB_TIMEOUT=' line='GRUB_TIMEOUT=3'
    - lineinfile: dest=${chroot_basedir}/etc/default/grub regexp='^GRUB_CMDLINE_LINUX=' line='GRUB_CMDLINE_LINUX="net.ifnames=0"'
    - file: path=${chroot_basedir}/boot/grub state=directory
    - shell: chroot ${chroot_basedir} /bin/bash -c "env-update && source /etc/profile && exec grub2-mkconfig -o /boot/grub/grub.cfg" &>/dev/null
    # - shell: chroot ${chroot_basedir} /bin/bash -c "env-update && source /etc/profile && exec grub2-install --efi-directory=/boot/efi --target=x86_64-efi /dev/sda --recheck" &>/dev/null

    - copy: backup=no src=${basedir}/templates/openvpn_conf_MINING01 dest=${chroot_basedir}/etc/openvpn/openvpn.conf owner=root group=root mode=0600
    - copy: backup=no src=${basedir}/files/vpn/MINING01/ca.crt dest=${chroot_basedir}/etc/openvpn/ca.crt owner=root group=root mode=0600
    - copy: backup=no src=${basedir}/files/vpn/MINING01/ta.key dest=${chroot_basedir}/etc/openvpn/ta.key owner=root group=root mode=0600
    - copy: backup=no src=${basedir}/files/vpn/MINING01/${host}.crt dest=${chroot_basedir}/etc/openvpn/server.crt owner=root group=root mode=0600
    - copy: backup=no src=${basedir}/files/vpn/MINING01/${host}.key dest=${chroot_basedir}/etc/openvpn/server.key owner=root group=root mode=0600

    - file: path=${chroot_basedir}/root/services state=directory

    - file: path=${chroot_basedir}/root/services/ntpd state=directory
    - copy: backup=no src=${basedir}/files/services/ntpd/run dest=${chroot_basedir}/root/services/ntpd/run owner=root group=root mode=0700
    - shell: chroot ${chroot_basedir} /bin/bash -c "ln -snf /root/services/ntpd /service/ntpd" &>/dev/null
    - file: path=${chroot_basedir}/etc/unbound/unbound.conf state=absent

    - file: path=${chroot_basedir}/root/services/unbound state=directory
    - copy: backup=no src=${basedir}/files/services/unbound/run dest=${chroot_basedir}/root/services/unbound/run owner=root group=root mode=0700
    - shell: chroot ${chroot_basedir} /bin/bash -c "ln -snf /root/services/unbound /service/unbound" &>/dev/null

    - file: path=${chroot_basedir}/root/services/openvpn state=directory
    - copy: backup=no src=${basedir}/files/services/openvpn/run dest=${chroot_basedir}/root/services/openvpn/run owner=root group=root mode=0700
    - shell: chroot ${chroot_basedir} /bin/bash -c "ln -snf /root/services/openvpn /service/openvpn" &>/dev/null

    - lineinfile: dest=${chroot_basedir}/etc/conf.d/xdm regexp='^DISPLAYMANAGER=' line='DISPLAYMANAGER="slim"'

    - file: path=${chroot_basedir}/${gentoo_stage3_latest} state=absent
    - file: path=${chroot_basedir}/${gentoo_portage_latest} state=absent

    - shell: umount ${chroot_basedir}/proc
    - shell: umount ${chroot_basedir}/dev/pts || true
    - shell: umount ${chroot_basedir}/dev || true
    - shell: umount ${chroot_basedir}/sys || true
    - shell: umount ${chroot_basedir}/boot/efi
    - shell: umount ${chroot_basedir}/boot
    - shell: mount -oremount,ro /mnt/gentoo

7. Manual step (because of the fucking usb key who virtualize the gentoo cd install, and hide uefi hardware)

# mount (or remount) disk
mount /dev/sda4 /mnt/gentoo
mount -oremount,rw /mnt/gentoo
mount /dev/sda2 /mnt/gentoo/boot
mount /dev/sda1 /mnt/gentoo/boot/efi
mount -t proc proc /mnt/gentoo/proc
mount --rbind /sys /mnt/gentoo/sys
mount --rbind /dev /mnt/gentoo/dev

# chroot
chroot /mnt/gentoo /bin/bash

# init env
env-update && source /etc/profile

# plug an usb key (check it with dmesg / dmesg -c)
# suppose she can be erased, and named sdc

# partition it !
parted --script --align optimal /dev/sdc mklabel msdos
parted --script --align optimal /dev/sdc mklabel gpt
parted --script --align optimal /dev/sdc mklabel msdos
parted --script --align optimal /dev/sdc mkpart primary fat32 0% 100%
parted --script --align optimal /dev/sdc set 1 boot on
parted --script --align optimal /dev/sdc print

# format it
mkfs.vfat -F32 -s 2 -n efi-boot /dev/sdc1

# mount it
mount /dev/sdc1 /media

# install grub on it !
grub2-install --target=x86_64-efi --efi-directory=/media --removable --modules=part_gpt

# umount it !
umount /media

# optionally set a static password (needed if something goes wrong at boot)
passwd

# leave the chroot
exit

# out of the chroot now

# umount disk (dev and sys will probably fail)
umount /mnt/gentoo/dev
umount /mnt/gentoo/sys
umount /mnt/gentoo/proc
umount /mnt/gentoo/boot/efi
umount /mnt/gentoo/boot
mount -oremount,ro /mnt/gentoo

8.  Check, and write grub on disk (to be able to definitly not use anymore the usb efi key

grub2-install --efi-directory=/boot/efi --target=x86_64-efi /dev/sda --recheck

also check :

  1. if VPN connection is up
  2. if unbound is ready and used in resolv.conf
  3. ntpd is up, and system is ntp synchronised

9. execute the mining playbook !

  1. move the rig in the [mining01] inventory place
  2. execute the mining01.yml playbook

 

- hosts: mining01

  vars:
    sgminer_tarball: sgminer-${sgminer_version}.tar.gz
    amdadl_tarball: ADL_SDK_${admadl_version}.zip

  vars_files:
    - ../global_vars.yml

  user: root

  tasks:

    - copy: backup=no src=${basedir}/files/distfiles/${amdadl_tarball} dest=/usr/portage/distfiles/${amdadl_tarball} owner=root group=root mode=0644
    - shell: emerge -qn x11-libs/amd-adl-sdk &>/dev/null
    - shell: bash -c "eselect opengl list | grep -- 'ati \*' || eselect opengl set ati"  &>/dev/null

    - file: path=/root/services/xinit state=directory
    - copy: backup=no src=${basedir}/files/services/xinit/run dest=/root/services/xinit/run owner=root group=root mode=0700
    - file: src=/root/services/xinit dest=/service/xinit owner=root group=root state=link

    - copy: backup=no src=${basedir}/files/distfiles/${sgminer_tarball} dest=/usr/portage/distfiles/${sgminer_tarball} owner=root group=root mode=0644
    - file: path=/root/services/sgminer state=directory
    - file: path=/root/.sgminer state=directory
    - copy: backup=no src=${basedir}/files/services/sgminer/sgminer_${host}.conf dest=/root/.sgminer/sgminer.conf owner=root group=root mode=0600
    - copy: backup=no src=${basedir}/files/services/sgminer/build.sh dest=/root/services/sgminer/build.sh owner=root group=root mode=0700
    - shell: /root/services/sgminer/build.sh ${sgminer_version} ${admadl_version} &>/dev/null
    - template: src=${basedir}/templates/mining_etc_worker_name dest=/etc/worker_name owner=root group=root mode=0600
    - template: src=${basedir}/templates/mining_etc_worker_password dest=/etc/worker_password owner=root group=root mode=0600
    - copy: backup=no src=${basedir}/files/services/sgminer/run dest=/root/services/sgminer/run owner=root group=root mode=0700

    # - shell: svc -t /service/sgminer

My firsts GPU Rig for mining CryptoCoins (scrypt)

There is many post describing how to make a Windows or a Linux rig to mining crypto coins, so, here, you will just find some useful links, informations or BIOS which helped me.

1. Install Operating System, Dependancy, and xGMINER :

Under Debian Linux :

http://www.lurkmore.com/wiki/Debian_Linux_cryptocoin_mining_rig_setup_guide

Under Windows :

http://www.cryptobadger.com/2013/04/build-a-litecoin-mining-rig-windows/

2. Launch CGMINER / SGMINER with the good options for your cards :

Following a Knowledge database :

https://litecoin.info/Mining_Hardware_Comparison

Find some samples on blog or websites :

http://davixx.fr/blog/cgminer-sgminer-vs-gpu-cards/

dvivgadummy005ah43. Must lie to graphics cards :

It’s a good practice and solve some problem (ADL, or driver loading) to plug into the DVI port, a DVI -> VGA adapter, with some 75 ohms resistors, making that a dummy plug :

http://www.overclock.net/t/384733/the-30-second-dummy-plug

4. Undervolt the GPU vddc :

Using MSI Afterburn, Sapphire TriXX, or an I2C tools knowing technical informations ; or :

By saving the native graphic card BIOS, modifying it with VBE7, load it in the graphic card

http://www.cryptobadger.com/2013/10/undervolting-in-linux-via-modified-bios/

http://rumorscity.com/2013/12/09/how-to-modify-video-bios-to-undervolt-gpu-in-linux/

Using a modified BIOS served by someone else :

http://davixx.fr/blog/gpu-cards-bios-firmware/