home kinesia products products
Embedded Linux Information

  1. Building the 2.4.x Kernel Basics
  2. Network Configuration
  3. Developing Applications and Modules for uClinux 2.4.x
  4. Connection between Linux PC and 44B0X Target Board
  5. LCD Configuration
  6. Audio Configuration
  7. Sharp ARM 9 Root FS with FC
  8. Modifying SDL-1.2.11 to support USB mouse for ARM

Configuring uClinux 2.4.x for 44B0X

by Tong Lai Yu and Felix Lo, July 2005

The following features and modifications on uClinux have been made.

The compiler used is "arm-elf-tools-20030314.sh" ( note that we were not able to install the 2004 version as newer dependent applications are required. ) which is installed in /usr/local/bin; the arm-elf-gcc is of version 2.95.3

We use the 'uclinux44b0.tar.gz' at /apps/uclinux/arm7/uclinux_44b0 of our directory, which actually comes with the CD of the 44B0X EV board ( purchased in China ); the package is uClinux of 2003 which is fairly old. It is expaned into the directory: /apps/uclinux/arm7/uclinux_44b0/uclinux44b0/uClinux-dist

We refer to this directory as uClinux-dist. We removed the linux-2.0.x package inside the directory and only linux-2.4.x remained. We downloaded linux-2.4.19.tar.bz2 from 'www.kernel.org' and expanded it into the uClinux-dist directory. We patched it at uClinux-dist with two patches in the following order

  
  1)  uClinux-2.4.19-uc1.diff.gz; we renamed linux-2.4.19 to uClinux-2.4.19
	and patched it  with command 
	gunzip -c /apps/download/linux/uClinux-2.4.19-uc1.diff.gz | patch -p0	
  2)   gunzip -c ../../tpu_uclinux/uClinux-2.4.19-uc1-s3c44b0.diff.gz | patch -p1 
patch 1) is downloaded from www.uclinux.org, patch 2) comes with the 44B0X CD.

After we had patched uClinux-2.4.19, we removed linux-2.4.x and then renamed uClinux-2.4.19 to linux-2.4.x.

We configured uClinux using 'make menuconfig'. This is the difficult part. It took us a few days to pick the correct packages and get rid of the compilation errors. ( According to Felix's notes, the following changes were made at directory uClinux-dist/linux-2.4.x. But later we could not find those changes. It seems that the changes were undone for some reasons.

  1) Edit 'arch/armnommu/kernel/entry-armv.S': at line 22, add 
	#include <include/asm-arm/constants.h>
  2) Edit 'arch/armnommu/kernel/Makefile': at line 79, at 4 lines of
	-I../include/asm-arm
  3) Edit  'arch/armnommu/mm/proc-arm6,7.S': add the line
	#include "<root>/include/asm-arm/constants.h>"
Tong commnet: these are not necessary as they are inside include directory the statement #include <asm-arm/constants.h> would do the job )

Eventually the following selections work:

                  --- Choose a Vendor/Product combination.

                  (Samsung/4510B) Vendor/Product

                    --- Kernel is linux-2.4.x

                      (uClibc) Libc Version

                      [ ] Default all settings (lose changes)

                      [*] Customize Kernel Settings (NEW)
 
                      [*] Customize Vendor/User Settings (NEW)

                      [ ] Update Default Vendor Settings

 ---------------------------------------------------------------------------                                                          

			code maturity level options  ---> ( NOTHING )                          
                     	Loadable module support  ---> ( NOTHING )

                        System Type  --->

                        General setup  --->

                       	Networking options  --->

  	                Network device support  --->

  	                Amateur Radio support  ---> ( NOTHING )

                        IrDA (infrared) support  ---> ( NOTHING )

                     	ATA/IDE/MFM/RLL support  ---> ( NOTHING )

                       	SCSI support  --->  ( NOTHING )
                                        
                   	ISDN subsystem  ---> ( NOTHING )

                        Parallel port support  ---> ( NOTHING )

                       	Plug and Play configuration  ---> ( NOTHING )      
			
			Block devices  --->
                                         
  	                File systems  --->

  	                Character devices  --->

                     	USB support  ---> ( NOTHING )

                     	I2O device support  ---> ( NOTHING )

                     	Kernel hacking  --->   ( NOTHING )
-----------------------------------------------------------------------------

System Type  --->


 			(S3C44B0) ARM system type                                   
                     	[ ] Generate big endian code

  	                [*] Set flash/sdram size and base addr

                     	(0c000000) (S)DRAM Base Address

                     	(00800000) (S)DRAM Size

                     	(00000000) FLASH Base Address

                     	(00200000) FLASH Size

