WWPC1000 low level programming and debugging

From EnneEnneWiki

Go_up.png


Contents


Here you can find how to setup a GNU/Linux based developing environment for the WWPC1000.

Downloading the toolchain

You can get the toolchain at:

Just download the tarball and install it with:

giometti@zaigor:~$ cd /
giometti@zaigor:/$ tar xvfz tarball.tgz

the software will be installed into /usr/local/mipsel/ directory.

Managing the boot loader

In this section you can find several information about u-boot which is the WWPC's bootloader.

Downloading the code

You can get u-boot sources at:

To get the code you need to give the command:

git clone git://git.enneenne.com/u-boot-wwpc1000

of course you need the GIT tools installed on your system.

Compiling the source

To compile the u-boot source you must go into directory u-boot-wwpc1000 and give the commands:

~/u-boot-wwpc1000$ make wwpc1000_config
Configuring for wwpc1000 board...
~/u-boot-wwpc1000$ make

The compilation process should start. You'll end up with 4 new files:

  • u-boot.bin the binary image (use this file to program the flash).
  • u-boot the ELF image.
  • u-boot.srec the SREC image.
  • u-boot.map the MAP file (useful to know where u-boot's symbols are mapped).

Please, note that if you have a WWPC1000 version 0.9 you must manually edit the file include/config.h and replace the line:

#define CONFIG_WWPC1000         100

with:

#define CONFIG_WWPC1000         90

The standard environment

Here are explained some environment variables that are used by u-boot to perform some useful commands. You may modify them as you wish in order to fit your system configuration.

After rebooting the WWPC on the serial line you can see the message:

U-Boot 1.1.4-gb65996ec-dirty (May 18 2006 - 14:45:50)                                                                                                   
DRAM:  64 MB                                                                    
Flash: 64 MB                                                                    
In:    serial                                                                  
Out:   serial                                                                   
Err:   serial                                                                   
Net:   Au1X00 ethernet                                                                                                                                          
Autobooting in 1 second or enter password to stop.                             

if you press the sequence 12 you'll get the command prompt wwpc1000> and you can start suppling your commands (plese refere to the u-boot documentation for a detailed commands explanation).

The WWPC factory environment is:

bootargs=wwpc=uc-on console=tty0 loglevel=0
bootcmd=usb start ; if fatload usb 0:1 $rambuff $bootfile ; then run usbargs ; b
ootm $rambuff; else if iminfo $linuxaddr ; then run flashargs ; bootm $linuxaddr
 ; else go $winceaddr ; fi ; fi
nfsboot=run nfsargs ; tftp $rambuff $tftppath/$bootfile ; bootm $rambuff
bootdelay=1
baudrate=115200
ethaddr=00:11:22:33:44:55
ipaddr=192.168.32.24
serverip=192.168.32.254
rootpath=/exports/nfsroot
netmask=255.255.255.0
hostname=wwpc1000
bootfile=wwpc1000.uImage
loadaddr=0xBFC80000
ubootaddr=0xBFC00000
linuxaddr=0xBFC80000
winceaddr=0xBC000000
sectorsize=0x40000
rambuff=0x81000000
netdev=eth0
tftppath=tftproot
ubootfile=wwpc1000.u-boot.bin
eraseenv=prot off $ubootenv +$sectorsize && erase $ubootenv +$sectorsize
updateuboot=usb start ; if fatload usb 0:1 $rambuff $ubootfile ; then run flashu
boot ; else if tftp $rambuff $tftppath/$ubootfile ; then run flashuboot ; fi ; f
i
flashuboot=prot off $ubootaddr +$sectorsize && erase $ubootaddr +$sectorsize && 
cp.b $rambuff $ubootaddr $filesize && prot on $ubootaddr +$sectorsize ; echo now 
reset the board
nfsargs=setenv bootargs $bootargs root=/dev/nfs rw nfsroot=$serverip:$rootpath i
p=$ipaddr:$serverip:$gatewayip:$netmask:$hostname:$netdev:off
usbargs=setenv bootargs $bootargs mtdparts=WWPC-Flash:- root=/dev/sda2 rw rootde
lay=5
flashargs=setenv bootargs $bootargs root=/dev/mtdblock0 rootfstype=jffs2 rw
ethact=Au1X00 ethernet

You can modify it by using the setenv command and you can restore it to the factory default buy using the command

run eraseenv

then you need reboot the board to take effect.

If you wish using WWPC as developing system I suggest you modify the variable tftppath in order to make it points to your TFTP server root path:

setenv tftppath mipsel/boards/wwpc1000/boot

and variable rootpath in order to make it points to your NFS server root directory:

setenv rootpath /home/develop/embedded/mipsel/distro/debian

If you wish using TFTP boot you should also change variable bootcmd as follow:

setenv bootcmd run nfsboot

in order to force TFTP boot at every reboot.

In the end, if you wish using the serial console, you have to use:

 setenv bootargs wwpc=uc-off console=uart,au,0x11100000,115200

Note that in this mode you cannot use the devices related to the internal microcontrollers like the on board keyboard, the backlight management atc..

Once you have finished save the new environment with the command

saveenv

and reboot the system.

Programming a new image into flash

To (re)program a new u-boot image into WWPC's flash memory you can use u-boot itself.

Once you have recompiled the source you should move file u-boot.bin into your tftp root directory or into the first partition (formatted as VFAT) of an USB stick and renaming it as "wwpc1000.u-boot.bin", then use the command on the u-boot console:

run updateuboot

The system will first try to load the file "wwpc1000.u-boot.bin" from the USB stick and, if nothing is found, it will try to download it from the TFTP server (in this case verify that variable "tftppath" is well configured).

If you don't like writing your flash with an automated script you may use, for USB load, the seuqence:

usb start
fatload usb 0:1 $rambuff $ubootfile

for TFTP load:

tftp $rambuff $tftppath/$ubootfile

then to erase the u-boot flash sector use:

prot off $ubootaddr +$sectorsize
erase $ubootaddr +$sectorsize

and then reprogram the flash and protect it again use:

cp.b $rambuff $ubootaddr $filesize
prot on $ubootaddr +$sectorsize

Done! Now you can safely reboot the board.

If something goes wrong during the erasing/reprogramming flash stage you are in a trouble!

First of all do not reset the board but try to erase again the flash and reprogram it insted. If your WWPC still refuses to collaborate you need a JTAG to reprogram the flash (see section Downloading a new u-boot image).

Booting options

The WWPC by default boots from the internal flash memory but, as anticipated above, it's possible to boot from several devices. Here you can find some useful hints expecially if you wish using the WWPC as developing board.

Booting from flash

Here you have nothing special to do, just turn on your WWPC and wait! :)

