2011-01-20

Embedded Linux from Scratch on VMWare: (3) 反思\过程改进

前面build\安装busybox时, 我手工把busybox所需的动态库拷贝到target上. 这样很不好, 容易出错\遗漏

1: uclibc
=========

更合适的做法是: 自己build uclibc, 利用 uclibc 提供的 make install_runtime 将所需的运行时库安装到合适的地方

借用buildroot 的 uclibc 配置文件
v4@elws:~/toy$ tar xjvf buildroot-2010.11/dl/uClibc-0.9.31.tar.bz2
v4@elws:~/toy$ cd uClibc-0.9.31/
v4@elws:~/toy/uClibc-0.9.31$ cp ../buildroot-2010.11/toolchain/uClibc/uClibc-0.9.31.config ./.config
v4@elws:~/toy/uClibc-0.9.31$ make oldconfig
v4@elws:~/toy/uClibc-0.9.31$ make menuconfig
Library Installation Options 下面的几个路径已经是标准的了:
-> Library Installation Options
(/) uClibc runtime library directory
(/usr/) uClibc development environment directory
(lib) library path component
[*] Hardwire absolute paths into linker scripts
uClibc development/debugging options 下面定义交叉工具prefix, 这里通过CFLAGS给它指定sysroot:
-> uClibc development/debugging options
(/home/v4/toy/buildroot-2010.11/output/staging/usr/bin/i686-unknown-linux-uclibc-) Cross-compiling toolchain
(--sysroot=/home/v4/toy/buildroot-2010.11/output/staging/) Enter any extra CFLAGS to use to build uClibc
注意只需要安装运行时(runtime)库:
v4@elws:~/toy/uClibc-0.9.31$ make
(下面以root执行!)
elws:/home/v4/toy/uClibc-0.9.31# make PREFIX=/mnt/toy/ install_runtime
2: busybox
===========

busybox 默认安装到了源码目录下的_install, 但安装目录也可以指定:
elws:/home/v4/toy/busybox-1.18.1# make CONFIG_PREFIX=/mnt/toy/ install
3: rootfs
==========

将target磁盘mount到host, 软件直接安装到上面, 这样做没有问题, 如果可以做到的话, 还是最方便的做法. 但实际开发嵌入式系统时, 可能就没法将target存储设备(如flash)mount到host了, "专业"的做法是在host上制作rootfs, 然后将rootfs"烧录"到target

对我们的磁盘+ext3文件系统, 可以这样创建一个rootfs:
elws:/home/v4/toy# dd if=/dev/sdd1 of=./rootfs.ext3
elws:/home/v4/toy# mkdir rootfs
elws:/home/v4/toy# mount -o loop rootfs.ext3 rootfs/
接下来所有对rootfs/目录的修改都直接反应到了rootfs.ext3 image文件中. 弄好了将image写到磁盘中就是一个反向的过程:
elws:/home/v4/toy# dd if=./rootfs.ext3 of=/dev/sdd1
对flash+jffs2, 基本原理相同, 只是将在host上的dd过程, 改为在target上利用bootloader提供的image烧写, 或者处理器提供的其他方式(如: 通过usb启动\下载image)

4: cross toolchain
===================

buildroot 生成的toolchain(output/staging)已经包含了uclibc C开发库\头文件\linux头文件, 是一个完整的c交叉编译开发环境. 但是, 开发一个应用时, 除了c以外, 还需要依赖另外一个库, 我们可以把这个库安装到target上, 或者安装在toolchain里面, 但是这样可能带来一个问题, 当我们需要重新build buildroot时, toolchain被覆盖了, 我们之前自己安装的库就丢失了

buildroot其实可以生成一个完整的<此处谬误!---->chroot环境, 包含了toolchain以外, 还有shell(busybox)\make\.... <----!!!>但是, 我认为buildroot不够稳健, 所以尽量少地依赖它. 但是, 我们可以在buildroot生成的toolchain基础之上(逐渐)增加自己的开发库\头文件. shell\make 等工具, 可以利用host上的, 不是一定必要在chroot环境下进行交叉编译

先把buildroot的toolchain拷贝出来, 重命名为toolchain
v4@elws:~/toy$ cp -fr buildroot-2010.11/output/staging ./toolchain
参照上面uclibc的部分, 在toolchain内重新安装uclibc, 但是需要修改一下交叉工具的路径为我们自己的toolchain
v4@elws:~/toy$ cd uClibc-0.9.31/
v4@elws:~/toy/uClibc-0.9.31$ make menuconfig
-> uClibc development/debugging options
-> Cross-compiling toolchain prefix
修改为: /home/v4/toy/toolchain/usr/bin/i686-unknown-linux-uclibc-
-> Enter any extra CFLAGS to use to build uClibc
修改为: --sysroot=/home/v4/toy/toolchain/
v4@elws:~/toy/uClibc-0.9.31$ make
v4@elws:~/toy/uClibc-0.9.31$ make PREFIX=$HOME/toy/toolchain/ install
将kernel 头文件也重新安装一下(无害)
v4@elws:~/toy/uClibc-0.9.31$ cd ../linux-2.6.36.1/
v4@elws:~/toy/linux-2.6.36.1$ make ARCH=x86 CROSS_COMPILE=$HOME/toy/toolchain/usr/bin/i686-linux-
v4@elws:~/toy/linux-2.6.36.1$ make INSTALL_HDR_PATH=$HOME/toy/toolchain/usr headers_install

2011-01-19

Project GW EB6510 Hacking: (2) Serial Output

0: serial param
=====================
  • 115200
  • 8
  • no flow ctl
  • stop 1
  • no parity
1: serial output - boot up
=============================
OKGABDEgreen led:567

battery1(567) normal power on

U-Boot 1.1.6 (Mar 31 2010 - 16:24:45) for SMDK2416


CPU: S3C2416@400MHz
Fclk = 800MHz, Hclk = 133MHz, Pclk = 66MHz
Board: SMDK2416 Mobile DDR
DRAM: 64 MB
Flash: 0 kB
NAND: ngp nand init
s3c24xx:board nand init--d3
1024 MB
ngp nand_base:nand read
*** Warning - bad CRC or NAND, using default environment

In: serial
Out: serial
Err: serial
S1d13521 interface init gpio
s1d13521 reset!
s1d13521fb_init: InterfaceInit ok
s1d13521 init display
green led:559
Now loading logo from 6200000
ngp nand_base:nand read
bmp bits:1, bmp_head_len:76 bmp size:3a982 nand addr:6200000 bmp file is support bs_cmd_ld_img_end disp_full(2, 15); bs_cmd_wait_disp_ready green led:561 3G power on Hit any key to stop autoboot: 0 ngp no hit key

