gaston feng

linux2.6.11.8在S3C44B0上的运行--三水
gaston feng | May 11, 2008 2:29:58 PM

linux2.6.11.8在S3C44B0上的运行

 

最近事情很多,人也很懒。完成了《嵌入式系统接口设计与LINUX驱动程序开发》的书稿就不愿意在写什么东西了。今天实验室同学聚会,喝得有点头疼,不干活了,写一遍调试心得吧。

这里,我把题目定为“linux2.6.11.8在S3C44B0上的运行”,而不是“移植”,因为移植的多数工作在
http://opensrc.sec.samsung.com/download.html
已经完成了。当时,只有linux-2.6.11.8-hsc0.patch.gz,是2.6.11.8的补丁,现在去看,还有针对2.6.14的补丁,不过我没有仔细看,不知道对s3c44b0支持的好不好,是不是还有我这里遇到的问题。好了,废话少说,直接说说我用这个补丁在S3C44B0处理器上运行过程、遇到的问题和解决方法吧。

编译器使用的就是上面网站上提供的arm-uclinux-tools-base-gcc3.4.0-20040713,不过这里没有给源码,不知道改了啥东西,反正现在看来编译应用程序和内核都没问题。

首先,补丁打上,编译器安装以后,选择44b0的配置,编译内核,没有啥大问题。可能因为编译不过,需要调整源码的一些地方,这个具体的没啥说的,编译出错了,看看错误,都可以调整过来。下载内核到板子上,运行,解压以后就没有反映了。好在我对ARM7很熟悉,调试工具也多,通过JTAG跟踪,发现问题出在启动处。

修改arch/arm/boot/compressed/head-s3c44b0.S中的call_kernel(280行附近),代码:
  ldr r2, S3C44B0_PROCESSOR_TYPE
  str     r2, [r6]
  ldr     r2, S3C44B0_MACH_TYPE
  str     r2, [r9]
改为:
  ldr r6, S3C44B0_PROCESSOR_TYPE
  ldr     r7, S3C44B0_MACH_TYPE
直接付值。

其实,这一段不是很清楚为什么,感觉好象是程序写错了,在解压缩内核的时候,应该把处理器类型号(S3C44B0_PROCESSOR_TYPE)和板类型号(S3C44B0_MACH_TYPE)保存在r6和r7中的。最后,传递给非压缩内核。

提示:内核启动的时候,在console没有正确初始化之前,控制台(串口)不能输出,为了调试方便,可以在kernel/printk.c中的vprintk前面加入
 putstr(fmt);
直接输出printk打印的字符串。putstr是解压之前,内核输出的宏定义,所以必须
 #i nclude <asm/arch/uncompress.h>
因为是uclinux,没有MMU,直接使用物理地址就可以访问外设,所以,putstr可以直接使用。

然后,需要根据2.6.11.8内核,修改timer挂载方式。
 在arch/arm/mach-s3c44b0x/time.c中,添加

 struct sys_timer s3c44b0x_timer = {
  .init  = s3c44b0x_time_init,
  .offset  = s3c44b0x_gettimeoffset,
  .resume  = s3c44b0x_systimer_setup
 };
 在arch/arm/mach-s3c44b0x/arch.c中,替换
 INITTIME(s3c44b0x_time_init)

 .timer  = &s3c44b0x_timer,

接着很关键的地方就是中断处理。因为ARM7TMDI处理器没有MMU,也不能实现异常向量表的重新映射。在我的bootloader中,异常向量位置有指令:
 add pc, pc, 0xC000000
就是让对应的异常处理,跳转到0xC000000+8的地址处——因为ARM7中3级流水线的影响,所以,实际的跳转地址需要加8。

因此,我们需要修改内核代码,重定向中断向量地址。在arch/arm/kernel/traps.c中函数trap_init负责初始化所有的异常入口,替换
 unsigned long base = (CONFIG_DRAM_BASE);

 unsigned long base = (CONFIG_DRAM_BASE+0x8);
中断才可以用。

至此,内核基本就可以跑起来了。但是,这个不定对S3C44B0的支持太少了。甚至都没有串口驱动程序,而只给了一个查询方式发送的工作的串口作为console。不过这些都好办,在Linux 2.6.11以后的内核,有很好的对S3C2410的支持。S3C2410的很多外设寄存器是和S3C44B0的兼容的。比如:我们很容易就可以利用S3C2410的串口驱动程序在44B0上。

最后,还有一个地方感觉内核也写错了。不知道为什么,这里对44B0还是定义了ARMv3支持的宏。我这个在我几年前,在移植Ne2000驱动程序在44B0上的时候就遇到过,44B0应该使用ARMv4的定义,否则,会影响一些对外设操作的函数。现在,我的板子上用的是DM9000的网卡,必须修改这里,驱动程序才可以正常工作。有了网卡的驱动,就容易调试多了。我们可以使用nfs做root,来调试根文件系统和启动——我太喜欢这种方式了:)



http://threewater.blog.com.cn/archives/2006/540693.shtml

Comment: (no reply)
To post your comment, Please login first.