Thursday, August 28, 2008
第一個 cross compile 成功的 kernel module - hello
第一個 kernel module - hello
依 The Linux Kernel Module Programming Guide 文上所說的,編寫第一個kernel module
- hello.c
#include
/* Needed by all modules */
#include/* Needed for KERN_INFO */
#include/* Needed for the macros */
#define DRIVER_AUTHOR "Peter Jay Salzman"
#define DRIVER_DESC "A sample driver"
static int __init init_hello(void)
{
printk(KERN_INFO "Hello, world\n");
return 0;
}
static void __exit cleanup_hello(void)
{
printk(KERN_INFO "Goodbye, world\n");
}
module_init(init_hello);
module_exit(cleanup_hello);
MODULE_LICENSE("GPL");
MODULE_AUTHOR(DRIVER_AUTHOR); /* Who wrote this module? */
MODULE_DESCRIPTION(DRIVER_DESC); /* What does this module do */
MODULE_SUPPORTED_DEVICE("testdevice"); - Makefile
obj-m += hello.o
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
確定是可以在 X86 host 上成功編譯,運作也一切正常。
但問題來了,我該如何改寫 Makefile,使其能 cross compile 呢?
目前還不知道該如何解決,因為對 Makefile 及 cross compile 步驟還在粗淺的認識階段,以前也都是利用套件所提供的 configure 工具來代勞。
所以就想到將新增的 module 加到 kernel source 中,這樣就可以利用 kernel source 所提供 cross compile 的功能來幫我做相關設定了。
利用 kernel source 來 cross compile 新增的 module
- 環境設定
- Target Board 是 arm,所以在Makefile 裡: ARCH=arm, CROSS_COMPILE=arm-none-linux-gnueabi-
- 新增一個 module,在 driver 目錄下新增一個測試目錄 rayn,測試 module 位於 driver/ryan/hello.c。
- 編輯 configure 的選項
- 修改 arch/arm/Kconfig (因為我們的target 為 arm,所以必需改在 arch/arm 裡的 Kconfig 才有用)
- 加入這一行 source "drivers/ryan/Kconfig",將新增的測試目錄加到 configure 選項中
- 修改 drivers/{Kconfig,Makefile}
- Kconfig
- 新增 source "drivers/ryan/Kconfig"
- Makefile
- 新增 obj-$(CONFIG_RYAN_TEST) += ryan/
- Kconfig
- 新增目錄,driver/ryan 及所需的檔案
- Kconfig
menu "RYAN test devices"
config RYAN_TEST
bool "RYAN test"
config RYAN_TEST_HELLO
tristate "The first kernel module - hello"
depends on RYAN_TEST
endmenu - Makefile
obj-$(CONFIG_RYAN_TEST_HELLO) += hello.o
- hello.c
- Kconfig
- 修改 arch/arm/Kconfig (因為我們的target 為 arm,所以必需改在 arch/arm 裡的 Kconfig 才有用)
- make menuconfig,將 hello 編為 module。可以看見新增的選項
[*] RYAN test
The first kernel module - hello
- make modules。可以看見 hello.ko 已生成。
Building modules, stage 2.
MODPOST 4 modules
CC drivers/ryan/hello.mod.o
LD [M] drivers/ryan/hello.ko
CC fs/jffs2/jffs2.mod.o
LD [M] fs/jffs2/jffs2.ko
- 在 target 上測試
bash-3.2# insmod ./hello.ko
<6>Hello, world
Hello, world
bash-3.2# rm
rm rmdir rmmod
bash-3.2# rmmod hello
<6>Goodbye, world
Goodbye, world
完畢…
Wednesday, August 27, 2008
vi 命令速查
Friday, August 22, 2008
LFS (Linux From Scratch) 初體驗
LFS (Linux From Scratch) 初體驗
- Version: Linux From Scratch 6.3 Ref
- 嚐試 LFS 是因為想要了解如何從頭建置一個基本的 Linux 系統,用最精簡的系統來幫助自己對 linux 初始流程的了解。在整個過程中,自己的閱讀方式是不求甚解,就像看本小說似的將它做一次,了解大致上的流程而已。雖然如此,我覺得在對於整個系統的初始流 程的了解(最基本的必要存在)還是很有幫助的。
- 我嚐試了到了第三次才成功,我猜前二次的失敗應該是因為某次的指令不完整 or something 才會導致到 build packages 就失敗了,所以第三次時我用 LFS 提供的 LiveCD,並在每次都用 cpoy 的方式來執行指令,以降低失誤的機會 (startx 啟動 X-window)。
- 大部份的時間都花在 build package 上(ch5/ch6),尤其是 GCC/Glibc 上,這部份可以了解幾個重要套件之間的關係、順序、其包含了那些工作。之前失敗在此時,真的不知該如何找出那個環節出錯,所以只好重做了 -_-。
- 其實在這二個章節裡面,內容不多但很基本,主要在述敘開機的過程,會參考那些設定檔,device 是如何產生並掛載的等等…,對之後需要更進一步了解時應該還蠻俱參考價值的。
- ch7. Setting Up System Bootscripts
- ch8. Making the LFS System Bootable
Wednesday, August 20, 2008
MTD study
partition assigning & tools of MTD
Target
- Assigning MTD partition
- from kernel source
- from u-boot
- 以 jffs2 格式,掛載 mtd device (Nand Flash)
- Cross Compiling mtd-utils for arm
- Modify ramdisk by cpio
- mtd-utils test
Assigning MTD partition
- References: Linux Command Line - mtdparts
- from kernel source
- 預設會讀取 kernel soruce 裡的定義,在此為 arch/arm/mach-omap2/board-2430sdp-flash.c
- 修改 mtd_partition nand_partitions 以符合所需
static struct mtd_partition nand_partitions[] = {
{
.name = "XLDR",
.offset = 0,
.size = 8*(32*512), /* 128 KB */
.mask_flags = MTD_WRITEABLE /* force read-only */
},
{
.name = "UBOOT",
.offset = MTDPART_OFS_APPEND,
.size = 16*(32*512), /* 256 KB */
.mask_flags = MTD_WRITEABLE /* force read-only */
},
{
.name = "uKernel",
.offset = MTDPART_OFS_APPEND,
.size = 1408*1024,
},
{
.name = "uRamdisk",
.offset = MTDPART_OFS_APPEND,
.size = 3*1024*1024, /* 3 MB */
},
{
.name = "UnUsed",
.offset = MTDPART_OFS_APPEND,
.size = MTDPART_SIZ_FULL,
},
};
- from u-boot
- 確定 kernel source configure 中有開啟 CONFIG_MTD_CMDLINE_PARTS
- 確定 u-boot source 中 CONFIG_BOOTCOMMAND 設定正確。(include/configs/omap2430sdp.h)
#define CONFIG_BOOTCOMMAND "nand read 80F00000 60000 160000;
nand read 84000000 1C0000 300000;bootm 80F00000 84000000"- 將 image 從 flash_address=60000 搬到 ram_address=80F00000, size=160000
- 0x160000 = 1408K (uKerkel)
- 將 image 從 flash_address=1C0000 搬到 ram_address=84000000 , size=300000
- 0x300000 = 3M (uRamdisk)
- bootm: boot application image from memory
- 將 image 從 flash_address=60000 搬到 ram_address=80F00000, size=160000
- mtd 的 name 必需與 kernel source 中定義的名字一樣,才會有效。
- kernel source, arch/arm/mach-omap2/board-2430sdp-flash.c
static struct platform_device sdp_nand_device = {
.name = "omap2-nand",
.id = -1,
.dev = {
.platform_data = &sdp_nand_data,
},
}; - 確定 u-boot source CONFIG_BOOTARGS 設定正確。 u-boot source, include/configs/omap2430sdp.h
#define CONFIG_BOOTARGS "root=/dev/ram0 console=ttyS2,115200n8
mtdparts=omap2-nand:128K(XLoad),256K(UBoot),1408K(uKernel),3M(uRamdisk),-(unused)"
- kernel source, arch/arm/mach-omap2/board-2430sdp-flash.c
- 確定 mtd partition 是否正確
- cat /proc/mtd
- demsg
Mount mtd device (NAND Flash) with jffs2
- 確定 kernel 中的 CONFIG_JFFS2_FS=y 有選取,否則會造成無法掛載,Errmsg: No Such Device
mount -t jffs2 /dev/mtdblock3 /mnt
Cross Compiling mtd-utils for arm
- cross compile mtd-utils 需要二個套件,zlib & lzo
- zlib是提供資料壓縮之用的函式庫
- LZO is a portable lossless data compression library written in ANSI C.
- MTD Utilities
- Cross compile zlib
wget http://www.zlib.net/zlib-1.2.3.tar.gz
tar xzvf zlib-1.2.3.tar.gz
cd zlib-1.2.3
CC=arm-none-linux-gnueabi-gcc LDSHARED="arm-linux-ld -shared" ./configure --shared
make
make prefix=/home/ryan/armlinux/zlib install
- Cross compile lzo
wget http://www.oberhumer.com/opensource/lzo/download/lzo-2.03.tar.gz
tar xzvf lzo-2.03.tar.gz
cd lzo-2.03
CC=arm-none-linux-gnueabi-gcc ./configure --host=arm-linux --prefix=/home/ryan/armlinux/lzo
make
make install
- Cross compile mtd-utils
# apt-get install git-core
git clone git://git.infradead.org/mtd-utils.git
cd mtd-utils
vi Makefile
make WITHOUT_XATTR=1- 必需修改 Makefile
ryan@ryan-ubuntu8:~/git$ diff mtd-utils/Makefile mtd-utils.git/Makefile -u
--- mtd-utils/Makefile 2008-08-06 15:05:03.000000000 +0800
+++ mtd-utils.git/Makefile 2008-08-06 15:06:53.000000000 +0800
@@ -6,8 +6,14 @@
SBINDIR=$(EXEC_PREFIX)/sbin
MANDIR=$(PREFIX)/share/man
INCLUDEDIR=$(PREFIX)/include
+ZLIBCPPFLAGS=-I/home/ryan/armlinux/zlib/include
+LZOCPPFLAGS=-I/home/ryan/armlinux/lzo/include
+ZLIBLDFLAGS=-L/home/ryan/armlinux/zlib/lib
+LZOLDFLAGS=-L/home/ryan/armlinux/lzo/lib
-#CROSS=arm-linux-
+CROSS=arm-none-linux-gnueabi-
CC := $(CROSS)gcc
CFLAGS ?= -O2 -g
CFLAGS += -Wall
@@ -47,7 +53,7 @@
.SUFFIXES:
all: $(TARGETS)
- make -C $(BUILDDIR)/ubi-utils
+ make -C ubi-utils
IGNORE=${wildcard $(BUILDDIR)/.*.c.dep}
-include ${IGNORE}- ZLIBCPPFLAGS, LZOCPPFLAGS, ZLIBLDFLAGS, LZOLDFLAGS 是用來指定所需的 zlib/lzo 的 include/lib 在何處,所以在cross compile時需要由我們自行指定
- make WITHOUT_XATTR=1,make command to compile without Posix ACL。若無指定時會出現以下錯誤時 Ref
> mips-linux-cc -I./include -g -O3 -G0 -pipe -fpic -fPIC -msoft-float
> -mabi=32 -march=mips32r2 -mtune=34kc -g -c -o mkfs.jffs2.o mkfs.jffs2.c
> -g -Wp,-MD,./.mkfs.jffs2.c.dep
> mkfs.jffs2.c:69:21: sys/acl.h: No such file or directory
> mkfs.jffs2.c: In function `formalize_posix_acl':
> mkfs.jffs2.c:1084: error: `ACL_USER_OBJ' undeclared (first use in this
.....
- 必需修改 Makefile
Modify ramdisk by cpio
- 解壓縮
mkdir ramdisk
cd ramdisk
cpio -i -F ../ramdisk.cpio
- 打包
find ./ -print | cpio -ivH newc -O ../ramdisk.cpio
- 當 ramdisk size 有更改,需要調整 size 時,有幾處需要更改 (kernel, uboot, ReadyImageForOST.bat),在此假設 ramdisk 調整為4M
- u-boot/include/configs/omap2430sdp.h
#define CFG_NAND_BOOT
-#define CONFIG_BOOTCOMMAND "nand read 80F00000 60000 160000;
nand read 84000000 1C0000 300000;bootm 80F00000 84000000"
+#define CONFIG_BOOTCOMMAND "nand read 80F00000 60000 160000;
nand read 84000000 1C0000 400000;bootm 80F00000 84000000"
//#define CFG_NO_FLASH I like to add this one but...
//#define CFG_NAND_LEGACY
//#define CFG_ENV_IS_IN_NAND
@@ -160,7 +160,7 @@ - 注意kernel 裡定義 mtd partition 的地方 或 u-boot CONFIG_BOOTARGS 要改,不然操作時會出現未知的錯誤(ex: erase/write/read 錯地方,因為 partition 配置錯誤)
- u-boot/include/configs/omap2430sdp.h
mtd-utils test
- 確認所規劃的 mtd 是否正常, Ref
bash-3.2# cat /proc/mtd
dev: size erasesize name
mtd0: 00020000 00020000 "XLDR"
mtd1: 00040000 00020000 "UBOOT"
mtd2: 00160000 00020000 "uKernel"
mtd3: 00400000 00020000 "uRamdisk"
mtd4: 00040000 00020000 "Test1"
mtd5: 00100000 00020000 "Test2"
mtd6: 0f900000 00020000 "UnUsed"#mtd_debug info /dev/mtdX (不能使用mtdblockX, mtdblockX 只是提供用來 mount 而已)
bash-3.2# mtd_debug info /dev/mtd5
<6>MTD_open
MTD_open
<6>MTD_ioctl
MTD_ioctl
<6>MTD_ioctl
MTD_ioctl
mtd.type = MTD_NANDFLASH<6>MTD_close
MTD_close
mtd.flags = MTD_CAP_NANDFLASH
mtd.size = 1048576 (1M)
mtd.erasesize = 131072 (128K)
mtd.writesize = 2048 (2K)
mtd.oobsize = 64
regions = 0
- 將 /dev/mtd5 裡的資料以 HEX 方式 dump 出來看
nand_dump -p -f /tmp/mtd3 /dev/mtd3
less /tmp/mtd5
- erase 完後,再 dump 出來看看,會發現 erase 的部份,數值均為 ff
flash_erase /dev/mtd5
- flashcp,若有出現 Attempt to write not page aligned data 的訊息,表示不按頁對齊的方式是不被允許的 (在此是指 2K)。我們可以以下列來操作,將寫滿了 0 的 2k 檔案寫入 flash 就ok了。
dd if=/dev/zero of=/tmp/zero.img bs=1k count=2
flashcp /tmp/zero.img /dev/mtd5
#會發現寫入成功,此時可以 nanddump 出來看看,發現其值全為0
Linux 2.6 的 initramfs 機制
Linux 2.6 的 initramfs 機制
References
- Jserv's blog: 深入理解 Linux 2.6 的 initramfs 機制 (上)
- Poorman 的雜記:initramfs 簡介,一個新的 initial RAM disks 的模型
- Introducing initramfs, a new model for initial RAM disks
- Jollen 的 Blog: 簡易的 initramfs 製作方式
之前在做 qemu 做測試,在製作 ramdisk 時,就不是很了解為何有時是用
- 以 dd 制作一固定大小的 size, formate 為 ext2 格式
- 以 cpio 制作,再以 gzip 壓縮
透過這幾篇文章,可以了解何其間的差異, initrd v.s. initramfs
- 其使用的技術不同,歷史的演進
- 在開機過程中所佔的角色
- 如何製作 initramfs 及測試
Tuesday, August 19, 2008
安裝 Apache/Subversion/Trac on Windows
安裝 Apache/Subversion/Trac on Windows
主要參考:
- 軟體安裝: http://blog.roodo.com/jaceju/archives/2703934.html
- Svn 使用: http://plog.longwin.com.tw/my_note-programming/2007/07/10/svn_tutorial_2007
軟體持續在更新,所以所需的版本及套件依需求會有不同。以下為此次安裝過程中的軟體
- apache_2.0.63-win32-x86-no_ssl.msi Ref
- python-2.5.2.msi Ref
- svn-win32-1.5.1.zip Ref
- Trac-0.11.1.win32.exe Ref
- svn-python-1.5.1.win32-py2.5.exe Ref
- setuptools-0.6c7.win32-py2.5.exe Ref
- Genshi-0.5.win32-py2.5.exe Ref
目錄架構,參考 Ref
S:
|
|- AppServ (伺服器相關程式)
| |
| |- Apache2 ( Apache 的主要程式檔)
| |
| |- python ( Python 的主要程式檔)
| |
| |- svn ( Subversion 的主要程式檔)
|
|- Repository (檔案庫)
| |
| |- svn
| |
| |- trac
安裝/設定
- apache_2.0.63-win32-x86-no_ssl.msi
- Install to 改到 D:\AppServ ,這樣下方 Apache Runtime 的 Install to 會自動變成 S:\AppServ\Apache2 。
- 我使用預設的 port:80
- 測試是否可看見網頁 http://localhost
- svn-win32-1.5.1.zip
- decompress the file to AppServ and rename to svn
- copy mod_authz_svn.so and mod_dav_svn.so from svn/bin to AppServ\Apache2\modules
- 將 S:\AppServ\svn\bin 加到 PATH 系統環境變數裡。
- python-2.5.2.msi
- Install to S:\AppServ\python
- 安裝好後,將 S:\AppServ\python 加入 PATH 系統環境變數裡
- 以下這幾個執行檔會自動在 Python 的安裝目錄中註冊該模組
- Install svn-python-1.5.1.win32-py2.5.exe
- Install Trac-0.11.1.win32.exe
- setuptools-0.6c7.win32-py2.5.exe
- Genshi-0.5.win32-py2.5.exe
- mod_python-3.3.1.win32-py2.5-Apache2.0.exe
- 需要指定 Apache2的安裝位址 S:\AppServ\Apache2,這時安裝程式會把 mod_python.so 複製到 S:\AppServ\Apache2\modules 底下。
- Apache 設定,請參照 http://blog.roodo.com/jaceju/archives/2703934.html
- Svn/Trac project 設定,請參照 http://blog.roodo.com/jaceju/archives/2703935.html
- 我目前並未使用任何 plugin
- 建立 svn 檔案庫
S:\>cd Repository\svn
S:\Repository\svn>svnadmin create projectname - 建立 trac 檔案庫
S:\Appserv\python\Scripts>trac-admin.exe S:\
Repository\trac\projectname initenv
- 設定預設使用者
S:\Appserv\python\Scripts>trac-admin.exe S:\
Repository\trac\projectname permission add admin
TRAC_ADMIN
使用
- Trac
- 確認 http://localhost/trac 是否會列出所有的 trac projects
- 登入帳號並做修改
- Svn, Ref
- 取出專案 (此專案必需在 Serv 已建置好了)
svn co http://10.2.7.65/svn/test
- 新增單個 檔案/資料夾
cd test
mkdir tmpDir
svn add tmpDir
svn ci -m 'message' tmpDir - 新增一整個資料夾的內容
mkdir -pv a/aa/{a1,a2}
mkdir -pv a/bb/{b1,b2}
svn import a http://10.2.7.65/svn/test/a - svn 做壞了,不想要,重建一個時,需要 resync trac with svn
- s:\>cd Repository\svn
- s:\Repository\svn>rm -rf projectname
- s:\Repository\svn>svnadmin create projectname
- # 若 svn project name 不同了,需要修改 S:\Repository\trac\zeppelin\conf\trac.ini -> [trac] -> repository_dir = s:\Repository\svn\projectname
S:\AppServ\python\Scripts>trac-admin.exe S:\Repository\trac\projectname resync
- 取出專案 (此專案必需在 Serv 已建置好了)
其它
- 圖片(header_logo)無法正常顯示: please configure the [header_logo] section in trac.ini
- assigning 一張預設的圖給 header_logo: source
- S:\Repository\trac\zeppelin\conf\trac.ini -> [header_logo] -> src = trac_banner.png
- trac_banner.png in S:\AppServ\python\Lib\site-packages\trac\htdocs