2013/06/27

Linux Power and Battery Life



這篇文章整理之前在看 Ubuntu 省電機制的。


電池資訊


Linux 系統中的電池資訊在 sysfs 裡都找得到,如下。或是直接使用 gnome-power-statistics 來看也可以,如上圖。

u-Latitude-E6440:/sys/class/power_supply/BAT01 ls
alarm               current_now   model_name     status      uevent
charge_full         cycle_count   power          subsystem   voltage_min_design
charge_full_design  device        present        technology  voltage_now
charge_now          manufacturer  serial_number  type

對 voltage_now, current_now, charge_full, voltage_min_design 做簡單的運算便能得到放電速度及總電量。底下的 script 提供了簡單的放電速度統計。



執行畫面如下:

u@u-Latitude-E6540:~1 ./power.sh  ts
Jun 13 16:20:43 current   average   capacity   full_capacity   time_left
Jun 13 16:20:43 14.13254   14.13254   37.19610   65.49000   2.63
Jun 13 16:20:48 14.07107   14.11409   37.17390   65.49000   2.63
Jun 13 16:20:53 14.08747   14.10610   37.15170   65.49000   2.63
Jun 13 16:20:58 13.77746   14.00750   37.14060   65.49000   2.65
Jun 13 16:21:03 14.03222   14.01491   37.11840   65.49000   2.64
Jun 13 16:21:08 13.16450   13.75978   37.09620   65.49000   2.69

有時沒儀器可以量時,用 script 來計算是蠻方便的。


延長電池使用時間


之前用了 2 種方式來讓系統更省電。

  1. Append boot coomand "pcie_aspm=force"
  2. Install PowerTOP
  3. Install Laptop Mode Tools

第一種 ASPM 的方法,大概可以省個 2 W 左右。第二種 PowerTOP 的方式,全部省電機制啟用,也可再省個 2 W 左右。最後第三種 laptop-mode-tools,這只是個方便的 PowerTOP 工具而已,它會讓你在沒插 AC 電源時,自動將 PowerTOP 的省電機制啟用。個人是建議一般的 NB 可以試試 1 + 3。

最近做到的平台都是 SharkBay (haswell),對於硬體比較有針對省電設計的,大概上面那些機制全下,大概平均耗電量是 6 W/h,對於常見的 50 W 的電池用個 8 小時是沒問題,但 8 小時也是要 NB 放著都不動,如果像我常看個影片,開個 VM,那還會有 5 小時嗎?呵呵

(對於 MBA 的 12 小時來說,8 小時跟垃圾一樣)

2013/06/17

GTK 3 and CSS in Python



最近在看 CSS 對於 GTK 3 程式的支援,並且寫了一些小程式玩了一下,覺得相當愉悅。

在 GTK 2 以前,要修改 widget 外觀要可以透過 gtkrc,但對於 GTK 3 可以直接給 CSS 相較之下,修改 CSS 簡單多了。此外 CSS 又提供像是背景的 gradient, transition, border-radius, border-image 這類的特性,要做到一些簡單的特效也變得十分容易。詳細的特效可參考 GtkCssProvider

想直接玩一下 CSS 的花樣可直接在 Ubuntu 13.04 下安裝 gtk-3-examples,並執行 gtk3-demo

$ sudo apt-get install gtk-3-examples
$ gtk3-demo

其中 css theming 的部分就可看到 CSS 帶來的特殊處。如同下面影片:




Hello World


接下來就來寫個簡單的 GKT 3 and CSS 的“你好世界”吧!在 Ubuntu 13.04 的環境下需安裝:

$ sudo apt-get install gir1.2-gtk-3.0 

程式如下,執行畫面類似 demo 裡的 CSS accordion。



Document


若是第一次使用 GTK 3 的朋友們可以先從這份 GTK 3 tutorial 開始看起。若是已經熟悉 GTK 開發的朋友,可接接產生 API reference 來看,產生方式如下:

$ sudo apt-get install yelp yelp-tools libgirepository1.0-dev libgtk-3-dev
$ g-ir-doc-tool --language Python -o ./output_dir /usr/share/gir-1.0/Gtk-3.0.gir
$ yelp ./output_dir/index.page

執行畫面如下:

2013/06/13

clutter-gtk 現況與發展


最近在嘗試如何用 GTK+ 做到視窗元件的動畫。