NAND read: device 0 offset 0x40000, size 0x1c0000 ngp nand_base:nand read
1835008 bytes read: OK
## Booting image at c0008000 ...
Image Name: Linux-2.6.21.5-cfs-v19
Created: 2010-04-09 6:44:28 UTC
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 1638968 Bytes = 1.6 MB
Load Address: 30008000
Entry Point: 30008000
Verifying Checksum ... OK
OK

Starting kernel ...

Uncompressing Linux...........................................................................................................
done, booting the kernel.
Linux version 2.6.21.5-cfs-v19 (fei@fedora) (gcc version 4.2.2) #391 Fri Apr 9 14:44:20 HKT 2010
CPU: ARM926EJ-S [41069265] revision 5 (ARMv5TEJ), cr=00053177
Machine: SMDK2416
Ignoring unrecognised tag 0x00000000
Memory policy: ECC disabled, Data cache writeback
ike: Detected CPU type 0x32450003
CPU S3C2416 EVT3 (id 0x32450003)
S3C24XX Clocks, (c) 2004 Simtec Electronics
S3C2416: mpll on 800.000 MHz, cpu 400.000 MHz, mem 133.333 MHz, pclk 66.666 MHz
S3C2416: epll on 96.000 MHz, usb-bus 48.000 MHz
CPU0: D VIVT write-back cache
CPU0: I cache: 16384 bytes, associativity 4, 32 byte lines, 128 sets
CPU0: D cache: 16384 bytes, associativity 4, 32 byte lines, 128 sets Built 1 zonelists. Total pages: 16256 Kernel command line: noinitrd root=/dev/mtdblock2 rw rootfstype=yaffs init=/linuxrc console=ttySAC0,115200
irq: clearing pending ext status 00003b00
irq: clearing subpending status 00000402
irq: clearing subpending status 00000002 PID hash table entries: 256 (order: 8, 1024 bytes) timer tcon=00500000, tcnt 28af, tcfg 00000f00,00000000, usec 00007ae2
Console: colour dummy device 80x30
Dentry cache hash table entries: 8192 (order: 3, 32768 bytes) Inode-cache hash table entries: 4096 (order: 2, 16384 bytes)
Memory: 64MB = 64MB total
Memory: 61452KB available (3076K code, 238K data, 96K init) Mount-cache hash table entries: 512
CPU: Testing write buffer coherency: ok
NET: Registered protocol family 16
S3C2410 Power Management, (c) 2004 Simtec Electronics
S3C2416: Initialising architecture
S3C2416: IRQ Support
S3C24XX DMA Driver, (c) 2003-2004,2006 Simtec Electronics DMA channel 0 at c4800000, irq 88 DMA channel 1 at c4800100, irq 89 DMA channel 2 at c4800200, irq 90 DMA channel 3 at c4800300, irq 91 DMA channel 4 at c4800400, irq 92 DMA channel 5 at c4800500, irq 93 DMA channel 6 at c4800600, irq 99 DMA channel 7 at c4800700, irq 100 SCSI subsystem initialized
usbcore: registered new interface driver usbfs
usbcore: registered new interface driver hub
usbcore: registered new device driver usb Sangoma WANPIPE Router v1.1 (c) 1995-2000 Sangoma Technologies Inc.
NET: Registered protocol family 2
IP route cache hash table entries: 1024 (order: 0, 4096 bytes) TCP established hash table entries: 2048 (order: 2, 16384 bytes) TCP bind hash table entries: 2048 (order: 1, 8192 bytes)
TCP: Hash tables configured (established 2048 bind 2048) TCP reno registered NetWinder Floating Point Emulator V0.97 (double precision) yaffs Apr 7 2010 14:04:47 Installing.
io scheduler noop registered
io scheduler anticipatory registered (default) io scheduler deadline registered io scheduler cfq registered reg is 47
Console: switching to colour frame buffer device 75x50 init ok!
S3C2416 ADC, (c) 2008 Simtec Electronics ***********enter ggw_show_logo and load draw ***********ggw_draw_progressbar:802,per =40
to=263,curx=191,cury=598,tmpw=72
command=4547,numbertypes=216,buffer=c3cb98e0,return=0
s3c2410_adc_probe: probe=c0329ff0
adc_PreScale= 32
initial pvi_io proc.
create pviio proc.
***********enter ggw_show_logo and not load draw ***********enter ggw_show_logo and not load draw
s3c2440-uart.0: s3c2410_serial0 at MMIO 0x50000000 (irq = 70) is a S3C2440
s3c2440-uart.1: s3c2410_serial1 at MMIO 0x50004000 (irq = 73) is a S3C2440
s3c2440-uart.2: s3c2410_serial2 at MMIO 0x50008000 (irq = 76) is a S3C2440 RAMDISK driver initialized: 16 RAM disks of 4096K size 1024 blocksize
loop: loaded (max 8 devices)
nbd: registered device at major 43
PPP generic driver version 2.4.2
PPP Deflate Compression module registered PPP BSD Compression module registered S3C24XX NAND Driver, (c) 2004 Simtec Electronics ***********enter ggw_show_logo and not load draw s3c-nand s3c2410-nand: Tacls=3, 22ns Twrph0=4 30ns, Twrph1=3 22ns initialising set 0 (c3d4b800, info c3d687e0) writesize:2048, oobsize:64, erasesize:131072 NAND device : Manufacturer ID: 0xec, Chip ID: 0xd3 (Samsung NAND 1GiB 3,3V 8-bit) Scanning device for bad blocks Bad eraseblock 628 at 0x04e80000 Creating 7 MTD partitions on "NAND 1GiB 3,3V 8-bit":
0x00000000-0x00040000 : "uboot"
0x00040000-0x00200000 : "kernel"
0x00200000-0x02200000 : "rootfs"
0x02200000-0x04200000 : "qt"
0x04200000-0x06200000 : "app"
0x06200000-0x06300000 : "boot frame"
0x06300000-0x40000000 : "user space"
spi /dev entries driver
S3C2443 HSPI Driver
***********enter ggw_show_logo and not load draw resource start : 52000000 hspi registers c4c00000 (c3d39920, c032b418) s3c2410-spi s3c2410-spi.0: s3c2410-spi.0: S3C SPI adapter
s3c2410-spi.0: S3C SPI adapter
Initializing USB Mass Storage driver...
usbcore: registered new interface driver usb-storage USB Mass Storage support registered.
usbcore: registered new interface driver usbhid
drivers/usb/input/hid-core.c: v2.6:USB HID core driver
mice: PS/2 mouse device common for all mice dir_sensor initialized !
***********enter ggw_show_logo and not load draw rtc-test rtc-test.0: rtc core: registered test as rtc0 rtc-test rtc-test.1: rtc core: registered test as rtc1 S3C24XX RTC, (c) 2004,2006 Simtec Electronics ***********enter ggw_show_logo and not load draw
res->start : 57005000 res->end : 570050ff<6>s3c2410-rtc s3c2410-rtc:
rtc disabled, re-enabling
s3c2410-rtc s3c2410-rtc: rtc core: registered s3c as rtc2 i2c /dev entries driver ***********enter ggw_show_logo and not load draw s3c2410-i2c s3c2410-i2c: slave address 0x10 s3c2410-i2c s3c2410-i2c: bus frequency set to 130 KHz s3c2410-i2c s3c2410-i2c: i2c-0: S3C I2C adapter ***********enter ggw_show_logo and not load draw
input: pcabutton as /class/input/input0
register IRQ-54 successful.[ret: 0]
reg 0x1F: 3
reg 0x1F: 3
reg 0x1F: 3
reg 0x1F: 3
sdhci: Secure Digital Host Controller Interface driver
sdhci: Copyright(c) Pierre Ossman
***********enter ggw_show_logo and not load draw s3c-sdhci s3c-sdhci.0: clock source 0: hsmmc (133333333 Hz) s3c-sdhci s3c-sdhci.0: clock source 1: hsmmc (133333333 Hz) s3c-sdhci s3c-sdhci.0: clock source 2: esysclk (96000000 Hz)
host->max_clk: 133333333
mmc0: SDHCI controller on samsung-hsmmc using ADMA s3c-sdhci s3c-sdhci.1: clock source 0: hsmmc (133333333 Hz) s3c-sdhci s3c-sdhci.1: clock source 1: hsmmc (133333333 Hz) s3c-sdhci s3c-sdhci.1: clock source 2: esysclk (96000000 Hz)
host->max_clk: 133333333
mmc1: SDHCI controller on samsung-hsmmc using ADMA GPIO L3 bus interface for s3c, installed Advanced Linux Sound Architecture Driver Version 1.0.14rc3 (Wed Mar 14 07:25:50 2007 UTC).
ASoC version 0.13.2
***********enter ggw_show_logo and not load draw
wm8753: WM8753 Audio Codec 0.16
asoc: WM8753 HiFi <-> s3c-i2s mapping ok
Wm8753 is in master mode
ALSA device list:
#0: smdk2416 (WM8753)
TCP cubic registered
NET: Registered protocol family 1
NET: Registered protocol family 17
rtc-test rtc-test.0: setting the system clock to 1970-01-01 00:00:01 (1) ***********enter ggw_show_logo and load draw ***********ggw_draw_progressbar:802,per =70
to=373,curx=191,cury=598,tmpw=182
command=4547,numbertypes=546,buffer=c3d8ba00,return=0
yaffs: dev is 32505858 name is "mtdblock2"
yaffs: Attempting MTD mount on 31.2, "mtdblock2"
yaffs: auto selecting yaffs2
Partially written block 225 being set for retirement Partially written block 225 being set for retirement Partially written block 225 being set for retirement Partially written block 225 being set for retirement Partially written block 225 being set for retirement Partially written block 225 being set for retirement Partially written block 225 being set for retirement Partially written block 225 being set for retirement Partially written block 225 being set for retirement Partially written block 225 being set for retirement Partially written block 225 being set for retirement Partially written block 225 being set for retirement Partially written block 225 being set for retirement Partially written block 225 being set for retirement Partially written block 225 being set for retirement Partially written block 225 being set for retirement Partially written block 225 being set for retirement Partially written block 225 being set for retirement Partially written block 225 being set for retirement Partially written block 225 being set for retirement Partially written block 225 being set for retirement Partially written block 225 being set for retirement Partially written block 225 being set for retirement Partially written block 225 being set for retirement Partially written block 225 being set for retirement Partially written block 225 being set for retirement Partially written block 225 being set for retirement Partially written block 225 being set for retirement Partially written block 225 being set for retirement Partially written block 225 being set for retirement Partially written block 225 being set for retirement Partially written block 225 being set for retirement Partially written block 225 being set for retirement Partially written block 225 being set for retirement
VFS: Mounted root (yaffs filesystem).
Freeing init memory: 96K
Starting mdev ...
ls: /dev/mmcblk*: No such file or directory
yaffs: dev is 32505860 name is "mtdblock4"
yaffs: Attempting MTD mount on 31.4, "mtdblock4"
yaffs: restored from checkpoint
Run /qte/app/bin/rcS
enable 3g power
create ,ggw_hcd_removed=0
s3c2410-ohci s3c2410-ohci: S3C24XX OHCI
s3c2410-ohci s3c2410-ohci: new USB bus registered, assigned bus number 1 s3c2410-ohci s3c2410-ohci: irq 42, io mem 0x49000000 usb usb1: configuration #1 chosen from 1 choice hub 1-0:1.0: USB hub found hub 1-0:1.0: 2 ports detected usb 1-1: new full speed USB device using s3c2410-ohci and address 2 usb 1-1: configuration #3 chosen from 1 choice cdc_acm 1-1:3.1: ttyACM0: USB ACM device cdc_acm 1-1:3.3: ttyACM1: USB ACM device cdc_acm 1-1:3.5: ttyACM2: USB ACM device
usbcore: registered new interface driver cdc_acm
drivers/usb/class/cdc-acm.c: v0.25:USB Abstract Control Model driver for USB modems and ISDN adapters
yaffs: dev is 32505859 name is "mtdblock3"
yaffs: Attempting MTD mount on 31.3, "mtdblock3"
yaffs: restored from checkpoint
yaffs: dev is 32505862 name is "mtdblock6"
yaffs: Attempting MTD mount on 31.6, "mtdblock6"
yaffs: restored from checkpoint
FAT: utf8 is not a recommended IO charset for FAT filesystems, filesystem will be case sensitive!

