Mini2440 Linux

From Kenneth Noyens
Jump to: navigation, search

Toolchain

First of all, we need a toolchain containing some command-line tools for our ARM platform:

  • C and C++ compilers
  • assembler
  • linker
  • C and C++ runtime libraries
  • GNU debugger


I'm going to use the Sourcery G++ Lite ARM that is available for free.
You can get the last version from http://www.codesourcery.com/sgpp/lite/arm/portal/subscription3053

Downloading and unpacking

mkdir mini2440
cd mini2440
wget http://www.codesourcery.com/sgpp/lite/arm/portal/package5353/public/arm-none-eabi/arm-2009q3-68-arm-none-eabi-i686-pc-linux-gnu.tar.bz2
tar jxf arm-2009q3-68-arm-none-eabi-i686-pc-linux-gnu.tar.bz2
export PATH=/home/ttts/mini2440/arm-2009q3/bin:$PATH

The last line will add the bin directory the $PATH variable so that we can use the commands in that directory like normal commands.
Every time you open a terminal, you have to enter that last line. (or you can add it to your .bashrc file)

Uboot

Download uboot for mini2440

mkdir uboot
cd uboot
git clone git://repo.or.cz/u-boot-openmoko/mini2440.git

Compile uboot

We have to compile 2 uboots:

- a uboot without USB support that can boot from RAM, to prepare the NAND
- a uboot with USB support that we can flash in the NAND

For an undefined reason the uboot with USB does not boot from RAM.
Buserror has writen the following on his blog about this issue:

The new u-boot doesn't work in RAM. Somehow the interupt code that I added
to get USB working makes it crash when launched at an arbitrary address.

To make it work anyway, edit include/configs/mini2440.h and disable the
interupt #define. That will build you a u-boot that works in ram, but
without usb. Once that is in RAM and runs, build another u-boot to flash to
NAND...


With USB

export CROSS_COMPILE=arm-none-eabi-
cd mini2440
make mini2440_config
make all
cd u-boot.bin ../../uboot.bin

When I tried to compile uboot I got an error about some weak declarations in lib_arm/board.c and common/main.c
I'm using the 4.4.x gcc, and the 4.3.x does not cause that error. You can downgrade your gcc or remove the "weak" definitions in those files like I did

Without USB

Edit include/configs/mini2440.h, search for:

#if 1
#define CONFIG_USB_OHCI_NEW     1
#define CONFIG_CMD_USB          1

#define CFG_USB_OHCI_CPU_INIT   1
#define CFG_USB_OHCI_REGS_BASE  0x49000000 /* S3C24X0_USB_HOST_BASE */
#define CFG_USB_OHCI_SLOT_NAME  "s3c2440"
#define CFG_USB_OHCI_MAX_ROOT_PORTS     2
#endif

#if 1
#define CONFIG_USB_DEVICE       1
#define CONFIG_USB_TTY          1
#define CONFIG_USB_STORAGE      1
#define CFG_CONSOLE_IS_IN_ENV   1
#define CONFIG_USBD_VENDORID            0x1457  /* FIC */
#define CONFIG_USBD_PRODUCTID_GSERIAL   0x5120  /* gserial */
#define CONFIG_USBD_PRODUCTID_CDCACM    0x511b  /* SMDK2440 CDC ACM */
#define CONFIG_USBD_MANUFACTURER        "MINI2440"
#define CONFIG_USBD_PRODUCT_NAME        "S3C2440 Bootloader " U_BOOT_VERSION
#define CONFIG_USBD_DFU                 1
#define CONFIG_USBD_DFU_XFER_SIZE       4096
#define CONFIG_USBD_DFU_INTERFACE       2
//#define CONFIG_USB_DFU_REVISION 0x0100
#endif

And change both "#if 1" to "#if 0" like this:

#if 0
#define CONFIG_USB_OHCI_NEW     1
...
#define CFG_USB_OHCI_MAX_ROOT_PORTS     2
#endif

#if 0
#define CONFIG_USB_DEVICE       1
#define CONFIG_USB_TTY          1
...

Then recompile:

make clean
make all
cd u-boot.bin ../../uboot.bin.nousb

Compile upload tool

cd ~/mini2440
wget http://mini2440.googlecode.com/files/s3c2410_boot_usb-20060807.tar.bz2
tar jxf s3c2410_boot_usb-20060807.tar.bz2
cd s3c2410_boot_usb
make

When make fails because he can not find the file "usb.h" install the ubuntu/debian package libusb-dev.

Upload the file

Prepare NAND

Open a terminal to the serial connection of the mini2440 board.
Put the NOR switch to NOR and power the board.
Now you get a "FriendlyARM BIOS"/supervivi menu, choose q to go to the supervivi shell.
In this shell typ:

load ram 0x31000000 232188 u

Where "232188" is the size of the uboot.bin file you are going to send. (ls -la mini2240/uboot/mini2440 | grep u-boot.bin)
Send the file from your linux terminal:

./s3c2410_boot_usb ../uboot/u-boot.bin.nousb

Sometimes the upload tool says that the upload is failed, but don't trust it :P
The upload of uboot didn't work for me at first but just keep trying.

Go back to the serial console and enter:

go 0x31000000

Now you see uboot booting from RAM.
Prepare the NAND for the uboot image:

nand scrub
nand createbbt

You have to confirm those 2 commands with y and enter.
The creating of the bb table will take a time, so be patient.

Flash UBOOT to NAND

Serial console:

load flash 0 232188 u

Send file:

./s3c2410_boot_usb ../uboot/u-boot.bin

Power off the board, set the NOR/NAND switch to NAND.
Power the board and see your uboot booting :)

