Nokia N800開發經驗

原文出處:劉建文 | 學術半·IT歌·文(http://arttech.us)

 

我是一位理論帝,想問題做事情更多的會從形而上的角度入手。這個結論的證據之一,是從我研究學習嵌入式Linux近一年後才決定購一臺掌上電腦做實驗。年初的時候就有朋友建議我購一塊開發板,通過做實驗快速掌握開發技術。但我並不以爲然,首先,我認爲基本功更重要,開發技術可短期內習得;什麼是基本功,對內核結構的深度把握,對硬件的透徹理解;其次,我想我花三五百購塊開發板做完後還有什麼用?前一個想法的結果是十月底我才購一臺機器做實驗,後一想法的結果是我購的是諾基亞的n800,而不一次性的祼機板。

到目前爲止我在n800上做了兩個簡單的實驗,本文記錄實驗全程,不求同和,但求錄之以照後來人。

第一個實驗交叉編譯一個hello模塊到n800上,驗證開發環境和開發硬件等的可用性;第二個實驗是定製一個新內核到n800上,新內核中觸摸屏和小鍵盤以模塊形式加載,而非默認的內置。

Nokia N800 設備元信息

  • OMAP2420 microprocessor with a native speed of 400 MHz
  • Memory : 128 MiB of RAM and 256 MiB of flash memory
  • Connectivity : IEEE 802.11 b/g, Bluetooth 2.0 (DUN, OPP, FTP, HFP, HID profiles as well as A2DP/AVRCP and PAN via third party emulation), and USB 2.0 OTG high-speed.
  • Display & resolution: pressure-sensitive resistive touch-screen LCD 4.1 inches 800×480 at 225 dpi
  • Expansion : 2 full-sized Secure Digital card slots
  • Camera : built-in pop-up rotating webcam.
  • Audio : microphone, stereo speakers, FM radio tuner, 3.5-mm headphone jack (compatible with standard stereo headphones, but also containing a fourth pin with microphone input).

主要設備芯片(控制器)型號

  • OMAP2420 N8x0 System-on-chip
  • TMS320 C55x N8x0 DSP
  • OMAP video N8x0 Video output
  • PowerVR MBX N8x0 OpenGL ES and OpenVG acceleration
  • OMAP Boot Tags N8x0 Provides boot information from bootloader (NOLO)
  • OMAP MMC N8x0 SD/MMC cards
  • tcm825x N8x0 Webcam + i2c bus
  • tea5761 N800 FM radio
  • blizzard N8x0 LCD controller
  • menelaus N8x0 GPIO extender + i2c bus + ???
  • tmp105 N8x0 Temperature sensor (menelaus GPIO)
  • McSPI N8x0 SPI bus
  • Sharp LS041Y3 N8x0 LCD panel (compatible with MIPID)
  • cx3110x / stlc4550 N8x0 802.11b/g WiFi
  • tsc2301 N800 Touchscreen + Keypad + GPIO + Audio
  • OneNAND N8x0 Flash memory
  • TUSB6010 N8x0 USB

開發過程

  • 搭建開發環境
    • 定義項目佈局
    • 搭建交叉編譯開發環境
    • 通過USB互聯n800和開發PC
  • 實驗一——hello測試模塊
  • 實驗二——定製模塊化內核
    • 編譯內核及驅動模塊
    • 修改initramfs
    • 燒製

搭建開發環境

定義項目佈局

  • 項目主目錄:~/n800
  • kernel src:~/n800/maemo/kernel-source-diablo/kernel-source
  • 交叉編譯工具鏈:~/n800/cross-tools
  • 輔助構建工具:~/n800/build-tools
  • 測試項目:~/n800/projects/hello_module | modulize_kernel

搭建交叉編譯開發環境

1. 下載maemo4.1源碼和補丁 :http://repository.maemo.org/pool/maemo4.1.2/free/k/kernel-source-diablo/

2. 解包並進補:

$ patch -p2 < kernel-source-diablo_2.6.21-200842maemo1.diff

3. 安裝pre-build交叉編譯工具鏈 :http://www.codesourcery.com/sgpp/lite/arm/releases/2005q3-2

這是一個商業免費版預編譯工具鏈,直接解壓到~/n800/cross-toolchain/下即可

4. 添加shell搜索路徑

$ export PATH=~/n800/cross-toolchain/bin:$PATH

5. 測試源碼樹與交叉編譯工具鏈的可用性

$cd ~/n800/maemo/kernel-source-diablo/kernel-source
$cp arch/arm/configs/nokia_2420_defconfig .confg
$make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- bzImage

此官方源碼竟然有一個符號聲明丟失:scripts/mod/sumversion.c PATH_MAX undeclared
修復辦法:modifying linux-2.6.x/scripts/mod/sumversion.c, and adding #include <limits.h> fixes this issue.

成功編譯內核後證明交叉編譯工具鏈和源碼樹可用。編譯源碼樹一遍爲編譯外部模塊作準備(也可以通過執行kbuild接口 make modules_prepare) ,因爲編譯外部模塊會對內核的一些信息有依賴,像內核輸出符號(Module.symvers)。詳見內核文檔Document/kbuild/modules.txt

--- 2.4 Preparing the kernel tree for module build

To make sure the kernel contains the information required to build external modules the target 'modules_prepare' must be used. 'modules_prepare' exists solely as a simple way to prepare a kernel source tree for building external modules. Note: modules_prepare will not build Module.symvers even if CONFIG_MODVERSIONS is set. Therefore a full kernel build needs to be executed to make module versioning work.

 

通過USB互聯n800和開發PC(我用的是fedora 13)

fedora 一端

1.enable USB networking support in the kernel.

# # USB Network Adapters #
CONFIG_USB_USBNET=m
CONFIG_USB_NET_CDCETHER=m

2.安裝usbnet模塊

Linux-PC: $ modprobe usbnet

3.配置usb網絡接口

通過ifup的配置文件(/etc/sysconfig/network-scripts/ifcfg-usb0)實現:

DEVICE=usb0
BOOTPROTO=static
IPADDR=192.168.2.14
# IPADDR=10.0.1.2/24 should imply this ...
# but its support code seems to be buggy.
BROADCAST=192.168.2.255
NETMASK=255.255.255.0
NETWORK=192.168.2.0
# this is likely to break sometime
GATEWAY=192.168.2.1
ONBOOT=yes

4.啓用網絡接口

Linux-PC: $ ifup usb0

n800一端

1.取得root權限並安裝ether_over_usb模塊(g_ether.ko):

取得root權限的方法有兩種,第一,開啓機器的R&D模式,使用gainroot;第二種這是安裝rootsh包,直接用root命令最得權限:

Nokia-N800: $ id uid=29999(user) gid=29999 (users)
#if use r&d mode
Nokia-N800: $ sudo /usr/sbin/gainroot
#or use rootsh
Nokia-N800: $ root
Nokia-N800: # insmod /mnt/initfs/lib/modules/2.6.18-omap1/g_ether.ko

2.啓用網絡接口

Nokia-N800: # ifup usb0

3.測試連通性

Nokia-N800: # ping 192.168.2.14

如果不通,再插拔一下USB線

使用ssh登陸

Linux-PC $ssh -l root 192.168.2.15
pw:111111 (此密碼在安裝OpenSSH時設置)

傳送文件 Linux-PC $ scp ~/n800/projects/modulize_kernel/tsc2301_kp.ko [email protected]:

實驗一——hello測試模塊

1. 編寫源文件hello_mod.c

01 


/* hello_mod.c */


02

#include <linux/init.h>


03

#include <linux/module.h>


04

#include <linux/kernel.h>


05


06

static int

hello_init

(

void

)


07

{


08

printk

(

KERN_ALERT "Hello, world

/n

"

);


09

return

0

;


10

}


11


12

static void

hello_exit

(

void

)


13

{


14

printk

(

KERN_ALERT "Goodbye, cruel world

/n

"

);


15

}


16


17

module_init

(

hello_init);


18

module_exit

(

hello_exit);


19

MODULE_LICENSE

(

"GPL"

);


 

2. 編寫kbuild Makefile

01 


# Makefile for the hello module


02

obj-m :=

hello_mod.o
03

KDIR :=

~/

n800/

maemo/

kernel-source-diablo/

kernel-source
04

PWD := $(

shell

pwd)


05

default:


06

$(

MAKE) -

C $(

KDIR)

M=$(

PWD)

modules

 

3. 編譯

$ cd ~/n800/projects/hello_module
$ export PATH=~/n800/cross-toolchain/bin:$PATH
$ make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi-

4.測試把編譯得到的hello_mod.ko 通過ssh下載到n800進行測試,過程略。

實驗二——定製模塊化內核

編譯內核及驅動模塊

1. 配置內核

配置任務是把小鍵盤和觸摸屏的驅動改爲模塊,官方內核是build-in 的。

$ cd ~/n800/maemo/kernel-source-diablo/kernel-source
$ cp arch/arm/configs/nokia_2420_defconfig .config
# 配置文件庫(arch/arm/configs)還有一個n800_defconfig,此配置不適合OS2008
$ make menuconfig

2. 配置項如下,可以在配置程序內查找其所在位置,配置過程略

CONFIG_KEYBOARD_TSC2301=m
CONFIG_TOUCHSCREEN_TSC2301=m

3. 檢查配置結果:

$ cat .config | grep TSC2301
CONFIG_KEYBOARD_TSC2301=m
CONFIG_TOUCHSCREEN_TSC2301=m
CONFIG_SPI_TSC2301=y
CONFIG_SPI_TSC2301_AUDIO=y

4. 編譯內核

$ export PATH=~/n800/cross-toolchain/bin:$PATH
$ export ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi-
$ make zImage
$ cp arch/arm/boot/zImage ~/n800/projects/modulize_kernel

5. 編譯模塊

$ INSTALL_MOD_PATH=~/n800/projects/modulize_kernel
$ make modules
$ make modules_install

修改initramfs

initramfs是kernel 的[前根文件系統]引導功能(他們用了一個新概念叫early-userspace)的2.6版新實現,前2.6版的是衆所周知的initrd。 initramfs不再是核外的一個虛擬盤,而是核內的內存根文件系統一個鏡像,filesystem是使用緩存機制實現的tempfs。簡單的理解是,initramfs是正在內存中運行的內核的根文件系統被轉存(object dump)到磁盤上的映像。爲了實現更好靈活性,新版內核的[前根文件系統]還是提供了[核內核外]配置的方式。核外配置的表象與initrd很像,但是完全不同的概念,內核使用完全不同的代碼解讀前根文件系統,initramfs只是一個cpio檔,被bootloader調入內存後,內核會自動識別,進行鏈接。

1. 下載固件( http://tablets-dev.nokia.com/nokia_N800.php )並解包至 ~/n800/firmware

2. 下載並安裝官方的擦寫程序flash3.5(這裏也可以使用一個開源的擦寫程序0xFFFF)直接解壓到~/n800/build-tools/flasher/即可

3. 解包固件至./firmware/43-7-fiasco

$ cd ~/n800/firmware
$ mkdir 43-7-fiasco;cd 43-7-fiasco
$ ~n800/build-tools/flasher-3.5 -F ~/n800/firmware/RX-34_DIABLO_5.2008.43-7_PR_COMBINED_MR0_ARM.bin -u

4. initramfs.jffs2 是jffs2鏡像,先作成虛擬盤

$ mknod /tmp/mtdblock0 b 31 0
$ mkdir /mnt/initfs
$ modprobe loop
$ losetup /dev/loop0 ~/n800/firmware/43-7-fiasco/initfs-0.95.22-200842maemo1w38b3
$ modprobe mtdblock
$ modprobe block2mtd
# Note the ,128KiB is needed (on 2.6.26 at least) to set the eraseblock size.
$ echo "/dev/loop0,128KiB" > /sys/module/block2mtd/parameters/block2mtd
$ modprobe jffs2
$ mount -t jffs2 /tmp/mtdblock0 /mnt/initfs/

5. 虛擬盤不能直接修改,必須拷出來,修改後再用MTD tool(mkfs.jffs2)重製作initramfs 鏡像

$ mkdir /mnt/tmp/initramfs
$ cp -a /mnt/initfs/ /mnt/tmp/initramfs

6. 拷貝驅動模塊並修改啓動腳本linuxrc

$ cp ~/n800/projects/modulize_kernel/tsc2301_kp.ko /mnt/tmp/initramfs/lib/modules/omapXXX/
$ cp ~/n800/projects/modulize_kernel/tsc2301_ts.ko /mnt/tmp/initramfs/lib/modules/omapXXX/
$ echo "insmod $MODULE_PATH/tsc2301_kp.ko" >> /mnt/tmp/initramfs/linuxrc
$ echo "insmod $MODULE_PATH/tsc2301_kp.ko" >> /mnt/tmp/initramfs/linuxrc

7. 重製作initramfs 鏡像(http://sources.redhat.com/jffs2/ )

$ mkfs.jffs2 -n -r /mnt/tmp/initramfs -e 20000 -o rootfs.jffs2

P.S. 事後發現原來可以直接在n800的maemo上修改,要修改,得行把initramfs閃存分區重掛接爲可讀寫:

Nokia-N800: # mount -o remount,rw /dev/mtdblock3 /mnt/initramfs

燒製

$ cd ~/n800/build-tools/
$ flash3.5 -k ~/n800/projects/modulize_kernel/zImage -f

#提示接入n800,把n800接好USB線,按住HOME鍵再開機

$ flash3.5 -n ~/n800/projects/modulize_kernel/initramfs.jffs2 -f -R

重啓後測試,測試過程略。

參考

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章