Please press Enter to activate this console.
/$
/$
/$
/$ Using 600x800x4 screen
map framebuffer, mapsize = 1920000, data = 0x416e2000
QLinuxFbScreen::connect: Invalid argument Error reading palette from framebuffer, using default palette solidFill:region = (0, 0, 600, 800), not supported yet QLinuxFbScreen::blit:x = 0, y = 0, w = 600, h = 800 run:EprThread started, id = 0x42d5f490 run:DownloadMgr started, id = 0x4355f490 processDownloadEvent:enter download event, thread = 0x4355f490 apm timeout = 15s, networktimeout = 600s, stoptimeout = 300s, autotimeout = 900s epr_get_download_info:join on download_table and book_table failed SELECT a.uid, a.contentid, url, ticketurl, product_license, content_license, title, length, mimetype, path, finished_time, authorid, authorname FROM download_table as a INNER JOIN book_table as b ON a.uid = b.uid AND a.contentid = b.contentid WHERE a.uid = ? AND state = ? ORDER BY finished_time DESC updateDownloadStatsFromDB:r = -1, failed processDownloadEvent:leave download event, thread = 0x4355f490 QLinuxFbScreen::blit:x = 0, y = 0, w = 600, h = 800

/$
/$ usbcore: deregistering interface driver cdc_acm QLinuxFbScreen::blit:x = 0, y = 0, w = 600, h = 800 QLinuxFbScreen::blit:x = 502, y = 6, w = 40, h = 22 QLinuxFbScreen::blit:x = 400, y = 0, w = 62, h = 36