This booting method can work when flash memory is at its default, if you start playing with WWPC's flash this method may fail and then you have to use one of the following alternative methods.

In any case you can force this method by using the commands:

run flashargs
bootm $linuxaddr

Booting from USB stick

You can boot a special GNU/Linux system by using an USB stick. This method is useful if you wish reprogram several WWPC boards in automatic manner.

In order to work this method requires som setting up steps on the USB stick.

First of all you have to make two partitions on the USB stick. You may use the command "fdisk" on a host system as follow:

giometti@gundam:~$ fdisk /dev/sda

Command (m for help):

I suppose your USB stick is mapped into device "/dev/sda" and that you have all necessary permissions on it.

Then clean all preexisting partitions by using the "d" command and make two new partitions as follows:

Command (m for help): n
Command action
   e   extended
   p   primary partition (1-4)
p
Partition number (1-4): 1
First cylinder (1-666, default 1): 
Using default value 1
Last cylinder or +size or +sizeM or +sizeK (1-666, default 666): +16M

Command (m for help): n
Command action
   e   extended
   p   primary partition (1-4)
p
Partition number (1-4): 2
First cylinder (88-666, default 88): 
Using default value 88
Last cylinder or +size or +sizeM or +sizeK (88-666, default 666): 
Using default value 666

Command (m for help): t
Partition number (1-4): 1
Hex code (type L to list codes): d
Changed system type of partition 1 to d (Unknown)

Command (m for help): p

Disk /dev/sda: 6 heads, 63 sectors, 666 cylinders
Units = cylinders of 378 * 512 bytes

   Device Boot    Start       End    Blocks   Id  System
/dev/sda1             1        87     16411+   d  Unknown
/dev/sda2            88       666    109431   83  Linux

Note that the first partition is "VFAT" and 16M bytes long, the second one is "Linux" and is long at least 32MB.

Now we can save the partition table with the "w" command and then we can start to format the two new partitions:

giometti@gundam:~$ mkfs.vfat /dev/sda1
mkfs.vfat 2.10 (22 Sep 2003)
giometti@gundam:~$ mkfs.ext2 /dev/sda2 
mke2fs 1.39-WIP (10-Dec-2005)
Filesystem label=
OS type: Linux
Block size=1024 (log=0)
Fragment size=1024 (log=0)
27440 inodes, 109428 blocks
5471 blocks (5.00%) reserved for the super user
First data block=1
14 block groups
8192 blocks per group, 8192 fragments per group
1960 inodes per group
Superblock backups stored on blocks: 
	8193, 24577, 40961, 57345, 73729

