Wednesday, December 10, 2008

TouchScreen driver has been done - porting Linux kernel 2.6.25 (Android version) to SAMSUNG S3C2440A

About writing touch screen driver, this URL is a good reference:
[轉錄帥哥] Touch Screen Driver
The patch file of S3C2410 touch screen, download path:
s3c2410_touchscreen.patch
In patch file, modified files include:
arch/arm/plat-s3c24xx/devs.c
include/asm-arm/plat-s3c24xx/devs.h
arch/arm/mach-s3c2410/mach-h1940.c
drivers/input/touchscreen/Kconfig
drivers/input/touchscreen/Makefile
drivers/input/touchscreen/s3c2410_ts.c
include/asm-arm/arch-s3c2410/ts.h

then, modifies the following files,
arch/arm/mach-s3c2440/mach-smdk2440.c
arch/arm/plat-s3c24xx/devs.c
arch/arm/plat-s3c24xx/s3c244x.c

works are done.

Burn the recompiled kernel file to board, the booting message:

Starting kernel ...

Uncompressing Linux........................................................................................................... done, booting the kernel.
Linux version 2.6.25 (armdev@test.intra.wizign.com) (gcc version 4.1.2) #14 Tue Dec 9 15:23:52 CST 2008
CPU: ARM920T [41129200] revision 0 (ARMv4T), cr=c0007177
Machine: SBZ2440
Memory policy: ECC disabled, Data cache writeback
CPU S3C2440A (id 0x32440001)
S3C244X: core 399.651 MHz, memory 133.217 MHz, peripheral 66.608 MHz
S3C24XX Clocks, (c) 2004 Simtec Electronics
CLOCK: Slow mode (2.116 MHz), fast, MPLL on, UPLL on
CPU0: D VIVT write-back cache
CPU0: I cache: 16384 bytes, associativity 64, 32 byte lines, 8 sets
CPU0: D cache: 16384 bytes, associativity 64, 32 byte lines, 8 sets
Built 1 zonelists in Zone order, mobility grouping on. Total pages: 16256
Kernel command line: root=/dev/nfs rw noinitrd console=ttySAC0,115200 init=/linuxrc nfsroot=192.168.1.12:/vdisk/armdev_fs ip=192.168.1.30:192.168.1.12:192.168f
irq: clearing pending ext status 00000080
irq: clearing subpending status 00000003
irq: clearing subpending status 00000002
PID hash table entries: 256 (order: 8, 1024 bytes)
timer tcon=00500000, tcnt d8d2, tcfg 00000200,00000000, usec 0000170f
Console: colour dummy device 80x30
console [ttySAC0] enabled
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: 61184KB available (3044K code, 508K data, 144K init)
Mount-cache hash table entries: 512
CPU: Testing write buffer coherency: ok
net_namespace: 152 bytes
NET: Registered protocol family 16
S3C2410 Power Management, (c) 2004 Simtec Electronics
S3C2440: Initialising architecture
S3C2440: IRQ Support
S3C24XX DMA Driver, (c) 2003-2004,2006 Simtec Electronics
DMA channel 0 at c4800000, irq 33
DMA channel 1 at c4800040, irq 34
DMA channel 2 at c4800080, irq 35
DMA channel 3 at c48000c0, irq 36
S3C244X: Clock Support, DVS off
usbcore: registered new interface driver usbfs
usbcore: registered new interface driver hub
usbcore: registered new device driver usb
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)
JFFS2 version 2.2. (NAND) �© 2001-2006 Red Hat, Inc.
fuse init (API version 7.9)
io scheduler noop registered
io scheduler anticipatory registered (default)
io scheduler deadline registered
io scheduler cfq registered
Console: switching to colour frame buffer device 30x40
fb0: s3c2410fb frame buffer device
lp: driver loaded but no devices found
ppdev: user-space parallel port driver
Serial: 8250/16550 driver $Revision: 1.90 $ 4 ports, IRQ sharing enabled
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
brd: module loaded
loop: module loaded
dm9000 Ethernet Driver, V1.30
eth0: dm9000 at c485e300,c4860304 IRQ 51 MAC: 08:00:3e:26:0a:5b (chip)
Uniform Multi-Platform E-IDE driver
ide: Assuming 50MHz system bus speed for PIO modes; override with idebus=xx
BAST NOR-Flash Driver, (c) 2004 Simtec Electronics
S3C24XX NAND Driver, (c) 2004 Simtec Electronics
s3c2440-nand s3c2440-nand: Tacls=1, 7ns Twrph0=4 30ns, Twrph1=1 7ns
NAND device: Manufacturer ID: 0xec, Chip ID: 0x76 (Samsung NAND 64MiB 3,3V 8-bit)
Scanning device for bad blocks
Creating 2 MTD partitions on "NAND 64MiB 3,3V 8-bit":
0x00000000-0x00200000 : "Kernel"
0x00200000-0x04000000 : "root partition"
usbmon: debugfs is not available
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
mice: PS/2 mouse device common for all mice
s3c2410 TouchScreen successfully loadedinput: s3c2410 TouchScreen as /class/input/input0
S3C24XX RTC, (c) 2004,2006 Simtec Electronics
s3c2440-i2c s3c2440-i2c: slave address 0x10
s3c2440-i2c s3c2440-i2c: bus frequency set to 378 KHz
s3c2440-i2c s3c2440-i2c: i2c-0: S3C I2C adapter
S3C2410 Watchdog Timer, (c) 2004 Simtec Electronics
s3c2410-wdt s3c2410-wdt: watchdog inactive, reset disabled, irq enabled
logger: created 64K log 'log_main'
logger: created 64K log 'log_events'
logger: created 64K log 'log_radio'
TCP cubic registered
NET: Registered protocol family 1
RPC: Registered udp transport module.
RPC: Registered tcp transport module.
drivers/rtc/hctosys.c: unable to open rtc device (rtc0)
eth0: link up, 100Mbps, full-duplex, lpa 0x45E1
IP-Config: Complete:
device=eth0, addr=192.168.1.30, mask=255.255.255.0, gw=192.168.1.1,
host=android, domain=, nis-domain=(none),
bootserver=192.168.1.12, rootserver=192.168.1.12, rootpath=
Looking up port of RPC 100003/2 on 192.168.1.12
Looking up port of RPC 100005/1 on 192.168.1.12
VFS: Mounted root (nfs filesystem).
Freeing init memory: 144K
--------mount /proc as proc
--------mount /sys as sysfs
--------mount /dev/shm as tmpfs
init started: BusyBox v1.12.1 (2008-11-25 00:32:40 CST)
starting pid 784, tty '': '/etc/rc.d/startup'
--------start mdev
--------mount tmpfs
OK
--------mount devpts
OK
Setting system clock: hwclock: can't open '/dev/misc/rtc': No such file or directory
FAIL
Setting hostname: OK
Cleaning up system: OK
Setting up interface lo: OK
Running start scripts.
Starting syslogd: syslogd: invalid number '80kb'
FAIL
Starting klogd: OK
Setting up interface eth0: OK
starting pid 805, tty '': '-/bin/login'
android login: root
Jan 1 00:00:18 login[805]: root login on 'console'
EMB#

Wednesday, November 26, 2008

Mounting File system - Porting Linux kernel 2.6.25 (Android version) to SAMSUNG S3C2440A

  Previous time, when linux kernel run at:

Freeing init memory: 140K

the system is halted, after some test, I find that it is the problem of cross-compiled gcc.

  The ARM core of SAMSUNG S3C2440A is ARM920T, therefore, I rebuild the cross-compiled gcc of generic arm with little endian version, the problem has fixed.

The success process of booting linux:


Starting kernel ...

Uncompressing Linux........................................................................................................... done, booting the kernel.
Linux version 2.6.25 (armdev@test.intra.wizign.com) (gcc version 4.1.2) #3 Tue Nov 25 01:55:06 CST 2008
CPU: ARM920T [41129200] revision 0 (ARMv4T), cr=c0007177
Machine: SBZ2440
Memory policy: ECC disabled, Data cache writeback
CPU S3C2440A (id 0x32440001)
S3C244X: core 399.651 MHz, memory 133.217 MHz, peripheral 66.608 MHz
S3C24XX Clocks, (c) 2004 Simtec Electronics
CLOCK: Slow mode (2.116 MHz), fast, MPLL on, UPLL on
CPU0: D VIVT write-back cache
CPU0: I cache: 16384 bytes, associativity 64, 32 byte lines, 8 sets
CPU0: D cache: 16384 bytes, associativity 64, 32 byte lines, 8 sets
Built 1 zonelists in Zone order, mobility grouping on. Total pages: 16256
Kernel command line: root=/dev/nfs rw noinitrd console=ttySAC0,115200 init=/linuxrc nfsroot=192.168.1.12:/vdisk/armdev_fs ip=192.168.1.30:192.168.1.12:1
92.168.1.1:255.255.255.0:android:eth0:off
irq: clearing pending ext status 00000080
irq: clearing subpending status 00000003
irq: clearing subpending status 00000002
PID hash table entries: 256 (order: 8, 1024 bytes)
timer tcon=00500000, tcnt d8d2, tcfg 00000200,00000000, usec 0000170f
Console: colour dummy device 80x30
console [ttySAC0] enabled
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: 61184KB available (3040K code, 507K data, 140K init)
Mount-cache hash table entries: 512
CPU: Testing write buffer coherency: ok
net_namespace: 152 bytes
NET: Registered protocol family 16
S3C2410 Power Management, (c) 2004 Simtec Electronics
S3C2440: Initialising architecture
S3C2440: IRQ Support
S3C24XX DMA Driver, (c) 2003-2004,2006 Simtec Electronics
DMA channel 0 at c4800000, irq 33
DMA channel 1 at c4800040, irq 34
DMA channel 2 at c4800080, irq 35
DMA channel 3 at c48000c0, irq 36
S3C244X: Clock Support, DVS off
usbcore: registered new interface driver usbfs
usbcore: registered new interface driver hub
usbcore: registered new device driver usb
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)
JFFS2 version 2.2. (NAND) © 2001-2006 Red Hat, Inc.
fuse init (API version 7.9)
io scheduler noop registered
io scheduler anticipatory registered (default)
io scheduler deadline registered
io scheduler cfq registered
Console: switching to colour frame buffer device 30x40
fb0: s3c2410fb frame buffer device
lp: driver loaded but no devices found
ppdev: user-space parallel port driver
Serial: 8250/16550 driver $Revision: 1.90 $ 4 ports, IRQ sharing enabled
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
brd: module loaded
loop: module loaded
dm9000 Ethernet Driver, V1.30
eth0: dm9000 at c485e300,c4860304 IRQ 51 MAC: 08:00:3e:26:0a:5b (chip)
Uniform Multi-Platform E-IDE driver
ide: Assuming 50MHz system bus speed for PIO modes; override with idebus=xx
BAST NOR-Flash Driver, (c) 2004 Simtec Electronics
S3C24XX NAND Driver, (c) 2004 Simtec Electronics
s3c2440-nand s3c2440-nand: Tacls=1, 7ns Twrph0=4 30ns, Twrph1=1 7ns
NAND device: Manufacturer ID: 0xec, Chip ID: 0x76 (Samsung NAND 64MiB 3,3V 8-bit)
Scanning device for bad blocks
Creating 2 MTD partitions on "NAND 64MiB 3,3V 8-bit":
0x00000000-0x00200000 : "Kernel"
0x00200000-0x04000000 : "root partition"
usbmon: debugfs is not available
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
mice: PS/2 mouse device common for all mice
S3C24XX RTC, (c) 2004,2006 Simtec Electronics
s3c2440-i2c s3c2440-i2c: slave address 0x10
s3c2440-i2c s3c2440-i2c: bus frequency set to 378 KHz
s3c2440-i2c s3c2440-i2c: i2c-0: S3C I2C adapter
S3C2410 Watchdog Timer, (c) 2004 Simtec Electronics
s3c2410-wdt s3c2410-wdt: watchdog inactive, reset disabled, irq enabled
logger: created 64K log 'log_main'
logger: created 64K log 'log_events'
logger: created 64K log 'log_radio'
TCP cubic registered
NET: Registered protocol family 1
RPC: Registered udp transport module.
RPC: Registered tcp transport module.
drivers/rtc/hctosys.c: unable to open rtc device (rtc0)
eth0: link up, 100Mbps, full-duplex, lpa 0x45E1
IP-Config: Complete:
device=eth0, addr=192.168.1.30, mask=255.255.255.0, gw=192.168.1.1,
host=android, domain=, nis-domain=(none),
bootserver=192.168.1.12, rootserver=192.168.1.12, rootpath=
Looking up port of RPC 100003/2 on 192.168.1.12
Looking up port of RPC 100005/1 on 192.168.1.12
VFS: Mounted root (nfs filesystem).
Freeing init memory: 140K
--------mount /proc as proc
--------mount /sys as sysfs
init started: BusyBox v1.12.1 (2008-11-25 00:32:40 CST)
starting pid 777, tty '': '/etc/rc.d/startup'
mkdir: cannot create directory '/dev/pts': File exists
mkdir: cannot create directory '/dev/shm': File exists
--------start mdev
--------mount tmpfs
OK
--------mount devpts
mount: mounting devpts on /dev/pts failed: No such file or directory
FAIL
Setting system clock: hwclock: can't open '/dev/misc/rtc': No such file or directory
FAIL
Setting hostname: OK
Cleaning up system: OK
Setting up interface lo: OK
Running start scripts.
Starting syslogd: syslogd: invalid number '80kb'
FAIL
Starting klogd: OK
Setting up interface eth0: OK
starting pid 800, tty '': '-/bin/login'
android login: root
ash: id -u: bad number
# uname -a
Linux android 2.6.25 #3 Tue Nov 25 01:55:06 CST 2008 armv4tl unknown
# hostname
android