/$
/$ s3c2410-ohci s3c2410-ohci: remove, state 4 remove ggw_hcd_removed=1 usb usb1: USB disconnect, address 1 usb 1-1: USB disconnect, address 2 after del_timer_sync s3c2410-ohci s3c2410-ohci: USB bus 1 deregistered s3c2410-ohci s3c2410-ohci: dma_pool_destroy buffer-128, ff645000 busy s3c2410-ohci s3c2410-ohci: dma_pool_destroy buffer-128, ff644000 busy wake enabled for irq 46 open /dev/apm_bios ...
1
sync ...
ioctl ...Stopping tasks ...
done.
Suspending console(s)
OKPMGenter s1d13521fb suspend!
timer tcon=00000000, tcnt 28af, tcfg 00000f00,00000000, usec 00007ae2 s3c-nand s3c2410-nand: Tacls=3, 22ns Twrph0=4 30ns, Twrph1=3 22ns enter s1d13521fb_resume!
reg is 47
s3c2410-i2c s3c2410-i2c: slave address 0x10 s3c2410-i2c s3c2410-i2c: bus frequency set to 130 KHz s3c2410-rtc s3c2410-rtc: rtc disabled, re-enabling Restarting tasks ... done.
res: 0wake disabled for irq 46

create ,ggw_hcd_removed=0
s3c2410-ohci s3c2410-ohci: S3C24XX OHCI
s3c2410-ohci s3c2410-ohci: new USB bus registered, assigned bus number 1 s3c2410-ohci s3c2410-ohci: irq 42, io mem 0x49000000 usb usb1: configuration #1 chosen from 1 choice hub 1-0:1.0: USB hub found hub 1-0:1.0: 2 ports detected MainWindow:key = 0x50 pressed, discard it usb 1-1: new full speed USB device using s3c2410-ohci and address 2 usb 1-1: configuration #3 chosen from 1 choice

/$
/$
/$ s3c2410-ohci s3c2410-ohci: remove, state 4 remove ggw_hcd_removed=1 usb usb1: USB disconnect, address 1 usb 1-1: USB disconnect, address 2 after del_timer_sync s3c2410-ohci s3c2410-ohci: USB bus 1 deregistered wake enabled for irq 46 open /dev/apm_bios ...
1
sync ...
ioctl ...Stopping tasks ...
done.
Suspending console(s)
2: Serial output - shutdown
==============================
OKPMGenter s1d13521fb suspend!
timer tcon=00000000, tcnt 28af, tcfg 00000f00,00000000, usec 00007ae2 s3c-nand s3c2410-nand: Tacls=3, 22ns Twrph0=4 30ns, Twrph1=3 22ns enter s1d13521fb_resume!
reg is 47
s3c2410-i2c s3c2410-i2c: slave address 0x10 s3c2410-i2c s3c2410-i2c: bus frequency set to 130 KHz s3c2410-rtc s3c2410-rtc: rtc disabled, re-enabling Restarting tasks ... done.
res: 0
QLinuxFbScreen::blit:x = 0, y = 0, w = 600, h = 800 wake disabled for irq 46 enable 3g power create ,ggw_hcd_removed=0 s3c2410-ohci s3c2410-ohci: S3C24XX OHCI s3c2410-ohci s3c2410-ohci: new USB bus registered, assigned bus number 1 s3c2410-ohci s3c2410-ohci: irq 42, io mem 0x49000000 usb usb1: configuration #1 chosen from 1 choice hub 1-0:1.0: USB hub found hub 1-0:1.0: 2 ports detected QLinuxFbScreen::blit:x = 0, y = 0, w = 600, h = 800 QLinuxFbScreen::blit:x = 34, y = 586, w = 532, h = 180 run:DownloadMgr finished, id = 0x4355f490 run:EprThread finished, id = 0x42d5f490 /qte/app/bin/FBReader exists normally, shutdown system usb 1-1: new full speed USB device using s3c2410-ohci and address 2 usb 1-1: configuration #3 chosen from 1 choice Using 600x800x4 screen map framebuffer, mapsize = 1920000, data = 0x40d72000
QLinuxFbScreen::connect: Invalid argument Error reading palette from framebuffer, using default palette QLinuxFbScreen::blit:x = 0, y = 0, w = 600, h = 800 QLinuxFbScreen::blit:x = 0, y = 0, w = 600, h = 800 QLinuxFbScreen::blit:x = 0, y = 0, w = 600, h = 800 entering rcH save exit: isCheckpointed 1 save exit: isCheckpointed 1 save exit: isCheckpointed 1 reboot
umount: none busy - remounted read-only
umount: /etc/mtab: No such file or directory
umount: /etc/mtab: No such file or directory
umount: /etc/mtab: No such file or directory The system is going down NOW!
Sent SIGTERM to all processes
Sent SIGKILL to all processes
Restarting system.

2011-01-17

Project GW EB6510 Hacking: (1) 硬件信息, 信息搜集

Greawall EB6510 电纸书阅读器, 为中国移动 OEM 的


开机显示的系统信息:


拆开后壳, 主板的情况: (下图顶部中间白色 12 pin 插槽是串口pinout, 个人的门路搞到的, 省掉了一个大麻烦. 需要TTL转换)


芯片信息:
===================

1 8Gb(1GB) NAND FLASH
----------------------------------

SAMSUNG 001
K9K8G08U0B
PCB0

2 400 MHz ARM926EJ MCU
---------------------------------------

SAMSUNG
S3C2416XH-40
C0947
ARM
N21H5BAL

3
--------

SEC 013 FGC6
X4X51163PG

4
-----

EPSON
D135211B2
F10080260
E-INK

5 512Mb/64MB MMSDRAM
---------------------------------------

SAMSUNG 004
K4M51323PG-HG75
EDL159PB

6
----

VM8753G
67ALGK9

7 温度感应?
------------------------

LM75A
35 04
h(??)6721
NXP

8
---

ATMLH932
168 1
9G0245A

9 Audio Amplifier
----------------------------

PAM8403
TSD93992

10
------

LJ(T?)9J
3455
J0616

11
-----

PZ418
T1 9AX
E300

12
----

WINBOND
25X20BVNIG
0951

13
------

2252AI
01T
AHKY

14 DISPLAY CABLE
----------------------------

ED060SC4(LF)
EMR60A1020(B44)
E0R004441K1M00141BT

800x600 6" EPD:electronic paper display
AZ DISPLAYS

15 3G MODULE
----------------------

WYLESS TM TD688
TD-SCDMA/GSM 双模无线数据终端
S/N: 021310042131479
IMEI: 353037025070595
CMIIT ID:2009CP0724
HOJY 深圳市华域无线技术有限公司

OM6361EL/2
9R910026 01
ESD09202
TD60291
Thunderbird

16 PCB
-----------

GREATWALL
EB6510_V1.0

从网上获取到的信息
===========================

(1) Hanlin v5 的硬件与此非常接近(cpu, e-ink controller 相同!) 下面是从网上找到的 v5 主板照片


(2) 已下载 Hanlin v5 官方提供源代码(u-boot, kernel, cross toolchain...)

从jinke网站下载(需注册+email激活)GPL_FOR_V5.tar.gz, 里面包含了 crosstool(gcc+glibc), kernel 源码等. 没有u-boot!! README.txt 包含简单的说明

用 crosstool 建造 toolchain(基于glibc). 我更想用 uclibc...

kernel .config 里面给的内核启动参数为 noinitrd root=/dev/mtdblock2 rootfstype=cramfs init=/linuxrc console=ttySAC0 mem=128M

关 于处理器选择了: Support ARM926T processor, S3C24XX Platform support , S3C MTD has 4 partitions, S3C2410 UART to use for low-level messages: (0), S3C2410 DMA support

没有看到有电纸书显示屏的设备驱动(关心!)? 可能没放在kernel source tree 中...

没有u-boot, 没有 显示屏驱动, 对我似乎没有什么用. 开源??? 我说怎么jinke公司这么open呢?

(3) Openinkpot 已经破解 hanlin v3; v5 他们似乎还在进行中. 粗略浏览了openinkpot 的源码git, 没找到针对v5的. (因为有 hanlin 官方源码, 就不情愿花时间去找了)

(4) 经过一些google, 有一些信息:
  • kernel 2.6.3x 中已经包含了对Epson E-ink Broadsheet 的驱动(CONFIG_FB_BROADSHEET).
  • S1D13521 = D135211B(Amason Kindle 等都是用的这个芯片), 芯片印刷为D135211B..., 实际型号为 S1D13521
  • 目前使用的电纸屏(EPD)驱动器只有2个, 要么是爱普生Broadsheet 要么是另一个记不清了(Apollo?)
  • 名为Jaya的人有一个ppt(Penguins prosper with epaper ), 说到除了broadsheet 的fb驱动外, 还需要其他的东东, waveform, 温度感应什么的, 好像没有这么简单? 这个人好像就是openinkpot发起者

2011-01-14

Embedded Linux from Scratch on VMWare: (2) Some Make-ups to Shell

1: 电源管理
============

执行halt或poweroff时, linux已 shut down, 系统提示"System halted"但硬件(电源)没有关闭



需要给kernel增加电源管理. 只需要启用电源管理(PM)和ACPI两个基本功能; idle, CPU频率调节, 睡眠等不是必须的
-> Power management and ACPI options
-> Power Management support
ACPI (Advanced Configuration and Power Interface) Support (NEW)
-> Future power /sys interface (NEW)
重建内核, 系统 poweroff 就可关机/断电了; halt 只关闭linux, 不断电, 这是预期的结果

2: 网络支持(TCP/IP)
======================

网络支持要启动的内核配置有: TCP/IP协议栈, Ethern和网卡驱动. 参考: http://tldp.org/HOWTO/NET3-4-HOWTO.html

首先增加TCP/IP协议栈
-> Networking support
-> Networking options
-> TCP/IP networking
以太网支持以及网络接口卡的驱动:
-> Device Drivers
-> Network device support
-> Ethernet (10 or 100Mbit)
-> EISA, VLB, PCI and on board controllers
->AMD PCnet32 PCI support
关于网络接口的硬件信息, 可在host上检查:
v4@elws:~$ lspci
...
02:00.0 Ethernet controller: Advanced Micro Devices [AMD] 79c970 [PCnet32 LANCE] (rev 10)
...
这是PCI网卡. lsmod 列出驱动模块, 可以找到名为 pcnet32 的 module
v4@elws:~$ lsmod | grep pcnet
pcnet32 27396 0
mii 4896 1 pcnet32
然后在menuconfig里搜索(按'/'键)pcnet32即可找到其设备驱动
重新build kernel, 启动 target. 检查以太网接口硬件是否识别
/ # dmesg | grep eth
pcnet32: eth0: registered as PCnet/PCI II 79C970A
设置一下 loop back:
/ # ifconfig lo 127.0.0.1
/ # ping 127.0.0.1
如果能ping通, 表明tcp/ip安装正常. 配置一下eth0(下面的地址是我的虚拟网络设置, 159.19.49.2 为网关)
/ # ifconfig eth0 159.19.49.43 netmask 255.255.255.0 broadcast 159.19.49.255
pcnet32 0000: 02:00.0: eth0: link up
/ # ping 159.19.49.2
如果能够ping通网关, 则表明以太网网络接口的设备驱动安装成功
可以将lo和eth0的配置命令放入/etc/init.d/rcS脚本中, 在系统启动时自动执行