Writing inode tables: done                            
Writing superblocks and filesystem accounting information: done

This filesystem will be automatically checked every 32 mounts or
180 days, whichever comes first.  Use tune2fs -c or -i to override.

Now we have to copy a kernel image into the first partition (see Compiling the source to know how to get a new kernel image) and we have to put a new rootfs into the second partition (see Creating a minimal rootfs)

Booting from TFTP server

As last resource and expecially for developing stages you can use a TFTP boot sequence to load your preferred GNU/Linux distribution.

To force this method, as already described above, you need a serial console connected with thw WWPC and use it to stop the booting sequence with the boot password. After that just run:

run nfsboot

In order to work this method needs that both "rootpath" and "tftppath" variable as correctly set up and that your developing system is set up and running (see Setting up a developing environment).

Managing the kernel

In this section you can find several information about Linux which is the WWPC's kernel.

Downloading the code

You can get linux sources at:

To get the code you need to give the command:

git clone git://git.enneenne.com/linux-wwpc1000

of course you need the GIT tools installed on your system.

Compiling the source

To compile the Linux source you must go into directory linux-wwpc1000 and give the commands:

~/linux-wwpc1000$ make wwpc1000_defconfig
~/linux-wwpc1000$ make

The compilation process should start. You'll end up with 3 new files:

  • uImage the binary image suitable for u-boot (use this file to program the flash).
  • vmlinux the ELF image suitable for the JTAG.
  • System.map the Linux symbols map useful for a simple debug.

Doing a custom kernel configuration

TODO

Programming a new Linux image

Once we have our new Linux image we can proceed to put it on the flash. First of all start your preferred GNU/Linux distribution on the WWPC and after the boot is finished check for device /dev/mtd2:

# ls -l /dev/mtd2
crw-r--r--    1 root     root      90,   4 Aug  8  2005 /dev/mtd2               

Then verify that the MTD support is enabled on the system:

# cat /proc/mtd
dev:    size   erasesize  name
mtd0: 03c00000 00040000 "rootfs"
mtd1: 00080000 00040000 "u-boot"
mtd2: 00200000 00040000 "kernel"
mtd3: 00180000 00040000 "data"

Now you should made the file uImage accesible by the WWPC (using your prefereed method: FTP, NFS, etc.) and then erase the "kernel" partition by using the command:

# flash_erase /dev/mtd2 0 8

where 8 is computed as 0x00200000/0x00040000 = 8.

Then just copy the Linux image on the erased partition (we suppose the file uImage has been put into /opt directory):

# cp /opt/uImage /dev/mtd2

Managing the rootfs

In this section you can find several information about how to create a roofs using _geek which is a custom GNU/Linux distribution.

Downloading the code

Eurotech's WWPC uses a custom distribution and you can get it at:

TO BE CONTINUED...

Creating a minimal rootfs

To create a minimal rootfs in order to put it on the flash you can use several embedded distibution. However, as example, we'll use the standard WWPC1000's distribution to create a very minimal rootfs by using the following commands:

~/wwpc/rootfs$ sudo _gpkg -i ~/_geek/packages/base-0.70.0-all-all.geek
_gpkg: installing "~/_geek/packages/base-0.62.0-all-all.geek"...
_gpkg: mmm... directory "~/wwpc/rootfs" doesn't seem to be a root dir...
_gpkg: are you sure you __really__ want to install this
_gpkg: package here? [y/N]: y
_gpkg: running "postinst" script... done.
_gpkg: done.
~/wwpc/rootfs$ sudo _gpkg -i ~/_geek/packages/libbase-0.80.0-mipsel-au1100.geek
_gpkg: installing "~/_geek/packages/libbase-0.80.0-mipsel-au1100.geek"...
_gpkg: running "postinst" script... done.
_gpkg: done.
~/wwpc/rootfs$ sudo _gpkg -i ~/_geek/packages/busybox-0.80.0-mipsel-au1100.geek
_gpkg: installing "~/_geek/packages/busybox-0.80.0-mipsel-au1100.geek"...
_gpkg: running "postinst" script... done.
_gpkg: done.

Please consider that _geek distribution is at very alpha release so it possible that the packages versions will vary quickly.

Once we have builded the rootfs we have to create the JFFS2 image to write on the flash:

