Chinaunix首页 | 论坛 | 博客
  • 博客访问: 358641
  • 博文数量: 120
  • 博客积分: 4010
  • 博客等级: 上校
  • 技术积分: 1810
  • 用 户 组: 普通用户
  • 注册时间: 2008-01-11 17:50
文章分类

全部博文(120)

文章存档

2008年(120)

我的朋友

分类:

2008-03-20 16:28:34

 
2.3.5 C语言中的硬件初始化
继续对硬件进行初始化,主要包括对以下设备的初始化:GPIO,Cache,Interrupt Controller,Watchdog Timer和UARTs。S3C44B0X处理器内置data/instruction合一的8KB Cache,且允许按地址范围设置两个Non-Cacheable区间。合理的配置是打开对RAM区间的Cache,关闭对其它地址区间(非存储器设备,I/O设备 )的Cache。所有硬件初始化完毕之后,开中断。
 
2.3.6 建立人机界面
引导过程的最后一步是在串行终端上建立人机界面,并等待用户输入命令。若接收到用户输入,则显示菜单模式或命令行模式的交互界面,等待用户进一步的命令。这里就不对此详细讨论了。
 
2.4加载ucLinux内核
ARMSYS提供的Bootloader支持两种ucLinux启动运行方式:直接从SDRAM中的内核映像中运行;从flash将压缩格式的内核映像加载到SDRAM,再从SDRAM运行。前者需要利用Bootloader提供的对映像文件下载的工具;后者则需要利用Bootloader提供的 flash烧录工具进行烧录,然后再加载运行。
压缩格式的ucLinux内核映像文件都是由开头的一段自解压代码和后面的压缩数据部分组成。对于Kernel而言,由于是以压缩格式存放,因此只能以非XIP方式执行。自解压类型的ucLinux 内核映像文件首先存放在Flash Memory中,由Bootloader加载到SDRAM中的0xc100000地址处,然后将控制权交给它。可执行的ucLinux Kernel将被解压到最终的执行空间,然后开始运行。压缩格式Image所占据的临时SDRAM空间可在随后由ucLinux回收利用。
可以从flash拷贝到SDRAM解压运行,自然同样也可以直接下载到SDRAM运行。这对于调试内核都是非常方便的。对于压缩格式的内核映像文件(image.rom和image.ram)都可以直接下载到SDRAM的特定地址处,并从该地址开始运行(参考2.2节)。
 
2.5调用Kernel
Bootloader调用ucLinux 内核的方法是直接跳转到Kernel的第一条指令处。
采用C语句:((void (*)(void))ram_addr)();
 
2.6工具
ARMSYS的Bootloader在人机界面上提供了8个功能项目,其中包括支持从主机通过USB口下载文件到目标板的SDRAM和Nandflash上;用SDRAM中的数据烧写Flash Memory。由于USB口下载速度快,利用这些功能项能够轻松地调试ucLinux的内核(具体使用方法参考《ucLinux移植包在ARMSYS上的使用说明》一文)。
对ucLinux专用Bootloader的介绍到此,下面开始对ucLinux的内核部分的移植进行说明。
 
3.ucLinux2.4.24内核组成
 
