發表文章

目前顯示的是有「Linux Kernel」標籤的文章

從 Linux Kernel 出發看!探討 Process 組成結構!

對所有電腦使用者而言,執行一支應用程式就像吃蛋糕一樣簡單。對於程式開發者而言,寫支 Hello World Program 並跑起來,也是三十秒內可以完成的事。但是,這樣容易的動作,其實底層有著複雜的機制,否則短短十行程式碼的 Hello World 能夠動起來,真的是奇跡了。想要知曉程式是怎麼被作業系統執行,要追溯到 Process 的機制,在研究過 Linux Kernel 的 Process 相關機制後,一切就將明朗。 註:在本篇文章內,都將會假設 binary program 已經被作業系統解析並放到記憶體執行,說明只著重於 Process 的部份 。雖然 Process 與 binary program 和其載體息息相關,但本文不會討論 ELF 的細節,有興趣的讀者可以自己去尋找相關文件閱讀。 若你是程式開發者,對『Process(程序)』一詞應該不陌生。嚴格來說, Process 就是處於執行狀態的程式,如果參考一些原文書或英文文獻,它們也許會這樣定義:『Process is a program in execution』。所以我們可以認定,Process 的組成,是擁有著『程式執行檔的 binary code + 記錄資料的記憶體』。 本文將 Process 分成內外兩個角度來探討: 從 Process 內部,程式執行的觀點  從 Process 外部,也就是作業系統的觀點  程式執行的觀點 單純以 Process 內部的角度來看,Process 就是一般的程式碼被放到記憶體執行。曾於舊文『 Linux 下程序的記憶體映射 』略為提及,一支程式擁有著數個 segments(區段),並仰賴著這些 segment 來持續運作。大致上來說,每個 segment 有不同的用途: Code Segment - 存放主要程式 Data Segment - 存放已被初始化並賦予值的全域變數 BSS Segment - 紀錄尚未被賦予值的全域變數 Stack Segment(Stack/Heap) - 紀錄 Process 在執行時動態註冊的變數包括 function 中的 local variable 對程式本身來說,會動態並隨機使用的是 Stack Segment,程式向作業系統(OS) 要記憶體空間...

Linux Kernel Sendfile() 的提升 Server 效能之路

Apache 和 Samba 這類伺服器,主要以傳送檔案資料的工作為主,他們最常做的工作不外乎是開啟檔案(Open)、讀取(Read)、寫入網路連線(Write to Socket)。但是以 Kernel 的角度來說,這樣一個讀取檔案資料和傳送出去的流程相當繁複,並擁有最少兩次的 Kernel/User Space 資料搬移, 導致同一筆資料需要經過兩次多餘的複製。舉例來說,若一個檔案有 1MB,則 Linux Kernel 需要多做 2MB 的記憶體複製,使得效能經常消耗在這種地方,尤以 CPU 不夠快的平台上狀況特別明顯。 而過去曾有 khttpd 這樣的實作,讓 Linux Kernel 自成一個小型的 Web Server,提供一個極有效率方式的讀取靜態網站頁面和 Server 服務,其加速的方法,便是於 Kernel Space 讀取檔案並直接從網路連線送出資料,目的也在於減少 Kernel/User space 之間不必要的 context switch。 想瞭解 User Space 和 Kernel 的資料搬移狀況,我們可以來研究應用程式在讀取和傳送網路資料的流程,經簡化後大致上是(以下簡稱 User Space 為 US,Kernel Space 為 KS): [US] open() [KS] do_sys_open() [KS] do_filp_open() - 找到檔案,並從所在的檔案系統取得 struct file [KS] Return File Object [US] malloc() - 準備一塊記憶體當 buffer [US] read(file, buffer) [KS] vfs_read(file) - 標準 VFS 的檔案讀取 API [KS] file->f_op->read() - 使用資料所在的檔案系統(filesystem),其提供的低階 read 操作 [KS] copy_to_user(buffer) - 將檔案資料從硬碟讀出來後,複製一份到 user space 的 buffer 接著是將讀到的資料透過網路傳送出去: [US] write(Socket, buffer) - 將 buffer 內資料傳送出去 [KS] copy_from_user(buffer) -...

