2010年11月9日 星期二

Ubuntu和mainline kernel的版號關係

Ubuntu kernel會自己maintain ABI number,ABI number會被加入kernel meta-package的版號的一部份,也會用來作為kernel image的package name的一部份。這部份比較複雜,可能要專文討論。

如果只是想查詢Ubuntu kernel某個版號和mainline kernel的對應關係,請見:

http://kernel.ubuntu.com/~kernel-ppa/info/kernel-version-map.html

2010年10月13日 星期三

Ubuntu切換外接video的hotkey作法

首先evdev driver必須從kernel input event得到正確的keycode,在/usr/include/linux/input.h定義為:
#define KEY_SWITCHVIDEOMODE     227


然後在xkb-data套件中定義了kernel keycode到X keycode的mapping:在/usr/share/X11/xkb/keycodes/evdev裡:
<I235> = 235;   // #define KEY_SWITCHVIDEOMODE     227


在/usr/share/X11/xkb/symbols/inet裡:
key <I235>   {      [ XF86Display           ]       };


於是當切換外接video的hotkey按下後,也就是scancode產生時,kernel input event會產生出值為227的keycode,evdev讀到之後,Xserver再依據xkbdata的設定轉換為XF86Display。

接下來gnome-settings-daemon會filter這個X key,如gnome-settings-daemon-2.32.0/plugins/xrandr/gsd-xrandr-manager.c:

if (xev->xany.type == KeyPress) {
if (xev->xkey.keycode == manager->priv->switch_video_mode_keycode)
handle_fn_f7 (manager, xev->xkey.time);
else if (xev->xkey.keycode == manager->priv->rotate_windows_keycode)
handle_rotate_windows (manager, xev->xkey.time);


g-s-d每收到一個XF86Display key時,會呼叫gnome-rr-* 相關的函式(請見libgnomeui/gnome-rr.h),透過RandR API切換螢幕顯示的設定,便會切換到如外接投影機等顯示設備。

參考:http://live.gnome.org/RandR

2010年10月6日 星期三

Kernel: 不列入git log的changelog

對Linux kernel或LKML來說,git log是十分正式的紀錄。不過還是有些時候,我們只想寫一些對於這個patch的意見、或是給subsystem maintainer的一些參考說明,這些東西就不是那麼適合列入正式的git log中。

一個常見的情況是maintainer對於你的patch會有不同意見,此時可能會有patch v2, v3...的出現,而這些版本之間如果可以有簡單的說明的話,對於patch review會有很大的幫助。

像是這些「非正式性」的log,可以被紀錄在diffstat之後,如:

From 1709e3f1b68a12ce05039a52182288d0f4e21c7a Mon Sep 17 00:00:00 2001
From: Keng-Yu Lin <keng-yu.lin@canonical.com>
Date: Tue, 28 Sep 2010 11:11:57 +0800
Subject: [PATCH v5] dell-laptop: Add debugfs support

Export the status of RF killswitch through debugfs.

The killswitch status is obtained by the SMI to BIOS. Exporting this status
through debugfs can help identify the issue with the misbehaving firmware.

Signed-off-by: Keng-Yu Lin <keng-yu.lin@canonical.com>
---
drivers/platform/x86/dell-laptop.c | 77 ++++++++++++++++++++++++++++++++++++
1 files changed, 77 insertions(+), 0 deletions(-)

V5 fixed operator precedence mess-up of hwswitch_state, and prints the
bit number so that this debug info is complete for hardare manufacturers.


diff --git a/drivers/platform/x86/dell-laptop.c b/drivers/platform/x86/dell-laptop.c
index 4413975..cf8a89a 100644
--- a/drivers/platform/x86/dell-laptop.c
+++ b/drivers/platform/x86/dell-laptop.c
(下略)
Patchwork: https://patchwork.kernel.org/patch/213982/

而在Linux Documentation/SubmittingPatches Section 1.15中也有說明:
Other comments relevant only to the moment or the maintainer, not suitable for the permanent changelog, should also go here. A good example of such comments might be "patch changelogs" which describe what has changed between the v1 and v2 version of the patch.

在live-helper config中加入自訂的套件

將要預設安裝的套件放在config/chroot_local-packages目錄中即可。

參考:Debian Live Manual 6.3.1 Using chroot_local-packages to install custom packages

在live-helper config中加入private PPA

首先確定在config目錄中的bootstrap有這一行:

LH_BOOTSTRAP_INCLUDE="apt-transport-https"


因為private PPA是透過HTTPS。

然後在config/chroot_sources/把PPA的source list加入在myppa.chroot當中。

接下來要加入PPA的public key,將它存在同一個目錄的myppa.chroot.gpg檔案中:

apt-key adv --recv-key <KEYID>
apt-key export <KEYID> > myppa.chroot.gpg


這樣lh build時應該就能加入private PPA。

2010年9月12日 星期日

DKMS和KERNELRELEASE變數

當 Makefile 是從 kernel build system 被呼叫執行時,KERNELRELEASE 變數會被 kbuild 定義。

這是一個常見的 Makefile 小技巧,判斷 KERNELRELEASE 是否定義來執行不同的設定。

如下列是compat-wireless的Makefile,就用到這樣的技巧:

  1. (SKIP)

  2. ifneq ($(KERNELRELEASE),)

  3. NOSTDINC_FLAGS := -I$(M)/include/ \
  4. -include $(M)/include/linux/compat-2.6.h \
  5. $(CFLAGS)

  6. obj-y := compat/

  7. obj-$(CONFIG_COMPAT_RFKILL) += net/rfkill/

  8. ifeq ($(BT),)
  9. obj-$(CONFIG_COMPAT_WIRELESS) += net/wireless/ net/mac80211/
  10. obj-$(CONFIG_COMPAT_WIRELESS_MODULES) += drivers/net/wireless/


  11. endif


  12. else

  13. export PWD := $(shell pwd)
  14. CFLAGS += \
  15. -DCOMPAT_BASE_TREE="\"$(shell cat compat_base_tree)\"" \
  16. -DCOMPAT_BASE_TREE_VERSION="\"$(shell cat compat_base_tree_version)\"" \
  17. -DCOMPAT_PROJECT="\"Compat-wireless\"" \
  18. -DCOMPAT_VERSION="\"$(shell cat compat_version)\""

  19. # These exported as they are used by the scripts
  20. # to check config and compat autoconf
  21. export COMPAT_CONFIG=config.mk
  22. export CONFIG_CHECK=.$(COMPAT_CONFIG)_md5sum.txt
  23. export COMPAT_AUTOCONF=include/linux/compat_autoconf.h
  24. export CREL=$(shell cat $(PWD)/compat_version)
  25. export CREL_PRE:=.compat_autoconf_
  26. export CREL_CHECK:=$(CREL_PRE)$(CREL)

  27. include $(PWD)/$(COMPAT_CONFIG)

  28. all: modules

  29. modules: $(CREL_CHECK)
  30. @./scripts/check_config.sh
  31. $(MAKE) -C $(KLIB_BUILD) M=$(PWD) modules
  32. @touch $@

  33. (SKIP)

  34. endif


當從 shell 執行 make 時,因為 KERNELRELEASE 沒有定義,所以第23行到第39行之間的一些變數和 CFLAGS 會被設定,然後第45行會呼叫 kbuild 的 Makefile:
$(MAKE) -C $(KLIB_BUILD) M=$(PWD) modules

之後 compat-wireless 的 Makefile 又會被呼叫一次,此時 KERNELRELEASE 已經被 kbuild 所定義,所以第5行到第18行會被執行。而做的事情就如同一般的 module Makefile 將 driver 的路徑加入 obj-$CONFIG_* 中,如第15行:
obj-$(CONFIG_COMPAT_WIRELESS_MODULES) += drivers/net/wireless/




不過,DKMS 在 build module 時會自己傳入 KERNELRELEASE 這個參數,如在 /usr/sbin/dkms:function do_build():
local the_make_command=`echo $make_command | sed "s/^make/make KERNELRELEASE=${kernelver_array[0]}/"`


我們可以看到,在 compat-wireless 的 Makefile 中,當 KERNELRELEASE 變數已被設值時,並沒有 target 可以 build,必須是經由 kbuild 的 Makefile 來 make 才可以。

所以一個 workaround 是在 dkms.conf 中將 MAKE[0] 寫成 make -C /lib/modules/`uname -r`/build M=`pwd` modules。但是在這個例子中我們還必須先在 CLFAGS 中加入一些 define。直接呼叫kbuild的話,這些 CFLAGS 都沒設定,這樣並無法正確的 build 出 module。

所以,一個可行的辦法是將 Makefile 拆開,然後在 dkms.conf:MAKE[0] 中自行指定 Makefile,如:
make -f dkms.mk


雖然必須更改原始的 Makefile,但是卻可讓 DKMS 正確運作。

CONFIG_LOCALVERSION_AUTO和git describe

最近在編譯某家大廠的BSP時,發現kernel version在正常的tag之後被加了一大串東西:
include/config/kernel.release:1:2.6.32.11+drm33.2-16040-g98cebdd

2.6.32.11+drm33.2是Ubuntu Lucid kernel的version沒錯,但是後面的-16040-g98cebdd並不是Ubuntu kernel版號的一部份,看起來是像`git describe`的結果。

執行一下,果然沒錯:

$ git describe
v2.6.31-rc4-16040-g98cebdd

v2.6.31-rc4是某個tag,16040表示目前的HEAD是從tag v2.6.31-rc4之後第16040個commit,g98cebdd表示目前commit的git sha1前幾個值是98cebdd...。

而這個版號是因為 CONFIG_LOCALVERSION_AUTO=y 產生出來的。從LOCALVERSION_AUTO的文義有點難聯想到它的行為。

以下是完整的文件說明:


config LOCALVERSION_AUTO
bool "Automatically append version information to the version string"
default y
help
This will try to automatically determine if the current tree is a
release tree by looking for git tags that belong to the current
top of tree revision.

A string of the format -gxxxxxxxx will be added to the localversion
if a git-based tree is found. The string generated by this will be
appended after any matching localversion* files, and after the value
set in CONFIG_LOCALVERSION.

(The actual string used here is the first eight characters produced
by running the command:

$ git rev-parse --verify HEAD

which is done within the script "scripts/setlocalversion".)

Ubuntu kernel module使用的優先順序

在Ubuntu中,主要的kernel module來源大略有三種:

(1) 來自DKMS package:
會被安裝到 /lib/modules/`uname -r`/updates/

(2) Ubuntu kernel加入的driver
會被安裝到 /lib/modules/`uname -r`/kernel/ubuntu/

(3) Linux kernel tree中原本就有的driver。

正常情況下,我們希望DKMS所安裝的kernel module在modprobe時有較高的優先順序,因為通常使用者是因為系統內建的driver無法正確工作而自行安裝DKMS的package。

而Linux Ubuntu Module是Ubuntu kernel自行加入所需的新或較新版本的driver,應該還是要比kernel tree內附的driver有較高的使用順序。

觀察 /etc/depmod.d/ubuntu.conf 便可發現這些目錄的使用順序都在這個設定檔案中被指定:

search updates ubuntu built-in

2010年6月13日 星期日

UDS-M落幕

Ubuntu 10.04 (Lucid Lynx)才剛發表,Canonical和Ubuntu社群又開始忙著準備下一個版本的開發。首先就是5月10日到14日在比利時布魯塞爾召開的UDS-M (Ubuntu Developer Summit for Maverick)

在這一星期中,會有滿滿的議程用來討論下一版Ubuntu的藍圖(bluesprints),而討論完成的bluesprints會成為下一版Ubuntu的工作項目,會被持續的追踪進度。 :-)