◎arch:arch目录下有多个子目录,它的每一个子目录都代表内核支持的一种CPU体系结构,每个子目录中又进一步分解为boot、mm、 kernel等子目录,分别包含与系统引导、内存管理、系统调用的进入和返回、终端处理以及其它内核中依赖于CPU和系统结构的底层代码。与ARM处理器(不带有MMU)相关的代码放在目录arch/armnommu下,与S3C44B0X相关的代码则放在目录arch/armnommu/match- S3C44B0X。
◎ include:include子目录包括编译核心所需要的大部分头文件。与平台无关的头文件在 include/linux子目录下,与ARM处理器(不带MMU)相关的头文件在include/asm-armnommu子目录下,与 S3C44B0X相关的代码在include/asm-armnommu/arch-S3C44B0X目录下;
◎ init:这个目录包含核心的初始化代码(注意:不是系统的引导代码),包含两个文件main.c和Version.c,这是研究核心如何工作的一个非常好的起点。
◎ kernel:主要的核心代码,此目录下的文件实现了大多数linux系统的内核函数,其中最重要的文件当属sched.c;同样,和体系结构相关的代码在arch/*/kernel中;
◎ drivers: 放置系统所有的设备驱动程序;每种驱动程序又各占用一个子目录:如,/block 下为块设备驱动程序,比如ide(ide.c)。
◎其他:例如mm ,这个目录包括所有独立于处理器体系结构的内存管理代码,如页式存储管理内存的分配和释放等;lib放置核心的库代码;net,核心与网络相关的代码; ipc,这个目录包含核心的进程间通讯的代码;fs,所有的文件系统代码和各种类型的文件操作代码,它的每一个子目录支持一个文件系统,例如fat和 ext2;Scripts,此目录包含用于配置核心的脚本文件等。
小呆:这里原来有个图,我略了,这个图没什么大意思,就是画了一个内核的文件结构。

 
一般在每个目录下,都有一个.depend 文件和一个 Makefile 文件,这两个文件都是编译时使用的辅助文件,仔细阅读这两个文件对弄清各个文件这间的联系和依托关系很有帮助;而且,在有的目录下还有Readme 文件,它是对该目录下的文件的一些说明,同样有利于我们对内核源码的理解。
ucLinux-dist-20040408发行包中的内核对S3C44B0X处理器的支持是不完整的,因此,我们不能够希望在make config配置选项中选中44B0X目标板后,直接编译它来得到一个很好地支持44B0X开发板的内核映像,我们必须为内核打上补丁。针对ARMSYS 的补丁文件可以在地址处下载得到。这款补丁是众多爱好 ucLinux和44B0X处理器的网友们共同完成的。下一节我们就对这个补丁中的主要修改项目进行介绍和分析,从中了解ucLinux移植中的要点。
 
4.移植项目及说明
 
4.1       压缩内核代码起始地址修改
修改文件:ucLinux-dist/linux-2.4.x/arch/armnommu/boot/Makefile
修改内容:
ifeq ($(CONFIG_BOARD_MBA44),y)
ZTEXTADDR = 0x0c100000
ZRELADDR = 0x0c008000
endif
说明:
ZTEXTADDR:自解压代码的起始地址。
ZRELADDR:内核解压后代码输出起始地址。
 
4.2       处理器配置选项的修改
修改文件:ucLinux-dist/linux-2.4.x/arch/armnommu/config.in
修改内容:
define_bool CONFIG_NO_PGT_CACHE y
define_bool CONFIG_CPU_WITH_CACHE y
define_bool CONFIG_CPU_WITH_MCR_INSTRUCTION n
- define_int CONFIG_ARM_CLK 60000000
- define_bool CONFIG_SERIAL_S3C44B0X y
- define_int CONFIG_FORCE_MAX_ZONEORDER 5
+ define_int CONFIG_ARM_CLK 64000000 #72000000
+# define_bool CONFIG_SERIAL_S3C44B0X y
+# define_int CONFIG_FORCE_MAX_ZONEORDER 5
if [ "$CONFIG_SET_MEM_PARAM" = "n" ]; then
- define_hex DRAM_BASE 0x00000000
+ define_hex DRAM_BASE 0x0C000000
define_hex DRAM_SIZE 0x00800000
- define_hex FLASH_MEM_BASE 0x01000000
+ define_hex FLASH_MEM_BASE 0x00000000
define_hex FLASH_SIZE 0x00200000
fi
fi
……
说明:
修改了对ARM处理器主频的定义:
define_int CONFIG_ARM_CLK 64000000
修改了存储器大小和起始地址的定义:
define_hex DRAM_BASE 0x0C000000        ;SDRAM的起始地址
define_hex DRAM_SIZE 0x00800000                ;SDRAM的大小
define_hex FLASH_MEM_BASE 0x00000000     ;flash的起始地址
define_hex FLASH_SIZE 0x00200000                ;flash的大小
 
4.3       内核起始地址的修改
修改文件:ucLinux-dist/linux-2.4.x/arch/armnommu/Makefile
修改内容:
ifeq ($(CONFIG_BOARD_MBA44),y)
-TEXTADDR = 0x0c000000
+TEXTADDR = 0x0c008000
MACHINE = S3C44B0X
INCDIR = $(MACHINE)
-CORE_FILES := $(CORE_FILES) romfs.o
+CORE_FILES := $(CORE_FILES) #romfs.o
endif
说明:
TEXTADDR:内核的起始地址,通常取值:DRAM_BASE+0x8000。
 
4.4       ROM文件系统的定位修改
修改文件:ucLinux-dist/linux-2.4.x/drivers/block/blkmem.c
修改内容:
+#ifdef CONFIG_BOARD_MBA44
+ {0, 0xc700000, -1},/*{0, 0x100000, -1},*/
#endif
说明:将ROM file system在SDRAM中的地址定位在0xc700000。
 
