⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 移植uclinux到44b0上的过程.txt

📁 uClinux上的应用程序设计对ARM芯片S3C44B0。
💻 TXT
字号:
  
移植UCLINUX到44B0上的过程 
电路设计  www.PCBTech.net   2003-12-24  中国PCB技术网 


我本人对于UCLINUX方面的开发和应用其实并不熟悉,因为看到电子产品世界论坛上有很多这方面的讨论觉得有点意思,后来就买了块代博的板子玩玩,然后对此兴趣渐浓,后来我觉得不在自己那块44B0上玩玩UC实在不甘心,就慢慢摸索着把它移植过去.当然碰到了不少的问题,不过现在已经在我的板上跑得很好,网络也通了,就跟在4510上运行差不多.我看看了本论坛上讨论4510的UC的贴子还是不少,希望大家也可以在44B0上跑通UC,而且完全可以把4510上运行UC的经验搬到44B0上来.TPU曾告诉我他以前在这上面跑过MICROWINDOW,这也很吸引人哦,快快学吧!
在好几个坛子上面看到大家对uC的讨论热火朝天,但差不多都是基于4510开发板的,而基于44B0的好象很少,并且不象4510的那样成熟和清晰。可能和4510主要是网络应用有关吧,它可以充分利用uC的网络功能。如果在44B0上加入uC,也可以体验一下这个操作系统,再加入往卡驱动的话,也能实现网络哦!记得以前在ARM开发论坛看到一位高人写过在44B0的uC上加网卡驱动的文章,想做这个的兄弟可以去找找。
我手头有4510和44B0的板子各一块,4510是代博的,上面带的uC挺好用。于是想在44B0上也跑跑uC,两周前我调通了8019后觉得条件差不多了,因为uC的IMAGE.RAM是非压缩的,有1M多,调试的时候如果不用到网络下载的话会很慢,即使用串口调到115.2K也要几分钟时间,而且可靠性也较低,所以有网卡芯片是移植的一个重要条件,当然有USB通讯的话也很快,不过我的板那块坏了,并考虑到以后会用到网络,还是用8019吧。从我有板开始我就一直找可用于44B0的uC,并下载过TPU兄的源文件,上次看到TPU兄的留言可帮忙移植就马上留言联系,后来通过一封MAIL好象就没消息了,只好自己摸索着做做,所以我的移植过程可能存在很多不对的地方,大家一起参考修正.
开始我想跑跑TPU的ZIMAGE,这是一个压缩后的文件,运行时需要自解压,查到它的起始运行地址是0XC300000,KENERL运行地址是0XC008000,用自己的BIOS将数据DOWN到设定地,再RUN,运行出现结果了,开始是些乱码,调了一下串口速率,在38400,显示UCOMPRESS KERNEL...不过到START KERNEL后,再没下文了,于是用AXD反汇编调试,发现是因为进入KERNEL后没找到PROCESSER ID而停掉,可能是要在BIOS中传递过去。后来想到一个办法,把我现在在4510板上跑的uC改动后移植到44B0上,在那一版上大家对uC的应用都做得比较熟了,编起来也比较方便。开始有这个想法没贴出来,因为首先得验证可行性,就先做做实验啦。
首先准备一分uC的源码,我用的是uCLinux-dist20030522版,本来是在4510上跑的,板的型号叫SNDS100,带上代博的PATCH,以前的版本应该也可以,我没有试。再准备一个BIOS,可以下载编译好的程序进行调试,可以看看我以前贴的那个。还需要一个串口调试工具,用来和BIOS和uC做人机交互,我用的是SSCOM3.2,在LINUX下也有相应程序。我的移植过程是从4510开发板上开始的,所以需要看本文的人对4510有一定了解。在这我只列出修改的地方,如果你有什么不明之处可以和我讨论。uC编译后在IMAGES目录生成三个文件,一个是IMAGE.RAM,这是带自启动的压缩版,可烧入FLASH运行,一个是IMAGE.RAM,这是没压缩的,须通过下载后直接运行.

首先,拿我的4510板开工做实验,尝试修改内核的一些参数。

一、
修改波特率
1、INCLUDE/ASM-ARMNOMMU/ARCH-SNDS100/HARDWARE.H中将
#define DEBUG_UBRDIV_REG_VAL (0x500) 改为
#define DEBUG_UBRDIV_REG_VAL (0x1a0)
此为启动期间输出信息所用串口波特率分频系数
2、DRIVERS/CHAR/SERIAL-SAMSUNG.C中将serial_console_setup函数中
int baud = 19200 改为 57600
此为CONSOLE STARTUP时设置的波特率,此时用的是这个文件,到后面移植到44B0X时换为另一个文件。
3、VENDERS/SAMSUNG/4510B/CONFIG-ARCH
19200->57600 不知有用否,为防止出错先改了。
编译运行成功。