Kernel

Download kernel

cd ~/mini2240
mkdir kernel
cd kernel
git clone git://repo.or.cz/linux-2.6/mini2440.git
cd mini2440

Config kernel

mkdir ../kernel-bin
CROSS_COMPILE=arm-none-eabi- ARCH=arm make O=../kernel-bin/ mini2440_defconfig
CROSS_COMPILE=arm-none-eabi- ARCH=arm make O=../kernel-bin/ menuconfig

After the last command you will get a menu where you can select the kernel options you want.

I had a problem compiling my kernel in the next stap and found this solution:
Mail-archive.com solution
Quote from the website above:
Try this:
in Kernel config
-->"User Space Binary formats"
-->un-check "Kernel support for a.out and ECOFF binaries"

Compile kernel

CROSS_COMPILE=arm-none-eabi- ARCH=arm make O=../kernel-bin/

Make kernel image

Because uboot expects some headers you have to add some headers to your fresh compiled kernel.

cd ~/mini2240
./uboot/mini2440/tools/mkimage -A arm -O linux -T kernel -C none -a 0x30008000 -e 0x30008000 -d kernel/kernel-bin/arch/arm/boot/zImage linux-image

A => Architecture
O => Operating system
T => image typ
C => compression
a => load adres in hex
e => entry point
d => image data

Load the kernel in the board

All command are entered as root

DHCP server

Install DHCP server:

apt-get install dhcp3-server

Put your pc on a static IP, edit /etc/network/interfaces

auto eth1
iface eth1 inet static
     address 192.168.0.2
     network 192.168.0.0
     netmask 255.255.255.0
     broadcast 192.168.0.255
     gateway 192.168.0.1

I use a special setup with a subnet behind NAT
eth0 is connected directly to my lan, eth1 is connected to a router where the mini2440 is connected
You don't want to run a DHCP server on a LAN where there is already a DHCP server!!
Open /etc/dhcp3/dhcd.conf with your favorite editor and add the folow lines:

subnet 192.168.0.0 netmask 255.255.255.0
{
        range 192.168.0.10 192.168.0.240;
        option routers 192.168.0.1;
        option domain-name-servers 8.8.8.8;
}
host mini2440    
{
        filename "linux";
        server-name "192.168.0.2";
        next-server 192.168.0.2;
        hardware ethernet 08:08:11:18:12:27;
        fixed-address 192.168.0.9;
}

Change the hardware address to the MAC address of your board
If you don't known the MAC address of your board, you can find this in the uboot console during boot
You can change the IP addresses to fit your needs.
8.8.8.8 is the open DNS server from google
192.168.0.1 => router
192.168.0.2 => debian server
192.168.0.9 => mini2440

Reboot DHCP server:

invoke-rc.d dhcp3-server restart

TFTP server

Install tftp server and client (client for testing):

apt-get install tftpd tftp
/etc/init.d/openbsd-inetd restart

Copy the linux-image to /srv/tftp/linux:

cp /home/ttts/mini2440/linux-image /srv/tftp/linux

Typ "dhcp" in the uboot console of the mini2440 board, normaly you should see the kernel loading.

Filesystem

All commands are entered as root

cd /home/ttts/mini2240
mkdir filesystem
cd filesystem
debootstrap --arch=armel --foreign lenny grip/ http://www.emdebian.org/grip/

Install kernel modules in the filesystem

cd ../kernel/mini2440/
CROSS_COMPILE=arm-none-eabi- ARCH=arm make INSTALL_MOD_PATH=/home/ttts/mini2440/filesystem/grip/ O=../kernel-bin/ modules_install

Config the filesystem

cd ../../filesystem/grip/
echo "proc /proc proc none 0 0" > etc/fstab 
echo "mini2440" > etc/hostname
mknod dev/console c 5 1
mknod dev/ttySAC0 c 204 64
echo "deb http://www.emdebian.org/grip/ lenny main" > etc/apt/sources.list

NFS server

apt-get install nfs-kernel-server

edit /etc/exports and add the folow line:

/home/ttts/mini2440/filesystem/grip     *(rw,no_root_squash,no_subtree_check,async)

Boot the system

The first time we boot the board we are not goining to load init but just sh that we get a shell to finish debootstrap
Open a serial console to the board, and power the board.
In the uboot console you enter this:

setenv bootargs console=ttySAC0,115200 noinitrd init=/bin/sh mini2440=0tb ip=dhcp root=/dev/nfs rw nfsroot=192.168.0.2:/home/ttts/mini2440/filesystem/grip
dhcp
bootm 0x32000000

mini2440=0tb for the 3,5" screen and =1tb for the 7" screen.
After entering the last command, the linux kernel will start booting and drop you in a shell

First see that the clock of the board is correct!
If the clock is not correct, the debootstrap command may fail.
Check and set the system clock and hardware clock.

date
date -s "20 JAN 2010 15:20:00"
hwclock -systohw

Finish the debootstrap install:

mount /proc /proc -t proc
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
/debootstrap/debootstrap --second-stage

Finish

After the debootstrap second stage has finished, we can boot in to the real system using init.
Reboot the board so that you are in the uboot console.

dynenv set 40000
setenv bootargs console=ttySAC0,115200 noinitrd init=/sbin/init mini2440=0tb ip=dhcp root=/dev/nfs rw nfsroot=192.168.0.2:/home/ttts/mini2440/filesystem/grip
setenv bootcmd 'dhcp ; bootm 0x32000000'
saveenv

Now, press the reset switch and see how you boot into your new system ...
The default login is root and no password.

If you have any remarks about my tutorial, please mail me at me [a-t] noyenskenneth [d0t] be