4.5       修改存储空间配置
 
修改文件:ucLinux-dist/linux-2.4.x/include/asm-armnommu/arch-S3C44B0X/memory.h
修改内容:
-#define PHYS_OFFSET (DRAM_BASE + 2*1024*1024)
+#define PHYS_OFFSET (DRAM_BASE)//(DRAM_BASE + 2*1024*1024)
#define PAGE_OFFSET (PHYS_OFFSET)
-#define END_MEM (DRAM_BASE + DRAM_SIZE - 2*1024*1024)
+#define END_MEM (DRAM_BASE+DRAM_SIZE)//(DRAM_BASE + DRAM_SIZE - 2*1024*1024)
说明:PHYS_OFFSET:RAM第一个bank的起始地址。
 
4.6初始化节拍定时器
 
修改文件:ucLinux-dist/linux-2.4.x/include/asm-armnommu/arch-S3C44B0X/time.h
修改内容:
-extern void s3c44b0x_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+//extern void s3c44b0x_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static inline void s3c44b0x_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+ do_leds();
+ do_timer(regs);
+}//modified by hzh
 
/* TODO: THE, 2003-08-13, do timer setup like in eCos */
-#define S3C44B0X_TIMER5_PRESCALER 16
+#define S3C44B0X_TIMER5_PRESCALER 32
 