Wednesday, November 19, 2008

Porting Linux kernel 2.6.25 (Android version) to SAMSUNG S3C2440A

It is fun! Last time, I was porting android to TI Davinci DM355 failed.

This time, I am porting android to SAMSUNG S3C2440A, successfully.

Now, the kernel is bootable, my next step has works:

  • Mounting file system (Temporarily, I can ping to OS, it means that the OS has worked)
  • Tuning GUI and some hardware related driver
  • Porting android's OS environment and demo APs
  • Developing applications

Following list describes basic configuration in the build process; for tuning in detail, some hardware related configuration is a must step, the good references are as following:

linux-2.6.26内核移植到S3C2440平台
linux-2.6.25内核移植到S3C2440平台
移植内核2.6.24.4到S3C2440
《Linux系统移植》


A simple description of porting steps:

CPU is SAMSUNG S3C2440A
Linux kernel Android version 2.6.25.
Cross compiled GCC and build basic OS eviroment, please check this site:
Cross-Compiled Linux From Scratch - Embedded (Version SVN-0.0.1-20080109-arm).


() Busybox-1.12.1 - OS's working environment

cd ${ARMDEV}/build
tar -jxvf ${ARMDEV}/sources/busybox-1.12.1.tar.bz2
cd busybox-1.12.1
patch -Np1 -i ../busybox-1.12.1-fixes-1.patch
patch -Np1 -i ../busybox-1.12.1-iptunnel_headers-1.patch
make defconfig

BUSYBOX_OPTIONS="CONFIG_DMALLOC CONFIG_BUILD_AT_ONCE CONFIG_BUILD_LIBBUSYBOX
CONFIG_FEATURE_SH_IS_NONE CONFIG_LOCALE_SUPPORT CONFIG_TFTP CONFIG_FTPGET
CONFIG_FTPPUT CONFIG_IPCALC CONFIG_TFTP CONFIG_HUSH CONFIG_LASH
CONFIG_MSH CONFIG_INETD CONFIG_DPKG CONFIG_RPM2CPIO CONFIG_RPM
CONFIG_FOLD CONFIG_LOGNAME CONFIG_OD CONFIG_CRONTAB CONFIG_UUDECODE
CONFIG_UUENCODE CONFIG_SULOGIN CONFIG_DC CONFIG_DEBUG_YANK_SUSv2
CONFIG_DEBUG_INIT CONFIG_DEBUG_CROND_OPTION CONFIG_FEATURE_UDHCP_DEBUG
CONFIG_TASKSET CONFIG_CHATTR CONFIG_FSCK CONFIG_LSATTR CONFIG_CHPST
CONFIG_SETUIDGID CONFIG_ENVUIDGID CONFIG_ENVDIR CONFIG_SOFTLIMIT
CONFIG_FEATURE_2_4_MODULES"
for config in $BUSYBOX_OPTIONS; do
cp .config{,.orig}
sed -e "s:${config}=y:${config}=n:" .config.orig > .config
done
BUSYBOX_OPTIONS="CONFIG_FEATURE_SH_IS_ASH CONFIG_FEATURE_TRACEROUTE_VERBOSE CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE"
for config in $BUSYBOX_OPTIONS; do
cp .config{,.orig}
sed -e "s:# ${config} is not set:${config}=y:" .config.orig > .config
done

make ARCH=arm CROSS_COMPILE="${ARM_TARGET}-"
make ARCH=arm CROSS_COMPILE="${ARM_TARGET}-" CONFIG_PREFIX="${ARMDEV}" install

cp examples/depmod.pl ${ARMDEV}/cross-tools/bin
chmod 755 ${ARMDEV}/cross-tools/bin/depmod.pl


() Ext2 - file system tool

cd ${ARMDEV}/build
tar -zxvf ${ARMDEV}/sources/e2fsprogs-1.39.tar.gz
cd e2fsprogs-1.39
mkdir -v build
cd build
CC="${CC} -Os" ../configure --build=${ARM_HOST} --host=${ARM_TARGET} --prefix=/usr --with-root-prefix="" --with-cc="${CC} -Os" --with-linker=${LD}
make
make DESTDIR=${ARMDEV} install
make DESTDIR=${ARMDEV} install-libs


() Iana-Etc-2.20 - network services and communication protocol

cd ${ARMDEV}/build
tar -jxvf ${ARMDEV}/sources/iana-etc-2.20.tar.bz2
cd iana-etc-2.20
make
make DESTDIR=${ARMDEV} install


() Zlib-1.2.3 0 - compress and uncompress program

cd ${ARMDEV}/build
tar -zxvf ${ARMDEV}/sources/zlib-1.2.3.tar.gz
cd zlib-1.2.3
patch -Np1 -i ${ARMDEV}/sources/zlib-1.2.3-DESTDIR-1.patch
cp configure{,.orig}
sed -e 's/-O3/-Os/g' configure.orig > configure

CC="${CC}" ./configure --prefix=/usr --shared
make
make DESTDIR=${ARMDEV} install
mv -v ${ARMDEV}/usr/lib/libz.so.* ${ARMDEV}/lib
ln -svf ../../lib/libz.so.1 ${ARMDEV}/usr/lib/libz.so


() Build password protection mechanics

echo "Create /etc/shadow file"
cat > ${ARMDEV}/etc/shadow << "EOF"
root:$1$BQY1.ACn$rvcsFmggQFH.jyCD/X/NV1:13553:0:99999:7:::
bin:x:13553:0:99999:7:::
daemon:x:13553:0:99999:7:::
adm:x:13553:0:99999:7:::
lp:x:13553:0:99999:7:::
mail:x:13553:0:99999:7:::
news:x:13553:0:99999:7:::
uucp:x:13553:0:99999:7:::
operator:x:13553:0:99999:7:::
postmaster:x:13553:0:99999:7:::
nobody:x:13553:0:99999:7:::
EOF


() cramfs-1.1 - tool for building file system

cd ${ARMDEV}/build
tar -zxvf ${ARMDEV}/sources/cramfs-1.1.tar.gz
cd cramfs-1.1
make

$ su
# cp mkcramfs /usr/bin
# cp cramfsck /usr/bin


() JFFS2 - manage file system of Flash memory

cd ${ARMDEV}/sources
cvs -d :pserver:anoncvs@cvs.infradead.org:/home/cvs login #password: anoncvs
cvs -d :pserver:anoncvs@cvs.infradead.org:/home/cvs co mtd
cd mtd/util/
make clean
make
cp mkfs.jffs /sbin
cp mkfs.jffs2 /sbin


() /etc/fstab

cat > ${ARMDEV}/etc/fstab << "EOF"
# Begin /etc/fstab

# Help information
# man 5 fstab

# file system mount-point type options dump fsck
# order

/dev/ram / ext2 defaults 1 1
proc /proc proc defaults 0 0
sysfs /sys sysfs defaults 0 0
devpts /dev/pts devpts gid=4,mode=620 0 0
shm /dev/shm tmpfs defaults 0 0
none /proc/bus/usb usbdevfs defaults 0 0

# End /etc/fstab
EOF


() Linux-2.6.25 (android version)

cd ${ARMDEV}/build
tar -jxvf ${ARMDEV}/sources/linux-2.6.25-android-1.0_r1.tar.gz
mv kernel.git linux-android-2.6.25
cd linux-android-2.6.25
make mrproper

make ARCH=arm CROSS_COMPILE=${ARM_TARGET}- s3c2410_defconfig
make ARCH=arm CROSS_COMPILE=${ARM_TARGET}- gconfig

The following configuration is only for my evaluation board, just for reference.
Device Drivers
Block Devices BLK_DEV
RAM block device support BLK_DEV_RAM
(2) Default number of RAM disks BLK_DEV_RAM_COUNT
(41984) Default RAM disk size (kbytes) BLK_DEV_RAM_SIZE
(1024) Default RAM disk block size (bytes) BLK_DEV_RAM_BLOCKSIZE

File systems
Kernel automounter support AUTOFS_FS
kernel automounter version 4 support AUTOFS4_FS
Filesystem in Userspace support FUSE_FS
Pseudo filesystems
/dev/ file system support DEVFS_FS
Virtual memory file system support (former shm fs) TMPFS
Userspace-driven configuration filesystem CONFIGFS_FS
Miscellaneous filesystems
YAFFS2 file system support YAFFS_FS
512 byte / page devices YAFFS_YAFFS1
2048 byte / page devices YAFFS_YAFFS2
Network File Systems NETWORK_FILESYSTEMS
NFS file system support NFS_FS
Provide NFSv3 client support NFS_V3
Root file system on NFS ROOT_NFS
Journalling Flash File System v2 (JFFS2) support JFFS2_FS
JFFS2 debugging verbosity (0 = quiet, 2 = noisy) JFFS2_FS_DEBUG
JFFS2 write-buffering support JFFS2_FS_WRITEBUFFER
Advanced compression options for JFFS2 JFFS2_COMPRESSION_OPTIONS
JFFS2 ZLIB compression support JFFS2_ZLIB
JFFS2 RTIME compression support JFFS2_RTIME
JFFS2 RUBIN compression support JFFS2_RUBIN

Boot options
Default kernel command string CMDLINE {command}
{command}
root=/dev/hda1 rw rootfstype=cramfs noinitrd init=/linuxrc console=ttySAC0,115200 mem=64M


() /linuxrc

cd ${ARMDEV}
mv linuxrc linuxrc.busybox
cat > ${ARMDEV}/linuxrc << "EOF"
#!/bin/sh

