![]() |
|
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 -p1patch 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:
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
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) #endif4) modify TEXTADDR in 'arch/armnommu/Makefile' at line 68:
ifeq ($(CONFIG_CPU_32),y) PROCESSOR = armv TEXTADDR = 0xC008000 endifAfter 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:
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 12) 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
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 ):
Now the kernel could run all the way to the end but not showing the shell prompt. Finally, we edited in directory uClinux-dist
......
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:
.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 */
}
/* * Please, configure the ROMFS for your system here */ #ifdef CONFIG_ARCH_S3C44B0 extern char romfs_data[]; extern char romfs_data_end[]; #endif
} arena[] = {
#ifdef CONFIG_ARCH_S3C44B0
{0, romfs_data, -1},
#endif
//these are there already
#ifdef INTERNAL_ROMARRAY
{0, (unsigned long)romarray, sizeof(romarray)},
#endif