UBOOT引导内核uImage问题

【转】UBOOT引导内核uImage问题

UBOOT引导内核uImage问题

现象:

[u-boot@MINI2440]# boot
dm9000 i/o: 0x20000300, id: 0x90000a46 
DM9000: running in 16 bit mode
MAC: 08:08:11:18:12:27
operating at 100M full duplex mode
Using dm9000 device
TFTP from server 192.168.1.62; our IP address is 192.168.1.144
Filename 'uImage'.
Load address: 0x30008000
Loading: T #################################################################
#################################################################
##########################################
done
Bytes transferred = 2517092 (266864 hex)
## Booting kernel from Legacy Image at 30008000 ...
Image Name:   Linux-2.6.32.2-FriendlyARM
Created:      2010-07-19  11:41:56 UTC
Image Type:   ARM Linux Kernel Image (uncompressed)
Data Size:    2517028 Bytes =  2.4 MB
Load Address: 30008000
Entry Point:  30008000
Verifying Checksum ... OK
XIP Kernel Image ... OK
OK

Starting kernel ...

data abort
pc : [<30008008>]          lr : [<33fa6500>]
sp : 33f3dd24  ip : 00000000     fp : 30008000
r10: 33fc2f08  r9 : 000007cf     r8 : 33f3ffe0
r7 : 33f3ffc4  r6 : 33f4131a     r5 : 30000100  r4 : 00000000
r3 : 00000000  r2 : 30000100     r1 : 000007cf  r0 : 00000000
Flags: nzCv  IRQs off  FIQs off  Mode SVC_32
Resetting CPU ...

resetting ...

分析:
uImage的制作办法是make uImage, 其中的mkimage: /usr/local/bin/mkimage工具来自UBOOT编译结果。

原来为了便于多内核引导,u-boot的mkimage会在kernel前加上0x40(64bytes)的头,真正的内核入口就变成了0x30008040了。而在新版2.6.32的加载地址和入口点地址相同,所以就造成abort……

解决办法
1. 手动制作uImage:
./mkimage -A arm -O linux -T kernel -C none -a 0x30008000 -e 0x30008040 -n mini2440 -d zImage uImage
2.修改内核 
linux-2.6.32.2/arch/arm/boot/Makefile
MKIMAGE         := $(srctree)/scripts/mkuboot.sh
quiet_cmd_uimage = UIMAGE  $@
cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A arm -O linux -T kernel \
-C none -a $(LOADADDR) -e $(STARTADDR) \
-n 'Linux-$(KERNELRELEASE)' -d $< $@
ifeq ($(CONFIG_ZBOOT_ROM),y)
$(obj)/uImage: LOADADDR=$(CONFIG_ZBOOT_ROM_TEXT)
els e
$(obj)/uImage: LOADADDR=$(ZRELADDR)

endif

# Note: the following conditions must always be true:
#   ZRELADDR == virt_to_phys(PAGE_OFFSET + TEXT_OFFSET)
#   PARAMS_PHYS must be within 4MB of ZRELADDR
#   INITRD_PHYS must be in RAM
ZRELADDR    := $(zreladdr-y)
PARAMS_PHYS := $(params_phys-y)
INITRD_PHYS := $(initrd_phys-y)

ifeq ($(CONFIG_THUMB2_KERNEL),y)
# Set bit 0 to 1 so that "mov pc, rx" switches to Thumb-2 mode
$(obj)/uImage: STARTADDR=$(shell echo $(LOADADDR) | sed -e "s/.$$/1/")
else
$(obj)/uImage: STARTADDR=$(LOADADDR)
endif

你可能感兴趣的:(C++)