echo "mount /etc as ramfs"
/bin/mount -n -t ramfs ramfs /etc
/bin/cp -a /mnt/etc/* /etc

# re-create the /etc/mtab entries
echo "re-create the /etc/mtab entries"
/bin/mount -f -t cramfs -o remount,ro /dev/mtdblock1 /

# mount some file system
echo "--------munt /dev/shm as tmpfs"
/bin/mount -n -t tmpfs tmpfs /dev/shm

# mount /proc as proc file system
echo "--------mount /proc as proc"
/bin/mount -n -t proc none /proc

# mount /sys as sysfs file system
echo "--------mount /sys as sysfs
/bin/mount -n -t sysfs none /sys

#input command to LCD
#sh < /dev/ttyS0

exec /sbin/init
EOF

chmod 775 ${ARMDEV}/linuxrc


() /etc/inetd.conf

cat > ${ARMDEV}/etc/inetd.conf << "EOF"
#
telnet stream tcp nowait root /usr/sbin/telnetd
EOF


() CLFS-Bootscripts-1.0-pre4

cd ${ARMDEV}/build
tar -jxvf ${ARMDEV}/sources/clfs-embedded-bootscripts-1.0-pre4.tar.bz2
cd clfs-embedded-bootscripts
make DESTDIR=${ARMDEV} install

() /etc/mdev.conf

cat > ${ARMDEV}/etc/mdev.conf << "EOF"
# /etc/mdev/conf
SLEEP=10

# Symlinks:
# Syntax: %s -> %s

MAKEDEV -> ../sbin/MAKEDEV
/proc/core -> kcore
fd -> /proc/self/fd
mcdx -> mcdx0
radio -> radio0
ram -> ram1
sbpcd -> sbpcd0
sr0 -> scd0
sr1 -> scd1
sr10 -> scd10
sr11 -> scd11
sr12 -> scd12
sr13 -> scd13
sr14 -> scd14
sr15 -> scd15
sr16 -> scd16
sr2 -> scd2
sr3 -> scd3
sr4 -> scd4
sr5 -> scd5
sr6 -> scd6
sr7 -> scd7
sr8 -> scd8
sr9 -> scd9
stderr -> fd/2
stdin -> fd/0
stdout -> fd/1

# Remove these devices, if using a headless system
# You will see an error mdev: Bad line 35
vbi -> vbi0
vcs -> vcs0
vcsa -> vcsa0
video -> video0
# Stop Remove for headless system

# Devices:
# Syntax: %s %d:%d %s
# devices user:group mode

null 0:0 777
zero 0:0 666

urandom 0:0 444

console 0:5 0600
fd0 0:11 0660
hdc 0:6 0660
kmem 0:9 000
mem 0:9 0640
port 0:9 0640
ptmx 0:5 0660

sda* 0:6 0660
sdb* 0:6 0660
hda* 0:6 0660
hdb* 0:6 0660

tty 0:5 0660
tty0* 0:5 0660
tty1* 0:5 0660
tty2* 0:5 0660
tty3* 0:5 0660
tty4* 0:5 0660
tty5* 0:5 0660
tty6* 0:5 0660

ttyS* 0:20 640
EOF


() /etc/profile

cat > ${ARMDEV}/etc/profile << "EOF"
# /etc/profile

# Set the initial path
export PATH=/bin:/usr/bin

if [ 'id -u' -eq 0 ] ; then
PATH=/bin:/sbin:/usr/bin:/usr/sbin
unset HISTFILE
fi

# Setup some environment variables.
export USER='id -un'
export LOGNAME=$USER
export HOSTNAME='/bin/hostname'
export HISTSIZE=1000
export HISTFILESIZE=1000
export PAGER='/bin/more '
export EDITOR='/bin/vi'
export INPUTRC=/etc/inputrc

# End /etc/profile
EOF


() Creating the /etc/inputrc File

cat > ${ARMDEV}/etc/inputrc << "EOF"
# Begin /etc/inputrc
# Modified by Chris Lynn

# Allow the command prompt to wrap to the next line
set horizontal-scroll-mode Off

# Enable 8bit input
set meta-flag On
set input-meta On

# Turns off 8th bit stripping
set convert-meta Off

# Keep the 8th bit for display
set output-meta On

# none, visible or audible
set bell-style none

# All of the following map the escape sequence of the
# value contained inside the 1st argument to the
# readline specific functions

"\eOd": backward-word
"\eOc": forward-word

# for linux console
"\e[1~": beginning-of-line
"\e[4~": end-of-line
"\e[5~": beginning-of-history
"\e[6~": end-of-history
"\e[3~": delete-char
"\e[2~": quoted-insert

# for xterm
"\eOH": beginning-of-line
"\eOF": end-of-line

# for Konsole
"\e[H": beginning-of-line
"\e[F": end-of-line

# End /etc/inputrc
EOF


() /etc/inittab

cat > ${ARMDEV}/etc/inittab << "EOF"
# /etc/inittab

::sysinit:/etc/rc.d/startup

::respawn:/usr/sbin/telnetd

tty1::respawn:/sbin/getty 38400 tty1
tty2::respawn:/sbin/getty 38400 tty2
tty3::respawn:/sbin/getty 38400 tty3
tty4::respawn:/sbin/getty 38400 tty4
tty5::respawn:/sbin/getty 38400 tty5
tty6::respawn:/sbin/getty 38400 tty6

# Put a getty on the serial line (for a terminal)
# uncomment this line if your using a serial console
#::respawn:/sbin/getty -L ttyS0 115200 vt100
::respawn:/sbin/getty -L ttySAC0 115200 vt100
#T0:12345:respawn:/sbin/getty -n -l /usr/local/sbin/autologin -L /dev/tts/1 115200 vt100

::shutdown:/etc/rc.d/shutdown
::ctrlaltdel:/sbin/reboot
EOF


() Setting Hostname

echo "android" > ${ARMDEV}/etc/HOSTNAME

() /etc/hosts File

Has network card

cat > ${ARMDEV}/etc/hosts << "EOF"
# Begin /etc/hosts (network card version)

127.0.0.1 localhost
192.168.1.30 android.wizign.com android

# End /etc/hosts (network card version)
EOF

Without network card

cat > ${ARMDEV}/etc/hosts << "EOF"
# Begin /etc/hosts (no network card version)

127.0.0.1 dpf-dev.wizign.com dpf-dev localhost

# End /etc/hosts (no network card version)
EOF

() Configuring the network Script

cat > ${ARMDEV}/etc/network.conf << "EOF"
# /etc/network.conf
# Global Networking Configuration
# interface configuration is in /etc/network.d/

# set to yes to enable networking
NETWORKING=yes

# set to yes to set default route to gateway
USE_GATEWAY=no

# set to gateway IP address
GATEWAY=192.168.1.1
EOF


() creates a sample interface.eth0 file for the eth0 device:

mkdir ${ARMDEV}/etc/network.d &&
cat > ${ARMDEV}/etc/network.d/interface.eth0 << "EOF"
# Network Interface Configuration

# network device name
INTERFACE=eth0

# set to yes to use DHCP instead of the settings below
DHCP=no

# IP address
IPADDRESS=192.168.1.30

# netmask
NETMASK=255.255.255.0

# broadcast address
BROADCAST=192.168.1.255
EOF


() Creating the ${ARMDEV}/etc/resolv.conf File

cat > ${ARMDEV}/etc/resolv.conf << "EOF"
# Begin /etc/resolv.conf

domain wizign.com
nameserver 168.95.1.1
nameserver 168.95.192.1

# End /etc/resolv.conf
EOF


() Copy the clean OS system, preparing to port on the evaluation board

su -

if [ ! -d /mnt/armdev_fs ]; then
mkdir /mnt/armdev_fs
fi
mount --bind /vdisk/armdev_fs /mnt/armdev_fs

export ARMDEV="/mnt/armdev"
export ARMDEV_FS="/mnt/armdev_fs"

for dir in $(ls "${ARMDEV}"); do
if [ "$dir" == 'sources' ]; then
echo "Skip $dir"
elif [ "$dir" == 'build' ]; then
echo "Skip $dir"
elif [ "$dir" == 'cross-tools' ]; then
echo "Skip $dir"
else
cp -avr ""${ARMDEV}"/$dir" "${ARMDEV_FS}/."
fi
done

rm -rfv ${ARMDEV_FS}/usr/src/*
rm -rfv ${ARMDEV_FS}/usr/include
rm -rfv ${ARMDEV_FS}/usr/man
rm -rfv ${ARMDEV_FS}/usr/share/man

FILES="'ls ${ARMDEV_FS}/lib/*.a ${ARMDEV_FS}/usr/lib/*.a'"
for file in $FILES; do
rm -fv $file
done

chown -Rv root:root ${ARMDEV_FS}
chgrp -v utmp ${ARMDEV_FS}/var/run/utmp ${ARMDEV_FS}/var/log/lastlog
mknod -m 0666 ${ARMDEV_FS}/dev/null c 1 3
mknod -m 0600 ${ARMDEV_FS}/dev/console c 5 1

If using cramfs
mkcramfs ${ARMDEV_FS} /mnt/rootfs.cramfs
cp /mnt/rootfs.cramfs /var/lib/tftpboot/ramdisk-android-2.6.25.cramfs

If using jffs2
mkfs.jffs2 -d ${ARMDEV_FS} -p -s 0x200 -e 0x4000 -n -l -U -o ramdisk.jffs2
cp /mnt/ramdisk.jffs2 /var/lib/tftpboot/ramdisk-android-2.6.25.jffs2


() This shell script is used to build RAM disk

cat > /mnt/mkramdisk.sh << "EOF"
#! /bin/bash

# Remove files
echo "remove files"
rm -f ramdisk.img.gz
rm -f ramdisk32.img
rm -f ramdisk.img
rm -fr ramdisk

# Create ramdisk32
echo "create ramdisk32"
cd /mnt
dd if=/dev/zero of=ramdisk32.img bs=1024 count=40960
mke2fs -F -vm0 ramdisk32.img
mkdir ramdisk
mount -o loop ramdisk32.img ramdisk
cd ramdisk/
cp -arv ${ARMDEV_FS}/* .
cd ..
umount ramdisk

# Make ram disk image
echo "make ram disk image"
cp ramdisk32.img ramdisk.img
gzip ramdisk.img
./mkimage -A arm -O linux -T ramdisk -C gzip -a 30080000 -e 30080000 -d ramdisk.img.gz -n 'SBZ2440 Ramdisk' ram.img

# copy files
echo "Copy RAM disk file"
cp ram.img /var/lib/tftpboot/ramdisk-android-2.6.25.s
echo "Copy uImage file"
cp ${ARMDEV}/build/linux-android-2.6.25/arch/arm/boot/uImage /var/lib/tftpboot/uImage-android-s3c2440
EOF


() The booting processes is as following:

Starting kernel ...

Uncompressing Linux........................................................................................................... done, booting the kerne.
Linux version 2.6.25 (armdev@test.intra.wizign.com) (gcc version 4.1.2) #54 Wed Nov 19 09:19:00 CST 2008
CPU: ARM920T [41129200] revision 0 (ARMv4T), cr=c0007177
Machine: SBZ2440
Memory policy: ECC disabled, Data cache writeback
CPU S3C2440A (id 0x32440001)
S3C244X: core 399.651 MHz, memory 133.217 MHz, peripheral 66.608 MHz
S3C24XX Clocks, (c) 2004 Simtec Electronics
CLOCK: Slow mode (2.116 MHz), fast, MPLL on, UPLL on
CPU0: D VIVT write-back cache
CPU0: I cache: 16384 bytes, associativity 64, 32 byte lines, 8 sets
CPU0: D cache: 16384 bytes, associativity 64, 32 byte lines, 8 sets
Built 1 zonelists in Zone order, mobility grouping on. Total pages: 16256
Kernel command line: root=/dev/nfs rw noinitrd console=ttySAC0,115200 init=/linuxrc nfsroot=192.168.1.12:/vdisk/armdev_fs ip=192.168.1.30:192.168.1.12f
irq: clearing pending ext status 00000080
irq: clearing subpending status 00000003
irq: clearing subpending status 00000002
PID hash table entries: 256 (order: 8, 1024 bytes)
timer tcon=00500000, tcnt d8d2, tcfg 00000200,00000000, usec 0000170f
Console: colour dummy device 80x30
console [ttySAC0] enabled
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: 61184KB available (3040K code, 507K data, 144K init)
Mount-cache hash table entries: 512
CPU: Testing write buffer coherency: ok
net_namespace: 152 bytes
NET: Registered protocol family 16
S3C2410 Power Management, (c) 2004 Simtec Electronics
S3C2440: Initialising architecture
S3C2440: IRQ Support
S3C24XX DMA Driver, (c) 2003-2004,2006 Simtec Electronics
DMA channel 0 at c4800000, irq 33
DMA channel 1 at c4800040, irq 34
DMA channel 2 at c4800080, irq 35
DMA channel 3 at c48000c0, irq 36
S3C244X: Clock Support, DVS off
usbcore: registered new interface driver usbfs
usbcore: registered new interface driver hub
usbcore: registered new device driver usb
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)
JFFS2 version 2.2. (NAND) �© 2001-2006 Red Hat, Inc.
fuse init (API version 7.9)
io scheduler noop registered
io scheduler anticipatory registered (default)
io scheduler deadline registered
io scheduler cfq registered
Console: switching to colour frame buffer device 30x40
fb0: s3c2410fb frame buffer device
lp: driver loaded but no devices found
ppdev: user-space parallel port driver
Serial: 8250/16550 driver $Revision: 1.90 $ 4 ports, IRQ sharing enabled
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
brd: module loaded
loop: module loaded
dm9000 Ethernet Driver, V1.30
eth0: dm9000 at c485e300,c4860304 IRQ 51 MAC: 08:00:3e:26:0a:5b (chip)
Uniform Multi-Platform E-IDE driver
ide: Assuming 50MHz system bus speed for PIO modes; override with idebus=xx
BAST NOR-Flash Driver, (c) 2004 Simtec Electronics
S3C24XX NAND Driver, (c) 2004 Simtec Electronics
s3c2440-nand s3c2440-nand: Tacls=3, 22ns Twrph0=8 60ns, Twrph1=3 22ns
NAND device: Manufacturer ID: 0xec, Chip ID: 0x76 (Samsung NAND 64MiB 3,3V 8-bit)
Scanning device for bad blocks
Creating 2 MTD partitions on "NAND 64MiB 3,3V 8-bit":
0x00000000-0x00200000 : "Kernel"
0x00200000-0x04000000 : "root partition"
usbmon: debugfs is not available
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
mice: PS/2 mouse device common for all mice
S3C24XX RTC, (c) 2004,2006 Simtec Electronics
s3c2440-i2c s3c2440-i2c: slave address 0x10
s3c2440-i2c s3c2440-i2c: bus frequency set to 378 KHz
s3c2440-i2c s3c2440-i2c: i2c-0: S3C I2C adapter
S3C2410 Watchdog Timer, (c) 2004 Simtec Electronics
s3c2410-wdt s3c2410-wdt: watchdog inactive, reset disabled, irq enabled
logger: created 64K log 'log_main'
logger: created 64K log 'log_events'
logger: created 64K log 'log_radio'
TCP cubic registered
NET: Registered protocol family 1
RPC: Registered udp transport module.
RPC: Registered tcp transport module.
drivers/rtc/hctosys.c: unable to open rtc device (rtc0)
eth0: link up, 100Mbps, full-duplex, lpa 0x45E1
IP-Config: Complete:
device=eth0, addr=192.168.1.30, mask=255.255.255.0, gw=192.168.1.1,
host=Android, domain=, nis-domain=(none),
bootserver=192.168.1.12, rootserver=192.168.1.12, rootpath=
prepare_namespace() - start
mount_root()
Looking up port of RPC 100003/2 on 192.168.1.12
Looking up port of RPC 100005/1 on 192.168.1.12
VFS: Mounted root (nfs filesystem).
prepare_namespace() - end
Freeing init memory: 144K


() Use ping to test that the system is booted

$ ping 192.168.1.30
PING 192.168.1.30 (192.168.1.30) 56(84) bytes of data.
64 bytes from 192.168.1.30: icmp_seq=1 ttl=64 time=0.417 ms
64 bytes from 192.168.1.30: icmp_seq=2 ttl=64 time=0.384 ms
64 bytes from 192.168.1.30: icmp_seq=3 ttl=64 time=0.381 ms

Saturday, November 15, 2008

Source code editor - kscope

If you are not customized the emacs editor style, maybe the kscope editor is a good choice to edit source code.
KScope is a source code editor, implementing Cscope, on KDE environment.


Let's doing a simple editing steps:

Open project:


















Add the related source code on the list (select tree button):


















Open the target source code file:


















Search the definition position of function:


















Use relational chart to display target function and other functions,


















To install kscope:

Fedora Core 9:

# yum install kscope

Ubuntu 8.10:

# apt-get install kscope

Source code editor - emacs + ecb

To browse, search, and edit the source code of linux kernel, the general editors is not a good tool. One of the best way is using emacs + ECB(Emacs Code Browse)

To use ECB, it supports following functional windows:
  • Directory tree window
  • Source code file list window
  • Display current opened file's functions, classes, method, and ....etc.
  • The history opened files window
  • Some convenient editing functions

To start the editing mode, after run emacs, presses {Alt+X} keys, keying ecb-activate{Enter}, now, you are preparing to edit source code file, the display window is as the showing picture.


To install emacs and ecb:

Fedora Core 9:

# yum install emacs ecb

Ubuntu 8.10:

# apt-get install emacs ecb
or
# apt-get install emacs22 ecb

If you want to install emacs for MS Windows, go to emacs,s web site. Then read some configuration from ecb web site.

Wednesday, November 5, 2008

Unfinished task - porting android linux-2.6.23 to TI Davinci DM355

This is an unfinished task, I post it for sharing my experience of encountered problems while I am porting linux kernel to a new hardware device.

Target device is TMS320DM355 DVEVM.
The linux kernel is android version 2.6.23.
Cross compiled GCC is built by myself, the study source is Cross-Compiled Linux From Scratch - Embedded (Version SVN-0.0.1-20080109-arm).

A good reference document about porting linux kernel is "Porting the Linux Kernel to a New ARM Platform", Wookey and Tak-Shing, Aleph One

The last encountered problem is that the kernel can not boot from DVEVM board, the display information is as following:

2048 MiB
In: serial
Out: serial
Err: serial
ARM Clock :- 216MHz
DDR Clock :- 171MHz
Hit any key to stop autoboot: 0
BOOTP broadcast 1
DHCP client bound to address 192.168.1.101
TFTP from server 192.168.1.12; our IP address is 192.168.1.101
Filename 'uImage-android'.
Load address: 0x80700000
Loading: #################################################################
#################################################################
#################################################################
#################################################################
#################################################################
####################
done
Bytes transferred = 1764160 (1aeb40 hex)
## Booting image at 80700000 ...
Image Name: Linux-2.6.23
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 1764096 Bytes = 1.7 MB
Load Address: 80008000
Entry Point: 80008000
Verifying Checksum ... OK
OK

Starting kernel ...

Uncompressing Linux.................................................................................................................. done, booting the kernel.

After my basic analysis, it seems that it is related to the process of enabling the MMU, the dependent file is arch/arm/kernel/head.S; other possible files are arch/arm/mm/proc-arm926.S and arch/arm/mach-davinci/board-evm.c.


The most files that I have modified are listed as following:

arch/arm/tools/mach-types
arch/arm/Kconfig
arch/arm/Makefile
arch/arm/kernel/head.S
arch/arm/kernel/head-common.S
arch/arm/kernel/debug.S
arch/arm/mm/Kconfig
arch/arm/mach-davinci/Kconfig
arch/arm/mach-davinci/Makefile
arch/arm/mach-davinci/io.c
arch/arm/mach-davinci/irq.c
arch/arm/mach-davinci/time.c
arch/arm/mach-davinci/clock.c
arch/arm/mach-davinci/serial.c
arch/arm/mach-davinci/gpio.c
arch/arm/mach-davinci/psc.c
arch/arm/mach-davinci/board-evm.c
include/asm-arm/arch-davinci/
include/asm-arm/arch-davinci/gpio.h
include/asm-arm/arch-davinci/io.h
include/asm-arm/arch-davinci/dma.h
include/asm-arm/arch-davinci/memory.h
include/asm-arm/arch-davinci/system.h
include/asm-arm/arch-davinci/timex.h
include/asm-arm/arch-davinci/hardware.h
include/asm-arm/arch-davinci/cpu.h
include/asm-arm/arch-davinci/uncompress.h
include/asm-arm/mach/arch.h
include/asm-arm/setup.h
include/asm-arm/procinfo.h


The following context describes the modified source code in each files:

### arch/arm/tools/mach-types ###

# machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number
#
anakin ARCH_ANAKIN ANAKIN 57
davinci_dm355_evm MACH_DAVINCI_DM355_EVM DAVINCI_DM355_EVM 1381


### arch/arm/Kconfig ###

config LEDS

depends on ARCH_CDB89712 || ARCH_CO285 || ARCH_EBSA110 || \
ARCH_EBSA285 || ARCH_IMX || ARCH_INTEGRATOR || \
ARCH_LUBBOCK || MACH_MAINSTONE || ARCH_NETWINDER || \
ARCH_OMAP || ARCH_P720T || ARCH_PXA_IDP || \
ARCH_SA1100 || ARCH_SHARK || ARCH_VERSATILE || \
ARCH_AT91 || MACH_TRIZEPS4 || ARCH_DAVINCI || \
ARCH_KS8695 || MACH_DAVINCI_EVM

config LEDS_TIMER

bool "Timer LED" if (!ARCH_CDB89712 && !ARCH_OMAP) || \
OMAP_OSK_MISTRAL || MACH_OMAP_H2 \
|| MACH_OMAP_PERSEUS2 || MACH_DAVINCI_EVM
depends on LEDS || MACH_DAVINCI_EVM


if PCMCIA || ARCH_CLPS7500 || ARCH_IOP32X || ARCH_IOP33X || ARCH_IXP4XX \
|| ARCH_L7200 || ARCH_LH7A40X || ARCH_PXA || ARCH_RPC \
|| ARCH_S3C2410 || ARCH_SA1100 || ARCH_SHARK || FOOTBRIDGE \
|| ARCH_IXP23XX || ARCH_DAVINCI
source "drivers/ide/Kconfig"
endif


### arch/arm/Makefile ###

CPPFLAGS_vmlinux.lds = -DTEXT_OFFSET=$(TEXT_OFFSET)

machine-$(CONFIG_ARCH_DAVINCI) := davinci

#Default value
head-y := arch/arm/kernel/head$(MMUEXT).o arch/arm/kernel/init_task.o
textofs-y := 0x00008000


### arch/arm/kernel/head.S ###

/* line 81~93 */