說到 GTK+ 一開始一定去查查 cairo 有沒有好用的 API,後來查到了這篇,稍微看了一下只覺得是杯具。我的需求只是針對 GTK+ 元件,在 mouseover 時,做個 scale,transparent(alpha), translate 這類常見的特效,但那篇文章裡一看到還要實作 timer function,就沒力了。

接著又想到 clutter 可以用,就開始用 clutter-gtk 埋頭幹起,搞了一整天結果像這樣:



程式可在這裡找到。

但過沒多久,看到一則訊息,說 clutter-gtk 只是實驗性質的東西,未來不會再使用。做了好幾天的白工,杯具呀...

那到底該怎麼做視窗元件的動畫呢?可以試試 GtkCssProvider

2013/06/06

製作多重 Ubuntu 開機 USB



感謝 4元 提供的這篇文章,裡頭描述了如何在同一支隨身碟放不同 Ubuntu 的版本來開機。可是因為小弟需要拿來開機的 ISO 除了眾多的 Ubuntu/Debian 外,還有很多 Ubuntu 系列的 ODM ISO,因此很需要一個 script 來幫我自動產生 grub.cfg。


準備工作


如果你的隨身碟超過 4G,請先分割它吧。舉例來說,小弟是用 16G 的隨身碟,分成了 2G 放 Ubuntu,14G 放 iso。如下

$ sudo fdisk -l /dev/sdc

Disk /dev/sdc: 16.7 GB, 16684941312 bytes
64 heads, 32 sectors/track, 15912 cylinders, total 32587776 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x8612adfe

   Device Boot      Start         End      Blocks   Id  System
/dev/sdc1            2048     4196351     2097152   83  Linux
/dev/sdc2         4196352    32587775    14195712   83  Linux

接著

  • 格式化硬碟
  • 建立 Ubuntu 開機光碟
  • 安裝 grub 工具

我的測試環境是 Ubuntu 12.04.2,最後一行安裝 grub 的部分可能會有點不同喔

$ sudo mkfs.vfat /dev/sdc1
$ sudo mkfs.ext2 /dev/sdc2
$ usb-creator-gtk -n -i ubuntu-13.04-desktop-amd64.iso
$ sudo apt-get install grub-pc-bin grub-efi-amd64-bin
$ sudo grub-install --root-directory=/media/97C4-B559/ /dev/sdc


制作 grub.cfg


先準備一些 iso 複制到第 2 個 partitions

$ ls ubuntu-*
ubuntu-12.04.2-desktop-amd64.iso  ubuntu-12.10-desktop-amd64.iso
ubuntu-12.04-server-amd64.iso     ubuntu-13.04-desktop-amd64.iso
$ cp ubuntu-1* /media/e39b1707-7f5c-4d0d-a019-13cdfd86b20d/

把 script 抓下來,執行它,第一個參數是放 iso 的位置,第二個參數是放 grub.cfg 路徑

$ cd /media/e39b1707-7f5c-4d0d-a019-13cdfd86b20d/
$ wget https://raw.github.com/fcwu/sys_prog/master/mkgrub.sh
$ chmod +x mkgrub.sh
$ sudo ./mkgrub.sh ./ ../97C4-B559/boot/grub/grub.cfg
Creating grub.cfg template
Scanning ./
    creating boot entry for file .//ubuntu-12.04.2-desktop-amd64.iso...ok
    creating boot entry for file .//ubuntu-12.04-server-amd64.iso...ok
    creating boot entry for file .//ubuntu-12.10-desktop-amd64.iso...ok
    creating boot entry for file .//ubuntu-13.04-desktop-amd64.iso...ok

完成。請拿著 USB 去開機看看吧,結果如上圖。

2013/06/05

PxeUbuntu: Install Ubuntu from network




現在整天都在安裝各式各樣的 Ubuntu,目前安裝的方式都是用 usb-creator-gtk 把 iso 放到隨身碟再從 USB 開機,過程花很多時間在製作隨身碟。網路上可以找到很多直接從網路開機,安裝 Ubuntu 的方式,只是那要安裝 NFS, DHCP, tftp server,還要設定一堆有的沒的,很麻煩。這次要介紹的 pxeubuntu 可以讓你免除那些煩惱。


Install PxeUbuntu


$ sudo add-apt-repository ppa:fcwu-tw/ppa
$ sudo apt-get update
$ sudo apt-get install pxeubuntu


Run


請先確定

  • 沒有裝 dhcp server,有裝的話建議先註解掉目前的設定,讓程式自動設定。
  • 已設定固定 IP

執行