在 Linux Kernel 中取得目錄中的檔案清單

寫一支程式在 User Space 下列出目錄中的檔案清單相當容易,我們可以用 readdir() 去一項項取得檔案內容,事實上, readdir() 是由 Linux Kernel VFS(Virtual Filesystem) 所提供的 API,真正的實作在檔案系統的核心模組(Kernel Module)中。然而因為 Kernel readdir() 的相關實作牽涉到 Kernel/User space 的資料交換問題,所以如果我們是在撰寫 Kernel 的驅動程式,當然就不能使用這系列的 APIs。不過也因為所有的資訊都存在於 Kernel 的資料結構中,我們可以直接從記憶體中的 Linked list 中快速取得檔案清單。 在取得某個目錄下所有檔案資訊前,要先得到該目錄的敘述 struct dentry,VFS 用 struct dentry 的串聯組合來描述整個檔案系統的目錄結構,檔案清單則被保存在 dentry 中的 Double Linked List,因此其實只要知道如何使用 Kernel 提供的 Double Linked list,就能得到該目錄下所有的檔案資訊。而這邊要注意的是 Kernel 提供的一個通用 Linked list 結構(struct list_head),用來統一整個核心的 Linked list 操作機制,這檔案清單的 Double Linked List 就是使用這通用的結構。 這裡是 Linux Kernel 2.6.37 中 dentry 的資料結構(定義在 linux/dcache.h,其中較不重要的部份以『...』做省略,此外,某些定義與較早版本的 Kernel 有所差異,將在文章最後補上說明): struct dentry { ...省略 struct hlist_node d_hash; /* lookup hash list */ struct dentry *d_parent; /* parent directory */ struct qstr d_name; struct list_head d_lru; /* LRU list */ /* * d_child and d_rcu can share memory *...

Linux 下程序的記憶體映射

Linux 下的執行檔為 ELF 格式,其啟動原理與各作業系統上的執行檔一樣,不外乎是載入檔案到記憶體上,並讀取需要的 Shared library link 清單,最後找到於 Filesystem 上對應的 symbol link 和 library,載入外部函式和執行程式。 這邊以 VIM 為例,我們透過 Linux 下的 ldd 指令可以得知執行檔需要的外部 Libraries: $ ldd /usr/bin/vim linux-gate.so.1 => (0xb7837000) libm.so.6 => /lib/i686/cmov/libm.so.6 (0xb77f2000) libncurses.so.5 => /lib/libncurses.so.5 (0xb77b8000) libselinux.so.1 => /lib/libselinux.so.1 (0xb779c000) libacl.so.1 => /lib/libacl.so.1 (0xb7795000) libgpm.so.2 => /usr/lib/libgpm.so.2 (0xb778f000) libc.so.6 => /lib/i686/cmov/libc.so.6 (0xb7649000) libdl.so.2 => /lib/i686/cmov/libdl.so.2 (0xb7645000) /lib/ld-linux.so.2 (0xb7838000) libattr.so.1 => /lib/libattr.so.1 (0xb763f000) 由以上結果可以看到 VIM 所需的 library,以及在 filesystem 上找到的對應 library ,然後還可以得到當 library 被載入到記憶體上時的起始位置。其中比較特別的是 linux-gate.so.1,實體並不存在於 filesystem 中,這代表 kernel system call 的記憶體映射和其位址。 Kernel 其實有 Interface 提供我們取得更多 Process 的記憶體映射資料,藉由讀取 /proc/[Process ID]/maps 這檔案,我們除了可以得到 Process 連結的 libra...

Add Devkit8000 and SBC8100 initial support to 0xdroid

圖片
As you know, I've done Android Eclair porting for Devkit8000 in the past, which is based on Embinux. It's a experimental work for passing time, I have no time to maintain and fix bugs friends reported after that. However, I think it is not good because the result will be getting lost as time goes by. 0xdroid is another Android distribution which is different from Embinux, its developer  Jim Huang(jserv)  who has contacted me a few months ago, and he hope that I can try porting 0xdroid on the Devkit8000. Actually, I am glad to make 0xdroid takes over my work, it is the best result for me. Currently, I've done most works, 0xdroid can run on Devkit8000 with success. And also, My patches have been committed to 0xlab-devel mailing list. Because I have another platform SBC8100 which is also produced by Embest, I've done works on that as well. You can see my patches from 0xlab-devel mailing list, or you can visit my website to download it directly: http://people.lin...

入門級 Mouse Linux Kernel Driver

每當說起 Linux Kernel Driver 入門,就不免提到如何寫個 Hello World 級的 Module,這樣的第一支程式,除了可供 Linux Kernel 動態載入和卸載,似乎是一點用處也沒有。與一般應用程式不同,開發 Linux Driver 最大的門檻不在於如何撰寫出 Module,而是如何設計系統架構與硬體兩者間的橋樑。其中懂得如何控制和結合 Kernel 內各種機制更是重點,最複雜的莫過於此。 這邊有個 Mouse Kernel Driver,會在 Kernel 上新增一個虛擬滑鼠裝置,然後使用者可從 sysfs 控制該虛擬滑鼠(virmouse.c): /*  * A Virtual Mouse Driver to send fake events from userspace.  *  * Written by Fred Chien <fred@ullab.org>  *  */ #include <linux/fs.h> #include <asm/uaccess.h> #include <linux/pci.h> #include <linux/input.h> #include <linux/platform_device.h> struct input_dev *virmouse_input_dev; static struct platform_device *virmouse_dev; /* Device structure */ /* Sysfs method to input simulated coordinates */ static ssize_t write_virmouse(struct device *dev,                               struct device_attribute *attr,        ...

Add GPIO Keys support for Devkit8000

圖片
Using Android on Devkit8000, we have problem of getting back to previous screen. The touchscreen can only be used to decide whether you select item or not, so a BACK button would be needed absolutely for Android. Devkit8000 board has four buttons on the corner, we can set one of it as Back functionality. First step, add a option to kernel config file to enable GPIO keyboard device: CONFIG_KEYBOARD_GPIO=y Second step, set USER_KEY as ESC Keycode for back functionality: diff --git a/arch/arm/mach-omap2/board-omap3devkit8000.c b/arch/arm/mach-omap2/board-omap3devkit8000.c index e86d254..ec17311 100644 --- a/arch/arm/mach-omap2/board-omap3devkit8000.c +++ b/arch/arm/mach-omap2/board-omap3devkit8000.c @@ -462,9 +462,11 @@ static struct platform_device leds_gpio = { static struct gpio_keys_button gpio_buttons[] = { { - .code = BTN_EXTRA, +// .code = BTN_EXTRA, + .code = KEY_ESC, .gpio = 26, .desc = "user", + .active_low = 1, .wakeup = 1, }, ...

Enable ads7846 Touchscreen in Android that works on Devkit8000

If you would like to make Android work on Devkit8000, you can follow to patch your kernel which is mentioned in my old article( Android Eclair Porting for Devkit8000 ). After that you might notice the touchscreen doesn't work, it is a ads7846 kernel driver bug from Embinux. So I modified a few lines of code to fix the bug. Here is the patch: http://people.linux.org.tw/~fred/patches/devkit8000-touchscreen-android-kernel.patch

Android Eclair Porting for Devkit8000

It's not only for fun! Porting Android is a great practice for me as well. Devkit8000 is a clone of OMAP3 Beagle(Beagleboard), so we can found many porting informations of Beagleboard from internet. It's helpful for us, we only need to deal with a few places which are some differences between Devkit8000 and Beagleboard. Google Android Eclair is working well on the Devkit8000 board now after I tried to port it last weekend. Here is the patch: http://people.linux.org.tw/~fred/patches/devkit8000-android-kernel.patch Based on Embinux , I added the Devkit8000 support, which includes: OMAP DSS Driver for display 4.3 inch LCD Panel support (480x272 60Hz) 7 inch LCD Panel support (800x480 60Hz) Touchscreen ADS7846 support Sound Codec (TWL4030) Keypad (TWL4030) Ethernet Device support (DM9000) Kernel Config for Android Compile Kernel with Devkit8000 kernel config: make omap3_devkit8000_android_defconfig make CROSS_COMPILE=arm-linux-gnueabi- uImage Kernel Comman...

CUSE - Userspace Character Device 機制

因為最近碰上了 KMS(Kernel Mode Setting)的 bug,造成偵測解析度出現問題,於是為了解決這問題,又開始追 Linux Kernel 的 Log,但原先的目標沒有追到,反而有些其它的意外發現。話說,2.6.31 已經在本月 9 日正式釋出,其中有些新的實作和令人興奮的支援,如:USB 3.0、日前提到過的『 Fanotify 更全面性的檔案監控機制 』,其實另外還有一個重要的機制『 CUSE(Character devices in Userspace) 』。 如同 FUSE(Filesystem in Userspace),CUSE 目標提供一個機制,讓開發者可在 userspace 實作 character device,而不用撰寫 kernel space 的 module 來達成這項目的。這機制有助於許多驅動程式的開發,甚至是讓 Linux 在未來開發各種支援時,能有更大的彈性以及使核心有更高的安全性。從 patch 來看,由於許多部份已經在過去開發 FUSE 時被實作過,讓開發者可以輕易的延用過去成果實作 CUSE。 這有一個專案『 OOSP(Open Sound System Proxy) 』,就嘗試著用 CUSE 實作一個假的裝置檔,讓老的音效應用程式可以在不修改的情況下,藉由這個 OOS Proxy 去使用新的音效驅動程式架構(如:Alsa),其做法就是產生 OSS 的 /dev/dsp、/dev/adsp、/dev/mixer 再將這些 character devices 接收到的訊息,處理並轉送到現代的音效驅動程式架構。

Linux Kernel - fanotify 更全面性的檔案監控機制

若是有在追 kernel development 的動態,就可以發現到 Linux Kernel 將在 2.6.31 引入 fanotify 這個新特性,其本意是『fscking all notification system』,目的在實現更全面性的檔案監控機制。除了可監聽 file description 的 events,亦可以當 open 和 write 的 event 觸發時決定是否給予存取,對做安全控管的程式有很大的幫助。 當初 fanotify 會被提出是就因為要保護系統,供惡意程式偵測軟體和一些系統安全軟體所使用,又因為了達成該需求,使用舊有的監控機制會效能不彰,而重新實作了 fanotify,以排除舊有機制實作過於複雜的缺點。 fanotify 分成兩個部份『Directed』和『Global』, Directed 的部份就如同 inotify/dnotify,可以單獨去針對特定 inode 進行 event 監聽;而 Global 部份提供了對整個系統進行監聽 event 的機制,在意義上對於真正完整的檔案監控有莫大的幫助。 至於 kernel/user-space 的溝通實作上,fanotify 採用的方法是 socket protocol,屆時會有一個新的 PF_FANOTIFY family 被提供,讓 user-space 的應用程式所呼叫使用。 關於 fanotify 的 kernel patch 可以在此找到: http://people.redhat.com/~eparis/fanotify/ 或是可以參考 kernel.org 上的兩則 commit logs: fsnotify: unified filesystem notification backend fsnotify: generic notification queue and waitq

FreedomHEC Taipei 2009 - Fastboot 簡報上線

今年的『 FreedomHEC Taipei 2009 』如期於 6 月 10 日開始,請來許多重量級的外國講者,傳授很多 Kernel Driver 以及硬體相關的寶貴實作開發經驗,有人還拿著『 Linux Device Driver』一書,去找講者簽名。 :-) 小弟很榮幸受『 資策會 』邀請,並於該活動給了一場主題為『Fastboot』的 talk。現在簡報檔上線有興趣的人可以參考: FreedomHEC Taipei 2009 - Fastboot [ PDF ] Fastboot 議題自從 Netbook 效應開始,就被廣泛提出討論,也不斷有不同的實作被發展出來,『快速開機』彷彿已經是個新一代消費性電子產品的必備標準。因此,就算該議題已經被討論和研究有許多時日,許多人仍對其非常有興趣。有更多的快訴開機方法,仍未被完善的發展出來,這也是值得我們探討的一部份。

Linux Kernel 記憶體管理機制之美

Linux Kernel 的穩定,有一部份可以歸功於它優良的記憶體管理機制,而探討該機制,有助於瞭解記憶體是如何被 Kernel 所使用,對開發 Linux Driver 的人來說,日後更有許多益處。最重要的是,Linux Kernel 之美是由此開始,優美的設計相當令人著迷。 Linux Kernel 的記憶體管理機制,主要由兩大部份組成: Buddy System Slab Allocator Buddy System(buddy allocator) 如一般的 Operating System Design,Linux Kernel 一樣是以 Page 為記憶體管理的單位,因此設計了一層針對 page(或稱分頁)的管理機制,該機制在 Linux Kernel 裡被稱為『Buddy System (buddy allocator,簡稱 buddy)』,buddy 是 Kernel 最底層的記憶體管理機制,日後所有的記憶體配置,最後都要經過 buddy 才能取得或釋放記憶體。 可以藉由觀察當前 /proc/buddyinfo ,了解目前的記憶體使用情況,當然,是以 page 為單位: $ cat /proc/buddyinfo Node 0, zone DMA 76 71 66 50 33 17 5 1 1 1 0 Node 0, zone Normal 22301 6425 45 0 1 1 1 1 1 1 0 Node 0, zone HighMem 97 13 6 10 3 0 2 0 0 0 0 如果沒有什麼意外,/proc/buddyinfo 列會出了三個 zone ,分別是 DMA、Normal、HighMem,這三種 zone 的分類,是以 Physical Memory 位置的範圍而區分,在 IA-32 架構上 為: DMA (16MB以下) Normal (16MB~896MB) HighMem (896MB以上) 不過,由於 Buddy ...

再談 FastBoot 快速開機簡記

因為某些案子的關係,春節後多日被迫關在飯店當 L (Who's L? 請參閱死亡筆記本),果然,龍崎這角色不是人當的,再關下去真的連坐姿和行為都會變得和他一樣奇怪(話說那樣的坐姿真的會讓智商提高!好像有?!)。沒枉費多日的努力,一個使用 ubuntu 的標準 config 所編譯出來之 Kernel 已經可以達到 1 秒的速度,理論上,若是再修剪 built-in 的 driver 應該可以達到更快速度。當然,單單只是 Kernel 快很容易做到,但 X Server 必需要在第 1.3 秒左右啟動,並在 第 2 秒前看到畫面,最重要的是有可用系統狀態,才算有實用的意義。 而關於 Kernel 部份,2.6.28 已做過許多快速開機的處理,其啟動已經非常快速,但是還會慢的瓶頸在於 initrd 的檢查,和各 device 初始的等待。經過 patch 後,這兩部份依硬體不同,可減少近 1 秒左右甚至更多的消耗。此外,盡可能讓 Root Filesystem 先被 Mount 也是一種手段,尤其再配合 initram 可以在瞬間就上到 User Space 的 Early boot 甚至進到 X Server,一般使用者可以看到 boot loader 一消失,緊接著就出現 X 的背景圖和 Cursor。 X Server 的快速開機處理有些方法,主要的做法是減少緩慢 I/O 的 Input Device 的等待時間,甚至是拖出正常 Initializing Progress,讓畫面先啟動。另外的瓶頸是各家 Video Driver 的問題,減少許多多餘的檢查有助於加快初始化速度。全部 patch 過後,基本上 XServer 啟動速度可達到 1 秒出頭(測試環境中,配合使用新的 Intel Video Driver)。 到此,一切看起來都很好,但最後發現 EDID 吃掉大半時間,單單為這 Monitor 的 Detect 就會影響使用 0.5 秒以上的時間,對某些 Specific 的 Hardware 可直接拿掉,但如何提前甚至時移到 Kernel 去跑,才是比較正確的做法。 目前,Boot Loader 的速度太慢,變成主要瓶頸,尤其以 Grub 的速度更令人不敢恭維,Loading 的速度比用 USB Drive 上的 Syslinux 還慢,這是還有...

Linux 的 Real-time 排程支援

POSIX.1b 定義了一系列的系統呼叫,去提供即時(Real-time)需求的支援,實作細節和實際效能則由各作業系統自行負責。當然,Linux 也依循了這標準,讓各個 Process 有能力的在有限度的範圍內,調整自己的在系統上排程。這裡所講,並不只是一般常見的系統優先權機制,而是建構在其之上的進階排程實作。 首先,可以從 sched_getscheduler(pid_t pid) 的回傳值中,取得目前程式的排程方法,有助於了解當前的排程情形,其可能回傳值如下: SCHED_OTHER SCHED_FIFO SCHED_RR SCHED_BATCH 範例原始碼(sched_policy.c): #include <stdio.h> #include <sched.h> const char *sched_policy[] = { "SCHED_OTHER", "SCHED_FIFO", "SCHED_RR", "SCHED_BATCH" }; int main(int argc, char *argv[]) { printf("Scheduler Policy is %s.\n", sched_policy[sched_getscheduler(0)]); return 0; } Compiling it: gcc sched_policy.c -o sched_policy Results: Scheduler Policy is SCHED_OTHER 標準預設的排程方法是 SCHED_OTHER,意味 Kernel 並不會為這些一般性 Process 做特別的即時排程處理。因為,我們所寫的程式,都沒有被特殊設定,所得到的將都會是使用 SCHED_OTHER。 值得探討的是 SCHED_FIFO 和 SCHED_RR,這是為即時(Real-time)需求所設計的兩種排程類型,在運作規則上,其實兩者是同樣的東西,只是 SCHED_RR 擁有時段分配的制約機制。 SCHED_FIFO (First In-First Out) SCHED_FIFO 顧名思義就是『先進先出(First In First Out)』,一但 Procees 是 FI...

Linux Suspend 之記憶體機制

休眠(Suspend)現在已經是 Laptop 必備的電源管理機制之一,而 Suspend 又分為 s2ram(Suspen to RAM)和 s2disk(Suspend to Disk) 兩種模式。若是啟動 Suspend 的機制,可以看到 Operating System 神奇的被暫停,然後 Resume 叫醒回到之前的工作狀態。如果說想深入瞭解這樣一個機制,可以從 Linux 的休眠實作來著手,swsusp 就提供了這樣一個 User-space 的實作,我們可以研究它的sourcecode。 大體上來說,Suspend 機制不過就是儲存當時系統 Memory 狀態,然後再啟動時還原回去,在實作時,必需先鎖定當時系統下所有的記憶體空間,以確保記憶體內容不再變動,可以分別用 mlockall() 和 munlockall() 來達成這樣的任務。 #include <sys/mman.h> int mlockall(int flags); int munlockall(void); flags 又分成: MCL_CURRENT 鎖定全部現有的記憶體分頁 MCL_FUTURE 鎖定未來將被新增的記憶體分頁 此外,swsusp 利用了 /dev/snapshot 來對 User Space Process 和 Swap 的操作,以產生目前 System 的記憶體映像檔,/dev/snapshot 可以用 ioctl() 去控制,其命令: SNAPSHOT_FREEZE 鎖定使 User Space Processes 靜止 SNAPSHOT_UNFREEZE 解除 User Space Processes 的鎖定 SNAPSHOT_ATOMIC_SNAPSHOT 建立一個系統的記憶體快照映像檔 SNAPSHOT_ATOMIC_RESTORE 還原系統記憶體狀態 SNAPSHOT_FREE 釋放快照映像檔的記憶體 SNAPSHOT_SET_IMAGE_SIZE 設定映像檔最大 Size,如果無法達到指定的 Size,kernel 會盡可能建立最小的 image SNAPSHOT_AVAIL_SWAP 取得可用的 Swap 大小 SNAPSHOT_GET_SWAP_PAGE 建立一個 Swap 頁 SNAPSHOT_FREE_SWAP_PAGES 釋放所有...

Thinkpad T60's ethernet device doesn't work

If you have the Thinkpad T60 laptop, maybe you will have a problem - ethernet device doesn't work. With command "dmesg", we can get some error messages that is just like: 0000:02:00.0: The NVM Checksum Is Not Valid ACPI: PCI interrupt for device 0000:02:00.0 disabled e1000e: probe of 0000:02:00.0 failed with error -5 It means the contents of EEPROM on the ethernet device was broken, because the checksum is not valid. For all I know, so many Thinkpad T60 laptops has the problem cause e1000e or e1000 driver return the error message and the device doesn't work. Here is a patch to add a parameter - "eeprom_bad_csum_allow" for the e1000e kernel driver: e1000e-allow_eeprom_bad_checksums.patch To enable the option will lead e1000e driver to ignore checking checksums of EEPROM. So you can use the command to load the e1000e driver be patched to enable your ethernet device: sudo modprobe e1000e eeprom_bad_csum_allow=1 BTW, I think you might see the similar patch for e...

快速開機實作瓶頸簡記

最近 , 『 Fast Boot』、『 快速開機』、『 5 秒開機』、『 XPUD』 這些關鍵字紅到爆炸 , 經常在快速開機的討論 話題 中所聽到 。自從 EeePC 的推出 , 自豪的標榜 15 秒開機後 , 『 快速開機 』 的話題越來越熱門 ,然後 Aspire One 驚人的 11 秒開機 ,讓 『 開機的速度 』一時間變成了各家研究的首要方向 。不久前 。 由知名 Penk 所發展的 7 秒開機 XPUD ,直到最近 『 Intel Moblin 』 所展示的 5 秒開機 ,都著實讓人感到不可思議 。 接下來呢?難道 5 秒開機真的已經是極限了嗎? 由於到處打工 ,也碰到許多與相關的案子 ,近來更被許多老闆們要求進行加快開機的速度 。進行加速的過程中 , 從開始幾秒鐘為單位的計較 ,到最後連小數位以下的時間都要精精算計 ,每一次都證明了 『 5 秒鐘 』 似乎真的是極限 。 一個開機速度所會碰到的瓶頸大致上如下: Kernel Initializing Driver Initializing Filesystem Initializing I/O 通常 Kernel + Driver + Filesystem 使用 2 秒(經過數不清的調較和修改 kernel 後) ,Userspace Initializing + Xorg + Desktop Environment 用 2.x 秒 ,整個估算大概會是 5 到 6 秒鐘 。經過測試 , 其實應該有可以再加速的空間 。 仔細觀察了 Kernel , Synaptic Touchpad 就吃了 0.5 秒 ,IDE 的 probe 也吃了 0.6 秒 ,單是這兩支 driver 就吃掉了近五分之一的開機時間 , 實在是慢的驚人 。其中有趣的是 ,通常在 netbook 上 , ide1 沒有 Device ,但在這部份卻要花上 0.16 秒 ,讓人很想要 dirty hack , 直 接讓 kernel 閃過 ide1 的 scan 。 :P 其實在整個開機流程中 ,最大的瓶頸在於 I/O ,Userspace 的程式都伴隨著大量的 config file 、Font、Library ,如何提升載入速度是很重要的課題 。這部份 , Moblin 的 Super Readahead 作法的確很暴力 ,...

Linux Kernel Patch: Suspend/Resume 以後無法 Restart

最近碰到個難解的問題 ,就是系統無法 Restart 的 Bug ,有 usplash 的人會卡死在關機畫面 ,在 console 底下 ,會停在 kernel 吐的最後一行訊息: 『 Restarting system 』。有趣的是 ,這 bug 只會在 suspend/resume 之後才發生 。沒錯 ,這應該是 ACPI 的 Bug ,但其實可以透過 Patch Kernel 來修正 。 這 patch 可由此下載: linux-kernel-restart.patch 後記 因為 BIOS 的人永遠不承認是自己的錯 ,我們只好自己動手 。

如何編譯特定的 Linux Module

這也不是一天兩天了,常常會對 Linux 的某些 Driver 做些 Patches,或對某些 Module 做修改,但每次要 compile 出那幾個 ko 檔時就很頭痛,既然只是修改特定的 module ,又不用重新做出新的 kernel image,為何每次都要將整個 kernel 重新 compile 呢?其實有方法可以只編譯特定的 kernel module 以並免不必要的時間浪費。 切換到目標 module 的目錄下,然後執行: make script make prepare make -C /usr/src/linux SUBDIRS=$PWD modules ※粗體字部份改成 kernel source 的位置即可。