對於kernel team而言,Jeremy Kerr關於device tree的session十分有趣:Device Tree OverviewALSA System on Chip (SoC) Flattened Device Tree BindingsUsing Device Tree on ARM

顯示Canonical是很重視ARM的這塊市場的(如新成立的LinaroCanonical也有參與)。

Canonical Kernel Team / 攝影者 Acelan


同時UDS也是Ubuntu開發者和社群間彼此討論、交換心得的一個機會,不只是可以和大廳走廊遇到的開發者閒聊,而是有一大堆的community team的session可以參加。只是可惜從沒遇到來自台灣的與會者。希望在下一次UDS-N可以遇到來自台灣社群的人參加。

如果你仔細看UDS的議程的話,會發現這是一個十分忙碌的一週,從早到晚的session、再加上時差、還有語言的隔閡、還要思考,更別提近20小時的飛行時間,每次回來都像是全身精力被抽光的狀態。

不過UDS的確是十分有生產力的一週,下一版Ubuntu的骨架都在這一週內被討論和決定。

2010年3月19日 星期五

處理無release event熱鍵的新方法

Notebook的熱鍵(hotkey)常是由客製化過的EC(embedded controller) code來控制,而且沒有一個統一的標準,所以常常帶來了一些混亂。

熱鍵缺少了key release event就是很常見的情形。像是在Fujitsu Amilo和Samsung NC系列,很多型號都有這樣的問題。