General setup  --->

 			[*] Networking support 

			(ELF) Kernel core (/proc/kcore) format                                                
Networking options  --->

			[*] Packet socket

	 		[*] TCP/IP networking   

Network device support  --->

			[*] Network device support? 

			 Ethernet (10 or 100Mbit)  --->
				 [*] Ethernet (10 or 100Mbit)  

Block devices  --->  
			[*] Loopback device support 
			[*] RAM disk support
			(1024)   Default RAM disk size
			[*] ROM disk memory block device (blkmem)

File systems  ---> 
			[*] /proc file system support
			[*] ROM file system support
			[*] Second extended fs support

Character devices  --->
			Serial drivers  --->
				[*] S3C44B0 serial port support
				[*]   Support for console on S3C44B0 serial
port
				(115200)   Default S3C44B0 serial baudrate
			[*] Non-standard serial port support 

---------------------------------------------------------------------------

		Core Applications  --->
		Library Configuration  ---> (NOTHING)
		Flash Tools  ---> (NOTHING)
		Filesystem Applications  ---> (NOTHING)
		Network Applications  ---> (NOTHING)
		Miscellaneous Applications  --->   (NOTHING) 
		BusyBox  --->
		Tinylogin  ---> (NOTHING)
		MicroWindows  --->  (NOTHING) 
		Games  --->  (NOTHING)
		Miscellaneous Configuration  --->  (NOTHING)
		Debug Builds  ---> (NOTHING)
---------------------------------------------------------------------------

Core Applications--->
		[*] init 
 		[*]   enable console shell
		(Sash) Shell Program
		[*] expand
		[*]   expand should not write zeroes
BusyBox--->
		[*] BusyBox
		[*] cat
		[*] chgrp
		[*] chmod 
		[*] chown
		[*] clear
		[*] cp
		[*] date
		[*] echo 
		[*] hostname
		[*] ifconfig
		[*] ls 
		[*] ls: show usernames
		[*] ls: show timestamps
		[*] ls: file types 
		[*] ls: sort files 
		[*] ls: recursive 
		[*] ls: follow links 
		[*] mkdir
		[*] more
		[*] mount
		[*] mv
		[*] ping
		[*] ps
		[*] reboot
		[*] rm
		[*] route
		[*] vi
--------------------------------------------------------------------------
Note that the processor clock rate should be 60000000. After 'make menuconfig', the configuration is saved in .config and linux-2.4.x/.config. We had to modify CROSS in uClibc/Rules.mak; we changed it to: CROSS=arm-elf- ( Executing 'which arm-elf-gcc' would show /usr/local/bin/arm-elf-gcc'. If this is not the case, modify the PATH in .bash_profile. )

Then we have to execute the following commands in sequence:

	make dep
	make lib_only
	make user_only
	make romfs
	make image  ( error may occur, simply ignore it )
	make

Optionally, one may need to execute 'make clean'. At this point, we could obtain the files image.ram and romfs.img which are loaded into the 44B0X board using hyper-terminal in a PC through network link; parameters used are: baud rate = 115200, 8N1. tftpd32.exe has to be executed from the DOS prompt. Inside hyper-terminal we execute

tftp 0xc008000 image.ram and tftp 0xc400000 romfs.img to load the ram and rom images to locations 0xc008000 and 0xc400000 of 44B0X EV board respectively. Note that both of these images are NOT compressed. To start execution, we execute in hyper-terminal the command go 0xC008000 But the system hangs and we have to reboot the board.

To have some messages displayed we make the following modifications in directory uClinux-dist/linux-2.4.x:

  1) modify arch/armnommu/boot/Makefile:
	ifeq ($(CONFIG_ARCH_S3C44B0),y)
	ZRELADDR        = 0x0c008000
	ZTEXTADDR       = 0x0c300000	
	endif

ZRELADDR determines the address where execution starts after finishing loading images ZTEXTADDR the starting address of FLASH where the compressed image of BOOTLOADER is saved

  2) modify 'arch/armnommu/kernel/head-armv.S' at line 148:

	mov     r1, #178                @ ADD by Felix MACH_TYPE_S3C44B0178
        mov     r0, #F_BIT | I_BIT | MODE_SVC   @ make sure svc mode
        msr     cpsr_c, r0                      @ and all irqs disabled

