more: Jollen 的 Embedded Linux 教育訓練

Jollen's Blog「Linux Device Drivers & Kernel」裡的所有文章!

  

Linux Kernel Porting #1, 基本概念

jollen 發表於 January 17, 2005 4:11 PM

(原文發表於 2005/01/17) 作者/陳俊宏 Copyright (c) 2005 www.jollen.org Last date: 2005/01/17 理論上,一個完整的 Embedded Linux 系統開機過程可分成 3 個階段: bootstrap loader boot loader linux kernel bootstrap loader 比較像是 PC 上的 BIOS,大部份的target device,像是evaluation board、reference board等,都是在設計板子時由廠商設計完成並提供(ship)給終端使用者(end-user)。 Boot loader 則是像 desktop Linux 上的 LILO、GRUB 等,支援 ARM...

Linux Kernel Porting #2, 基本流程與方法

jollen 發表於 January 17, 2005 4:13 PM

Copyright (c) 2005 www.jollen.org Last date: 2005/01/17 在將 Linux kernel porting 到其它的 ARM 平臺之前, 必須先取得標準 Linux kernel,然後再做 ARM Linux patch。 下載以下檔案: ftp://ftp.arm.linux.org.uk/pub/armlinux/source/kernel-patches/v2.4/patch-2.4.26-vrs1.gz ftp://ftp.nsysu.edu.tw/Linux/Kernel/linux/kernel/v2.4/linux-2.4.26.tar.bz2 安裝 Linux kernel 與 patch: # bzip2 -dc linux-2.4.26.tar.bz2 | tar xf - # mv linux-2.4.26 linux-2.4.26-vrs1...

Kernel 2.6 核心與模組編譯

jollen 發表於 May 2, 2006 11:08 AM

Jollen 的 Linux 驅動程式課程是以 kernel 2.4 做為實習環境,但 kernel 2.6 與 kernel 2.4 的核心與模組編譯步驟不同;本文說明如何在 kernel 2.6 環境下編譯核心與模組,供同學參考。 作者/陳俊宏www.jollen.orgKernel 2.4 & 2.6 編譯底下用一個表格來比較編譯 kernel 2.4 與 kernel 2.6 的步驟差異。Kernel 2.4Kernel 2.61.編譯設定:# make menuconfig2.編譯核心:# make dep # make bzImage3.編譯模組並安裝:# make modules # make...

Linux 驅動程式觀念解析, #1: 驅動程式的大架構

jollen 發表於 May 4, 2006 8:15 AM

本文說明 Linux 驅動程式的整體大架構,並說明基本的三種驅動程式類型。了解 Linux 驅動程式的大架構,絕對是學好驅動程式的第一步。 作者/陳俊宏www.jollen.orgLinux 驅動程式的大架構 Linux 驅動程式的整體架構如下: application 透過 system call 介面與 kernel 溝通。 透過 kernel 的 VFS 層與 Linux 驅動程式物件溝通。 Linux 驅動程式可分為 3 大類型,如下圖綠色部份。 Linux 驅動程式三類型 Linux device driver 可分成 3 種類型: character device driver block device...

Linux 驅動程式觀念解析, #2: System Calls

jollen 發表於 May 4, 2006 8:30 AM

Linux 驅動程式的大架構中,system call 是屬於第一層的架構;本文以一個 Linux 範例程式來展示 user application 與 Linux 驅動程式的關係。 作者/陳俊宏www.jollen.org System Call 與驅動程式的關係 System call 是 user application 與 Linux device driver 的溝通介面。 User application 透過呼叫 system call 來「叫起」driver 的 task,user application 要呼叫 system call 必須呼叫 GNU C...

Linux 驅動程式觀念解析, #3: Device File

jollen 發表於 May 4, 2006 8:38 AM

Linux 驅動程式大架構的第二層為 VFS 層,由 VFS 所帶出來的重要觀念便是 device files。 作者/陳俊宏www.jollen.org 什麼是 Device File Device files 是 UNIX 系統的獨特觀念,在 UNIX 系統底下我們把外部的周邊裝置均視為一個檔案,並透過此檔案與實體硬體溝通,這樣的檔案就叫做 device files,或 special files。 Linux device driver 與 user 的重要溝通橋梁為 device files,在 Linux 系統底下,我們看到的 device files 如圖所示。檔案屬性的第一個位元如果顯示為 “c” 表示這是一個字元型裝置的 device file、若為...

Linux 驅動程式觀念解析, #4: Linux 驅動程式一般化設計流程

jollen 發表於 May 4, 2006 9:06 AM

了解重要的架構觀念面後,接著就是 Linux 驅動程式本身了!Linux 驅動程式的設計雖然沒有一定的標準流程,但是由「觀念」層面可以歸納出一個一般化的流程。 作者/陳俊宏www.jollen.org 一般化設計流程 我們提過,依照驅動程式本身的實作,可以將 Linux 驅動程式分為 2 大部份:virtual device driver與physical device driver。 此流程為一個觀念流程,實際撰寫驅動程式時,並不會完全以這個流程來設計。但初學Linux驅動程式時,則應以此流程為主循序學習,才能理解基本的Linux驅動程式實作。 對Linux驅動程式而言,virtual device driver的重要性遠在physical device driver之上,乍聽之下這或許不太能理解,因為沒有physical device driver是無法真正驅動硬體的。但實作上,physical device driver是一成不變的程式寫法,能不能寫出好的驅動程式,關鍵是在virtual device driver的部份。 struct file_operations struct file_operations 是 kernel 提供的一個重要資料結構,這是學習 Linux 驅動程式第一個會認識的對象,也是最重要的一個主題。 Linux 驅動程式建構在 file_operations 之上。file_operations定義驅動程式的system...

Linux 驅動程式觀念解析, #5: 依流程來實作 -- Virtual Device Driver

jollen 發表於 May 4, 2006 9:53 AM

根據Linux驅動程式的一般化設計流程,我們來設計一個真正可以動的驅動程式。 作者/陳俊宏 www.jollen.org 根據流程寫程式 定義 file_operations struct file_operations card_fops = { open: card_open, write: card_write, release: card_release, ioctl: card_ioctl, }; 由此定義可以,我們所計的驅動程式將提供 open/write/close(release)/ioctl 4 個 system call 介面給 user application。 實作 System Call 接著要實作我們所提供的4個 system call。open/close(即 release)/read/write/ ioctl 是初學 Linux 驅動程式最重要的...

Linux 驅動程式觀念解析, #6: 依流程來實作 -- Physical Device Driver

jollen 發表於 May 4, 2006 10:18 AM

接續前文的實作,繼續完成 physical device driver 部份;由於 physical device driver 與 I/O 存取密切相關,因此我們會先說明 Linux 的 I/O 存取函數。 作者/陳俊宏 www.jollen.org I/O 存取的觀念 I/O device必須透過I/O port來存取與控制,每個I/O port都會被指定一個memory address,稱為I/O port address(或port address),此即所謂的memory mapped I/O。 memory mapped I/O的意義為,我們可以透過I/O port被指定的memory address來存取I/O device,如此可將複雜的I/O device存取變成簡單的memory存取,也不需要使用 assembly 來存取 I/O device。...

Linux 驅動程式觀念解析, #7: 觀念大追擊

jollen 發表於 May 4, 2006 10:27 AM

您是否能看圖說明範例的觀念。 作者/陳俊宏www.jollen.org TIP fops所指的driver function其實是被Linux kernel所「回呼」(callback)。 Linux驅動程式將fops「註冊」至kernel裡後,並不是被user application直接呼叫,而是透過system call interface,因此fops所指的函數應是被kernel回呼。 Callback的機制有一個好處是,當函數被呼叫時,表示此時系統符合該函數被回呼的條件。因此,driver function可以預期自己是在符合一些條件的環境下執行。Callback機制另一個特點是,Linux kernel會傳遞「適當」的參數給driver function,driver function可以直接使用所接收的參數資料。 這張圖是範例 (debug card 0.1.1) 的執行圖 (Execute Flow/Path),如果您能根據範例程式清楚地說明此圖,表示您已經掌握最主要的 Linux 驅動程式觀念了!...

最精彩的一道菜:驅動程式

jollen 發表於 September 30, 2006 12:46 PM

軀動程式本身是屬於「軟體硬介面」的程式設計技術,不管是學習WinCE或是Embedded Linux,最精彩的部份絕對是驅動程式莫屬。由於嵌入式系統整體來看,除了軟體開發外,也包含硬體的客制化,因此驅動程式在嵌入式系統技術領域中,佔了舉足輕重的地位。 學習驅動程式需要確實瞭解硬體的規格與微處理器架構,並且工程師還要能分得清楚哪些東西是介面(interfacing)也就是與硬體無關的程式(machine-independent);以及哪些是站在第一線做硬體控制的程式(machine-dependent)。各種軟體硬介面與滙流排也都要精通。 現在的嵌入式系統學習主軸 現今嵌入式系統的實作,幾乎都會加入嵌入式作業系統(embedded OS)的元素,有了作業系統,我們都可以為目標裝置「寫軟體」。總合來看,如果要學習所謂的嵌入式系統,從熱門的WinCE或Embedded Linux領域切入是相當不錯的選擇。 驅動程式是「寫軟體」與「做硬體」的 “connectivity”,因此現今資訊業界最熱門的嵌入式系統學習主軸為驅動程式的設計。 WinCE驅動程式 WinCE驅動程式的核心人物當然就是在WDM(Windows Driver Model)身上了。WDM是Windows 98/2000之後的驅動程式架構,WDM是一個嚴密的分層(layered)架構,架構層間以IRPs(I/O Request Packets)做通訊。 WDM驅動程式分為三種類型:bus driver、function driver與filter driver。Bus driver是device-independent的驅動程式,主要在驅動I/O bus,例如:PCI bus driver、USB bus driver;function driver是 “device” 的驅動程式,我們常講的「驅動程式設計」大部份都是講 function driver,function driver 主要在驅動各種裝置,因此大多是由裝置廠造商撰寫並提供給使用者安裝,function driver 的設計大多著墨在「讀/寫」外部裝置。Filter driver是非必要的驅動程式,主要在過瀘 I/O requests。 WDM驅動程式的設計是使用Windows DDK,學習資源豐富並且完整;相較於Linux驅動程式,WDM驅動程式的學習材料較系統化。...