$ sudo pxeubuntu start
2013-06-05 05:40:41,895 INFO     args: work_dir: /home/u
2013-06-05 05:40:41,895 INFO     args: iso_dir: /home/u/iso
2013-06-05 05:40:41,895 INFO     args: nfs_dir: /home/u/exportfs
2013-06-05 05:40:41,895 INFO     args: tftp_dir: /var/lib/tftpboot
Add PXE boot configure to dhcpd.conf? (Y/N) y
2013-06-05 05:40:43,052 INFO     check ISOs - TD(TFTP DIR) TB(TFTP BOOT) M(MOUNT) MP(MOUNT POINT) E(EXPORTS)
2013-06-05 05:40:43,060 INFO     Start monitoring file in /home/u/iso

在第一次使用,且沒有 dhcp 的設定時,它會問是否要加入 dhcp 設定,回答 y 就沒錯了。

有問題的話請也先確定有沒有手動把 NFS, DHCP TFTP server 給關掉。


加入/刪除 ISO


將你的 ISO 放到 ~/iso/ 即會自動建立 boot entry 及所有設定。移除檔案時相關設定也會被移掉。

$ # Add boot entry
$ sudo mv ubuntu.iso ~/iso
$ # remove boot entry
$ sudo mv ~/iso/ubuntu.iso ~/

有 boot entry 被修改時,在執行 pxeubuntu 的視窗會顯示這些 log

2013-06-05 05:45:22,801 INFO     Inert image ubuntu-13.04-desktop-amd64 in path /home/u/iso/ubuntu-13.04-desktop-amd64.iso.
2013-06-05 05:45:22,856 INFO     Insert successfully
2013-06-05 05:45:38,640 INFO     FILE MOVE FROM: /home/u/iso/ubuntu-13.04-desktop-amd64.iso
2013-06-05 05:45:38,640 INFO     FILE DELETE: /home/u/iso/ubuntu-13.04-desktop-amd64.iso
2013-06-05 05:45:38,640 INFO     Remove image ubuntu-13.04-desktop-amd64 in path /home/u/iso/ubuntu-13.04-desktop-amd64.iso
2013-06-05 05:45:38,681 INFO     Remove successfully

開機測試


將測試機台跟執行 pxeubuntu 的伺服器用網路線接著,再從開機選項裡選網路開機,便會看到上圖了。

以上,夠簡單吧!


其它指令


$ sudo pxeubuntu -h
usage: pxeubuntu [-h] [--log-level {notset,debug,info,warning,error,critical}]
                 [--log-dir LOG_DIR] [--work-dir WORK_DIR] [--iso-dir ISO_DIR]
                 [--nfs-dir NFS_DIR] [--tftp-dir TFTP_DIR] [-d] [-i INTERFACE]
                 {start,stop,restart,insert,remove,check,insert_copy,version}

A PXE boot assistant service

positional arguments:
  {start,stop,restart,insert,remove,check,insert_copy,version}
                        Action is one of start, stop, restart, insert, remove,
                        check, insert_copy, version

optional arguments:
  -h, --help            show this help message and exit
  --log-level {notset,debug,info,warning,error,critical}
                        Log level. One of notset, debug, info, warning, error
                        or critical (info by default)
  --log-dir LOG_DIR     Path to the directory to store log files
  --work-dir WORK_DIR   Path to the working directory. $HOME directory is
                        default. Some directories refer this option as base
                        folder, such as iso, nfs mount point, tftp
  --iso-dir ISO_DIR     Directory to put iso files
  --nfs-dir NFS_DIR     Directory to mount iso files
  --tftp-dir TFTP_DIR   Directory to tftp root
  -d, --daemon          Run as daemon
  -i INTERFACE, --interface INTERFACE
                        network interface such as eth0, wlan0 for DHCP and NFS
                        binding

2013/06/03

Kernel Module Insert Failure: disagrees about version of symbol module_layout, Unknown symbol __fentry__ and __stack_chk_fail





由於沒有我家那台 NAS 的 kernel 的 source code 及 config 所以在編一些 kernel module 時發生了一堆問題,這篇文章整理了發生的問題。

在開始之前,我要大力抨擊我用的這家 NAS 公司,請他們儘快將 kernel source code 公佈及把 /proc/config.gz 打開,這不只是為 GPL 的問題,也是對我們這些玩家的友善表現。

Q1: disagrees about version of symbol module_layout



喔,版本不合,先看一下自己編出來 module version

$ modprobe --dump-modversions ./vboxguest.ko | grep module_layout
0x8495e121 module_layout