.type stext, %function
ENTRY(stext)
msr cpsr_c, #PSR_F_BIT | PSR_I_BIT | SVC_MODE @ ensure svc mode
@ and irqs disabled
mrc p15, 0, r9, c0, c0 @ get processor id
bl __lookup_processor_type @ r5=procinfo r9=cpuid
movs r10, r5 @ invalid processor (r5=0)?
beq __error_p @ yes, error 'p'
bl __lookup_machine_type @ r5=machinfo
movs r8, r5 @ invalid machine (r5=0)?
beq __error_a @ yes, error 'a'
bl __vet_atags
bl __create_page_tables


# comment
__vet_atags:arch/arm/kernel/head-common.S
__create_page_tables


### arch/arm/kernel/head-common.S ###

/* line 80~114 */

.type __error_a, %function
__error_a:
#ifdef CONFIG_DEBUG_LL
mov r4, r1 @ preserve machine ID
adr r0, str_a1
bl printascii
mov r0, r4
bl printhex8
adr r0, str_a2
bl printascii
adr r3, 3f
ldmia r3, {r4, r5, r6} @ get machine desc list
sub r4, r3, r4 @ get offset between virt&phys
add r5, r5, r4 @ convert virt addresses to
add r6, r6, r4 @ physical address space
1: ldr r0, [r5, #MACHINFO_TYPE] @ get machine type
bl printhex8
mov r0, #'\t'
bl printch
ldr r0, [r5, #MACHINFO_NAME] @ get machine name
add r0, r0, r4
bl printascii
mov r0, #'\n'
bl printch
add r5, r5, #SIZEOF_MACHINE_DESC @ next machine_desc
cmp r5, r6
blo 1b
adr r0, str_a3
bl printascii
b __error
str_a1: .asciz "\nError: unrecognized/unsupported machine ID (r1 = 0x"
str_a2: .asciz ").\n\nAvailable machine support:\n\nID (hex)\tNAME\n"
str_a3: .asciz "\nPlease check your kernel config and/or bootloader.\n"
.align
#endif


### arch/arm/kernel/debug.S ###

Debug Serial Output
addruart, rx - Provide UART address in \rx
senduart rd, rx - Send character in \rd (@ address \rx)
busyuart rd, rx - Wait until UART is done sending
waituart rd, rx - Wait for Clear to Send


### arch/arm/mm/Kconfig ###

# ARM926T
config CPU_ARM926T
bool "Support ARM926T processor"
depends on ARCH_GOLDFISH || ARCH_INTEGRATOR || ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || MACH_REALVIEW_EB || ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 || ARCH_AT91SAM9260 || ARCH_AT91SAM9261 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_NS9XXX || ARCH_DAVINCI
default y if ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 || ARCH_AT91SAM9260 || ARCH_AT91SAM9261 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_NS9XXX || ARCH_DAVINCI
select CPU_32v5
select CPU_ABRT_EV5TJ
select CPU_CACHE_VIVT
select CPU_CP15_MMU
select CPU_COPY_V4WB if MMU
select CPU_TLB_V4WBI if MMU
select ARM_THUMB
help
This is a variant of the ARM920. It has slightly different
instruction sequences for cache and TLB operations. Curiously,
there is no documentation on it at the ARM corporate website.

Say Y if you want support for the ARM926T processor.
Otherwise, say N.


### arch/arm/mach-davinci/Kconfig ###

config ARCH_DAVINCI355
default n
bool "DaVinci DM355 based system"

comment "DaVinci Board Type"

config MACH_DAVINCI_EVM
bool "TI DaVinci EVM"
default y
depends on ARCH_DAVINCI644x
help
Configure this option to specify the whether the board used
for development is a DaVinci EVM

config MACH_DAVINCI_DM355_EVM
bool "TI DM355 EVM"
default n
depends on ARCH_DAVINCI355
help
Configure this option to specify the whether the board used
for development is a DM355 EVM

config DAVINCI_I2C_EXPANDER
bool "TI DaVinci I2C Expander"
default y
depends on ARCH_DAVINCI644x
select I2C_DAVINCI
help
Configure this option to specify whether the board used
has I2C exapnder with ATA, USB, CF.

config DAVINCI_MCBSP
bool
prompt "DaVinci McBSP Driver" if SOUND_DAVINCI=n
depends on ARCH_DAVINCI
default SOUND_DAVINCI
---help---
DaVinci McBSP driver. Auto-enabled by DaVinci sound driver.

comment "DaVinci Options"

config DAVINCI_BLK_DEV_CF
bool "TI DaVinci CF Card Support"
default Y
depends on BLK_DEV_DAVINCI
help
Configure this option to enable CF Card support.

config DM355_NAND_256KB_BLOCKS
bool "NAND chip installed on DM355 EVM has 256KB blocks"
default y
depends on MACH_DAVINCI_DM355_EVM
help
The boot firmware on the DM355 EVM assumes a default partition map
for NAND flash based on erase block offsets. Thus, the partition map
varies based on the size of the erase blocks in the particular NAND
flash component installed on the board. Answer Y here if the NAND
chip (e.g a 16 Gigabit Micron MT29F16G08QAA) installed on your board
has 256KB blocks. Answer N here if the NAND chip (e.g. a 4 Gigabit
Micron MT29F4G08AAA) installed on your board has 128KB blocks.

choice
prompt "Low-level debug console UART"
default DAVINCI_LL_DEBUG_UART0

config DAVINCI_LL_DEBUG_UART0
bool "UART0"

config DAVINCI_LL_DEBUG_UART1
bool "UART1"

endchoice

config DM355_SPI
bool "TI DM355 SPI device"
default y
help
Configure this option to specify whether the board used
has SPI device.


### arch/arm/mach-davinci/Makefile ###

# Common objects
obj-y := time.o irq.o clock.o serial.o io.o id.o psc.o gpio.o mux.o

# Board specific
# obj-$(CONFIG_MACH_DAVINCI_EVM) += board-evm.o
obj-$(CONFIG_MACH_DAVINCI_DM355_EVM) += board-evm.o


### arch/arm/mach-davinci/io.c ###

static struct map_desc davinci_io_desc[] __initdata = {
{
.virtual = IO_VIRT,
.pfn = __phys_to_pfn(IO_PHYS),
.length = IO_SIZE,
.type = MT_DEVICE
},
{
.virtual = DAVINCI_IRAM_VIRT,
.pfn = __phys_to_pfn(DAVINCI_IRAM_BASE),
.length = SZ_16K,
.type = MT_DEVICE
},
};

void __init davinci_map_common_io(void)
{
...

davinci_clk_init();
}


### arch/arm/mach-davinci/irq.c ###

### arch/arm/mach-davinci/time.c ###

### arch/arm/mach-davinci/clock.c ###

#include

int __init davinci_clk_init(void)
{
...

if (cpu_is_davinci_dm355()) {
/*
* FIXME
* We're assuming a 24MHz reference, but the DM355 also
* supports a 36MHz reference.
*/
unsigned long postdiv;

/*
* Read the PLL1 POSTDIV register to determine if the post
* divider is /1 or /2
*/
postdiv = (davinci_readl(DAVINCI_PLL_CNTRL0_BASE + 0x128) & 0x1f) + 1;

fixedrate = 24000000;
armrate = (PLL1_PLLM + 1)*(fixedrate/(16*postdiv));
commonrate = armrate/2;
} else {
...
}
...

}


### arch/arm/mach-davinci/serial.c ###

void __init davinci_serial_init(struct platform_device *pdev)
{
struct clk *uart_clk;
struct device *dev = &pdev->dev;
struct plat_serial8250_port *p;
int uart;
char uart_name[6];

memset(uart_name, 0, sizeof(uart_name));
for (p = dev->platform_data; p && p->flags; p++) {
switch (p->mapbase) {
case DAVINCI_UART0_BASE:
uart = 0;
break;
case DAVINCI_UART1_BASE:
uart = 1;
break;
case DM644X_UART2_BASE:
case DM355_UART2_BASE:
uart = 2;
break;
default:
dev_err(dev,
"Unknown UART base address 0x%08lx\n",
p->mapbase);
continue;
}
sprintf(uart_name, "UART%i", uart);
uart_clk = clk_get(dev, uart_name);
if (IS_ERR(uart_clk))
dev_err(dev, "failed to get %s clock\n", uart_name);
else
clk_enable(uart_clk);
davinci_serial_reset(p);
}
}


### arch/arm/mach-davinci/gpio.c ###

int gpio_interrupt_bank_enable(int gpio)
{
void *__iomem ptr1;
u32 temp = 0;
u32 mask = 0;
u32 gpio_bank;
u32 max_gpio = 0;

if (cpu_is_davinci_dm355())
max_gpio = DM355_NUM_GIOS;
else if (cpu_is_davinci_dm6443())
max_gpio = DM644x_NUM_GIOS;

if (gpio >= max_gpio)
return -EINVAL;
gpio_bank = gpio/16;

ptr1 = (void *__iomem) IO_ADDRESS(DAVINCI_GPIO_BASE + 0x8);
mask = (1 << temp =" __raw_readl(ptr1);" g =" gpio2controller(gpio);" mask =" gpio_mask(gpio);">set_rising);
if (trigger & TRIGGER_FALLING_EDGE)
__raw_writel(mask, &g->set_falling);
return 0;
}
EXPORT_SYMBOL(gpio_interrupt_enable);

int gpio_interrupt_disable(unsigned gpio, int trigger)
{
struct gpio_controller *__iomem g = gpio2controller(gpio);
u32 mask;
if (!g)
return -EINVAL;

if (trigger & ~(TRIGGER_RISING_EDGE|TRIGGER_FALLING_EDGE))
return -EINVAL;

mask = gpio_mask(gpio);

if (trigger & TRIGGER_RISING_EDGE)
__raw_writel(mask, &g->clr_rising);
if (trigger & TRIGGER_FALLING_EDGE)
__raw_writel(mask, &g->clr_falling);
return 0;
}
EXPORT_SYMBOL(gpio_interrupt_disable);


### arch/arm/mach-davinci/psc.c ###

void __init davinci_psc_init(void)
{
// board_setup_psc() - in DM355
...

davinci_psc_config(DAVINCI_GPSC_ARMDOMAIN, DAVINCI_LPSC_McBSP1, 1);
davinci_psc_config(DAVINCI_GPSC_ARMDOMAIN, DAVINCI_LPSC_SPI, 1);

/* Turn on WatchDog timer LPSC. Needed for RESET to work */
davinci_psc_config(DAVINCI_GPSC_ARMDOMAIN, DAVINCI_LPSC_TIMER2, 1);

davinci_serial_init(&serial_device);
davinci_writel(0x56837210, DAVINCI_VPSS_REGS_BASE + 0x810);
davinci_writel(0x7b3c0004, DAVINCI_VPSS_REGS_BASE + 0x814);

}


### arch/arm/mach-davinci/board-evm.c ###

MACHINE_START(DAVINCI_EVM, "DaVinci DM355 EVM")
/* Maintainer: MontaVista Software */
.phys_io = IO_PHYS,
.io_pg_offst = (io_p2v(IO_PHYS) >> 18) & 0xfffc,
.boot_params = (DAVINCI_DDR_BASE + 0x100),
.map_io = davinci_evm_map_io,
.init_irq = davinci_evm_irq_init,
.timer = &davinci_timer,
.init_machine = davinci_evm_init,
MACHINE_END

static __init void davinci_evm_init(void)
{
davinci_psc_init();

...

platform_add_devices(davinci_evm_devices,
ARRAY_SIZE(davinci_evm_devices));
}



static void __init davinci_evm_map_io(void)
{
davinci_map_common_io();

// start - montavista - 2008/04/18
#ifdef CONFIG_KGDB_8250
early_serial_setup((struct uart_port *)&serial_platform_data[kgdb8250_ttyS]);
kgdb8250_add_platform_port(kgdb8250_ttyS, &serial_platform_data[kgdb8250_ttyS]);
#endif
/* Initialize the DaVinci EVM board settigs */
board_init ();
// end - montavista - 2008/04/18
}


### include/asm-arm/arch-davinci/ ###

Add files as following:
davinci_aew.h
davinci_aew_hw.h
davinci_af.h
davinci_af_hw.h
davinci_previewer.h
davinci_previewer_hw.h
davinci_pwm.h
davinci_resizer.h
davinci_resizer_hw.h
dm355_aew.h
dm355_aew_hw.h
dm355_af.h
dm355_af_hw.h
dm355_ipipe.h
dm355_ipipe_hw.h

edma.h

### include/asm-arm/arch-davinci/gpio.h ###

extern int gpio_interrupt_bank_enable(int gpio);
extern int gpio_interrupt_enable(unsigned gpio, int trigger);
extern int gpio_interrupt_disable(unsigned gpio, int trigger);


### include/asm-arm/arch-davinci/io.h ###

/*
difference
android dm355
IO_PHYS 01c00000 01c00000
IO_VIRT fec00000 e1000000
IO_SIZE 00400000 00400000
IO_OFFSET fd000000 df400000
*/

#define IO_PHYS 0x01c00000
#define IO_VIRT 0xe1000000
#define IO_SIZE 0x00400000
#define io_p2v(pa) (((pa) & (IO_SIZE-1)) + IO_VIRT)
#define io_v2p(va) (((va) & (IO_SIZE-1)) + IO_PHYS)
#define IO_ADDRESS(x) io_p2v(x)


### include/asm-arm/arch-davinci/dma.h ###

#include
#include


### include/asm-arm/arch-davinci/memory.h ###

#define DAVINCI_IRAM_BASE 0x00008000 /* ARM Internal RAM(Data) */
#define DAVINCI_IRAM_VIRT 0xe1400000 /* after 4M of IO space (io.h) */


### include/asm-arm/arch-davinci/system.h ###

static void arch_idle(void)
{
if (!hlt_counter) {
unsigned long flags;
local_irq_save(flags);
if (!need_resched())
cpu_do_idle();
local_irq_restore(flags);
}
}


### include/asm-arm/arch-davinci/timex.h ###

#ifdef CONFIG_ARCH_DAVINCI355
#define CLOCK_TICK_RATE 24000000
#else
#define CLOCK_TICK_RATE 27000000
#endif

extern void davinci_watchdog_reset(void);
extern cycles_t davinci_get_cycles(void);
static inline cycles_t get_cycles(void)
{
return davinci_get_cycles();
}


### include/asm-arm/arch-davinci/hardware.h ###

#define DAVINCI_UART0_BASE (0x01C20000)
#define DAVINCI_UART1_BASE (0x01C20400)

#define DAVINCI_TIMER0_BASE (0x01C21400)
#define DAVINCI_TIMER1_BASE (0x01C21800)
#define DAVINCI_WDOG_BASE (0x01C21C00)

#define DAVINCI_ARM_INTC_BASE (0x01C48000)

#define DM644X_ASYNC_EMIF_CNTRL_BASE (0x01E00000)
#define DM644X_UART2_BASE (0x01C20800)

#define DM355_MMC1_BASE (0x01E00000)
#define DM355_UART2_BASE (0x01E06000)
#define DM355_ASYNC_EMIF_CNTRL_BASE (0x01E10000)
#define DM355_MMC0_BASE (0x01E11000)

#define DAVINCI_MCBSP0_BASE (0x01E02000)
#define DAVINCI_MCBSP1_BASE (0x01E04000)

/* Power and Sleep Controller (PSC) Domains */
#define DAVINCI_GPSC_ARMDOMAIN 0
#define DAVINCI_GPSC_DSPDOMAIN 1

#define DAVINCI_LPSC_VPSSMSTR 0 // VPSS Master LPSC
#define DAVINCI_LPSC_VPSSSLV 1 // VPSS Slave LPSC
#define DAVINCI_LPSC_TPCC 2 // TPCC LPSC
#define DAVINCI_LPSC_TPTC0 3 // TPTC0 LPSC
#define DAVINCI_LPSC_TPTC1 4 // TPTC1 LPSC
#define DAVINCI_LPSC_EMAC 5 // EMAC LPSC
#define DAVINCI_LPSC_EMAC_WRAPPER 6 // EMAC WRAPPER LPSC
#define DAVINCI_LPSC_MDIO 7 // MDIO LPSC
#define DAVINCI_LPSC_MMC_SD1 7 // MMC_SD1 LPSC
#define DAVINCI_LPSC_IEEE1394 8 // IEEE1394 LPSC
#define DAVINCI_LPSC_McBSP1 8 // McBSP1 LPSC
#define DAVINCI_LPSC_USB 9 // USB LPSC
#define DAVINCI_LPSC_ATA 10 // ATA LPSC
#define DAVINCI_LPSC_PWM3 10 // PWM3 LPSC
#define DAVINCI_LPSC_VLYNQ 11 // VLYNQ LPSC
#define DAVINCI_LPSC_UHPI 12 // UHPI LPSC
#define DAVINCI_LPSC_DDR_EMIF 13 // DDR_EMIF LPSC
#define DAVINCI_LPSC_AEMIF 14 // AEMIF LPSC
#define DAVINCI_LPSC_MMC_SD0 15 // MMC_SD0 LPSC
#define DAVINCI_LPSC_MEMSTICK 16 // MEMSTICK LPSC
#define DAVINCI_LPSC_McBSP0 17 // McBSP0 LPSC
#define DAVINCI_LPSC_I2C 18 // I2C LPSC
#define DAVINCI_LPSC_UART0 19 // UART0 LPSC
#define DAVINCI_LPSC_UART1 20 // UART1 LPSC
#define DAVINCI_LPSC_UART2 21 // UART2 LPSC
#define DAVINCI_LPSC_SPI 22 // SPI LPSC
#define DAVINCI_LPSC_PWM0 23 // PWM0 LPSC
#define DAVINCI_LPSC_PWM1 24 // PWM1 LPSC
#define DAVINCI_LPSC_PWM2 25 // PWM2 LPSC
#define DAVINCI_LPSC_GPIO 26 // GPIO LPSC
#define DAVINCI_LPSC_TIMER0 27 // TIMER0 LPSC
#define DAVINCI_LPSC_TIMER1 28 // TIMER1 LPSC
#define DAVINCI_LPSC_TIMER2 29 // TIMER2 LPSC
#define DAVINCI_LPSC_SYSTEM_SUBSYS 30 // SYSTEM SUBSYSTEM LPSC
#define DAVINCI_LPSC_ARM 31 // ARM LPSC
#define DAVINCI_LPSC_SCR2 32 // SCR2 LPSC
#define DAVINCI_LPSC_SCR3 33 // SCR3 LPSC
#define DAVINCI_LPSC_SCR4 34 // SCR4 LPSC
#define DAVINCI_LPSC_CROSSBAR 35 // CROSSBAR LPSC
#define DAVINCI_LPSC_CFG27 36 // CFG27 LPSC
#define DAVINCI_LPSC_CFG3 37 // CFG3 LPSC
#define DAVINCI_LPSC_CFG5 38 // CFG5 LPSC
#define DAVINCI_LPSC_GEM 39 // GEM LPSC
#define DAVINCI_LPSC_IMCOP 40 // IMCOP LPSC

/* NOR Flash base address set to CS0 by default */
#define DAVINCI_CS0_PHYS 0x02000000


### include/asm-arm/arch-davinci/cpu.h ###

#ifndef _ASM_ARCH_CPU_H
#define _ASM_ARCH_CPU_H

extern unsigned int system_rev;

#define GET_DAVINCI_CPU_TYPE ((system_rev >> 16) & 0xffff)

#define IS_DAVINCI_CPU(type, id) \
static inline int cpu_is_davinci_dm ##type (void) \
{ \
return (GET_DAVINCI_CPU_TYPE == (id)) ? 1 : 0; \
}

/* following generates the cpu_is_davinci_dmxxx */
IS_DAVINCI_CPU(6443, 0x6443) /* cpu_is_davinci_dm6443() */
IS_DAVINCI_CPU(6467, 0x6467) /* cpu_is_davinci_dm6467() */
/*IS_DAVINCI_CPU(355, 0x350)*/ /* cpu_is_davinci_dm355() */
IS_DAVINCI_CPU(355, 0x355) /* cpu_is_davinci_dm355() */

#endif


### include/asm-arm/arch-davinci/uncompress.h ###

#ifdef CONFIG_DAVINCI_LL_DEBUG_UART1
#define DAVINCI_UART_BASE DAVINCI_UART1_BASE
#else
#define DAVINCI_UART_BASE DAVINCI_UART0_BASE
#endif

typedef struct uart_registers_t {
unsigned int rbr_thr;
unsigned int ier;
unsigned int iir_fcr;
unsigned int lcr;
unsigned int mcr;
unsigned int lsr;
unsigned int msr;
unsigned int scr;
unsigned int dll;
unsigned int dlh;
unsigned int pid1;
unsigned int pid2;
unsigned int pwremu;
} uart_registers;

/* Initialize Serial port */
static void do_nothing(void)
{
unsigned int counter;
for (counter = 0; counter < uartregs =" (volatile">lsr & 0x20) {
/* Do Nothing */
}
}

static void serial_putc(const char c)
{
volatile uart_registers *uartregs;

uartregs = (volatile uart_registers *) DAVINCI_UART_BASE;
if (c == '\n')
serial_putc('\r');
uartregs->rbr_thr = c;

serial_waitfortxcharcomplete();
}

/* Send string on UART */
static void putstr(const char *str)
{
volatile uart_registers *uartregs;

uartregs = (volatile uart_registers *) DAVINCI_UART_BASE;
while (*str != '\0') {
serial_putc(*str);
str++;
}
}


### include/asm-arm/mach/arch.h ###

struct machine_desc {
/*
* Note! The first four elements are used
* by assembler code in head-armv.S
*/
unsigned int nr; /* architecture number */
unsigned int phys_io; /* start of physical io */
unsigned int io_pg_offst; /* byte offset for io
* page tabe entry */

const char *name; /* architecture name */
unsigned long boot_params; /* tagged list */

unsigned int video_start; /* start of video RAM */
unsigned int video_end; /* end of video RAM */

unsigned int reserve_lp0 :1; /* never has lp0 */
unsigned int reserve_lp1 :1; /* never has lp1 */
unsigned int reserve_lp2 :1; /* never has lp2 */
unsigned int soft_reboot :1; /* soft reboot */
void (*fixup)(struct machine_desc *,
struct tag *, char **,
struct meminfo *);
void (*map_io)(void);/* IO mapping function */
void (*init_irq)(void);
struct sys_timer *timer; /* system tick timer */
void (*init_machine)(void);
};

#define MACHINE_START(_type,_name) \
static const struct machine_desc __mach_desc_##_type \
__used \
__attribute__((__section__(".arch.info.init"))) = { \
.nr = MACH_TYPE_##_type, \
.name = _name,

#define MACHINE_END \
};

static const struct machine_desc __mach_desc_DAVINCI_DM355_EVM
.nr = MACH_TYPE_DAVINCI_DM355_EVM, \
.name = "DaVinci DM355 EVM",


__attribute__((__section__(".arch.info.init")))



### include/asm-arm/setup.h ###

#define ATAG_OMAP 0x414f4d50

struct tag_omap {
u8 data[0];
};


### include/asm-arm/procinfo.h ###

#define PROC_INFO_SZ 48

#define HWCAP_SWP 1
#define HWCAP_HALF 2
#define HWCAP_THUMB 4
#define HWCAP_26BIT 8 /* Play it safe */
#define HWCAP_FAST_MULT 16
#define HWCAP_FPA 32
#define HWCAP_VFP 64
#define HWCAP_EDSP 128
#define HWCAP_JAVA 256

Thursday, October 30, 2008

Build Cross-Compiled gcc for ARM by myself

This work is done by studying Cross-Compiled Linux From Scratch - Embedded (Version SVN-0.0.1-20080109-arm) material, The steps of building cross compiled gcc for ARM:

[Adding the ARMDEV User]

$ su -
# groupadd armdev
# useradd -s /bin/bash -g armdev -m -k /dev/null armdev
# useradd -s /bin/bash -g wizign -m armdev
# passwd armdev
# chown -Rv armdev ${ARMDEV}


[Preparing a New Partition]

# export ARMDEV='/mnt/armdev'
# install -dv ${ARMDEV}
# mkdir /vdisk/arm_disk
# mkdir -pv ${ARMDEV}
# mount --bind /vdisk/arm_disk ${ARMDEV}

[Create source directory]
# mkdir -v ${ARMDEV}/sources
# chmod -v a+wt ${ARMDEV}/sources

[Check and download packages]

$ su - armdev

[]Binutils (2.18)
$ wget http://ftp.gnu.org/gnu/binutils/binutils-2.18.tar.bz2

[]Busybox (1.4.1)
$ wget http://busybox.net/downloads/busybox-1.4.1.tar.bz2

[]CLFS-Bootscripts (1.0-pre4)
$ wget http://cross-lfs.org/files/packages/embedded-0.0.1/clfs-embedded-bootscripts-1.0-pre4.tar.bz2

[]E2fsprogs (1.39)
$ wget http://prdownloads.sourceforge.net/e2fsprogs/e2fsprogs-1.39.tar.gz

[]GCC (4.1.2)
$ wget http://ftp.gnu.org/gnu/gcc/gcc-4.1.2/gcc-4.1.2.tar.bz2

[]Iana-Etc (2.20)
$ wget http://www.sethwklein.net/projects/iana-etc/downloads/iana-etc-2.20.tar.bz2

[]Linux (2.6.20.1)
$ wget http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.20.1.tar.bz2

[]Linux-Headers (2.6.20.1-02252007)
$ wget http://cross-lfs.org/files/packages/embedded-0.0.1/linux-headers-2.6.20.1-02252007.tar.bz2

[]uClibc (0.9.29)
$ wget http://www.uclibc.org/downloads/uClibc-0.9.29.tar.bz2

[]Zlib (1.2.3)
$ wget http://www.zlib.net/zlib-1.2.3.tar.gz

[Check and download patched]

[]Binutils Posix Patch
$ wget http://svn.cross-lfs.org/svn/repos/cross-lfs/branches/clfs-sysroot/patches/binutils-2.18-posix-1.patch

[]Binutils Posix Patch
$ wget http://svn.cross-lfs.org/svn/repos/cross-lfs/branches/clfs-embedded/patches/binutils-2.17-posix-1.patch

[]Binutils uClibc Patch
$ wget http://svn.cross-lfs.org/svn/repos/cross-lfs/branches/clfs-embedded/patches/binutils-2.17-uclibc-1.patch

[]Busybox Fixes Patch
$ wget http://svn.cross-lfs.org/svn/repos/cross-lfs/branches/clfs-embedded/patches/busybox-1.8.2-fixes-1.patch

[]GCC Cross Search Paths Patch
$ wget http://svn.cross-lfs.org/svn/repos/cross-lfs/branches/clfs-embedded/patches/gcc-4.1.2-cross_search_paths-1.patch

[]GCC Posix Patch
$ wget http://svn.cross-lfs.org/svn/repos/cross-lfs/branches/clfs-embedded/patches/gcc-4.1.2-posix-1.patch

[]GCC uClibc Patch
$ wget http://svn.cross-lfs.org/svn/repos/cross-lfs/branches/clfs-embedded/patches/gcc-4.1.2-uclibc-1.patch

[]Zlib DESTDIR Patch
$ wget http://svn.cross-lfs.org/svn/repos/cross-lfs/branches/clfs-embedded/patches/zlib-1.2.3-DESTDIR-1.patch

[Final Preparations]

[]Setting up the environment

$ cat > ~/.bash_profile << "EOF"
> exec env -i HOME=${HOME} TERM=${TERM} PS1='\u:\w\$ ' /bin/bash
> EOF

$ cat > ~/.bashrc << "EOF"
> set +h
> umask 022
> ARMDEV=/mnt/armdev
> LC_ALL=POSIX
> PATH=${ARMDEV}/cross-tools/bin:/bin:/usr/bin
> export ARMDEV LC_ALL PATH
> EOF

$ source ~/.bash_profile

[]Creating directories

$ mkdir -pv ${ARMDEV}/build
$ mkdir -pv ${ARMDEV}/{bin,boot,dev,{etc/,}opt,home,lib/{firmware,modules},mnt}
$ mkdir -pv ${ARMDEV}/{proc,media/{floppy,cdrom},sbin,srv,sys}
$ mkdir -pv ${ARMDEV}/var/{lock,log,mail,run,spool}
$ mkdir -pv ${ARMDEV}/var/{opt,cache,lib/{misc,locate},local}
$ install -dv -m 0750 ${ARMDEV}/root
$ install -dv -m 1777 ${ARMDEV}{/var,}/tmp
$ mkdir -pv ${ARMDEV}/usr/{,local/}{bin,include,lib,sbin,src}
$ mkdir -pv ${ARMDEV}/usr/{,local/}share/{doc,info,locale,man}
$ mkdir -pv ${ARMDEV}/usr/{,local/}share/{misc,terminfo,zoneinfo}
$ mkdir -pv ${ARMDEV}/usr/{,local/}share/man/man{1,2,3,4,5,6,7,8}
$ mkdir -pv ${ARMDEV}/cross-tools{,/bin}
$ for dir in ${ARMDEV}/usr{,/local}; do
> ln -sv share/{man,doc,info} ${dir}
> done


[]Creating the passwd, group, and log Files

$ ln -svf ../proc/mounts ${ARMDEV}/etc/mtab

$ cat > ${ARMDEV}/etc/passwd << "EOF"
> root::0:0:root:/root:/bin/ash
> bin:x:1:1:bin:/bin:/bin/false
> daemon:x:2:6:daemon:/sbin:/bin/false
> adm:x:3:16:adm:/var/adm:/bin/false
> lp:x:10:9:lp:/var/spool/lp:/bin/false
> mail:x:30:30:mail:/var/mail:/bin/false
> news:x:31:31:news:/var/spool/news:/bin/false
> uucp:x:32:32:uucp:/var/spool/uucp:/bin/false
> operator:x:50:0:operator:/root:/bin/ash
> postmaster:x:51:30:postmaster:/var/spool/mail:/bin/false
> nobody:x:65534:65534:nobody:/:/bin/false
> EOF


$ cat > ${ARMDEV}/etc/group << "EOF"
> root:x:0:
> bin:x:1:
> sys:x:2:
> kmem:x:3:
> tty:x:4:
> tape:x:5:
> daemon:x:6:
> floppy:x:7:
> disk:x:8:
> lp:x:9:
> dialout:x:10:
> audio:x:11:
> video:x:12:
> utmp:x:13:
> usb:x:14:
> cdrom:x:15:
> adm:x:16:root,adm,daemon
> console:x:17:
> cdrw:x:18:
> mail:x:30:mail
> news:x:31:news
> uucp:x:32:uucp
> users:x:100:
> nogroup:x:65533:
> nobody:x:65534:
> EOF


$ touch ${ARMDEV}/var/run/utmp ${ARMDEV}/var/log/{btmp,lastlog,wtmp}
$ chmod -v 664 ${ARMDEV}/var/run/utmp ${ARMDEV}/var/log/lastlog


[Constructing Cross-Compile Tools]

[]Build CFLAGS
$ echo "Build CFLAGS"
$ echo unset CFLAGS >> ~/.bashrc
$ echo unset CXXFLAGS >> ~/.bashrc

# Application Binary Interface (ABI) for the ARM Architecture
# ABI Variables
# Table 6.1. List of Build Variables
# ABI BUILD=Value
# ------------------------- --------------------------------
# 32-Bit MIPS -mabi=32
# 32-Bit All Others -m32
# N32 MIPS -mabi=n32
# 64-Bit MIPS -mabi=64
# 64-Bit All Others -m64
echo "ABI Variables"
export BUILD="-m32"

# Build Variables
# Table 6.2. Processor Type and Target Triplets
# Processor Target Triplet
# ---------------------------------------------- -----------------------------------------
# Generic arm, little endian arm-unknown-linux-uclibc
# Generic arm, version 5, little endian armv5l-unknown-linux-uclibc
# Generic arm, version 5, big endian armv5b-unknown-linux-uclibc

$ export ARM_HOST="$(echo $MACHTYPE | sed "s/$(echo $MACHTYPE | cut -d- -f2)/cross/")"
# Generic arm, little endian
$ export ARM_TARGET="arm-unknown-linux-uclibc"
$ echo export ARM_HOST=\""${ARM_HOST}\"" >> ~/.bashrc
$ echo export ARM_TARGET=\""${ARM_TARGET}\"" >> ~/.bashrc

[]Linux-Headers-2.6.20.1-02252007

$ mkdir ${ARMDEV}/build
$ cd ${ARMDEV}/build
$ tar -jxvf ${ARMDEV}/sources/linux-headers-2.6.20.1-02252007.tar.bz2
$ install -dv ${ARMDEV}/usr/include
$ cp -av ${ARMDEV}/build/linux-headers-2.6.20.1/include/{asm-generic,linux,mtd,scsi,sound} ${ARMDEV}/usr/include
$ cp -av ${ARMDEV}/build/linux-headers-2.6.20.1/include/asm-arm ${ARMDEV}/usr/include/asm


[]Cross Binutils-2.17

$ cd ${ARMDEV}/build
$ tar -jxvf ${ARMDEV}/sources/binutils-2.17.tar.bz2
$ cd binutils-2.17
$ patch -Np1 -i ${ARMDEV}/sources/binutils-2.17-posix-1.patch
$ patch -Np1 -i ${ARMDEV}/sources/binutils-2.17-uclibc-1.patch
$ mkdir -v ../binutils-build
$ cd ../binutils-build
$ ../binutils-2.17/configure --prefix=${ARMDEV}/cross-tools --host=${ARM_HOST} --target=${ARM_TARGET} --with-sysroot=${ARMDEV} --disable-nls --enable-shared --disable-multilib
$ make configure-host
$ make
$ make install
$ cp -v ../binutils-2.17/include/libiberty.h ${ARMDEV}/usr/include


[]uClibc-0.9.29

$ cd ${ARMDEV}/build
$ tar -jxvf ${ARMDEV}/sources/uClibc-0.9.29.tar.bz2
$ cd uClibc-0.9.29

$ cp extra/Configs/Config.arm extra/Configs/Config.arm.orig
$ sed -e "/default/s:OABI:EABI:" extra/Configs/Config.arm.orig > extra/Configs/Config.arm
$ cp Makefile{,.orig}
$ sed -e 's/$(LN) -fs/cp/g' Makefile.orig > Makefile
$ for file in `find libc/sysdeps/linux -name Makefile`; do
> cp $file{,.orig}
> sed -e 's/$(LN) -fs/cp/g' -e 's@../libc/@$(TOPDIR)libc/@g' $file.orig > $file
> done

$ make defconfig ARCH=arm
$ cp .config{,.orig}
$ sed -e "/^CROSS_COMPILER_PREFIX/s:=.*:=\"${ARM_TARGET}-\":" -e "/^KERNEL_HEADERS/s:=.*:=\"${ARMDEV}/usr/include\":" -e "/^SHARED_LIB_LOADER_PREFIX/s:=.*:=\"/lib\":" -e "/^DEVEL_PREFIX/s:=.*:=\"/usr\":" -e "/^RUNTIME_PREFIX/s:=.*:=\"/\":" .config.orig > .config

$ UCLIBC_OPTIONS="DO_C99_MATH UCLIBC_HAS_RPC UCLIBC_HAS_CTYPE_CHECKED UCLIBC_HAS_WCHAR UCLIBC_HAS_HEXADECIMAL_FLOATS LDSO_PRELOAD_FILE_SUPPORT UCLIBC_HAS_FOPEN_EXCLUSIVE_MODE UCLIBC_HAS_PRINTF_M_SPEC UCLIBC_HAS_IPV6 UCLIBC_HAS_GLIBC_CUSTOM_PRINTF UCLIBC_USE_NETLINK UCLIBC_HAS_FTW"
$ for config in $UCLIBC_OPTIONS; do
> cp .config{,.orig}
> sed -e "s:# ${config} is not set:${config}=y:" .config.orig > .config
> done
$ UCLIBC_OPTIONS="UCLIBC_HAS_CTYPE_UNSAFE"
$ for config in $UCLIBC_OPTIONS; do
> cp .config{,.orig}
> sed -e "s:${config}=y:# ${config} is not set:" .config.orig > .config
> done
$ echo "UCLIBC_HAS_FULL_RPC=y" >> .config
$ echo "UCLIBC_HAS_REENTRANT_RPC=y" >> .config

# If your ARM system is Big Endian, you will need at add the following lines to your configuration:

$ echo "ARCH_ANY_ENDIAN=y" >> .config
$ echo "ARCH_BIG_ENDIAN=y" >> .config
$ echo "ARCH_WANTS_BIG_ENDIAN=y" >> .config

# If your ARM system is Little Endian, you will need at add the following lines to your configuration:

$ echo "ARCH_ANY_ENDIAN=y" >> .config
$ echo "ARCH_LITTLE_ENDIAN=y" >> .config
$ echo "ARCH_WANTS_LITTLE_ENDIAN=y" >> .config

$ make oldconfig
$ make headers
$ mkdir ${ARMDEV}/usr/include/bits
$ make PREFIX=${ARMDEV} install_headers

[]Cross GCC-4.1.2 - Static

$ cd ${ARMDEV}/build
$ tar -jxvf ${ARMDEV}/sources/gcc-4.1.2.tar.bz2
$ cd gcc-4.1.2
$ patch -Np1 -i ${ARMDEV}/sources/gcc-4.1.2-posix-1.patch
$ patch -Np1 -i ${ARMDEV}/sources/gcc-4.1.2-uclibc-1.patch
$ patch -Np1 -i ${ARMDEV}/sources/gcc-4.1.2-cross_search_paths-1.patch
$ mkdir -v ../gcc-build
$ cd ../gcc-build
$ ../gcc-4.1.2/configure --prefix=${ARMDEV}/cross-tools --host=${ARM_HOST} --target=${ARM_TARGET} --disable-multilib --with-sysroot=${ARMDEV} --without-headers --disable-nls --disable-shared --disable-threads --enable-languages=c
$ make all-gcc
$ make install-gcc


[]ToolChain Variables

$ export CC="${ARM_TARGET}-gcc"
$ export CXX="${ARM_TARGET}-g++"
$ export AR="${ARM_TARGET}-ar"
$ export AS="${ARM_TARGET}-as"
$ export LD="${ARM_TARGET}-ld"
$ export RANLIB="${ARM_TARGET}-ranlib"
$ export STRIP="${ARM_TARGET}-strip"


[]uClibc-0.9.29

$ cd ${ARMDEV}/build
$ cd uClibc-0.9.29

$ make CC="${CC}"
$ make PREFIX=${ARMDEV} install


[]Clear ToolChain Variables

$ unset CC
$ unset CXX
$ unset AR
$ unset AS
$ unset LD
$ unset RANLIB
$ unset STRIP

[]GCC-4.1.2 - Cross Compiler Final

$ cd ${ARMDEV}/build
$ rm -fr gcc-4.1.2
$ tar -jxvf ${ARMDEV}/sources/gcc-4.1.2.tar.bz2
$ cd gcc-4.1.2
$ patch -Np1 -i ${ARMDEV}/sources/gcc-4.1.2-posix-1.patch
$ patch -Np1 -i ${ARMDEV}/sources/gcc-4.1.2-uclibc-1.patch
$ patch -Np1 -i ${ARMDEV}/sources/gcc-4.1.2-cross_search_paths-1.patch
$ rm -fr ../gcc-build
$ mkdir -v ../gcc-build
$ cd ../gcc-build
$ ../gcc-4.1.2/configure --prefix=${ARMDEV}/cross-tools --host=${ARM_HOST} --target=${ARM_TARGET} --disable-multilib --with-sysroot=${ARMDEV} --disable-nls --enable-shared --enable-languages=c,c++ --enable-__cxa_atexit --enable-c99 --enable-long-long --enable-threads=posix
$ make
$ make install

Friday, October 10, 2008

Make MCU Board - Music Box Module


The music notes is defined by frequency variations,
reference wiki - music note and
C (musical note).

Generally, the calculation is based on A4 music note:
f = [2 ^ (n/12)] × 440 Hz

For easily doing calculation, here we use C-1 as the base level:
There are all 11 levels, each level has 12 music notes
n = (i x 12)(level) + j (jth note)
f = [2 ^ (n/12)] x 8.176 Hz

Calculate all music note's frequencies by python:
# calculate number array
musicNotes = []
for i in range(11):
 row = []
 for j in range(12):
   row.append(8.176 * (2**((i*12+j)*(1.0/12))))
 musicNotes.append(row)

# display frequency table
for i in range(11):
 musicNotes[i]

[8.1760000000000002, 8.6621702594815986, 9.1772497069774346, 9.7229573722622469, 10.301114503940484, 10.913650647694201, 11.562610085962426, 12.250158660543748, 12.978591000891997, 13.75033818222874, 14.567975839030828, 15.434232760971051]
[16.352, 17.324340518963197, 18.354499413954866, 19.445914744524494, 20.602229007880968, 21.827301295388398, 23.125220171924852, 24.500317321087497, 25.957182001783995, 27.50067636445748, 29.135951678061655, 30.868465521942102]
[32.704000000000001, 34.648681037926387, 36.708998827909731, 38.891829489048988, 41.204458015761929, 43.654602590776797, 46.250440343849704, 49.000634642174987, 51.914364003567989, 55.001352728914959, 58.271903356123303, 61.736931043884205]
[65.408000000000001, 69.297362075852774, 73.417997655819462, 77.783658978097975, 82.408916031523859, 87.309205181553594, 92.500880687699407, 98.001269284349974, 103.82872800713598, 110.00270545782992, 116.54380671224661, 123.47386208776841]
[130.816, 138.59472415170555, 146.8359953116389, 155.56731795619595, 164.81783206304772, 174.61841036310716, 185.00176137539881, 196.00253856869995, 207.6574560142719, 220.00541091565984, 233.08761342449321, 246.94772417553673]
[261.63200000000001, 277.1894483034111, 293.67199062327779, 311.1346359123919, 329.63566412609543, 349.23682072621432, 370.00352275079763, 392.00507713739989, 415.3149120285438, 440.01082183131967, 466.17522684898643, 493.89544835107347]
[523.26400000000001, 554.3788966068222, 587.34398124655559, 622.2692718247838, 659.27132825219087, 698.47364145242864, 740.00704550159526, 784.01015427479979, 830.6298240570876, 880.02164366263935, 932.35045369797285, 987.79089670214694]
[1046.528, 1108.7577932136444, 1174.6879624931112, 1244.5385436495676, 1318.5426565043817, 1396.9472829048573, 1480.0140910031905, 1568.0203085495996, 1661.2596481141752, 1760.0432873252787, 1864.7009073959457, 1975.5817934042939]
[2093.056, 2217.5155864272874, 2349.3759249862223, 2489.0770872991352, 2637.0853130087612, 2793.8945658097145, 2960.028182006381, 3136.0406170991969, 3322.5192962283504, 3520.0865746505574, 3729.4018147918891, 3951.1635868085878]
[4186.1120000000001, 4435.0311728545748, 4698.7518499724447, 4978.1541745982704, 5274.1706260175224, 5587.7891316194291, 5920.0563640127621, 6272.0812341983938, 6645.0385924567008, 7040.1731493011148, 7458.8036295837783, 7902.3271736171755]
[8372.2240000000002, 8870.0623457091497, 9397.5036999448894, 9956.3083491965408, 10548.341252035045, 11175.578263238858, 11840.112728025524, 12544.162468396788, 13290.077184913402, 14080.34629860223, 14917.607259167557, 15804.654347234351]

Base on above calculated values, we define const float gMusicNotes[11][12] , all the frequencies are recorded in the array.


The circuit schematic:















The main process:
(Depends on MCU's characters, for PIC16F877A , the compiler is PICC, the memory size of music_cell gSong[] is limited.)
(This program implements delay process, the deviation of sound frequency is obvious; replace by timer process, the sound frequency would be better than delay process)
/*******************************************************************************

  Copyright (c) 2008 Wizign Ltd.
  All Rights Reserved.

  main.c: Main program for demo trigger of speaker

  Version: 1.0.0

  Date: Oct 03, 2008

  Author: YenHung Chen

  E-mail: yhchen@wizign.com

  Revision:
  ---------- -----------------------------------------------------------------
  2008/10/03 Created by YenHung Chen, demo trigger of speaker for both 8051 and PIC

******************************************************************************/
/*******************************************************************************

<>For AT89S52

LCD display:
  There are 8 data pins, which are connected P2.
  The control pins are connected to P1_0, P1_1, and P1_2.

Speaker:
  P3_0


<>For PIC16F877A

LCD display:
  There are 8 data pins, which are connected PORTD
  The control pins are connected to RA0, RA1, and RA2.

Speaker:
  RC0


******************************************************************************/

#include "global.h"
#include "delay.h"
#include "lcd.h"
#include "timer.h"
#include "music.h"

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// define IO and global variables

#ifdef MCU_PIC
/*
// Configurations
typedef unsigned int config;
config at 0x2007 __CONFIG = _XT_OSC & _PWRTE_OFF & _BODEN_OFF & _WDT_OFF & _LVP_OFF;
*/
#endif

#ifdef MCU_PIC
bank1 static music_cell gSong[] = {
#else   // default is MCU_8051
music_cell gSong[] = {
#endif
  {C4, LA,    1}, {C4, LA, 0.25}, {C4, SO, 0.25}, {C4, LA,  0.5},
  {C4, SO,    1}, {C4, MI,    1}, {C4, SO,  0.5}, {C4, MI,  0.5},
  {C4, MI,  0.5}, {C4, RE,  0.5}, {C4, MI,    2}, {C4, MI,    0},
  {C4, RE,    1}, {C4, RE,  0.5}, {C4, DO,  0.5}, {C4, RE,  0.5},
  {C4, RE,  0.5}, {C4, SO,    1}, {C4, SO,  0.5}, {C4, MI,  0.5},
  {C4, MI,  0.5}, {C4, RE,  0.5}, {C4, MI,    2}, {C4, MI,    0},
  {C4, LA,    1}, {C4, LA,  0.5}, {C4, SO,  0.5}, {C4, LA,  0.5},
  {C4, SO,  0.5}, {C4, MI,    1}, {C4, FA,  0.5}, {C4, FA, 0.25},
  {C4, FA, 0.25}, {C4, MI,  0.5}, {C4, RE,  0.5}, {C4, MI,    2},
  {C4, MI,    0}, {C4, SO,    1}, {C4, SO,  0.5}, {C4, SO,  0.5},
  {C4, SO,  0.5}, {C4, SO,  0.5}, {C4, SI,    1}, {C4, LA,  0.5},
  {C4, LA, 0.25}, {C4, LA, 0.25}, {C4, LA,  0.5}, {C4, SO,  0.5},
  {C4, LA,    2}, {C4, LA,    0}, {C5, DO,    1}, {C5, DO,  0.5},
  {C5, DO,  0.5}, {C4, SI,    1}, {C4, SO,    1}, {C4, LA,  0.5},
  {C4, LA, 0.25}, {C4, LA, 0.25}, {C4, LA,  0.5}, {C4, SO,  0.5},
  {C4, LA,  1.5}, {C4, SO, 0.25}, {C4, MI, 0.25}, {C4, SO,    1},
  {C4, SO, 0.75}, {C4, SO, 0.25}, {C4, SO,  0.5}, {C4, SO,  0.5},
  {C4, SI,    1}, {C4, LA, 0.33}, {C4, LA, 0.33}, {C4, LA, 0.33},
  {C4, LA,  0.5}, {C4, SO,  0.5}, {C4, LA,    2}, {C4, LA,    0}
};

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// define functions

/* Initilize parameters before run the main loop */
void InitParams(void)
{
  LCDInit();
  MusicInit();
}

/* Display message on LCD panel */
void DisplayMusicStatus(char* pMsg)
{
  LCDGoto(0);    // goto 1st line
  LCDPuts("  WIZIGN LTD.  ");

  // Display rotate status
  LCDGoto(0x40);    // goto 2nd line
  LCDPuts(pMsg);
}

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// main program

void main(void)
{
  int count = 0;
  int direction = 0;  // 0:clockwise, 1:counter clockwise

  // Initilize parameters
  InitParams();

  /* do loop */
  while(1){
      DisplayMusicStatus("Play Music");
      MusicPlay(10, gSong);
  }
}