Linux 2.4.29 System Calls Table (LSCT)

jollen 發表於 October 7, 2006 1:11 PM

以下是 Linux 2.4.29 的 system call 整理表格,提供給「Embedded Linux 嵌入式系統實作演練」的讀者您做參考。這是一張很方便的表格,可以取代 unistd.h 與 "man"。 這張工具表格可以幫助我們: 1. 最主要的目的:當然是研究作業系統,了解 Linux 提供的 sytsem call service。 2. Trace kernel. 3. Writing shellcode. 供您參考 :) Linux (kernel 2.4.29) System Call Table 1. sys_ni_syscall 為保留號碼 2. 更新日期: 2006/10/07...

Linux 2.6.11 System Calls Table (LSCT)

jollen 發表於 October 7, 2006 11:41 PM

以下是 Linux 2.6.11 的 system call 整理表格,提供給「Embedded Linux 嵌入式系統實作演練」的讀者您做參考。這是一張很方便的表格,可以取代 unistd.h 與 "man"。 這張工具表格可以幫助我們: 1. 最主要的目的:當然是研究作業系統,了解 Linux 提供的 sytsem call service。 2. Trace kernel. 3. Writing shellcode. 供您參考 :) Linux (kernel 2.6.11) System Call Table 1. sys_ni_syscall 為保留號碼 2. 更新日期: 2006/10/07...

Linux 2.6 的 System Call:12 大類

jollen 發表於 October 11, 2006 2:58 PM

把 Linux 提供的 sytsem call service 依分類做整理,並提供實作檔案。本表使用於 Jollen 的「2. GNU Toolchains 與 Embedded Linux Programming」課程中,在此提供給大家做參考。目前依據 Linux 2.6.11 原始碼製成,請搭配 2.6.11 以上的版本做研究。 no Syscall name Implementation file in Linux 2.6.11 (or above) 目前大致把 Linux 2.6.11 的 system call 分成以下幾個類別: Machine-dependent (i386) Filesystem...

Linux System Calls' Forum, #1:(第20號系統服務) sys_getpid

jollen 發表於 October 11, 2006 5:01 PM

對於 Linux system call 的研究,我們採取的策略是「依分類」來做討論,而不是依 system call 編號依序討論。透過 system call (kernel-space 端) 的研究,我們除了可以更深入了解作業系統外,更能一探 Linux kernel 的奧妙。 20 sys_getpid linux/kernel/timer.c 類別:Kernel Timer & Process 原型宣告:long sys_getpid(void); 用途說明:取得目前 process 的 thread ID (process ID)。 Kernel (2.6.11 or above) 實作: /** * sys_getpid...

Linux System Calls' Forum, #2:(第199,201,200,202,224號系統服務) sys_getuid, sys_geteuid, sys_getgid, sys_getegid, sys_gettid

jollen 發表於 October 12, 2006 12:57 PM

199 sys_getuid linux/kernel/timer.c 類別:Kernel Timer & Process 原型宣告:long sys_getuid(void); 用途說明:取得目前 process 的 real user ID (UID)。 Kernel (2.6.11 or above) 實作: asmlinkage long sys_getuid(void) { /* Only we change this so SMP safe */ return current->uid; } 201 sys_geteuid...

ext4 檔案系統現身了!

jollen 發表於 October 13, 2006 9:29 AM

新一代的檔案儲存 (storage) 檔案系統 (filesystem) - ext4 已經出現在Linux 2.16.19rc1-mm1 的核心原始碼裡了!ext4 是更先進的檔案系統,他前身就是知名的 ext3 檔案系統;ext3 是目前 Linux 普遍使用的知名檔案系統。 ext4 加入了 "extent file writing" 技術的支援,這是一個能減少 "fragmentation" 並增進效能的技術。有興趣的朋友可以閱讀 Linux-watch 上的官方新聞: http://www.linux-watch.com/news/NS3183866977.html '-mm' 系列的 2.6 kernel 是由 Andrew Morton 所釋出的 Linux 分支,主要性質以「實驗」與「新功能」為主;'ext4' 一睹為快,搶鮮下載 (mm patch 下載官網):...

Linux System Calls' Forum, #3:(第64號系統服務) sys_getppid

jollen 發表於 October 14, 2006 10:49 PM