隨便找個 "they" module 來參考

$ modprobe --dump-modversion /lib/modules/3.1.2/ath.ko | grep module_layout
0x2b701e76 module_layout

至此,大概就知道要把 module_layout 的版本改成 0x2b701e76。推薦使用 hte 這套軟體,Ubuntu 就 apt-get install ht。hte 怎麼用?先用它找到 ELF section __versions 的 offset,之後再直接 goto 到那個位置,最後修改結果如下:

$ readelf -x __versions vboxguest.ko 

Hex dump of section '__versions':
0x00000000 21e19584 00000000 6d6f6475 6c655f6c !.......module_l
0x00000010 61796f75 74000000 00000000 00000000 ayout...........
0x00000020 00000000 00000000 00000000 00000000 ................
0x00000030 00000000 00000000 00000000 00000000 ................

題外話,module 在編譯時除了放 version 外,還有 info,它就放在 .modinfo section。

$ modinfo ./vboxguest.ko 
filename:       ./vboxguest.ko
version:        4.1.12_Ubuntu
license:        GPL
description:    Oracle VM VirtualBox Guest Additions for Linux Module
author:         Oracle Corporation
srcversion:     9E8128FBCF872CA4EA6525A
alias:          pci:v000080EEd0000CAFEsv00000000sd00000000bc*sc*i*
depends:        
vermagic:       3.2.0-41-generic SMP mod_unload modversions 

$ readelf -x .modinfo vboxguest.ko 

Hex dump of section '.modinfo':
0x00000000 76657273 696f6e3d 342e312e 31325f55 version=4.1.12_U
0x00000010 62756e74 75006c69 63656e73 653d4750 buntu.license=GP
0x00000020 4c006465 73637269 7074696f 6e3d4f72 L.description=Or
0x00000030 61636c65 20564d20 56697274 75616c42 acle VM VirtualB
0x00000040 6f782047 75657374 20416464 6974696f ox Guest Additio
0x00000050 6e732066 6f72204c 696e7578 204d6f64 ns for Linux Mod
0x00000060 756c6500 61757468 6f723d4f 7261636c ule.author=Oracl
0x00000070 6520436f 72706f72 6174696f 6e007372 e Corporation.sr
0x00000080 63766572 73696f6e 3d394538 31323846 cversion=9E8128F
0x00000090 42434638 37324341 34454136 35323541 BCF872CA4EA6525A
0x000000a0 00616c69 61733d70 63693a76 30303030 .alias=pci:v0000
0x000000b0 38304545 64303030 30434146 45737630 80EEd0000CAFEsv0
0x000000c0 30303030 30303073 64303030 30303030 0000000sd0000000
0x000000d0 3062632a 73632a69 2a006465 70656e64 0bc*sc*i*.depend
0x000000e0 733d0076 65726d61 6769633d 332e322e s=.vermagic=3.2.
0x000000f0 302d3431 2d67656e 65726963 20534d50 0-41-generic SMP
0x00000100 206d6f64 5f756e6c 6f616420 6d6f6476  mod_unload modv
0x00000110 65727369 6f6e7320 00                ersions .



Q2: Unknown symbol __fentry__ (err 0)



錯誤訊息

[13101.595874] xxxxx: Unknown symbol __fentry__ (err 0)

Unknown symbol 的問題,我在前幾篇文章有提到解法,但是 __fentry__ 卻在 /proc/kallsyms 裡找不到。

這個追一下 kernel source code 可以發現跟 ktrace 有關,把 kernel config CONFIG_KTRACE 關掉即可。


Q3: Unknown symbol __stack_chk_fail (err 0)



錯誤訊息

[13102.472194] xxxxx: Unknown symbol __stack_chk_fail (err 0)

這個問題有玩 stack overflow 過的來都會很熟悉,這個編 module 時加個 CFLAGS += -fno-stack-protector 就行。估計是廠商為了 downsize kernel 所以關了一堆東西。

Reference

  • 解析 Linux 內核可裝載模塊的版本檢查機制, http://www.ibm.com/developerworks/cn/linux/l-cn-kernelmodules/
  • 有人遇到过 Unknown symbol __stack_chk_fail 这样的问题么, http://bbs.chinaunix.net/thread-2049091-1-1.html
  • 模塊不能插入的問題解決 disagrees about version of symbol struct_module, http://lagignition.blog.163.com/blog/static/12873002320109135292479/

(真是一個失敗的標題)