QQ登录

只需一步,快速开始

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 4545|回复: 7

我的s3c44b 0x + uclinux2.4.19移植

[复制链接]
发表于 2004-1-11 21:13:51 | 显示全部楼层 |阅读模式
from feny
http://www.linuxforum.net/forum/showthreaded.php?Cat=&Board=embedded&Number=466240&page=0&view=collapsed&sb=5&o=31&fpart=1

终于看到一点结果了...

首先很感谢tpu, coldwind等给的帮助.
第一次做这个,很多概念都是在这里得到各位的帮助.
至今为止还有很多概念问题,没搞清楚,以后多多指教.

附件里是,我参考过的两篇文档.
但是tpu曾建议不要用dist来做,直接用纯的linux源码包来做,
我后来也是用linux源码包来做的.
个人也倾向于直接用linux kernel源码包来做,这样更清晰,
就是Makefile也清楚很多倍.
而,romfs我是用dist的包来做的.

下面附带,我移植过程中的一些问题,有点象日志,呵呵
但愿对后面的初学者有点用吧,(总要回报点给论坛,就怕质量太差)

1. tar xvzf linux-2.4.19.tar.gz
2. patch uclinux
3. patch s3c44b0x(from tpu)
4. 修改$topdir/Makefile中使
arch:=armnommu
CROSS_COMPILE:=arm-elf-
5. 修改$topdir/arch/armnommu/config.in
============修改===========
if [ "$CONFIG_ARCH_S3C44B0" = "y" ]; then
define_bool CONFIG_NO_PGT_CACHE y
define_bool CONFIG_CPU_32 y
define_bool CONFIG_CPU_26 n
define_bool CONFIG_CPU_ARM710 y
define_bool CONFIG_CPU_WITH_CACHE y
define_bool CONFIG_CPU_WITH_MCR_INSTRUCTION n
define_hex DRAM_BASE 0x0c000000
define_hex DRAM_SIZE 0x00800000 要修改dram和flash的大小
define_hex FLASH_MEM_BASE 0x00000000
define_hex FLASH_SIZE 0x00200000
fi
============
6.make menuconfig
make dep
make Image 注意关于Image zImage的make选项并不在$TOPDIR/Makefile中

而是这样
$TOPDIR/Makefile中 include arch/$(ARCH)/Makefile
而arch/$(ARCH)/Makefile中
由MAKEBOOT对Image zImage等进行处理
MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot LINUX=$(LINUX)

所以,根本上是在arch/$(ARCH)/boot/Makefile中对make Image处理的

7.
ARCH/ARMNOMMU/MAKEFILE
定义了
PROCESSOR为armv (32位的)。
定义了
HEAD := arch/armnommu/kernel/head-$(PROCESSOR).o \
arch/armnommu/kernel/init_task.o


TEXTADDR 决定KERNEL起始运行地址,即IMAGE应DOWN到的位置

ARCH/ARMNOMMU/BOOT/MAKEFILE
ZREALADDR 决定KERNEL解压后数据输出的地址,同1
ZTEXTADDR 带BOOTLOADER的压缩内核文件烧入FLASH的起始地址,即从哪个位置开始执行
BOOTLOADER,若启动时直接执行,将其设为0,若自带BIOS可以跳到你想要的地址,可改为你要的位置。

8.image的组成(其中HEAD见7中)
$(LINUX): include/linux/version.h $(CONFIGURATION) init/main.o init/version.o init/do_mounts.o linuxsubdirs
$(LD) $(LINKFLAGS) $(HEAD) init/main.o init/version.o init/do_mounts.o \
--start-group \
$(CORE_FILES) \
$(DRIVERS) \
$(NETWORKS) \
$(LIBS) \
--end-group \
-o $(LINUX)

9.启动文件/arch/armnommu/kernel/head-armv.S