sys_getppid 是很有趣的一個實作常式。 當 process fork 新的 process 後,便成為該 process 的 parent process,當然,新的 process 便成為 child process。在 UNIX 的 multithreaded 程式設計的理論中,process 之間的關係是相當重要的,比如說,只有 related process (e.g. parent process v.s. child process) 可以透過 pipe 的機制來交換資料。 process 呼叫 fork() 函數(更正確的說法是 fork system call 的...

Linux System Calls' Forum, #4:(第34號系統服務) sys_nice

jollen 發表於 October 15, 2006 12:55 AM

nice() 是用來變更 process 優先序(priority)的 system call,nice() system call 叫用(invoke)的 system call 實作常式為 sys_nice。sys_nice 服務常式(service routine)是 Linux 排程(scheduling)相關的服務常式中最基本(也是最古老)的一個。 34 sys_nice linux/kernel/sched.c 類別:Scheduling 原型宣告:long sys_nice(int increment); 用途說明:變更 process 的優先序。 Kernel (2.6.11 or above) 實作: /* * sys_nice - change the priority of...

是蟲啦,不是警告。

jollen 發表於 October 18, 2006 9:20 PM

是蟲啦,不是警告。在 Linux kernel 的 mailing list 看到一則有意思的張貼,全文如下,Jollen 把重點用紅色標示出來: * Jeremy Fitzhardinge wrote: > A warning is a warning, not a BUG. > - printk("BUG: warning at %s:%d/%s()n", __FILE__, > + printk("WARNING at %s:%d %s()n", __FILE__, i'm not really happy about...

Linux System Calls' Forum, #5:(第96號系統服務) sys_getpriority

jollen 發表於 October 19, 2006 9:07 PM

nice() 是用來變更 process 優先序(priority)的 system call 也是最古老的一個,sys_getpriority() 與 sys_setpriority() 則是取代 sys_nice() 的新實作,今天我們先討論一下 'sys_getpriority'。 96 sys_getpriority linux/kernel/sys.c 類別:Systems 原型宣告:long sys_getpriority(int which, int who); 用途說明:取得 process 的排程優先序(Priority)。 Kernel (2.6.11 or above) 實作: /* * Ugh. To avoid negative return values, "getpriority()" will...

Kernel 2.6 的 KVM (Kernel Virtual Machine) 驅動程式來了

jollen 發表於 October 19, 2006 11:27 PM

在伺服器(server)技術的發展藍圖中(roadmap),虛擬伺服器(virtual server)是 Intel 近來所著墨的重點。由以往單一硬體對單一作業系統(operating system)的伺服器架構(1 physical server v.s. 1 OS),未來將會演進成為單一硬體對多個作業系統的架構(1 physical server v.s. multiple OS)。 Intel 的 Virtualization Technology 就是一個這樣的新技術。Intel 的 Virtualization Technology 可以讓處理器支援多個 OS,不過這其實是基於我們所熟悉的虛擬機器軟體(例如:VMware、QEMU、Xen等)才能達到的,所以這是一個由「processor + chipsets + BIOS + 虛擬機器軟體」互相運作所實現的技術。 Virtual Machine Monitor (VMM) 軟體實作的虛擬機器在此技術領域中被統稱為「VMM - Virtual Machine Monitor」,現在已經有支援...

再探 sys_getpriority()

jollen 發表於 October 20, 2006 4:13 PM

getpriority() 若指定 which 是 PRIO_PGRP 的話,那麼便能取得 process group 裡的「最大 priority 值」。先節錄相關 kernel code 如下: asmlinkage long sys_getpriority(int which, int who) { ... case PRIO_PGRP: if (!who) who = process_group(current); do_each_task_pid(who, PIDTYPE_PGID, p) { niceval = 20 - task_nice(p); if (niceval...

Linux System Calls' Forum, #6:(第97號系統服務) sys_setpriority

jollen 發表於 October 20, 2006 7:38 PM

了解 sys_getpriority() 後,要看懂 sys_setpriority() 就不是問題了。 97 sys_setpriority linux/kernel/sys.c 類別:Systems 原型宣告:long sys_setpriority(int which, int who, int niceval); 用途說明:變更 process 的排程優先序(Priority)。 Kernel (2.6.11 or above) 實作: asmlinkage long sys_setpriority(int which, int who, int niceval) { struct task_struct *g, *p; struct user_struct *user;...

Jollen 的 Linux 核心分享包,#1: 《開工篇》

jollen 發表於 October 22, 2006 9:04 PM

Jollen 計畫在自己的 Blog 陸續與大與分享一些 Linux kernel 的研究心得,我們的寫作方向是以重點式的心得整理為主,不過希望加入一些教學性的風格,希望對大家有幫助。到目前為止,我們與大家分享了 Linux system call service 的幾篇日記,接下來仍會再討論幾個系統服務。 故事是這樣開始的 「Linux System Calls' Forum(LSCT)」旨在討論重要的系統服務(system service),以便將來我們能用最有效率的方式研究 kernel;「Jollen 的 Linux 核心分享包」則是在討論 Linux kernel 與作業系統有關的主題,方向是「討論 kernel 實作」。 Jollen 打算以「講義配合 Blog 開講」的方式跟大家一起玩核心!「一份講義」會以多篇日記方式跟大家討論,這裡的講義是從以前的筆記、演講、內訓課程或是討論會節錄並整理而成(需要時當然也會重新編製),Jollen 打算以講義的形式來整理,因此可能並不適合當做「教材」來使用;因此,在與朋友分享這份講義的同時,也要請大家一同分享 Jollen's Blog 網站。 第一份講義請由本文最後的網址下載,在開始看 kernel 前,以下的準備工作是很重要的: 1. 準備一份...

網路上的 ext4 filesystem benchmark

jollen 發表於 October 23, 2006 11:15 AM

網路上已經有人發表初步的 ext4 filesystem benchmark 數據了,該測試報告的作者將 ext4 的 "extents" 模式開啟,I/O scheduler 為 CFQ。CFQ 是 kernel 2.6.18 之後預設的 I/O 排程法。 由這篇測試報告來看,ext4 在「寫入」的效能表現上,大幅領先 ext3 與 raiser4;不過在其它測試項,ext4 則是與 ext3/raiser4 互有領先。但是整體來看,ext4 的整體效能表現確實比 ext3 來得優秀。 該測試報告也提到,由於 ext4 仍在開發測試階段,一切都要等穩定版出現後,再來做更進一步的評估了。測試報告原文: http://linux.inet.hr/first_benchmarks_of_the_ext4_file_system.html Linux-kernel mailing list 也有討論串: http://forum.jollen.org/index.php?showtopic=6705 Also See...

ReiserFS 日誌式檔案系統

jollen 發表於 October 24, 2006 11:22 AM

自 kernel 2.4.1 開始,Linux 已經支援一種稱為 ReiserFS 的日誌式檔案系統。日誌式檔案系統可以提供更安全的檔案保護機制,特別是可以運用在伺服器或是商業環境的應用上。 目前有 4 種較廣為人知的日誌式檔案系統: □ XFS □ JFS □ ext3 / ext4 □ ReiserFS 其中 JFS 是由 IBM 所發展,有興趣的讀者可以參考 IBM 的說明: http://www-128.ibm.com/developerworks/linux/library/l-jfs.html 另外 XFS 是由 SGI 所發展。我們選擇目前較受觀迎的 ReiserFS 來做介紹。 ReiserFS 的特點 ReiserFS 官方網站:http://www.namesys.com/。 日誌式檔案系統被認為相當適合應用在大型的商業伺服器環境中。在這類的環境裡,資料完整性相當的重要。...

Jollen 的 Linux 核心分享包,#2: 《講義1~5》

jollen 發表於 October 24, 2006 10:33 PM

講義第1頁到第5頁的說明。 課前說明 作業系統(operating system)理論的教材書,與 process 和 scheduling(排程)相關的主題都是最先被討論的議題。因此,對於 Linux kernel 原始碼的研究,我們也從 process 與 scheduling 有關的部份開始講起。 Process 是執行中的程式,因此「程式如何被執行」是第一個重點,這個部份的觀念當然也包含「程式如何由儲存裝置載入」。緊接著的是,「程式載入記憶體後的佈局(layout)」,這是第二個要研究的重點。當程式被載到記憶體後,作業系統的 scheduler(排程器)便負責排程的工作與執行本文切換(context switch),這是第三個所要討論的重點。 因此,我們將會研究 Linux kernel 的 3 個「process and scheduling」議題: 1. Shell 如何載入執行檔(ELF executables)至記憶體。 2. Process 的 memory 資枓結構。 3. Linux scheduling 與...

kernel 2.6 的 battery class 驅動程式

jollen 發表於 October 25, 2006 10:35 AM

"class driver" 是 kernel 2.6 driver model 的新觀念,從系統管理面的角度來看,就是 /sysfs。現在 kernel 2.6 已經出現專門針對電池電源管理的驅動程式了:battery class。這是一個有別於以往對於電源管理的實作,雖然 "battery class" 仍只是一個初步實作的驅動程式,但未來 "battery" 與 "AC powe" 在 Linux 驅動程式新觀念底下,將會是一個獨立的 "device"。 新的 battery class 實作中,我們也看到了 OLPC(百元美金電腦)專用的電池驅動程式。程式碼目前可由 kernel 的 git 下載,並可追磫此討論串:http://forum.jollen.org/index.php?showtopic=6899...

什麼是 "asmlinkage"?

jollen 發表於 October 26, 2006 4:15 PM

有網友來信問到,kernel 裡的 system call 實作函數中(C 函數),為什麼每一個函數原型宣告的前面都有一個 "asmlinkage" 的字串?例如: asmlinkage long sys_nice(int increment) "asmlinkage" 是在 i386 system call 實作中相當重要的一個 gcc 標籤(tag)。 當 system call handler 要呼叫相對應的 system call routine 時,便將一般用途暫存器的值 push 到 stack 裡,因此 system call routine 就要由 stack 來讀取 system...

Preemptive Process Scheduling 的觀念

jollen 發表於 November 2, 2006 2:55 PM

先前我們在介紹 sys_getppid 時,跳掉了一段 code 如下: #if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT) { ... } #endif 這段 code 在判斷 kernel 是否有 'CONFIG_SMP'(多處理器)與 'CONFIG_PREEMPT'(可搶先的 process 排程)。目前 kernel 2.6 在各種處理器平臺已經支援 preemptive process scheduler,當然也包含了 i386 處理器。 這個 kernel 的設定位於 arch/i386/Kconfig,我們節錄 Kconfig 內容如下: config PREEMPT bool "Preemptible...

KVM 驅動程式的 HOWTO

jollen 發表於 November 2, 2006 10:03 PM

之前提到過 Kernel 2.6 的 KVM 驅動程式現身了,今天看到 KVM 驅動程式的 HOWTO 已經上線了。KVM 的官方網站是:http://kvm.sourceforge.net/ 裡頭除了有 HOWTO 外,也有 mailing list 可以加入了。KVM 的驅動程式除了有 kernel-space 的 driver 外,也包含一個 user-space 的 library,以及給 QEMU 的 patch。...

目前的「Linux System Calls' Forum」與「Jollen 的 Linux 核心分享包」專欄進度報告。

jollen 發表於 November 4, 2006 9:34 PM

「Linux System Calls' Forum」與「Jollen 的 Linux 核心分享包」是二個相互配合的專欄,因此相關的日記彼此之間是具備相依性與次序的。建議的閱讀順序是「依照日記的時間(即發佈順序)」來閱讀「Linux System Calls' Forum」與「Jollen 的 Linux 核心分享包」。這是這二個系統日記的閱讀建議。 目前的狀況報告 對於 Linux system call 的討論,我們已經來到了 scheduler 的門口了,要深入了解 Linux scheduler 的設計原理與相關理論前,Jollen 還必須多做一點功課才行。到目前為止,我們所討論過的幾個 system call 如下。 跟上我們的腳步:請讀以下的文章,再看這篇日記! 2006.10.11: Linux System Calls' Forum, #1:(第20號系統服務) sys_getpid 2006.10.12: Linux System Calls'...

Linux System Calls' Forum, #7:(第157號系統服務)sys_sched_getscheduler

jollen 發表於 November 5, 2006 12:03 AM

「作業系統的排程器(scheduler)提供好幾種排程演算法,並在不同的應用場合,或是不同的 process 採取適合的排程策略(policy)。」 Linux 的 process descriptor 資料結構為 struct task_struct,我們最早開始談論與 process 有關的 system call 時,就看過這個用來描述 process 的資料結構。struct task_struct 裡頭的 policy 欄位便是用來描述該 process 的排程策略。 與排程有關的系統呼叫 整理與 scheduling 有關的幾個 system call 如下(可參考「Linux 2.6 的 System Call:12 大類」),另外 Jollen 也把到目前為止已介紹過的 system call 加上紅色註記。...

Jollen 的 Linux 核心分享包,#3: fork_init()《講義6》

jollen 發表於 November 9, 2006 11:41 PM

我們知道,在 start_kernel() 的開機過程中,會呼叫許多初始化核心的常式。其中 fork_init() 是用來初始化 kernel 的"fork" 環境的。"fork()" 是用來產生 child process 的 system call,當 parent process 想要執行外部程式時,會先 fork child process,接著 child process 再利用 exec system call 自己的空間取代為外部程式。 從講義第 5 頁開始,我們把問題做分割,找出與 Scheduling 有關的初始化流程來做研讀,因為我們想要以 Scheduling 做為深入 Linux kernel 的第一門課。 講解 fork_init() 1....

深入淺出 insmod, #1

jollen 發表於 November 15, 2006 8:52 PM

深入淺出 insmod, #1 作者/陳俊宏 http://www.jollen.org 這篇文章的目的是為了解釋 Linux 驅動程式課程中,經常被詢問的部份,我把這個地方以紅色來標示: struct file_operations { struct module *owner; loff_t (*llseek) (struct file *, loff_t, int); ssize_t (*read) (struct file *, char *, size_t, loff_t *); ssize_t (*write) (struct file *, const char *, size_t,...

讓 kernel 常在我心:探討如何與 kernel 的發展同步

jollen 發表於 November 20, 2006 7:53 PM

從事 Embedded Linux(GNU/Linux systems on devices)工作的朋友,除了日常的讀書功課外,另外一個重要的工作就是「隨時注意 Linux kernel 的發展狀況」。要能與 Linux kernel 的發展同步,嚴格來說,已經是一件吃重的工作了,不過還是可以列出幾個基本的工作原則如下: 1. 每天閱讀 linux-kernel 郵遞論壇(mailing-list)的「標題」。 2. 隨時上 kernel.org 看看最新釋出的 kernel 版本(或留意 linux-kernel-announce mailing-list)。 3. 閱讀釋出版本的 Changelog。 4. 不要與 git 系統的距離太遠,定時看看 git 系統,保持一定的「短距離」。 Mailing List linux-kernel 上的 posts 每天的量大約在 200~350...

System Call 專題討論, #1:什麼是System Call

jollen 發表於 December 1, 2006 4:10 PM

System call 是 process 與作業系統之間的介面。System call 是由 Linux kernel 所實作並提供給使用者,user-space program 可透過 system call 與Linux kernel 溝通。以 C 語言來呼叫 system call 的話,則是透過 GLIBC(libc)來間接呼叫。 GLIBC 提供呼叫 system call 的介面稱為 wrapper routine,wrapper routine 會叫起 Linux 的 system call handler,最後再由 system call handler...

System Call 專題討論, #2:使用 C 語言呼叫 System Call

jollen 發表於 December 1, 2006 4:24 PM

在 Linux system 底下,必須透過 GLIBC 裡的 system call function 來取得 kernel 的 system call 服務。 由 GLIBC 提供用來呼叫 system call 的函數稱為 wrapper function,wrapper function會呼叫 Linux kernel的handler routine,即 system_call() 函數。 呼叫 getpid() system call 的範例: #include #include #include int main() {...

System Call 專題討論, #3:使用 Assembly 呼叫 System Call(x86)

jollen 發表於 December 1, 2006 4:30 PM

Wrapper routine 透過 0x80 號中斷(軟體中斷)進入 kernel space,並且跳至 system call handler執行。由於透過軟體中斷即可達成呼叫 system call的目地,因此使用 assembly來寫程式時,我們也可以直接呼叫system call。 在產生軟體中斷前,我們必須告訴 Linux kernel 所要呼叫的 system call 編號,system call 的編號透過 %eax 暫存器來指定;若要傳遞參數,則是透過其它暫存器來傳遞。 參數傳遞與傳回值 Linux system call最多可傳遞6個參數,參數的傳遞是透過以下的暫存器來完成: %ebx:第1個參數。 %ecx:第2個參數。 %edx:第3個參數。 %esi:第4個參數。 %edi:第5個參數。 %ebp:第6個參數(做臨時用途)。 System call 的編號由 %eax 暫存器指定。System...

System Call 專題討論, #4:x86 的 Interrupt

jollen 發表於 December 1, 2006 4:36 PM

我們由之前的 hello.S 程式範例來做切入: movl $len,%edx movl $msg,%ecx movl $1,%ebx movl $4,%eax int $0x80 System call 編號 4(%eax = 4)為 sys_write 函數,其原型宣告如下: ssize_t sys_write(unsigned int fd, const char * buf, size_t count) 根據 sys_write 的參數宣告,我們必須傳遞參數如下: ˙ 第 1 個參數為 unsigned int...

System Call 專題討論, #5:0x80 軟體中斷

jollen 發表於 December 1, 2006 4:44 PM

System call 是透過中斷來呼叫,而在 x86 系統的架構中,32-255 是所謂的 maskable interrupts 即使用者定義的中斷。Linux 在 i386 上實作system call可透過以下 2 個機制: ˙ lcall7/lcall27(call gates,呼叫閘道) ˙ int 0x80(software interrupt.軟體中斷) Linux 應用程式使用 int 指令來觸發 0x80 號軟體中斷,其它作業系統像是 Solaris 的應用程式,則是使用 lcall7。在開機時,IDT是由arch/i386/kernel/traps.c:trap_init() 做初始化的設定: void __init trap_init(void) { #ifdef CONFIG_EISA if (isa_readl(0x0FFFD9)...

System Call 專題討論, #6:unistd.h(x86)

jollen 發表於 December 1, 2006 4:52 PM

unistd.h 是一個重要的標頭檔,裡頭是 system call 編號的定義;另外,linux/arch/i386/kernel/entry.S 則是每一個 system call 的進入點,也就是 system call table(位於 .data section)。 unistd.h也定義了處理不同參數個數的 system call handler,在這個標頭檔裡可以看到處理 0~6個參數的 handler(_syscall0~_syscall6)。例如以下是處理 1 個參數的handler: #define _syscall1(type,name,type1,arg1) \ type name(type1 arg1) \ { \ long __res; \ __asm__ volatile ("int $0x80" \ :...

我要怎麼知道 kernel 更新了什麼東西?

jollen 發表於 December 6, 2006 10:15 PM

這是一個時常被問到的問題,由於 kernel 的變動快速,因此 Jollen 在日前便寫了一篇「讓 kernel 常在我心:探討如何與 kernel 的發展同步」的日記,內容是大略介紹如何與 kernel 的發展同步(day-by-day)。 但是,如果並不是很需要每天去注意 kernel 的動態的話,只要在每個 kernel 穩定版(stable)釋出後去看 Changlog 就好了。特別是 kernel 2.6.1x 的更新項目(update)、臭蟲修正(big fix)、新的驅動程式與 filesystem 更是以可怕的「量」在 patch,特別是最近半年的 3 個 kernel 版本(2.6.17~19),變化量真是到了油門全開的狀態,所以每天看 kernel 會是沈重的負擔。 話說回來,改變是好事。期待的是,看著這麼多的改變與越來越多的新驅動程式加入,以及企業級(enterprise-class)功能的成熟,我們已經可以拿到越來越棒的「成熟」kernel 了。誠如 Linus 在 2.6.19 stable 釋出時的玩笑話「It's one of...

Linux 2.6.19 正式支援 Atmel AVR32 架構

jollen 發表於 December 9, 2006 6:28 PM

Linux 2.6.19 正式加入了 Atmel AVR32 architecture 的支援,這是由 Atmel 原廠所實作的 architecture-level porting。引用一段節錄至 KernelNewbies.org 的 changelog wiki 上的說明: AVR32 is a new high-performance 32-bit RISC microprocessor core, designed for cost-sensitive embedded applications, with particular emphasis on low power consumption and high code...

Linux 驅動程式的 I/O, #1: 基本概念

jollen 發表於 December 12, 2006 12:02 PM

由本篇日記開始,我們將進行「Linux Device Driver 入門:I/O 處理」的議題討論。這裡所提的 I/O 處理定義是:user process 與 physical device 的 I/O 存取。 在讀「Linux Device Driver 入門:I/O 處理」專欄前,您必須熟悉 Linux 驅動程式的架構,因此「Linux Device Driver 入門:架構層」的專欄是 Jollen's Linux Device Driver 系列專欄的先備知識;此外,接下來的專欄使用的語法也必須對架構層有基本認識後才能看得懂。 Linux 驅動程式 I/O 機制 Linux device driver 處理 I/O 的「基本款」是: fops->ioctl...

Linux 2.6.20 將正式加入 KVM 驅動程式

jollen 發表於 December 12, 2006 10:10 PM

方才在 slashdot 上撇見「It looks like the newest version of the Linux kernel (2.6.20) will include KVM, the relatively new virtualization environment.」這篇 blog,kernel 2.6.20 已正式加入了 KVM 驅動程式,這也宣告 Linux 已經正式踏入「虛擬化(virtualization)」這個熱門的伺服器技術領域了。 Linux 的 kernel-space 虛擬機器驅動程式稱為「KVM」,KVM 於今年的 10 月 19 日首次正式發佈於 linux-kernel mailing list,並且於...

理解 dynamic loader 內部原理的幾個先備知識(上):ELF 端的議題

jollen 發表於 December 14, 2006 11:39 PM

接下來,即將啟動 ELF 格式的「execution view」介紹。本日記是進入「dynamic loader」前的準備工作「之一」。 果然是很大挑戰的研究。說明幾個注意事項如下。 必須了解 ELF 的格式觀念 「Executable and Linking Format」專欄已經把 ELF 格式的「linking view」做了初步的介紹,在此專欄裡,Jollen 針對 ELF 格式的概念以 loader v0.1~v0.5 共五個範例做說明。想要了解 ELF 格式的朋友,可以參考此專欄。 Section 的用途摘要說明 每個 section 都有不同的用途,在 SysV ABI 裡所定義的特殊 section 與其用途整理如下: Section 用途 .bss  用來置放程式裡未初始化的資料(uninitialized data),當程式執行時預設會將這裡的資料初始化為0(zero)。 .comment...

.bss section 的觀念:uninitialized data section

jollen 發表於 December 15, 2006 1:11 AM

.bss 節區存放「uninitialized data」,由程式碼的角度來看,就是「未初始化的變數」。我們直接以一段 code 來說明,讓大家更清楚這樣的概念。 #include <stdio.h> int foo; int bar; int main(void) { int *ptr; printf(".bss section starts at %08p\n", &foo); printf("foo is %d.\n", foo); ptr = &foo; *ptr = 12345; printf("foo is %d.\n", foo); printf(".bss section starts at...

.bss section 的觀念:執行時期的長度

jollen 發表於 December 15, 2006 2:02 AM

在「理解 dynamic loader 內部原理的幾個先備知識(一)」講到:.bss 節區「linking view」上不佔檔案空間。這點可以用 readelf 來做 ELF linking view 端的印證: # readelf -e bss|more (bss 是我們的範例執行檔) ... Section Headers: [Nr] Name Type Addr Off Size ES Flg Lk Inf Al [ 0] NULL 00000000 000000 000000 00 0...

bss section 的觀念:執行時期的結構說明

jollen 發表於 December 17, 2006 10:02 PM

目前已經了解到:.bss section 在 linking view 時是不佔檔案長度的,在 execution view 時,根據其長度來佔用記憶體大小。 關於 .bss section 的結構,其實一張圖就夠了。直接切入重點吧! 前言 先重新編譯 bss.c 範例: # gcc -g -o bss bss.c # ./bss .bss section starts at 0x8049588 foo is 0. foo is 12345. .bss section starts at...

Linux 驅動程式的 I/O, #2: I/O 存取相關函數

jollen 發表於 December 20, 2006 10:57 PM

I/O 存取相關函數 要提到「I/O 處理」當然要整理 Linux 提供的相關函數,以下分 3 大類來整理: 1. I/O port 2. I/O memory 3. PCI configuration space 4. ioremap I/O Port 以下是 Linux 提供最原始的 I/O port 存取函數: ˙ unsigned inb(unsigned port); ˙ unsigned inw(unsigned port); ˙ unsigned inl(unsigned port);...

Linux 的 SDIO Stack 也有 open-source 的版本了!

jollen 發表於 December 21, 2006 5:09 PM

SDIO 是走 SD 插糟的週邊介面,SDIO 也是普及於 PDA/Mobile 的週邊規格,實際應用例如:透過 SDIO(SD 插糟),可以外接許多 SDIO 的週邊卡,像是 SDIO WiFi card 或是 SDIO CMOS sensor。Linux 從 2.6.17 開始正式加入了 SD/MMC 的 stack driver(也就是 API core 層),但是並沒有 SDIO 的 stack driver。 因此,「玩家」可以試著由現有的 SD/MMC stack 做修改,並實作 machine-dependent 的驅動程式(例如:s3c24x0)。或是花錢買解決方案,例如:MontaVista、印度的 embWise 公司。...

Linux 驅動程式的 I/O, #3: kernel-space 與 user-space 的「I/O」

jollen 發表於 December 26, 2006 11:40 PM

重要觀念 任何作業系統底下的「驅動程式」,都需要分二個層面來討論所謂的「I/O 處理」: 1. 實體層:驅動程式 v.s. 硬體。 2. 虛擬層:驅動程式 v.s. user process 在前一篇日記「Linux 驅動程式的 I/O, #2: I/O 存取相關函數」中所提到的 I/O 函數是處理「實體層」的 I/O;本日記所要介紹的 copy_to_user() 與 copy_from_user() 則是在處理「虛擬層」的 I/O。另外,在繼續往下讀之前,您必須了解以下的觀念都是「等價」的: 1. 驅動程式與 user process 的 I/O;等於 2. 驅動程式與 user process 間的 data communication;等於 3....

理解 dynamic loader 內部原理的幾個先備知識(下):Kernel 端的議題

jollen 發表於 December 29, 2006 9:20 PM

前些日子寫到「理解 dynamic loader 內部原理的幾個先備知識(上)」時提及,必須略懂 .bss section 的觀念,並且最後也提到「之後再寫日記,以一段 code 來說明。」。其實之後幾天我就把介紹 .bss section 觀念的日記寫好了,只是還沒有加入到專欄索引,趕快來把索引做好! 今天加入「BSS Section Concepts: .bss section 的基本觀念介紹」的專欄索引。 以下是必讀的二個專欄(及理由): 1. 必須先懂 ELF 到底是什麼東西,才會知道 .bss 是 ELF 的「一個節區」。可以參考 Jollen 的「 Executable and Linking Format: 重要的 ELF 格式介紹」專欄。 2. 接著才是讀「BSS Section Concepts:...

Process Creation, #1:由 shell 執行外部程式《基本觀念與範例》

jollen 發表於 December 31, 2006 8:14 PM

本系列專欄是「了解 ELF 動態時期行為」的前導專欄,建議您先行爬文「理解 dynamic loader 內部原理的幾個先備知識(下):Kernel 端的議題」。 Shell 執行外部程式的觀念 在 2006 年的最後一天,就先來解說一下「下指令後、程式怎麼載入與執行」的觀念。首先,您必須知道並具備以下的 Linux 系統程式觀念: 1. fork() 系統呼叫:用來建立 child process。 2. exec 系列系統呼叫:以一個「外部程式」來取代自己(current process)的執行空間。 3. parent process、child process 與 Linux process tree。 了解以上三個主題後,就可以很容易理解「下指令後、程式怎麼載入與執行」的過程;這是很重要且基本的三個議題,若您不是很清楚這三個議題的觀念,可以查詢「Linux Systems Programming」的相關文件。 接下來,首先我們要知道的是,Linux 並沒有提供 "spawn" 的 system call;再來,shell...

Process Creation, #2:Running a "User Process"

jollen 發表於 January 2, 2007 11:08 PM

Process Creation 在討論「Process Creation」議題時,首先要了解的就是「Linux 的三種 Process」。同樣是「執行中的程式(process)」,但是依其「特性(design perspective)」區分的話,可以歸納為以下三種: idle process kernel threads user process 其中「user process」就是我們此系列日記所要介紹的對象。User process 是很單純的一種 process,簡單來說,以下二種「執行程式的方式」就是 user process: 在 shell 模式中輸入 Linux command 所執行的外部程式 由 init process 所執行的外部程式 那麼 user process 是怎麼執行的呢?嗯,先前我們提過的日記「Process Creation, #1:由 shell 執行外部程式《基本觀念與範例》」便介紹了這樣的觀念。 Process Creation:Running...

Linux 的 Virtual Memory Areas(VMA):基本概念介紹

jollen 發表於 January 5, 2007 2:08 PM

由 user process 角度來說明的話,VMA 是 user process 裡一段 virtual address space 區塊;virtual address space 是連續的記憶體空間,當然 VMA 也會是連續的空間。VMA 對 Linux 的主要好處是,可以記憶體的使用更有效率,並且更容易管理 user process address space。 從另一個觀念來看,VMA 可以讓 Linux kernel 以 process 的角度來管理 virtual address space。Process 的 VMA 對映,可以由 /proc/<pid>/maps 檔案查詢;例如 pid...

Process Creation, #3:sys_fork《基本觀念》

jollen 發表於 January 8, 2007 1:44 PM

fork() 是「Process Creation」議題的重要里程碑:提到 system call 代表著我們的研究要正式進入 kernel space 的層面了。 值得附帶一提的是,sys_fork 是一個 machine-dependent 的 system call,以 i386 為例,其實作位於 linux/arch/i386/kernel/process.c。*1 Operating System 端的觀念 sys_fork 是非常重要的 system call,從作業系統的角度來解釋的話,這就是「建立 process」的主要 system call。當外部程式(即 ELF image)被使用者鍵入指令後,shell 便會呼叫 fork() 系統呼叫,並透過作業系統的 fork system call 來產生新的 process,以執行此外部程式。這種類型的 fork 也稱做...

Process Creation, #4:sys_fork《核心實作》

jollen 發表於 January 11, 2007 11:17 PM

接續前一記日記的觀念:「Linux 以 sys_fork 或 sys_clone 來產生新的 process,而這二個 system call 最後都會呼叫到 do_fork() 函數,do_fork() 是 Linux 主要的 fork-routine。」 將此觀念以實作角度來說明的話,do_fork() 必須要做的工作便是「copy 原來的 process 成為另一個新的 process」。Linux 的 sys_fork() 內部實作就是以「copy process」的方式來實作。也就是說,當 user program 呼叫 fork() wrapper function 後,sys_fork() 便會「copy」原來的 process,以得到一個新的 process。 由此觀念的推導,我們便能了解到,sys_fork() 的內部實作關鍵便是: 1. 如何...

Process Creation, #5:copy_process()

jollen 發表於 January 14, 2007 1:59 AM

Before We Start Trace Linux kernel 時,有幾個相當重要的原則要掌握住: 不要對 Linux kernel 做逐行的研讀(trace line-by-line、最忌諱的做法),而是掌握我們想要了解的核心觀念,並針對此核心觀念來了解相關的實作細節。 必須整理觀念與程式碼的對應,但並不是要大家對原始碼做逐行註解,而是針對細部觀念,將相關的實作片斷整理出來即可。 每個 kernel API 的實作原本就會包含許多的「OS 基礎概念與理論」,例如:mutex、semaphore、locking 等等。與這些基礎知識相關的程式碼,本來就是屬於整體的部份,所以應該「跳脫」個別的 kernel API 實作。 如 3.,也就是說,如果我原本就懂這些東西,就應該很清楚了解這些「片段程式碼」的作用,應避免「完美主意」作祟:不要急於看懂這些片斷的程式細節,以免因小失大。 如 3.,如果我原本就不懂這些東西,可以試著把這些程式碼當做「黑盒子」來看待。這樣的,這也是「學習方法」的問題,並非要刻意逃避這些自己不懂的東西。 以本日記為例,我們想要了解 Linux kernel 如何產生新的 process,而其中的關鍵便是 copy_process() 函數。但是,目前我們在做的是 sys_fork() 的 trace,而 sys_fork() 並不指定任何的 clone_flags 參數值,因此,在...

Linux 的 Virtual Memory Areas(VMA):Process 與 VMA 整體觀念

jollen 發表於 January 15, 2007 3:27 PM

要了解 VMA(Virtual Memory Area)的「整體觀念」,最好的方式就是圖解說明。下圖說明了 process 與 VMA 的整體觀念。 圖:Process 與 VMA 整體觀念 Memory Descriptor Linux 的「Process Descriptor」資料結構為 struct task_struct(include/linux/sched.h)。Process descriptor 裡的 mm field 紀錄了 process 的 VMA 資訊: struct task_struct { ... struct mm_struct *mm; ... } struct mm_struct 即是...

[筆記] Linux 2.6 的 MMC Core

jollen 發表於 January 20, 2007 12:06 AM

以下整理自 Jollen 筆記(非教學文件),許多地方未能清楚交待,這部份有請大家自行補齊了。本文分享給有志研究 Linux MMC 驅動程式實作(MMC Core)的朋友參考。以下分析基於 Linux 2.6.17.7,更新版本的 kernel 加入了許多 patch(例如 Linux 2.6.19 的 SDHC patch),這些更新內容不在討論之列。 續前一篇日記「Linux(open source)的 SD/MMC/SDIO 支援現況概要」所提到的,目前的 Linux SD/MMC/SDIO 「嚴格來說」,只支援 MMC 記憶卡,如果是要插上 SD 記憶卡,使用上則會有諸多限制。 由 Linux 驅動程式的角度來看,單就 MMC 的部份來分析的話,Linux 的 SD/MMC 驅動程式層包含以下實作(Kconfig): CONFIG_MMC CONFIG_MMC_BLOCK 相關檔案位於 drivers/mmc/...

Linux 驅動程式的 I/O, #4: fops->ioctl 實作

jollen 發表於 February 2, 2007 9:28 PM

延續前一篇文章的介紹,在了解 copy_to_user() 與 copy_from_user() 二個 API 後,接著 Jollen 將由 Linux device driver 的架構層來討論 user-space 與 kernel-space 的 I/O 機制。 同時,也延續在「架構層」系列教學專欄的 debug card 範例。 基本觀念 需要由 user-space 讀取資料,或是寫入資料給 user-space 的主要 3 個 driver method 為:read、write 與 ioctl。指向 user-space 資料空間(buffer)的指標是 kernel 回呼...

ELF 之 Program Loading 教學文件, #1: Segment 的觀念

jollen 發表於 March 5, 2007 12:05 PM

「Program Loading」的議題在討論「如何將程式載入記憶體」,以便後續的「執行」。在「ELF(Executable and Linking Format)格式教學文件」第 1~8 篇文章裡,我們了解基本的 ELF 觀念,並建立所謂的「節區」知識。 本系列日記「ELF 之 Program Loading 教學文件」將會介紹有關程式載入(program loading)的核心主題,在此之前,請先閱讀 Jollen 的「Executable and Linking Format」專欄,以基本基礎的先備知識。 Segments 由 "execution view" 的角度來看程式(即 process),所謂的節區(section)已經被進化成區段(segment)的觀念了。廣義來說,section 可被分為以下 3 種 segment: Text segment - 指存放唯讀(read-only)程式碼與資料的所有 section 。 Data segment - 指存放可寫(writable...

ELF 之 Program Loading 教學文件, #2: Program Header Table

jollen 發表於 March 8, 2007 4:19 PM

了解系統行為的研究方法,我認為有效的步驟應分成三個階段來進行。 初次入門:一開始進行研究時,因為對於系統的基本觀念還不夠完備,因此「學中做、做中學」成了最有效率的入門方式,透過「概念的實作」與「實作讀到的概念」的過程,最可以幫助我們在短時間內掌握重要的核心知識。以 ELF 專欄為例,在入門時期,我用了 loader 0.1~0.5 共 5 個小範例來陳述 ELF 的格式以及 section 的觀念。 掌握觀念:首先發表一個自己的看法。「將所有理論或概念全部動手實作一遍」,在我看來,並不是很有效率的辦法,這種做法應當很有幫助,但是卻會延緩學習速度,因此,這個時 期的重點如果是在「通盤掌握整體的重要關鍵」,那麼「善用工具來做分析」自然是最有成 效的方式。以「工具來操作並驗證觀念」是建議的做法,另外一個理由是,這種做法比較能貼近實務面。在「ELF 之 Program Loading 教學文件」的日記裡,我將會以此做法來分享教學文件。 思考與研究:這個階段有點像是「實驗室」的做法,在這裡不再贅述。 Program Header Table 這裡有幾個重要的觀念: 1. Program header table 是程式要能執行的重要資訊,program header table 紀錄 ELF image 裡的 'segment' 分佈,請參考 Jollen's Blog「ELF...

Process Creation, #6:Exec System Call 的觀念

jollen 發表於 March 8, 2007 7:47 PM

有關 exec system call 的前言,除了以下日記外: 2006.12.31: Process Creation, #1:由 shell 執行外部程式《基本觀念與範例》 2007.01.02: Process Creation, #2:Running a "User Process" 也請閱讀以下日記: 2007.01.05: Linux 的 Virtual Memory Areas(VMA):基本概念介紹 2007.01.15: Linux 的 Virtual Memory Areas(VMA):Process 與 VMA 整體觀念 Exec system call 的 service routine...

ELF 之 Program Loading 教學文件, #3: Segment Type 與 Kernel Space Loader

jollen 發表於 March 9, 2007 7:46 PM

Segment Type Program loading 時期會處理以下 4 種 segment: #define PT_LOAD 1 /* Loadable program segment */ #define PT_DYNAMIC 2 /* Dynamic linking information */ #define PT_INTERP 3 /* Program interpreter */ #define PT_PHDR 6 /* Entry for header table itself...

ELF 之 Program Loading 教學文件, #4: Program Loader 整體流程

jollen 發表於 March 13, 2007 2:26 PM

Program loader 的整體流程如下: 1. 使用者在 shell 模式下執行外部程式(stored program)。 2. shell 以 fork+exec system call 的方式執行外部程式。 3. 透過 0x80H 軟體中斷(x86)叫用 kernel 的 exec(sys_execvp)system call service。 Kernel Space Program Loader4. Exec system call 呼叫 program loader(ELF loader),將 process image(ELF image)載入。 5. Program...

小結 Program Loading 觀念

jollen 發表於 March 23, 2007 10:56 AM

由「Program Loading」專欄所得到的觀念如下。 外部程式(stored program)的執行是透過 fork system call,先將 current process 複製一份成為他的 child process。接著再透過 exec system call 將外部程式的 ELF image 載入,並取代原來的 process。Kernel ELF loader 會讀取 ELF image,並將 text segment 與 data segment 重新 mapping,接著再找到程式的 program interpreter。 外部程式的最初執行是由 program interpreter 開始,program interpreter 透過...

看 Linux kernel 應具備的首要觀念是?

jollen 發表於 March 24, 2007 4:09 PM

Linux kernel 是狀態機還是結構化程式流程? 作業系統(Operating System)的研究,我們以 Linux kernel 的探討來說明一些應有的正確觀念。 對於 Linux kernel 的研究,最經常聽到有人提起「kernel source code」的研讀與分析,並且最常看到的研究方式為「尋找 kernel 進入點,並依照程式流程(flow)做循序研究」,不過,這卻是一種「大部份情況下都錯誤」的研究方式。 由於電腦系統是一種 foreground-background system,並且 Linux kernel 是在此系統上的作業系統,因此整體的 kernel 行為是「control patch」,也就是「控制權的轉移」與「系統狀態的改變」,並不是「程式(函數)流程(flow)」,或是「程式結構(structure)」的問題;最近有朋友問起這方面的議題, 正好也在進行 Linux device driver 的 training,因此特別整理這則日記,來與大家分享,若有任何論述上的失誤,或是有不同的觀點,歡迎在這裡留言 分享。 許多人對於「作業系統」的觀念可能真的有點薄弱;具體來說,對於 kernel 內部原理的研究,其方法應該是: 1. kernel 的開機階段,是以「流程(flow)」的角度來做討論。 2. kernel...

Kernel 2.6.21 將正式加入 VMI(Virtual Machine Interface)

jollen 發表於 March 29, 2007 11:12 PM

在 LinuxDevices.com 上的一則新聞「Linux kernel gains paravirtualization option」指出,kernel 2.6.21 將加入 VMI(virtual machine interface)的功能,讓 kernel 得以「 modify itself for faster performance when run under a hypervisor」另外可參考這篇較完整的報導「Linux Kernel to Add VMI」。VMI 是由 VMware 公司所貢獻的實作,VMware 是知名度相當高的虛擬機器軟體商,同時也是老牌子的虛擬機器軟體,目前,Intel 與 AMD 已經將虛擬化技術列入重要的產品規劃(roadmap)項目裡了,再加上 VMware 公司的貢獻,可見虛擬化技術真的是 2007 年的重要技術發展趨勢之一。 上面所提到的「Hypervisor」指的是支援虛擬化處理器的虛擬機器管理軟體(Virtual...

struct map_desc 與抽象化程式碼小談

jollen 發表於 May 11, 2007 11:29 AM

前日與客戶進行 Linux device driver 教育訓練時,簡單討論到有關 JK2410 的 IO memory layout 描述方式。在 linux 2.6.20.x 的 BSP 實作中,kernel 提供用來描述 board-level(machine)IO mapping 的資料結構稱為 'struct map_desc',其定義如下: 1 /* 2 * linux/include/asm-arm/map.h 3 * 4 * Copyright (C) 1999-2000 Russell King 5 * 6 *...

Linux frame buffer 驅動程式開發簡報下載

jollen 發表於 August 29, 2007 7:12 PM

今天有幸受邀發表了一場演講,和大家分享「Linux frame buffer 驅動程式開發」的議題。時間並不長(1個小時),因此只能針對整體架構與部份重點做介紹。簡報檔案下載 [Linux_FB_Driver_Intro_v0.2.pdf]。 本次演講分為二個階段進行,首先是背景知識的部份,針對 Linux 2.6 的 driver model 做總覽;第二部份則是本次的講題,以 s3c2410fb 的驅動程式為例,介紹了 kernel subsystem 與底層(low-level)驅動程式的整個關係。 同時,也在演說中提到 register 與 callback 的觀念。由於 subsystem 的實作是分層架構,C 的實作採用 in-direct function call,所以不能依照傳統結構化程式的方式,單純以 function call 的流程來 trace 驅動程式。...

register_netdev 的入門實例: bonding.c

jollen 發表於 December 2, 2007 2:30 PM

今天在「Linux 驅動程式: 進階」的訓練課程中提到,找到正碓的入門實例,比起什麼都來得重要。 有時,老舊的程式碼,更容易幫助初學者掌握基本的架構與 API 用法。在 Linux 驅動程式的課程裡,我推薦同學研究一個早期的網路介面驅動程式,叫做 bonding.c。bonding 是一個用來合併網路卡的驅動程式,而早期的 bonding 驅動程式並沒有太多額外的 algorithm 實作,因此我建議同學,拿出 kernel 2.4.14 裡的 bonding.c 來做實例研究。由於這個版本的 bonding 驅動程式非常赤祼祼地呈現 register_netdev、struct net_device 與封包傳送的介面實作,因此肯定比許多最新的網路卡驅動程式更適合初學者。 kernel 2.4.14 的 bonding.c 可以在 2.6.x 的 kernel 上使用,美中不足的是,使用古老的 bonding driver 無法將 eth 介面合併進來,但至少可以配合 ifconfig 指令來做動態的操作與觀察,例如了解...

簡報下載:Linux 驅動程式的 read/write 觀念解析

jollen 發表於 December 21, 2007 4:15 PM

12/19(三) 下午於 [OpenMoko] 的 [OpenLab] 發表了一場演說,時間是一個小時。這是一場有關 Linux 驅動程式的演講訓練活動,本次演講主要在解析 Linux 驅動程式的 read/write 程式碼框架(framework)與觀念解析。大綱如下: * read/write system call * vfs switch * user-space vs. kernel-space: I/O data * short discussion on wait queue: blocking I/O * cdata example 時間只有一個小時,因此在規劃簡報時,決定採取範例導向的方式做介紹。當天以一個 cdata 的範例做主軸,直接透過程式碼來做講解。在此提供簡報電子檔供參考 [linux-device-drivers-read-write]。...

Linux 2.6.22 新增 display class

jollen 發表於 December 29, 2007 8:22 PM

Linux 2.6.22 於 2007 年 7 月 8 日正式釋出,這個版本的 kernel 有一個令我感興趣的新功能。Linux 2.6.22 新增一個 class driver,稱為「display class」。顧名思義,這個新的 class driver 是用來管理與 "display" 有關 device driver。以下引用自 [include/linux/display.h]: 28 struct display_device; 29 30 /* This structure defines all the properties of a Display. */...

新的 Linux Wireless Stack 現身

jollen 發表於 December 29, 2007 11:14 PM

Linux 2.6.22 有一個重要的更新,就是改進了過去對於 wireless 支持的不足。一家叫做 [Devicespace] 的公司,為 open source 做了一項重要的貢獻,他們將一份新的 wireless stack 實作提交給 kernel,並正式收錄於 Linux 2.6.22。詳情可參考 kernelnewbies.org 上的說明 [New Wireless stack]。 Linux 在 wireless stack 上的功能並不是很充份,在 Devicespace 貢獻 kernel 更好的全新 wireless stack 實作後,對 Linux 在無線網路上的支援與應用,將是一個重要的進展。由 Devicespace 所提交的新一代 wireless stack 包含的實作有(引述...

Linux 驅動程式的 Semaphore 觀念小談

jollen 發表於 January 20, 2008 10:53 AM

這二天在進行 Linux 驅動程式的訓練,課程裡談論到 semaphore 可以用來宣告 critical section。在作業系統所述敘的 critical section 觀念中提及,critical section 具備互斥性(mutual exclusive)與單一性(atomic)。對單一性來講,我們必須確保在 critical section 裡不會發生任何的排程(scheduling)動作,wait queue 的使用就是一個例子。Linux kernel 提供的 wait queue 可以讓驅動程式在進行 I/O polling 時,以睡覺(sleep)方式進行,以讓出系統時間;若以 busy-loop 方式進行,是不正確的做法。 所以,sleep 的動作就不能寫在 critical section 裡面,必須先做一個釋放的動作,再呼叫 wait queue 的 API 做睡覺的動作,醒來後再進入 critical section。但是,事情並沒有這麼單純,若是驅動程式的架構設計,能支援多個...

Linux 驅動程式的中斷處理, #1: request_irq 基本觀念

jollen 發表於 March 1, 2008 11:58 PM

在Linux device driver 中,名為 “interrupt handler” 的 routine 負責處理(回應)實體的硬體中斷。當裝置中斷被觸發時,interrupt handler 便會執行,而 interrupt handler 就工作便是回應該中斷的請求(request)。 Interrupt handler 執行於 interrupt mode,並無 process context 資訊,因此,在 interrupt mode 下執行的執行碼需注意以下 3 點: 1. 由於沒有 process context 的關係,因此無法存取 user space。 2. 無法存取 current 巨集。current 巨集是一個指向自己的 kernel...

Linux 驅動程式的中斷處理, #2: 深入淺出中斷模式

jollen 發表於 March 2, 2008 10:09 PM

Interrupt handler 的工作是負責處理裝置的中斷請求,並將結果回報(feedback)給裝置。一般而言,裝置產生中斷時,都是與資料讀寫有關的請求。Interrupt handler 便要根據中斷的特性,來判斷此中斷是要請求驅動程式將資料寫入至裝置,或是由裝置讀取資料。 Linux 驅動程式的 interrupt handler 實作原則如下: 1. 在 interrupt handler 裡,叫醒真正負責此中斷的 task 後立即結束執行。 2. Interrupt handler 應儘量執行最少的程式碼。 3. Interrupt handler 若執行過久,會造成中斷的關閉時間過長,因此可能會遺失緊接著產生的中斷請求。 4. 若 interrupt handler 裡有過長的計算動作或執行過久的程式碼,則應使用 tasklet 或 task queue 將該段程式碼做排程,留待其它時間再執行。如此便可避免interrupt handler執行時間過久。 此外,在中斷模式下做同步控制時,還要考慮是否會佔用過久 CPU 時間的問題。為什麼中斷模式下寫 code...

Linux 驅動程式的中斷處理, #3: Bottom Half 的觀念

jollen 發表於 March 3, 2008 11:36 PM

為了能寫出很棒的 interrupt handle,Linux 採用一種稱為 bottom half 的觀念來實作 interrupt handler。 Linux 將完整的 interrupt handler 切成2個部份(half):top half 與 bottom half。Top half 是在呼叫 request_irq() 時所指定的 interrupt handler 函數,bottom half 則是由 top half 所排程(scheduling),真正負責回應中斷的 task。 一般來說,top half 的基本實作原則如下: 1. 儲存裝置相關資料,這個部份會涉及「中斷不同步」的議題,在這裡先不做解釋。 2. 將 bottom half...

Linux WiMAX Driver 實作現況分析

jollen 發表於 June 1, 2008 11:20 PM

前陣子接受 DigiTimes 的「手持行動裝置開發關鍵軟體技術發展」研討會邀請,當時就在思考要以什麼主題為主。一些題目大概都是老生常談了,而且又不想以介紹性的方式進行。想了又想,發現最近最當紅的主題非 WiMAX 莫屬,WiMAX 也是今年 Computex 展的主題,因此決定以 Intel 的 [Linux WiMAX development project] 專案做為討論標的。5 月 29 日這一天的演講就以「Linux WiMAX Driver 實作現況分析」定題了。 linuxmax.org 是 Intel 所支持的一個專案計畫,此計畫目前已釋出第一個 WiMAX device driver 以及 WiMAX stack。目前在 linuxwimax.org 上已能找到 Intel WiMAX Connection 2400m 的驅動程式,以及一個 WiMAX stack...

Process State 與 Wait Queue

jollen 發表於 July 17, 2008 11:52 PM

本週要繼續進行 Linux Device Driver 的教育訓練,正好上週有同學問到「process 狀態」的問題,原因是我們在講解範例時,提到 O'Reilly 的 Linux Device Driver 書上以「half sleep」來說明「手動變更 current 狀態」的做法,以及為何不直接呼叫 sleep_on() API 的原因。 當時只做了相當簡要的回答,同學也對 OS 書上講到的 process state 有些不了解。本週打算做比較深入的討論,結果發現我的 Linux Kernel 專欄休眠許久,「Process State」這個章節居然還沒有整理上來,因此在這裡補上這個部份,以免上課要講解時無料可用。 Process 的狀態(state)紀錄在 process descriptor 的 state 欄位。如果您對 process、fork(process creation)以及 preemptive 不熟悉的話,建議您先從頭依序閱讀「Linux Kernel...

可以開機就好:談作業系統的基礎訓練

jollen 發表於 July 24, 2008 3:50 PM

最近在和朋友在討論 Embedded Linux 課程的規劃事宜,希望可以歸納過去所收集的學員意見,以及就助教所提出的課堂問題,對現有課程做調整以及精進。二個星期前,和 thinker 以及 dennis 在聊課程時,興起了一個念頭,我們想要規劃一門「作業系統」的課程。 過去的教育訓練發現,有些學員對於作業系統的背景知識不足,也有些學員對於 Linux kernel 的原理很有興趣,更有些學員對如何寫一個 OS 感興趣,但,由於沒有系統化的文件提供這方面的資訊,因此,讓大家只能由片斷的文件(googling)自己拼湊相關知識,不但沒有效率,而且也經常徒勞無功。 我們想要做的「作業系統」課程,可不是把「恐龍書」搬出來教一教就行了,而是希望走「實務」路線,因此,thinker 提出了一個想法:教大家做一個「只能開機」的 OS。我跟 dennis 都覺得這是一個很不錯的構想,透過「建構式」教學,讓大家從無到有自己寫一個作業系統,這個作業系統也不需要很完整,只要能做到「可以開機」就好了。 昨天晚上,大家再次聚會,再討論了這個「boot only」的 OS。「從無到有自己寫」是一個不太可行的做法,畢竟訓練時數有限,況且「有現成的 Linux kernel」可以用,因此,「從 Linux kernel 剪貼程式碼來做一個新的 OS」是一個最具體可行的做法,也是大家的共識。 透過由 Linux kernel「copy-and-paste」程式碼,拼裝出一個 OS,是一件有意義的事情。雖然是一個拼裝的 OS,但是要讓它可以動,就要了解處理器架構,以及整個開機流程,而且也要知道「要讓一個 OS 可以開機,至少要實作什麼單元。」這是一件有趣的事,大家興趣都來了,一陣技術討論後,很快地,在不到一個小時內,我們就把主題都抓出來了。初步的構想如下。 要知道 Linux kernel 的開機流程,就要有一個學習環境,我們一致認為,透過 Qemu...

Linux 驅動程式的 I/O, #4: 什麼是 Blocking I/O

jollen 發表於 August 4, 2008 8:13 AM

在先前的專欄中,我們為大家介紹了「I/O」以及「interrupt handling」,接下來我們要將這二個部份合在一起,並討論幾個相當重要的觀念以及機制。首先,我們回到最早在介紹 Linux 驅動程式架構的部份,我們介紹到了 system call 以及 file operations 的觀念;接續 I/O 的部份,我們又提到 read/write system call。到這裡,我們就要融合貫通先前所介紹的重要觀念。請大家先將先前的專欄讀熟,再接續本系列專欄。 在 Linux 驅動程式的整個框架中,最重要,而且必須一開始就先了解的主題有二個: 1. Blocking I/O 的觀念。 2. Wait queue 以及 event-driven(event-polling)的觀念。 雖然這裡分成二個小主題,不過其實這是同樣的一個主題。這裡有很多值得提出討論的觀念,首先針對 Blocking I/O 的觀念進行深度探討。 什麼是 blocking I/O? 當 user process 透過 read/write system...

演講「加入 kernel 除蟲大隊:簡介 kernel debug 工具」簡報上線

jollen 發表於 September 14, 2008 8:00 PM

近期受邀發表了一場與「kernel debug」有關的演講,進行時間大約是70分鐘,在此提供簡報電子檔[加入 kernel 除蟲大隊]供有興趣的朋友下載。本次演講的目的是對 kernel debug 主題做「開場」,再加上時間有限,因此並沒有對 kernel debug 的技術做太深入的討論,反而是透過整理的方式,對幾個常見的 kernel debug 工具與方法做總覽。 演講最後展示了使用 gdb+qemu 來進行 kernel source-level debug 的方法。「加入 kernel 除蟲大隊」需要具備什麼樣的基本技能呢? 首先,主要的工具「GNU Debugger」當然是必學的主題,不過因為這次的主題是 kernel debug,因此只約略介紹 user-space 下幾個重要的除錯觀念: Breakpoint, single step, inspect variables 如何設定中斷點,進行單步執行,並在程式 run-time 時期檢視變數內容。 Segmentation fault 程式被訊號(signal)被中止時,怎麼找到不正常終止的程式碼。一個典型的 segmentation...

Linux 驅動程式的 scheduling 觀念, #1:

jollen 發表於 December 14, 2008 11:58 AM

本週進行「Linux Device Drivers: Jollen 的 10 堂課」教育訓練,發現有些同學對於作業系統的「排程(scheduling)」觀念仍有些疑問,因此,在課程中以三段小程式來說明「什麼是排程」,以協助同學建立紮實的排程觀念。 以下是一段正常的 open system call 實作: int card_open(struct inode *inode, struct file *filp) { return 0; } 當 process 開啟 device file 後,因為 kernel-space 的 open system call 實作會直接 return,因此 CPU 會切換至前景(foreground)、 process 繼續往下執行。...

Linux Input Device 介紹: APIs

jollen 發表於 April 8, 2009 12:18 PM

Linux 的 Input Device 是重要的一個 subsystem,在進行實例介紹前,先大略了解一下相關的 API。 Linux Input Device input.c是Linux的”input”驅動程式,主要支援鍵盤與滑鼠的輸入;input.c介面有趣的地方是採用了事件(event)的方式來處理輸入,以下是input.c介面重要的資料結構與函數: * struct input_dev * void input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) * void input_register_device(struct input_dev *); * void input_unregister_device(struct input_dev *); * void input_register_handler(struct...

Linux 2.6.30 釋出

jollen 發表於 June 16, 2009 10:56 AM

Linux 2.6.30於2009年6月9日釋出,Linux kernel的發展進入了Linux 2.6.3x的時代。最近一年的 Linux 2.6核心發展有相當重大的進展,除了幾個知名大廠不斷貢獻程式碼外,新產品的開發,也帶動Linux kernel的快速發展。 Linux 2.6.30加入了新的filesystem: 1. NILFS2 一種log-structured filesystem,由John K. Ousterhout與Fred Douglis於1988年提出的設計,主要針對high write throughput的應用。 2. POHMELFS (Parallel Optimized Host Message Exchange Layered File System) 一個分散式平行處理的檔案系統,在讀寫操作方面,根據[POHMELFS]官方的數據指出,POHMELFS的效能比NFS還好。 3. DST(Distributed STorage) 一個具高效能與可信賴的網路儲存檔案系統。 4. EXOFS(Object-Based Storage Devices) 支援OSD protocol的檔案系統。 5....

Android SystemServer 對 Linux 驅動程式程式碼風格的影響,一個簡單的概念

jollen 發表於 July 8, 2010 12:02 AM

今天為一家國際手機廠進行 Android 底層相關的內訓,課堂中提到一個概念,就是基於 Android 的 SystemServer 架構,可以藉由「架構面」改善過去 Linux 驅動程式在 Rentrant Code 議題面的程式碼模式。藉由模式的調整,可改善程式碼的效率。 過去,多個 Process 同時(Concurrency)存取同一份 Linux 驅動程式時,若驅動程式進行 Re-scheduling 操作,驅動程式的 Driver Method 就會重覆進入,因此需要考量做同步控制。 若是藉由 SystemServer 的架構,也就是「Single Process 存取驅動程式」,就能簡化重覆進入的議題。如下圖所示。 這是一個很簡單的模型,在 Middleware 層面,透過「限制應用程式的模式」來達到簡化重覆進入的議題。以 Android 作業系統為例,SystemServer 可以扮演這個「Single Process」的角色。當然,也可以設計成一個獨立的「My SystemServer」,根據對問題的分析來決定要修改 SystemServer,或是建立 My SystemServer。 對應用程式來說,只需要透過 IPC...

Top | 授權條款 | Jollen's Forum: Blog 評論、討論與搜尋
Copyright(c) 2006 www.jollen.org