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.
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:
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
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
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
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
# 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
# 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
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
# 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
$ 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
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 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.
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:
.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.
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;
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
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);
}
}