因為沒有release event,所以會發生「只有第一次按有用」「只按一下降低音量的鍵,卻變成靜音」等奇怪的情況。

2.6.31之前的kernel會在AT keyboard驅動程式(atkbd.c)中加了許多DMI quirk和熱鍵的scan code,只要型號和scan code符合,atkbd會自動加入release event。

不過,在這麼一般的驅動程式中加入一堆DMI quirk,並不是一個好主意。所以在2.6.32 kernel,便在/sys下加入了一個可以由userspace控制的介面:
/sys/devices/platform/i8042/serio0/force_release


要讓某些scan code自動的產生出release event,只要把hotkey的scan code用逗號隔開,再寫入(echo + pipeline)這個檔案,之後kernel便會自動的幫這些scan code產生出release event。

對於一個distro來說,最好能夠收集這些有問題的型號和熱鍵的scan code,並且自動的偵測和設定。以Ubuntu而言,從Ubuntu Karmic之後,熱鍵便從HAL改為由udev來管理。所以在Ubuntu Lucid中,udev也加入了這個新功能:

將DMI quirk紀錄在此:
/lib/udev/rules.d/95-keyboard-force-release.rules


將熱鍵的scan code紀錄在此:
/lib/udev/keymaps/force-release/


在Ubuntu Lucid中,處理這類問題,就不須再更動、重編kernel,只要簡單的修改一些udev script即可。

2010年3月16日 星期二

top中數值的意義

us: user cpu time
sy: system cpu time
ni: user nice cpu time
id: idle cpu time
wa: io wait cpu time
hi: hardware irq (servicing hardware interrupts)
si: software irq (servicing software interrupts)
st: steal time (time in involuntary wait by virtual cpu while hypervisor is servicing another processor)

man vmstat
man mpstat

2010年3月15日 星期一

為什麼用startx啟動X-window時 suspend會失敗

When login from the console, libpam-ck-connector will create XDG_SESSION_COOKIE. While you run `startx`, In /etc/X11/Xsession.d/90consolekit, it checks the environment variable XDG_SESSION_COOKIE is already set and will not create a proper CK session.

Try to `unset XDG_SESSION_COOKIE` before `startx` to see if suspend/hibernate works.

2010年2月25日 星期四

檢查kernel coding style

在linux kernel中的scripts/checkpatch.pl不只可以用來檢查patch的coding style,也可以用來檢查c source的coding style:

scripts/checkpatch.pl --file *.c