另一种配置网络接口的方式是使用 ifup 命令, 它将设置在 /etc/network/interfaces 脚本中的网络接口 bring up. 该接口定义支持dhcp, 例如
auto lo eth0
iface lo inet loopback
#iface eth0 inet static
#address 159.19.49.43
#netmask 255.255.255.0
#gateway 159.19.49.2
iface eth0 inet dhcp
然后执行
ifdown -a # required to execute this before ifup
ifup -a
如果抱怨有/etc/networ/if-up.d 之类的目录找不到, 则创建对应目录
dhcp 是通过启动 busybox udhcpc 进程来配置的, 如果报错
udhcpc: socket: Address family not supported by protocol
google一下, 需要给内核配置以下几项:
-> Networking support
-> Networking options
-> Packet socket
-> Network packet filtering framework
现在, udhcpc 可以获取到IP地址了, 启动时可看到屏幕打印
udhcpc (v1.18.1) started
Sending discover...
Sending select for 159.19.49.136...
Lease of 159.19.49.136 obtained, lease time 1800
但是, ifconfig eth0 看到eth0起来了, 但还是没有分配ip v4地址. dmesg 可看到
pcnet32 0000:02:00.0: eth0: link up
eth0: no IPv6 routers present
ip v6倒不是问题. 主要是udhcpc 取得IP地址后, 将调用一个脚本, 该脚本进一步调用 ifconfig 来配置eth0. 启动到 host 上将 buildroot-2010.11/output/target/usr/share/udhcpc/default.script 拷贝到 target 的 /usr/share/udhcpc/default.script(注意: man udhcpc 说默认脚本为 /etc/udhcpc/default.script, 实际并非如此), 这样就应该可以正常 ifdown/ifup 来配置lo 和 eth0.

但是在udhcpc 执行 /usr/share/udhcpc/default.script脚本的过程中还有一条错误信息
route: SIOCDELRT: No such process
这是
route del default gw 0.0.0.0 eth0
一行产生的, 我还不清楚为什么会这样, 网上有人说到可以忽略. 现在还需要设置一下 hostname:
echo toy > /etc/hostname
hostname `cat /etc/hostname`
同时, 需要把第2行加入到 /etc/init.d/rcS 中, 让系统启动时自动设置

3: 禁用 console idle timeout
=================================

console 设备默认10分钟没有输入会黑屏, 如果不想要这个特性可以在 /boot/grub/menu.lst 中增加内核启动参数
consoleblank=0
其单位为秒, 0 表示禁用

4: 企鹅logo
=============

启用framebuffer, 获得图形界面的console(以及企鹅logo!)
参考 kernel 文档
  • Documentation/fb/framebuffer.txt
  • Documentation/fb/fbcon.txt
  • Documentation/fb/vesafb.txt
  • Documentation/svga.txt
  • 《Essential Linux Device Drivers》, Chapter 12, Linux-Video Subsystem 一节
需要为内核增加
  • vt(virtual terminal) 驱动 - 工作在 fbcon 或 vgacon 之上
  • fbcon 驱动 - 工作在 vesafb 之上, 对等于 vgacon 的地位
  • vesafb 驱动 - VESA 兼容图形卡的 framebuffer 驱动(framebuffer 对 VESA 的实现), 直接驱动硬件
启用 vesafb:
-> Device Drivers
-> Graphics support
-> Support for frame buffer devices
-> VESA VGA graphics support
启用 fbcon:
-> Device Drivers
-> Graphics support
-> Console display driver support
-> Framebuffer Console support
选择一个比较好的字体:
-> Device Drivers
-> Graphics support
-> Console display driver support
-> Select compiled-in fonts
-> VGA 8x16 font
启用linux企鹅logo:
-> Device Drivers
-> Graphics support
-> Bootup logo
在内核启动参数增加 vga=ask, 启动时将提示回车选择支持的vga模式. 选择340(800x600, 32位), kernel 启动并显示企鹅logo:


我们修改一下 /boot/grub/menu.lst:
kernel /boot/bzImage rw root=/dev/sda1 consoleblank=0 vga=0x341
# 0x341=>1024x768, 32 bit
创建一个 framebuffer 设备节点:
mknod /dev/fb0 c 29 1
Done!

5: NEXT TODO
==============

现在有了网络 + framebuffer, 系统大小 2.9 MB; 后面接下来要安装 GTK+2.0(gtk direct fb), 然后是一个浏览器

2011-01-13

Embedded Linux from Scratch on VMWare: (1) Boot Up to sh# Prompt

在虚拟机上从头建造一个linux系统(穷人的嵌入式), 主要参考: http://uuu.enseirb.fr/~kadionik/rmll2005/presentation/michael_opdenacker.pdf.
target硬件配置为:

host也是vmware虚拟机, 安装 debian 5.0 lenny. 把 target 硬盘连接在 host 上(scsi 0:3, linux 设备节点为 /dev/sdd)
host 上用户名为v4, 工作目录为 ~/toy
需要的一些软件包放在~/tarballs/

0: 目标
========

建立一个最小的linux系统
  • bootloader 用 grub
  • 安装 busybox
  • 安装 uclibc 运行时库(为了以后能安装其他工具); busybox 动态链接到 uclibc

1: 建立 cross toolchain
=======================