extern __inline__ void setup_timer (void)
{
u_int32_t tmod;
u_int32_t period;
+ __u32 rw_tmp;
 
period = (CONFIG_ARM_CLK/S3C44B0X_TIMER5_PRESCALER)/HZ;
outl(period, S3C44B0X_TCNTB5);
@@ -36,8 +42,14 @@
outl(tmod, S3C44B0X_TCON);
 
/* initialize the timer period and prescaler */
- outl((5-1) << 16, S3C44B0X_TCFG0);
- outl( (0x3 <<20), S3C44B0X_TCFG1); /* prescaler */
+ rw_tmp = inl(S3C44B0X_TCFG0);
+ rw_tmp &= ~(0xff<<16);
+ rw_tmp |= (16-1)<<16;
+ outl(rw_tmp, S3C44B0X_TCFG0); // prescaler = 1/16
+ rw_tmp = inl(S3C44B0X_TCFG1);
+ rw_tmp &= ~(0xf<<20);
+ rw_tmp |= 0<<20;
+ outl(rw_tmp, S3C44B0X_TCFG1); // mux = 1/2
说明:这里,ucLinux使用了S3C44B0X的内部定时器5,并利用定时器5的中断来产生节拍。
 
4.7       定义二级异常中断矢量表的起始地址
修改文件:ucLinux-dist/linux-2.4.x/include/asm-armnommu/proc/system.h
修改内容:
+#ifdef CONFIG_BOARD_MBA44
+#undef vectors_base()
+#define vectors_base() (DRAM_BASE)
+#endif
说明:vectors_base()定义了二级异常中断矢量表的起始地址,这个地址与Bootloader中的_IRQ_BASEADDRESS相对应。
 
4.8       定义CPU体系结构和交叉编译器
 
修改文件:ucLinux-dist/linux-2.4.x/Makefile
修改内容:
-# ARCH := armnommu
+ARCH := armnommu
# ARCH := m68knommu
# ARCH := h8300
# ARCH := niosnommu
……
HOSTCFLAGS = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer
# CROSS_COMPILE = m68k-elf-
-# CROSS_COMPILE = arm-elf-
+CROSS_COMPILE = arm-elf-
# CROSS_COMPILE = h8300-elf-
# CROSS_COMPILE = nios-elf-
# CROSS_COMPILE = e1-coff-
说明:这里定义了CPU体系结构:ARCH := armnommu和对应的交叉编译器名称:CROSS_COMPILE = arm-elf-。
 
4.9       以太网卡寄存器地址的偏移量修改
这里针对ARMSYS的硬件结构,要做两处特殊的修改:
修改文件:ucLinux-dist/linux-2.4.x/driver/net/8390.h
修改内容:#define ETH_ADDR_SFT 8
说明:访问RTL8019内部寄存器地址的偏移量。
 
4.10     以太网设备基地址修改
修改文件:ucLinux-dist/linux-2.4.x/driver/net/ne.c
修改内容:dev->base_addr = base_addr = 0x08000000;
说明:修改了以太网设备的基地址。
 
5.移植的步骤
 
5.1    解压ucLinux-dist发行包
到以下地址下载ucLinux-dist-20040408.tar.gz源代码包:
. ucLinux.org/pub/ucLinux/dist/ucLinux-dist-20040408.tar.gz
该版本在很多方面比早先的20030522版本要完善很多,这也使我们的移植工作变得方便很多。其中使用的内核版本是Linux 2.4.24。
以下工作在装有Linux操作系统(例如RedHat9.0)的PC机上进行。
将ucLinux-dist-20040408.tar.gz拷贝到/home/下(或者其它目录都可以),运行解压命令:
tar xvzf ucLinux-ARMSYS-20040801.tar.gz
解压结束后会在/home/下生成ucLinux-dist目录。
 
5.2安装补丁
到以下地址下载补丁文件:
解压后产生patch文件,安装patch文件:
patch –p1 < ucLinux-20040408-ARMSYS.patch
安装过程中可能会出现一些错误信息,可以手动地按照patch文件的内容在指定的文件处进行修改一下。
 
6.配置与编译
 
6.1    安装编译环境
到以下地址下载arm-elf工具链:
. ucLinux.org/pub/ucLinux/m68k-elf-tools/arm-elf-tools-20030314.sh
将arm-elf-tools-20030314.sh拷贝到根目录,运行安装:
sh arm-elf-tools-20030314.sh
 
6.2    内核配置
下面就可以开始配置ucLinux的内核和用户选项了。打开终端。
# cd /home/ucLinux-dist
# make menuconfig
进入ucLinux配置(ucLinux v3.1.0 Configuration),选中“Kernel/Library/Defaults Selectionà”敲空格进入。其中有两个选项:定制内核设置和定制用户选项设置:
[*] Customize Kernel Settings
[ ] Customize Vendor/User Settings
选中定制内核设置选项,按下ESC键退出,在询问是否保存时,选择Yes并回车。
终端将首先进入内核配置选单。我们在配置ucLinux内核时,就可以通过对这些选项的选择和取消选择来设定内核所具有的功能项。这也是裁减ucLinux内核的基本方法。
每个选项都对应着一个宏定义,make menuconfig执行结束后,自动将配置结果保存为.config文件,将前一次的配置结果备份为.config.old文件。
读者可到 处下载内核配置文件(其中包括对网卡驱动的配置),读者可对照进行配置。
 
6.3交叉编译
按下面的步骤对ucLinux源码包进行编译:
# make dep
# make clean (非必要)
# make lib_only
# make user_only
# make romfs
# make image
# make
初次移植时,在make lib_only到make这5步编译过程中很可能产生错误,无法继续下去。如果产生了错误,可以尝试根据报告的错误内容修改一下源程序,这一过程将有助于你熟悉ucLinux内核源程序的结构,或者可以跟我们联系 。
交叉编译成功后,在ucLinux-dist/目录下产生images目录,其中包含的3个文件:image.ram, image.rom和romfs.img就是我们可以使用的二进制文件。参考《ucLinux的移植包在ARMSYS上的使用说明》的方法,下载或烧录这些二进制文件,并启动运行ucLinux。
 
7.启动信息
 
正确启动信息的例子如下:
Linux version 2.4.24-uc0 () (gcc
version 2.95.3 20010315 (release)(ColdFire patches - 20010318 from
.net/coldfire/)(ucLinux XIP and shared lib patches from
)) #165 五 10月 8 20:04:10 CST 2004
Processor: Samsung S3C44B0X revision 0
Architecture: S3C44B0X
On node 0 totalpages: 2048
zone(0): 0 pages.
zone(1): 2048 pages.
zone(2): 0 pages.
Kernel command line: root=/dev/rom0 init=/linuxrc
Calibrating delay loop... 31.84 BogoMIPS
Memory: 8MB = 8MB total
Memory: 6592KB available (1270K code, 155K data, 40K init)
Dentry cache hash table entries: 1024 (order: 1, 8192 bytes)
Inode cache hash table entries: 512 (order: 0, 4096 bytes)
Mount cache hash table entries: 512 (order: 0, 4096 bytes)
Buffer cache hash table entries: 1024 (order: 0, 4096 bytes)
Page-cache hash table entries: 2048 (order: 1, 8192 bytes)
POSIX conformance testing by UNIFIX
Linux NET4.0 for Linux 2.4
Based upon Swansea University Computer Society NET3.039
Initializing RT netlink socket
Starting kswapd
ttyS0 at I/O 0x1d00000 (irq = 3) is a S3C44B0
ttyS1 at I/O 0x1d04000 (irq = 2) is a S3C44B0
ne.c:v1.10 9/23/94 Donald Becker ()
Last modified Nov 1, 2000 by Paul Gortmaker
NE*000 ethercard probe at 0x8000000: 00 00 e8 12 34 56
eth0: NE1000 found at 0x8000000, using IRQ 22
Blkmem copyright 1998,1999 D. Jeff Dionne
Blkmem copyright 1998 Kenneth Albanowski
Blkmem 1 disk images:
0: C400000-C47CBFF [VIRTUAL C400000-C47CBFF] (RO)
RAMDISK driver initialized: 16 RAM disks of 1024K size 1024 blocksize
NET4: Linux TCP/IP 1.0 for NET4.0
IP Protocols: IC
IP: routing cache hash table of 512 buckets, 4Kbytes
TCP: Hash tables configured (established 512 bind 512)
VFS: Mounted root (romfs filesystem) readonly.
Freeing init memory: 40K
Shell invoked to run file: /etc/rc
Command: hostname Samsung
Command: /bin/expand /etc/ramfs.img /dev/ram0
Command: mount -t proc proc /proc
Command: mount -t ext2 /dev/ram0 /var
Command: mkdir /var/config
Command: mkdir /var/tmp
Command: mkdir /var/log
Command: mkdir /var/run
Command: mkdir /var/lock
Command: cat /etc/motd
Welcome to
____ _ _
/ __| ||_|
_ _| | | | _ ____ _ _ _ _
| | | | | | || | _ \| | | |\ \/ /
| |_| | |__| || | | | | |_| |/ \
| ___\____|_||_|_| |_|\____|\_/\_/
| |
|_|
For further information check:
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.253.2 netmask 255.255.255.0 up
Execution Finished, Exiting
Sash command shell (version 1.1.1)
/>
出现以上信息后,可以尝试从键盘输入ls、ping命令,来查看系统的运行情况。我们还建议读者按照ucLinux-dist\ Documentation下的Adding-User-Apps-HOWTO文档编写一个简单的Helloworld应用程序,看是否能够正确运行。
阅读(1103) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~