The modification was to set MACH_TYPE which is 178 for S3C44B0. Note that when uClinux starts, it first checks the ID of CPU and the TYPE of the platform. If these are not right, the program will fall into an infinite loop.

3) modify 'include/asm-armnommu/proc-armv/system.h' at line 47:

	#ifdef CONFIG_ARCH_S3C44B0
	#undef vectors_base()
	//#define vectors_base()  (0x0c000008)
	//Tong: double-checked already, indeed it should be 0x0c000000
	#define vectors_base()  (0x0c000000)
	#endif
4) modify TEXTADDR in 'arch/armnommu/Makefile' at line 68:
	ifeq ($(CONFIG_CPU_32),y)
	PROCESSOR        = armv
	TEXTADDR         = 0xC008000
	endif
After these modifications, we did a 'make clean' and recompiled the kernel. Now when we downloaded the images to the 44B0X board and 'go c008000', some messages were displayed but the ARMBOOT rebooted. We saw the message "Warning: bad configuration page, trying to continue'. This is the confusing part. Some documents pointed out that the boot loader loads boot parameters from a certain location set at the file 'arch.c' but it seems that those parameters were over-written by some routines. We also ran into the trouble that we did not know where ARMBOOT put those parameters. When we do 'bdinfo' in ARMBOOT environment, it says that the boot parameters are located at locations 0x000000. However, when we examine those locations with command 'md 0x000000', we find that the values are essentially some garbage values which are some operation codes as they start with prefix '0xe....'. If we use the location 0xc000100 that many uClinux archives recommend, we find that the values there are all 0s. Anyway, we made the following modifications at uClinux/linux-2.4.x: 1)modify 'drivers/block/blkmem.c':
	added in blkmem_init():

	arena[0].length = (unsigned long)(-1);  //FELIX
  	arena[0].address = (unsigned long)0x0C400000; //FELIX
  	arena[0].rw = 1; //FELIX

	and made changes:
	//Felix
	//#define arenas (sizeof(arena) / sizeof(struct arena_t))
	#define arenas 1
2) modify 'arch/armnommu/mach-s3c44b0/arch.c'
	MACHINE_START(S3C44B0, "mba-44b0")
       		MAINTAINER("tpu")
        	BOOT_MEM(0x0c000000, 0x01c00000, 0x01c00000)
        	BOOT_PARAMS(0x0c000100)
       		INITIRQ(genarch_init_irq)
	MACHINE_END
However, this did not fix the problem. A lot more traces and debugs were made. We learned that the statement BOOT_PARAMS(0x0c000100) will set 'params' of 'parse_params(struct param_struct *params)' in 'arch/armnommu/kernel/setup.c' to 0x0c000100. If BOOT_PARMS(0x0000000) were used, 'params' is set to 0 and the message 'Warning: bad configuration page, trying to continue'. But it has not fixed the problem. This is because in 'setup.c', setup_arch() calls parse_param() under the following condition:
	 if (params) {
		.....
		parse_params(params);
		.....
	}
So if 'params == 0', parse_params(), which displays the warning message will never be called.

Because the boot parameters were not passed correctly, we added an extra function in 'arch/armnommu/kernel/setup.c'

	//added by Tong
	void update_params( struct param_struct *params, char *cmdline){
	// struct param_struct *linuxpars = &PARAMS_BASE;
 	params->u1.s.page_size = 4096;
 	params->u1.s.nr_pages = 8*1024*1024/4096; //2048
 	params->u1.s.rootdev = 31<<8;
	// linuxpars->u1.s.rootdev = 44<<8;
 	//params->u1.s.initrd_start=MAPTOPHYS((unsigned long)&_end);i
 	params->u1.s.initrd_start = 0xC400000;
 	params->u1.s.initrd_size=2*1024;       //2048K?
 	params->u1.s.video_num_cols = 80;
 	params->u1.s.video_num_rows = 24;
 	params->u1.s.flags = 0x01 | FLAG_RDLOAD| FLAG_RDPROMPT;  //mount root read only..
 	params->u1.s.rd_start = 0;
 	params->u1.s.ramdisk_size = 1024;      //in KBytes

 	memcpy(¶ms->commandline, cmdline, strlen(cmdline));
}
This function is called at the beginning of parse_params() of setup.c:
	static void __init parse_params(struct param_struct *params)
	{
        	//added by Tong
        	update_params( params, "/dev/rom0" );
		....
	}