target 与 host 都是虚拟机, 架构是相同的(x86), 为何还需要 cross toolchain呢? 罪恶之源在uclibc: (1)用来build uclibc 的工具, 必须是built against uclibc的(见: http://www.uclibc.org/toolchains.html; 鸡->蛋->鸡->...); (2)用来build 与 uclibc 链接的程序的工具, 也必须是built against uclibc的; 而host上编译工具是链接到glibc的, 不符合这2个要求
利用buildroot工具来建造一个 cross toolchain
手工建造cross toolchain也是uclibc难搞
理论上, 用 buildroot 可以建造出我们最终想要的 target rootfs(uclibc + busybox + kernel + ...), 但是, 实践证明(theory vs. reality): (1)目标越大, 出问题的可能性越高; (2)自动化程度越高, 出了问题越难解决(花费额外时间解决自动化工具本身的问题; buildroot 的 make 系统的质量还比不上 kernel 或 gcc)
此外, 我也希望了解手工建立一个linux系统的过程. 因此, 我这里只是用buildroot建立一个最简化的toolchain(uclibc+gcc+binutils+kernel headers(?)), 不包含任何其它工具. 如果以后需要其它的工具, 可以用这个 toolchain 自己 build, 即使有问题, 也可各个击破
v4@elws:~/toy$ tar xjvf ../tarballs/buildroot-2010.11.tar.bz2 -C .
v4@elws:~/toy$ cd buildroot-2010.11/
v4@elws:~/toy/buildroot-2010.11$ make distclean
v4@elws:~/toy/buildroot-2010.11$ make allnoconfig # 只需要 toolchain
v4@elws:~/toy/buildroot-2010.11$ make menuconfig
-> Target Architecture: 选i386
-> Target Architecture Variant: 选pentium pro
-> Toolchain: 选择 Build/install c++ compiler and libstdc++?
v4@elws:~/toy/buildroot-2010.11$ make source # 提前下载所需软件包
buildroot 把自动下载的软件包放在 dl/ 目录. gcc, uclibc 等比较慢, 可以自己提前下载对应版本的放到 dl/ 下. 我总结的 buildroot-2010.11 对应的软件包及版本号(不完全):
  • gcc-4.3.5.tar.bz2
  • uClibc-0.9.31.tar.bz2
  • linux-2.6.36.1.tar.bz2
  • gmp-4.2.4.tar.bz2
  • mpfr-2.4.1.tar.bz2
  • binutils-2.20.1.tar.bz2
v4@elws:~/toy/buildroot-2010.11$ make uclibc-menuconfig
uclibc配置保存在 output/toolchain/uClibc-0.9.31/.config
uclibc很可能以后还需要重新配置(缺少某些功能没有选择), 需要回到这里重复开始
-> Target Architecture Features and Options
-> Target x86 Processor Family 选Pentium-Pro
v4@elws:~/toy/buildroot-2010.11$ cp output/toolchain/uClibc-0.9.31/.config toolchain/uClibc/uClibc-0.9.31.config
buildroot 使用的uclibc配置为 toolchain/uClibc/uClibc-0.9.31.config (通过make menuconfig 查看/修改)
v4@elws:~/toy/buildroot-2010.11$ make
make 一次要很久(更糟糕的是: 有时, 重复make时, buildroot会再次下载已经下载过的软件包, 这对身在大国的网络用户来说是一个噩梦)(足够洗个热水澡->出去跑一圈->再洗个热水澡:<) 生成的cross toolchain 在 output/staging(不是output/toolchain, 参考 http://buildroot.uclibc.org/buildroot.html#using)
  • c 头文件: output/staging/usr/include (包含 linux 头文件!)
  • 库文件: output/staging/usr/lib
  • 工具: output/staging/usr/bin/i686-linux-{gcc, ld, strip...}
2: build kernel
=================

build kernel 要小心的是使用cross toolchain
v4@elws:~/toy$ tar xjvf buildroot-2010.11/dl/linux-2.6.36.1.tar.bz2 -C .
内核版本最好与buildroot 使用的一致. 这里直接使用buildroot下载的
v4@elws:~/toy$ cd linux-2.6.36.1/
v4@elws:~/toy/linux-2.6.36.1$ make mrproper
修改 Makefile 中这一行: EXTRAVERSION = .1-toy-1.0
v4@elws:~/toy/linux-2.6.36.1$ make ARCH=x86 allnoconfig # 从零开始
kernel支持的架构在arch/目录下. 这里其实可以省略 ARCH=...
v4@elws:~/toy/linux-2.6.36.1$ make ARCH=x86 menuconfig
选择:
-> Processor type and features
-> Processor family(选 Processor family, 默认已选中)
Generic x86 support
计划在target 硬盘上建立 ext3 文件系统, 因此kernel要支持 ext3
-> File systems
-> Ext3 journalling file system support
硬盘为scsi, 要支持pci, scsi
-> Bus options (PCI etc.)
-> PCI support
PCI Express support
-> Device Drivers
-> SCSI device support
SCSI disk support
-> Device Drivers
-> Block devices
接下来的部分比较 tricky(提前公布谜底): host 与 target 都是虚拟机, 它们硬件架构是相同的. 在 host 执行 lspci 命令, 关于 scsi 控制器的输出为
00:10.0 SCSI storage controller: LSI Logic / Symbios Logic 53c1030 PCI-X Fusion-MPT Dual Ultra320 SCSI (rev 01)
说明 scsi 控制器采用了 Fusion 架构. linux 要从 Fusion 设备上启动, 必须在内核内建 Fusion 驱动
-> Device Drivers
-> Fusion MPT device support
-> Fusion MPT ScsiHost drivers for SPI
顺便启用DMA
-> Device Drivers
-> DMA Engine support
另外, 要启用 ELF 支持, 否则kernel 启动后将不能执行任何程序! (提前公布谜底. 我通过失败得来)
-> Executable file formats / Emulations
-> Kernel support for ELF binaries
保存配置后开始编译
v4@elws:~/toy/linux-2.6.36.1$ make ARCH=x86 CROSS_COMPILE=$HOME/toy/buildroot-2010.11/output/staging/usr/bin/i686-linux-
kernel 编译一般不会出什么问题, 因为 kernel 不依赖于任何外部库(但是编译过程中要使用一些工具, 如 perl)
10分钟左右编译完, 生成的kernel为 arch/x86/boot/bzImage

3: boot kernel
=================

接下来在target硬盘上建立文件系统, 安装grub和kernel
下面的操作以root执行
elws:~# fdisk /dev/sdd # 在target 硬盘上划分一个主分区
elws:~# mke2fs -j /dev/sdd1
elws:~# mkdir -p /mnt/toy/
elws:~# mount /dev/sdd1 /mnt/toy/
elws:~# grub-install --root-directory=/mnt/toy/ /dev/sdd
可以给grub设置一下启动菜单, 免得以后启动target手动输入启动参数
elws:~# vi /mnt/toy/boot/grub/menu.lst
输入其内容为:
default 0
timeout 5

title toy linux
root (hd0,0)
kernel /boot/bzImage rw root=/dev/sda1
把kernel 拷贝到 target 硬盘
elws:~# cp /home/v4/toy/linux-2.6.36.1/arch/i386/boot/bzImage /mnt/toy/boot/
现在可以关闭host(target 硬盘还挂在host上), 启动 target. 如果前面一切正常, kernel 应该可以挂载根分区, 然后到运行 init 时 kernel panic, 如下:


4: build busybox
===============

使用cross toolchain 来 build busybox
v4@elws:~/toy$ tar xjvf ../tarballs/busybox-1.18.1.tar.bz2 -C .
v4@elws:~/toy$ cd busybox-1.18.1/
v4@elws:~/toy/busybox-1.18.1$ make defconfig
v4@elws:~/toy/busybox-1.18.1$ make menuconfig
-> Busybox Settings
-> Build Options
-> Build BusyBox as a static binary (no shared libs) 不要选择(默认不选择)
-> Busybox Settings
-> Build Options
-> Cross Compiler prefix
填: /home/v4/toy/buildroot-2010.11/output/staging/usr/bin/i686-linux-
v4@elws:~/toy/busybox-1.18.1$ make
如果编译成功: (如果出错了, 看本节末尾的错误记录)
v4@elws:~/toy/busybox-1.18.1$ make install
busybox 安装在 _install/

编译过程中可能出错, 记录如下

(1)
In file included from /home/v4/toy/buildroot-2010.11/output/staging/usr/include/limits.h:27,
from /home/v4/toy/buildroot-2010.11/output/staging/usr/lib/gcc/i686-unknown-linux-uclibc/4.3.5/include-fixed/limits.h:122,
from /home/v4/toy/buildroot-2010.11/output/staging/usr/lib/gcc/i686-unknown-linux-uclibc/4.3.5/include-fixed/syslimits.h:7,
from /home/v4/toy/buildroot-2010.11/output/staging/usr/lib/gcc/i686-unknown-linux-uclibc/4.3.5/include-fixed/limits.h:11,
from include/platform.h:153,
from include/libbb.h:13,
from include/busybox.h:10,
from applets/applets.c:9:
/home/v4/toy/buildroot-2010.11/output/staging/usr/include/features.h:216:5: error: #error It appears you have defined _FILE_OFFSET_BITS=64. Unfortunately, uClibc was built without large file support enabled.
解决:(先后顺序重要! 如果buildroot不支持, uclibc也不会支持)
重新配置buildroot, 添加LFS
-> Toolchain
-> Enable large file (files > 2 GB) support?
重新配置uclibc, 添加Large File Support (LFS)
-> General Library Settings
-> Large File Support
(2)
networking/inetd.c:163:21: error: rpc/rpc.h: No such file or directory
解决: (顺序重要!)
给buildroot增加rpc支持:
-> Toolchain
-> Enable IPv6
Enable RPC
需要给uclibc增加rpc支持:
-> Networking Support
-> Remote Procedure Call (RPC) support
IP version 6 support
Use netlink to query interfaces
5: 启动到 sh# 提示符
==================

现在要将busybox以及uclibc运行时库安装到target
检查busybox需要的动态库:
v4@elws:~/toy$ buildroot-2010.11/output/staging/usr/bin/i686-linux-ldd busybox-1.18.1/_install/bin/busybox
checking sub-depends for 'not found'
checking sub-depends for 'not found'
libm.so.0 => not found (0x00000000)
libc.so.0 => not found (0x00000000)
/lib/ld-uClibc.so.0 => /lib/ld-uClibc.so.0 (0x00000000)
即: busybox 只依赖于libc.so, libm.so 和 ld-uClibc.so

(以下以root执行)
elws:~# mount /dev/sdd1 /mnt/toy/
elws:~# mkdir -p /mnt/toy/etc \
> /mnt/toy/etc/init.d \
> /mnt/toy/lib \
> /mnt/toy/proc \
> /mnt/toy/sys \
> /mnt/toy/dev \
>
elws:~# cd /home/v4/toy/buildroot-2010.11/output/target/lib/
elws:/home/v4/toy/buildroot-2010.11/output/target/lib# rsync -a ld-uClibc* libc.so.0 libuClibc-0.9.31.so libm* /mnt/toy/lib/
elws:/home/v4/toy/buildroot-2010.11/output/staging# cd
elws:~# rsync -a /home/v4/toy/busybox-1.18.1/_install/ /mnt/toy/
elws:~# sync
创建 busybox init 脚本:
elws:~# vi /mnt/toy/etc/inittab
输入以下内容:
# This is run first script
::sysinit:/etc/init.d/rcS

# Start an "askfirst" shell on the console
::askfirst:-/bin/sh

# Stuff to do when restarting the init process
::restart:/sbin/init

# Stuff to do before rebooting
::ctrlaltdel:/sbin/reboot
::shutdown:/bin/umount -a -r
创建系统启动时运行的脚本(系统初始化):
elws:~# mkdir -p /mnt/toy/etc/init.d
elws:~# vi /mnt/toy/etc/init.d/rcS
在启动脚本中mount 虚拟文件系统:
#!/bin/sh

mount -t proc none /proc
mount -t sysfs none /sys
创建 /dev/console, null 2个设备节点(否则, target kernel 启动后, shell 的输出不显示在屏幕上):
elws:~# mkdir -p /mnt/toy/dev
elws:~# mknod /mnt/toy/dev/console c 5 1
elws:~# mknod /mnt/toy/dev/null c 1 3
(注: 可通过在 host 上 ls -l /dev/xyz 查看节点号)

修改文件权限:
elws:~# cd /mnt/toy/
elws:/mnt/toy# chown -R root:root .
elws:/mnt/toy# chmod +x etc/init.d/rcS
关闭host, 启动 target:


6: TODO
============

现在已经建造了一个最基本的linux系统, rootfs 大小为2.3MB:
elws:/mnt# du -sh toy/
2.3M toy/
通过细致地精简busybox及uclibc, 还可较大幅度减小. 接下来要做:
  • acpi 电源管理. 目前 halt 后, 虚拟机电源没有切断
  • tcp/ip 网络支持
  • 启用 framebuffer, 获得图形控制台(以及企鹅logo!)

2011-01-04

使用 Android NDK Stand-alone 交叉编译工具

NDK r5 正式支持作为独立的交叉编译toolchain(不必依靠Android Make 系统),参考android-ndk-r5/docs/STANDALONE-TOOLCHAIN.html
gcc 目录相关选项参考:http://gcc.gnu.org/onlinedocs/gcc/Directory-Options.html
shared library参考:http://ehuss.net/shared/

1: Source Code => Executable Binary
------------------------------------------------------

$ export NDK=$HOME/android/android-ndk-r5
$ export CC=$NDK/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc
$ export SYSROOT=$NDK/platforms/android-4/arch-arm
$ $CC --sysroot=$SYSROOT -o hello hello.c

关于--sysroot=dir:Use dir as the logical root directory for headers and libraries. For example, if the compiler would normally search for headers in /usr/include and libraries in /usr/lib, it will instead search dir/usr/include and dir/usr/lib

2: Shared Library(.so) 
----------------------------

$ $CC --sysroot=$SYSROOT -fPIC -c hello_lib.c
$ $CC --sysroot=$SYSROOT -shared -o libhello_lib.so hello_lib.o
$ $CC --sysroot=$SYSROOT -L. -lhello_lib -o hello hello.c

关于-Ldir:Add directory dir to the list of directories to be searched for -l
关于-llibrary:Search the library named library when linking