二、
修改运行地址
1、ARCH/ARMNOMMU/MAKEFILE
TEXTADDR 决定KERNEL起始运行地址,即IMAGE.RAM应DOWN到的位置
2、ARCH/ARMNOMMU/BOOT/MAKEFILE
ZREALADDR 决定KERNEL解压后数据输出的地址,同1
ZTEXTADDR 带BOOTLOADER的压缩内核文件烧入FLASH的起始地址,即从哪个位置开始执行
BOOTLOADER,若启动时直接执行,将其设为0,若自带BIOS可以跳到你想要的地址,可改为你要的位置。
我把KERNEL运行地址改为0X00208000,编译运行成功。

三、(重点)
修改uC使其在不REMAP的情况下在4510上运行。因为44B0与4510第一点区别就是4510可REMAP而44B0不行。在这点上遇到点问题花了我三天时间才搞掂,其实是在个很简单的地方设置一下。
1、修改存储器参数 
ARCH/ARMNOMMU/CONFIG.IN里面对应的SNDS100下的参数:
DRAM_BASE,DRAM_SIZE,FLASH_MEM_BASE,FLASH_SIZE
针对不同的开发板,这些参数也可能不同,我的4510板原值分别为
0X00000000,0X01000000,0X01000000,0X00200000
这些参数意思一看就明,我将它们分别改为
0X01000000,0X01000000,0X00000000,0X00200000
即不对内存分配REMAP。
2、把第二步中的KERNEL运行地址改为0X01008000。
3、修改VECTORS_BASE的宏定义,原值在INCLUDE/ARMNOMMU/PROC-ARMV/SYSTEM.H中定义为0,意思是KERNEL将向量表COPY到DRAM中的地址,现改DRAM_BASE即0X01000000,因为实际向量还是在0地址即FLASH起始地址,所以在FLASH中向量处做个跳转:
0: LDR PC,=0X01000000
4: LDR PC,=0X01000004
.........
我的BIOS有下载和运行程序的功能,因此没有改地址0的指令。这样发生中断时先到实际地址0X18,再跳到UCLINUX的中断向量地址0X01000018。
4、修改ARCH/ARMNOMMU/MACH-SNDS100/ARCH.C,
在 MAINTAINER("XXX") 后加上
BOOT_MEM(DRAM_BASE, 0x00000000, 0x00000000)
5、修改ARCH/ARMNOMMU/INIT.C,在reserve_node_zero函数里将
if (machine_is_integrator() || machine_is_snds100() ||
machine_is_evS3C4530HEI() ) 
reserve_bootmem_node(pgdat, 0, __pa(&_stext));
改为
if (machine_is_integrator() || machine_is_snds100() ||
machine_is_evS3C4530HEI() )
reserve_bootmem_node(pgdat, DRAM_BASE, __pa(&_stext)-DRAM_BASE);
6、make menuconfig时不要选择自己手动设置存储器参数!(很简单的一点,搞了我好久)