Despite all these, the problem persisted. Further trace show that the problem was due to the mounting of the ext2 file system. After a lot of effort, we found that the address of the open() function that opens a ext2 was not passed correctly. The problem was due to the incorrect mapping of the fucntions of blkmem_fops in the file drivers/block/blkmem.c:
  static struct block_device_operations blkmem_fops=
  {
     	open:           blkmem_open,
        release:        blkmem_release,
        ioctl:          blkmem_ioctl,
    #ifdef MAGIC_ROM_PTR
        romptr:         blkmem_romptr,
    #endif
  };
It might be that the the variable blkmem_fops is used somewhere else and its values ( thus the function addresses ) are over-written. To fix the problem, we simpley create another similar variable called blkmem_fops0 in blkmem.c and use it to register ( in fucntion blkmem_init() of blkmem.c ): register_blkdev(MAJOR_NR, DEVICE_NAME, &blkmem_fops0 ) ( this function is in fs/block_dev.c. )

Now the kernel could run all the way to the end but not showing the shell prompt. Finally, we edited in directory uClinux-dist

vendors/Samsung/4510B/rc adding the command, '/bin/sh'. The shell prompt appeared:
......

Command: #mount -t ext2 /dev/ram1 /ramdisk
Command: chmod 777 /var
Command: mkdir /var/config
Command: mkdir /var/tmp
Command: mkdir /var/log
Command: mkdir /var/run
Command: mkdir /var/lock
Command: ifconfig lo 127.0.0.1
Command: route add -net 127.0.0.0 netmask 255.255.255.0 lo
Command: ifconfig eth0 192.168.1.73 netmask 255.255.255.0 up
SIOCSIFADDR: No such device
SIOCSIFNETMASK: No such device
SIOCGIFFLAGS: No such device
pid 20: failed 768
Command: #mkdir /ramdisk/web
Command: #cp /home/httpd/index.html /ramdisk/web
Command: cat /etc/motd
Welcome to
          ____ _  _
         /  __| ||_|                 
    _   _| |  | | _ ____  _   _  _  _ 
   | | | | |  | || |  _ \| | | |\ \/ /
   | |_| | |__| || | | | | |_| |/    \
   |  ___\____|_||_|_| |_|\____|\_/\_/
   | |
   |_|

For further information check:
http://www.uclinux.org/

Command: /bin/sh

Sash command shell (version 1.1.1)
/> Reading command line: Bad file descriptor
pid 22: failed 256
Execution Finished, Exiting
init: Booting to single user mode

Sash command shell (version 1.1.1)
/> ls
bin             dev             etc             home            lib
mnt             proc            ramdisk         sbin            tmp
usr             var
/>
----------------------------------------------------------------
P.S. Some other files that you may need to check concerning communication parameters at uClinux-dist/linux-2.4.x are
	drivers/serial/Config.in
	drivers/serial/serial_core.c
	include/linux/autoconf.h   ( check DRAM address )
	include/config/serial/s3c44b0/console.h
	../vendors/config/armnommu/config.arch ( set BAUD rate )

If you want to combine image.ram and romfs.img into one image file, you need to edit three files:

  1. linux-2.4.x/arch/armnommu/vmlinux-armv.lds.in: Add *(.got) ... to .text { .. }
    
    .text : {                       /* Real text segment            */
                  	_text = .;      /* Text and read-only data      */
    		........
    		........
     		*(.got)      	/* Global offset table          */
                    romfs_data = .;
                    romfs.o
                    romfs_data_end = .;
    
                    _etext = .;   	/* End of text section          */
    }
    
  2. Edit linnux-2.4.x/drivers/block/blkmem.c at two places:
  3. add the following:
    /*
     * Please, configure the ROMFS for your system here
     */
    #ifdef CONFIG_ARCH_S3C44B0
    extern char romfs_data[];
    extern char romfs_data_end[];
    #endif
    

  4. add the following to arenea[]:
    } arena[] = {
    
    #ifdef CONFIG_ARCH_S3C44B0
    {0, romfs_data, -1},
    #endif
    
    //these are there already
    #ifdef INTERNAL_ROMARRAY
            {0, (unsigned long)romarray, sizeof(romarray)},
    #endif
    
  5. change arenas to 1: #define arenas 1

  6. Edit linux-2.4.x/arch/armnommu/kernel/setup.c and comment out update_params()
Then 'make' as usual and at the end, both the ram fs and romfs will be automatically combined into the file 'image.ram'. We only need to load this file to the target board as usual ( i.e. tftp c008000 image.ram ).