ID检查问题。在head-armv.S应加入对MACH_TYPE的设定。在uClinux启动时,首先会检查CPU的ID和平台的TYPE,如果不对会陷入死循环。在TPU的Patch中,加入了对CPU ID的设定,但没有加入对平台类型的设定。平台类型可能是应该从BootLoader中设好传进来,但对我们自已的BootLoader,没有完成此设定,所以应把MACH_TYPE(17设到r1寄存器。否则,在系统调用lookup_architecture_type之后就没戏了。修改如下:
mov r1, #178 ;《==此句为新加的
mov r0, #F_BIT | I_BIT | MODE_SVC @ make sure svc mode
msr cpsr_c, r0 @ and all irqs disabled

10.vectors_base
在include/asm-armnommu/proc-armv/system.h中定义
在arch/armnommu/kernel/traps.c fiq.c 和sys_arm.c使用

fiq.c中
#define FIQ_VECTOR (vectors_base() + 0x1c)

11.pc行为
(指令地址4) add pc,pc,0xc000000
结果会跳转到0xc00000c
为什么不是8呢?
arm7用的是3级流水线,程序计数器pc必须在当前指令前计数.
所以指令在第一个周期必须为下一条指令取指pc+=4.
所以在执行周期前,pc+=8了.
所以add pc,pc,0xc000000 在执行的时候是(4+8+0xc000000).

12.设计
bootloader 在flashrom中0x0-0x1000段
kernel image在flashrom中0x1000-0x1fffff段
由bootloader把kernel image从rom0x1000中拷到ram0xc000000处
irq vector 在ram 0xc7fff00 - 0xc7fffff段
在bootloader中_ISR_STARTADDRESS 指定.
在kernel 中由vectors_base指定.

==修改
arch/armnommu/Makefile中
TEXTADDR 决定KERNEL起始运行地址,即IMAGE应DOWN到的位置0xc000000
==修改
ARCH/ARMNOMMU/BOOT/MAKEFILE中
ZREALADDR 决定KERNEL解压后数据输出的地址,同1,0xc000000
ZTEXTADDR 带BOOTLOADER的压缩内核文件烧入FLASH的起始地址,即从哪个位置开始执行,0xc300000.
==修改
include/asm-armnommu//proc-armv/system.h中
#ifdef CONFIG_ARCH_S3C44B0
#undef vectors_base()
#define vectors_base() (0x0c7fff00)
#endif
13.串口的波特率调整
串口问题:经常碰到的是串口显示乱码或是没有显示。对于串口无显示,极可以是没有在uClinux核心中配置支持Serial Port。而显示乱码多半是波特率不对。对于前者如已配置了串口支持还没显示,则可用JTAG跟入到Kernel中的第一个printk中去看看。对于后者,有几种情况。第一种是BootLoader中的波特率设定与uClinux中不一样,这种情况下直接让两者一致就可以了。第二种情况是波特率设的虽一样,但两边的频率设定不一样。在加入TPU的Patch之后,uClinux中默认的时钟为60MHz,如果BootLoader设定的PLL时钟不是60Mhz,就会造成uClinux与BootLoader中的设定不一致而产生乱码。还有一种情况是以上设定都对,但是uClinux在计算时会舍去小数点后的数,使较高的波特率发生偏差。这时应把算法改为四舍五入。最后还有一种情况是uClinux前面的输出很正确,但进行CONSOLE后,就变成乱码了,这也是由于是计算时的误差造成的。

(data 12/0遇到乱码的情况,查看bootloader中的PLL时钟设置发现
设成了pin为10Mhz,pout为60Mhz.错误就在这里,pin其实是8m的.
所以修改bootloader
[ PLLCLK = 60000000
M_DIV EQU 52 ;Fin=8MHz Fout=60MHz
P_DIV EQU 2
S_DIV EQU 1
]
重新烧写bootloader,显示正确!
*^_^*

14.start_kernel中,无法通过calibrate_delay函数
简单测试,初步认为与sti()函数的位置无关.

经历了无数次的测试发现,
好像是这样的.

start_kernel中在calibrate_delay周围,
如果调用了init_main.c中的__init函数就会停在此函数处.
如果调用了其他.c(如 drivers/serial/s3c44b0.c)中的__init函数,表现正常.

但是呢,start_kernel中的parse_options也是__init函数如果把它放在前面没错,
如果放在calibrate周围也会停住.

calibrate_delay如果放在parse_options周围,没错可以通过.
calibrate_delay如果放在console_init周围,有错,无法通过.

查到一点信息
case:
是8m sdram 0xc000000-0xc800000
把vector_base置为0xc7fff00
Image装载到0xc000000处.

problem:
calibrate_delay的代码段(.init段0xc000200)被覆盖了.
出现的时机好像不固定,有时在start_kernel的init_IRQ之前有时在之后.

每次都是
0xc000100-0xc000200之后的一段空间,
被vector_IRQ ,vector_data ,vector_prefetch(arch/armnommu/kernel/entry-armv.S中) 他们的代码覆盖.
所以calibrate被调用时就会出错.

答:

15.修改12部的设计方案
bootloader 在flashrom中0x0-0x1000段
kernel image在flashrom中0x1000-0x1fffff段
由bootloader把kernel image从rom0x1000中拷到ram0xc008000处

irq vector 从ram 0xc000000 开始
在bootloader中_ISR_STARTADDRESS 指定.
在kernel 中由vectors_base指定.

BOOTLOADER===============
b ResetHandler ;for debug
ldr pc,=0xc000004 ;handlerUndef 0xc000004
ldr pc,=0xc000008 ;SWI interrupt handler 0xc000008
ldr pc,=0xc00000c ;handlerPAbort 0xc00000c
ldr pc,=0xc000010 ;handlerDAbort 0xc000010
ldr pc,=0xc000014 ;handlerReserved 0xc000014
ldr pc,=0xc000018 ;irq 0xc000018
ldr pc,=0xc00001c ;fiq 0xc00001c

把内核image拷贝到0xc008000处,再跳到0xc008000处执行

KERNEL==================

==修改
arch/armnommu/Makefile中
TEXTADDR 决定KERNEL起始运行地址,即IMAGE应DOWN到的位置0xc008000
==修改
ARCH/ARMNOMMU/BOOT/MAKEFILE中
ZREALADDR 决定KERNEL解压后数据输出的地址,同1,0xc008000
ZTEXTADDR 带BOOTLOADER的压缩内核文件烧入FLASH的起始地址,即从哪个位置开始执行,0xc300000.
==修改
include/asm-armnommu//proc-armv/system.h中
#ifdef CONFIG_ARCH_S3C44B0
#undef vectors_base()
#define vectors_base() (0x0c000000)

&&&&&&&&&&&&&&&&
&problem 14解决&
&&&&&&&&&&&&&&&&

16
但是,为什么为发生代码段的拷贝, 0x8000的空间分配是怎样的?
答:
先看arch/armnommu/kernel/entry_armv.S中的__trap_init
在vectors_base处(0xc000000) @set up the vectors
把stubs拷贝到vectors_base+0x200处(0xc000200) .
stubs即每种异常(irq,fiq,data,undefined等)的分类处理路线.
这样从0xc000000-0xc000200-到0xc000***,就建立起了完整的中断处理表.

而在这中间0xc000100处有其他信息请参见17.

17.启动时setup_arch中出现Warning: bad configuration page, trying to continue
原因是,parse_params()要获取相关参数信息,
在arch/armnommu/mach-s3c44b0/arch.c中
把arch的params定位在0xc000100处,
这个params是bootloader应该做的工作.!!

18.无法 在blkmem和vfs处停住
现象:
(make menuconfig时选定romfs 和rom disk support)
(修改blkmem_init()加入此二句.
arena[0].length = (unsigned long)(-1);
arena[0].address = (unsigned long)0x0C700000;
在装载内核的时候,要把romfs.img装载到0xc70000处.
)
生成romfs
/*referring to the Makefile of uclinux-disk-20030909*/
genromfs -v -V "ROMdisk" -f $(ROMFSIMG) -d $(ROMFSDIR)
cat $(IMAGEDIR)/linux.text $(IMAGEDIR)/linux.data $(ROMFSIMG) > $(IMAGE)

Blkmem 0 disk images:
device is 0, arenas is 0
arena open of 0 failed!
VFS: Cannot open root device "rom0" or 1f:00
Please append a correct "root=" boot option
Kernel panic: VFS: Unable to mount root fs on 1f:00
问题:
是不是如果我选择把romfs放在ram中就应该support ram disk
如果把romfs放在rom中就应该support rom disk啊.

我把blkmem_init()中加了两句.
arena[0].length = (unsigned long)(-1);
arena[0].address = (unsigned long)0x0C700000;

但是不管选support ram disk还是rom disk都不行,
请问这可能是什么原因?

解决:
发现arenas始终为0. 也就是说config时,选定的flash芯片不符,
所以初始化时arena[]数组大小为0.

所以修改#define arenas 1
然后编译.

现在显示:
Blkmem 1 disk images:
0: C700000-C742BFF [VIRTUAL C700000-C742BFF] (RW)
device is 0, arenas is 1
, address is c700000
VFS: Mounted root (romfs filesystem) readonly.
Freeing init memory: 32K
BusyBox v0.60.4 (2002.11.25-19:05+0000) multi-call binary

Usage: busybox [function] [arguments]...
or: [function] [arguments]...

BusyBox is a multi-call binary that combines many comKernel panic: Attem
pted to kill init!
mon Unix
utilities into a single executable. Most people will create a
link to busybox for each function they wish to use, and BusyBox
will act like whatever it was invoked as.

Currently defined functions:
[, busybox, cat, chmod, clear, cp, date, dd, df, dmesg, du, echo,
env, false, free, hostname, insmod, kill, killall, ln, ls, lsmod,
mkdir, mknod, modprobe, mount, msh, mv, ps, pwd, rm, rmdir, rmmod,
sh, sleep, syslogd, test, touch, true, umount, uname

19.
>>make menuconfig(这里选用0522dist,只用它来编译romfs)
在user application 配置选上
init ;console shell;login;sash(如果用bash无法编译通过);busybox等
>>make dep;
>>make lib_only;
>>make user_only;
>>make romfs;
>>genromfs -v -V "ROMdisk" -f [ROMFSIMAGE] -d [ROMFSDIR]
现在执行完
/etc/rc就出现"Execution finished!. exiting..."

修改/etc/rc,
最后加一句
sh
让sash跑起来
出现
____ _ _
/ __| ||_|
_ _| | | | _ ____ _ _ _ _
| | | | | | || | _ \| | | |\ \/ /
| |_| | |__| || | | | | |_| |/ \
| ___\____|_||_|_| |_|\____|\_/\_/
| |
|_|

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

Command: sh

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

Sash command shell (version 1.1.1)
name is (null).
/>
还有一个问题,
我现在是这样调试的
0x0-0x1000放bootloader代码,
调试的时候把kernel load到0xc008000
把romfs load到0xc700000.
然后pc设置为0,开始执行.

但是现在每次中断后,重新置为pc = 0.
重新执行就oops了.

shell的符号终于出现了...
发表于 2004-1-14 12:47:17 | 显示全部楼层
好东西,拷下来研究研究!
回复

使用道具 举报

发表于 2004-3-5 17:42:54 | 显示全部楼层
很好!!!!
回复

使用道具 举报

发表于 2004-3-7 11:09:30 | 显示全部楼层

好,真是很详细.

好,真是很详细.
回复

使用道具 举报

发表于 2004-3-17 23:10:50 | 显示全部楼层
请问第2、3步的patch哪里有下载?
回复

使用道具 举报

 楼主| 发表于 2004-3-21 10:06:15 | 显示全部楼层
可以到linuxforum问问原作者
回复

使用道具 举报

发表于 2004-3-21 18:33:26 | 显示全部楼层
没有回应呀,陈斑竹如果有的话,能否mail到[email protected]里面来?
谢谢!
回复

使用道具 举报

 楼主| 发表于 2004-3-22 08:23:20 | 显示全部楼层
sorry,我也没有,只是看到他的文章。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

GMT+8, 2024-11-27 16:49 , Processed in 0.057826 second(s), 15 queries .

© 2021 Powered by Discuz! X3.5.

快速回复 返回顶部 返回列表