~/wwpc/rootfs$ cd ..
~/wwpc$ mkfs.jffs2 -v -l -q -e 0x20000 -p -r rootfs/ -o rootfs.jffs2
...
/var
     d 0755         0     0:0   lock
     d 0755         0     0:0   log
     d 0755         0     0:0   run
/var/lock
/var/log
/var/run


Compression mode: priority
Compressors:
      none             compr: 6 blocks (194)  decompr: 0 blocks
      zlib (prio:60) + compr: 648 blocks (1165576/2540740)  decompr: 0 blocks 
     rtime (prio:50) + compr: 0 blocks (0/0)  decompr: 0 blocks
       lzo (prio:40) - compr: 0 blocks (0/0)  decompr: 0 blocks
     lzari (prio:30) - compr: 0 blocks (0/0)  decompr: 0 blocks
Compression errors: 0

You'll end up with a new file called rootfs.jffs2.

Programming a new rootfs image

Once we have our new rootfs image we can proceed to put it on the flash. First of all start your preferred GNU/Linux distribution on the WWPC and after the boot is finished check for device /dev/mtd0:

# ls -l /dev/mtd0
crw-r--r--    1 root     root      90,   0 Aug  8  2005 /dev/mtd0               

Then verify that the MTD support is enabled on the system:

# cat /proc/mtd
dev:    size   erasesize  name
mtd0: 03c00000 00040000 "rootfs"
mtd1: 00080000 00040000 "u-boot"
mtd2: 00200000 00040000 "kernel"
mtd3: 00180000 00040000 "data"

Now you should made the file rootfs.jffs2 accesible by the WWPC (using your prefereed method: FTP, NFS, etc.) and then erase the "rootfs" partition by using the command:

# flash_erase /dev/mtd0 0 240

where 240 is computed as 03c0000/0x00040000 = 240.

Then just copy the JFFS image on the erased partition (we suppose the file rootfs.jffs2 has been put into /opt directory):

# cp /opt/rootfs.jffs2 /dev/mtd0
# mount -t jffs2 /dev/mtdblock0 /mnt/
# ls /mnt/
bin  boot  dev  etc  home  lib  linuxrc  mnt  proc  root  sbin  tmp  usr  var

Using a JTAG

In this section I'll show some steps in order to use a JTAG support with your WWPC.

Currently supported JTAG is:


Lauterbach TRACE32

Verify the JTAG/System connection

First of all you should follow the Lauterbach's instruction in order to install your TRACE32. After that you can verify that you can connect with the system by using the following commands:

RESET
WINCLEAR
DATA.LIST
SYSTEM.CPU AU1100
SYSTEM.OPTION.RESBREAK OFF
SYSTEM.UP

You should see that the system is stopped at location 0xbfc00000.

Setting up the JTAG environment

In order to load the TRACE32 toolkit with a proper environment for the WWPC you should add an init file to the TRACE32's system directory. Do the following steps:

~$ cat >> $T32SYS/t32.cmm
LOCAL &file
ENTRY &file

if "&file"==""
(
  GOTO l_end
)

IF !OS.FILE(&file)
(
  GOTO l_error_fileexist
)

DO &file
GOTO l_end

l_error_fileexist:
  PRINT "t32: init file &file doesn't exist"
  GOTO l_end

l_end:
  ENDDO

In this manner your TRACE32 will automatically load a special configuration file if invoked with:

~$ t32mips <filename>

We provide two special configuration for the WWPC. One for debugging u-boot or just for reprogramming the flash and one for debugging Linux (see Lauterbach directory).

As example I report here contents of file u-boot.cmm but consider that this may vary:

;
; --- Reset -------------------------------------------------------------------
;  

RESET
WINCLEAR
FLASH.RESET

;
; --- Setup the CPU -----------------------------------------------------------
; 

SYSTEM.CPU AU1100
SYSTEM.OPTION.RESBREAK OFF
SYSTEM.OPTION.UNPROTECT ON
SYSTEM.UP

TRONCHIP.USEWATCH ON
MAP.BONCHIP 0xBE000000--0xBFFFFFFF

;
; --- Define flash ------------------------------------------------------------
; 

FLASH.CREATE 1. 0xBE000000--0xBFFFFFFF 0x40000 AM29LV256 LONG

print "WWPC/u-boot environment loaded"

Now, to load it into TRACE32, you should execute:

~$ cd wwpc
~/wwpc$ t32mips jtag/lauterbach/u-boot.cmm

If every works well you should see that your TRACE32 displays the string WWPC/u-boot environment loaded into its messages bar.

Managing u-boot

Debugging u-boot

To debug u-boot you should start TRACE32 with the command:

~/wwpc$ t32mips jtag/lauterbach/u-boot.cmm

If everything works well you can see the start location is 0xBFC00000 by using the data.list command.

Now you can load the bootloader symbols with command:

DATA.LOAD.ELF u-boot/u-boot-wwpc1000/u-boot /GNU /NOCODE

Now you can setup hardware or software breakpoints (use hardware ones if you wish block WWPC during execution of code into flash), run or stop the code ad you wish.

Please, note that u-boot, at some point relocate itself into RAM so the bootloader symbols, after this relocation, are not valid anymore. To resolve this problem you have to inform your JTAG to relocate the symbols with the command:

DATA.LOAD.ELF u-boot/u-boot-wwpc1000/u-boot /GNU /NOCODE /RELOC .text AT 0x83f94000
Downloading a new u-boot image

First of all you have to (re)compile a new u-boot image with debuggin support enabled. To do it verify that into file u-boot-wwpc1000/board/wwpc1000/config.mk you have:

~/u-boot-wwpc1000$ grep JTAG board/wwpc1000/config.mk 
# Enable EJTAG debugging support
PLATFORM_CPPFLAGS += -DDEBUG_EJTAG

then you can use make to start compilation. During compilation stage verify that both -g and -DDEBUG_JTAG are arguments of mipsel-linux-gcc command.

At the end you should get file u-boot.bin who can be downloaded into WWPC flash memory (please, note that you can program the flash memory from u-boot itself without using TRACE32, see section Programming a new image into flash).

To program the flash memory you should use the following procedure.

Setup the WWPC's static bus controller:

PER.S D:0xB4001008 %LONG 0x11E03F80
PER.S D:0xB4001004 %LONG 0x22080B20
PER.S D:0xB4001000 %LONG 0x00000003

Erase u-boot sector and put it into "program" mode:

FLASH.UNLOCK 0xBFC00000--0xBFC3FFFF
FLASH.ERASE 0xBFC00000--0xBFC3FFFF
FLASH.PROGRAM 0xBFC00000--0xBFC3FFFF

Then load the binary image:

DATA.LOAD.BINARY ~/u-boot-wwpc1000/u-boot.bin 0xBFC00000 /LONG

In the end lock the flash memory again:

FLASH.PROGRAM OFF
FLASH.UNLOCK OFF
Bugged TRACE32

If after u-boot image flashing you get wrong code you may have a bugged TRACE32 version.

In order to know if this is your case you should use the command data.list 0xBFC00000 and look the first assembly codes. If you read into "mnemonic" field:

sd    r0,0x10(r24)

instead of:

b     0xBFC00400

then your image has been endianess swapped by the buggy TRACE32! To resolve the problem use the utulity program er (see directory jtag/lauterbach/utils).

Just compile it:

~/jtag/lauterbach/utils$ make CFLAGS="-Wall -O2" er
cc -Wall -O2    er.c   -o er

and use it to endianess swap the u-boot image:

~/jtag/lauterbach/utils$ ./er < ../u-boot/u-boot-wwpc1000/u-boot.bin \
                        > ../u-boot/u-boot-wwpc1000/u-boot.bin.swapped

Now download the file u-boot.bin.swapped as above.

Managing Linux

Debugging Linux

First of all you have to (re)compile a new Linux image with debugging support enabled. To do it verify that into you kernel configuration file .config you have:

~/linux-wwpc1000$ rgrep CONFIG_DEBUG_INFO .config
CONFIG_DEBUG_INFO=y

Then you should recompile the code with command:

 ~/linux-wwpc1000$ make uImage

You'll end up with uImage which you should use as running kernel (how to use the current Linux image is depending on your developing technique, see section Setting up a developing environment) and with file ./arch/mips/boot/vmlinuz which is the ELF version.

Now you should start TRACE32 with the command:

~/wwpc$ t32mips jtag/lauterbach/linux.cmm

If everything works well you can see the start location is 0xBFC00000 by using the data.list command.

Now you can load the kernel symbols with command:

DATA.LOAD.ELF linux/linux-wwpc1000/vmlinux /GNU /NOCODE

and then set a break point to the kernel entry point:

BREAK.SET kernel_entry /ONCHIP

Now start the system and wait for the programmed break is reached. Then you can enable the MMU translation by usimg the commands:

MMU.FORMAT LINUX32 swapper_pg_dir
MMU.COMMON 0x80000000++0xffffff
MMU.ON
MMU.SCAN

Then continue execution with command:

GO

MacRaigor OCDemon

TODO

Personal tools