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/即可

  • flash3.5:http://tablets-dev.nokia.com/maemo-dev-env-downloads.php
  • 0xFFFF:http://www.nopcode.org/0xFFFF/?p=home

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

重启后测试,测试过程略。

参考

  • http://elinux.org/N800
  • http://en.wikipedia.org/wiki/N800

你可能感兴趣的:(Nokia N800开发经验)