上诉过程完成后,可以证明这版uC是可以移植到44B0X上的,之后开始移植过程。先做些基本修改,把上面第二步中的KERNEL运行地址改为0X0C008000,这是44B0X中的DRAM地址。把上面第三步中的1中DRAM_BASE, DRAM_SIZE 分别改为0X0C000000, 0X00800000, 另外把FLASH中0-0X1C中的指令改跳转到0X0C000000-0X0C00001C。
基础做好了,之后看看在原版中对应于4510的硬件操作包括些什么。第一个是网络部分,我们可以先把它去掉,以后在加自己的驱动,我在DRIVERS/NET/MAKEFILE里面屏蔽了
obj-$(CONFIG_ETH_S3C4510) += s3c4510.o这一行,使网络驱动不被编译,也不知道有什么相关的遗留问题,不过我把VENDORS/SAMSUNG/4510B/下面inittab和rc两个文件中启动网络的命令也关了。剩下的和硬件相关的操作还有三个,一是中断处理,二是TIMER,三是串口控制台,另外在编译IMAGE.ROM时用到ARCH/ARMNOMMU/BOOT/COMPRESSED/HEAD.S文件,原文件因是启动版包含了相关的硬件初始化,因为先不用可以都屏蔽掉。
下面仔细对付先前提的三个问题。和4510相关的寄存器定义都在INCLUDE/ASM-ARMNOMMU/ARCH-SNDS100/HARDWARE.H中,同时在这个目录下还包含了一些需要修改的头文件,在后面说明。在HARDWARE.H中根据寄存器的用途和地址作出修改,我并没改它们的名字,只是先改成44B0中相对的寄存器所在的地址,另外还有些修改我不能尽述,可以把文件贴出来。其实对三个问题的解决应该是同时搞好才行,缺了哪个都不能看到正常结果输出,但我只能一一说明。
调试中我遇到不少问题,但不能都写出来,就讲必须作的吧。第一要保证中断可以开了,在
ARCH/ARMNOMMU/MACH-SNDS100/IRQ.C里加上中断初始化,设置模式及预清一次所有中断,使能全局中断。
时钟的初始化和中断使能在INCLUDE/ASM-ARMNOMMU/ARCH-SNDS100/TIME.H中设置,频率在TIMEX.中,我用的是TIMER5。 
对于中断,开始的处理过程和在4510上面不REMAP的情况差不多,差别就在于获取中断号,可以看看源文件ARCH/ARMNOMMU/KERNEL/ENTRY-ARMV.S里面有个get_irqnr_and_base的宏定义,我先自己改了个,后来试了在calibrate_delay中TIMER中断老有问题,我也没再仔细研究,把TPU的相关代码直接COPY来用,呵呵,好了!显示出我的BogoMIPS了,不过显示值是我实际运行频率的一半,我想是因为我的DRAM数据总线只有16位的原因吧。后来运行老是会死掉,要不就显示一些错误信息停掉,要不就疯狂打出乱七八糟的数据来,反正显示不到SH这个SHELL下,让我一直怀疑这样做是不是有问题。后来才用降频法,我原来用50M,和4510板一样,后来改到20M才算是正常了,(好在我的BIOS可以交互式改频
,不用退到98下修改再烧入),这个我估计和硬件稳定性有关,也可能你的可跑高频。不过正常的时候是停住了,没错误信息也没疯狂打印,我敲了下键盘,之后就显示出一堆数据,进入了SH,再按键没有输出,奇怪!这是串口控制台的问题了。
再讲讲串口控制台,我开始把4510中相对的寄存器换到44B0中相应的位置,并对状态寄存器做了相应的转换,因为4510的是一个寄存器而44B0是两个,我把DRIVERS/CHAR/SERIAL-SAMSUNG.C中相应读状态的语句都加了加读一个寄存器内容的操作,以为做得可以了,实际还是出了些问题,先是忘了改注册发送中断的部分,所以出现前面的问题,改过后能输出我按的键了,不过是按键有时没显示有时显示两三个字符,但输入命令后居然可以执行。我想再仔细研究一下源码吧,可觉得这是一项很艰苦的工作,我对LINUX并不熟,SEIRAL文件有一百多K四千多行,再加上相关部分各种结构和控制台、中断等等,不是能短期内完成的。后来还是TPU兄的源码帮了忙,我看了那里面使用串口控制台的部分,有个SERIAL-CORE.C和一个S3C44B0.C文件,前者应该是个标准文件,后者比较小,包括控制台的一些标准操作,里面调用前者的一些函数。摸索一番后把它们COPY到CHAR目录下,作了一些修改,并在MAKEFILE里面去掉SERIAL-SAMSUNG,加上后面两个,编译-出错-修改-编译......,最后搞掂,怀着忐忑不安的心情把IMAGE.RAM下到板上RUN,呵呵,一用就好。运行自己以前在4510下编了个最简单的用户程序输出“Hello,uCLinux”(我的LINUX编程水平仅限于此)也成功了!
通过上述总结,大家应该可以自己动手做做了,之后就测试其是否可以正常运转了,如果有什么缺陷漏洞的话我想应都可解决,希望高手们可以帮忙修改。这一招可叫做借壳上市,如果成功的话可以在uC编译增加一项44B0的选项以为其正名。

把我的步骤总结一下,文件位置就不说了
1.修改运行地址和存储器参数,包括两个MAKEFILE和一个CONFIG.IN,再 make menuconfig不选手动输入存储器参数.
2.改ARCH.C(加BOOT_MEM), 改IRQ.C(改中断初始化,并加一句 INTCON = 5),改SYSTEM.H(VECTORS_BASE),改INIT.C(reserve_node_zero),改你的FLASH向量处指令
3.改HARDWRE.H,TIME.H,TIMEX.H,IRQS.H
4.改网络驱动中的MAKEFILE, 改字符驱动中的MAKEFILE,加入SERIAL-CORE.C H, S3C44B0.C H
5.改ENTRY-ARMV.S, HEAD.S

记住在你的BIOS中设好一些外围参数,或者用压缩内核时在HEAD.S中初始化

从我移植的经历来看,把UC转到一个类似的核上去并不是一件很艰深的工作,当你熟悉之后就会找到诀窍很快搞掂. 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -