在上一章節中描述的兩個問題,這裡做下簡單回顧。
在執行到接收以太幀的時候,出現了data abrot異常,如下:首先我們需要根據uboot中列印的出錯資訊,分析出異常位址,根據arm abi呼叫規則,pc暫存器儲存當前執行指標,通過objdump生成的u-boot(elf檔案),便可查詢到出現異常的原因。在解決完上面問題後,又出現了啟動linux核心的時候,出現校驗失敗的問題,如下:data abort
pc : [<7fe9a2a0>] lr : [<7aede325>]
reloc pc : [<43e432a0>] lr : [<3ee87325>]
sp : 7ae54ce0 ip : 00000014 fp : 00000fff
r10: 00000fff r9 : 7ae54ed8 r8 : 0000002e
r7 : 00000fff r6 : 7aede303 r5 : 0000001c r4 : 7aede311
r3 : 00000000 r2 : 7aede311 r1 : 00000014 r0 : 7aede311
flags: nzcv irqs off fiqs off mode svc_32
resetting cpu ...
verifying checksum ... bad data crc
error: can't get kernel image!
根據上面所述,發現reloc pc的值為重定位前的值,即elf檔案對應的位址。上面的日誌中為reloc pc : [<43e432a0>]
通過arm-linux-gnueabihf-objdump -d -s u-bot > dump.log,然後搜尋改檔案中的43e432a0位址對應的指令。
116932
unsigned
compute_ip_checksum
(const
void
*vptr,
unsigned nbytes)
116933
116935
43e43244
: e080e001 add lr, r0, r1
116936
int sum, oddbyte;
116937
const
unsigned
short
*ptr = vptr;
116938
43e43248
: e1a02000 mov r2, r0
116939
116940 sum =0;
116941
43e4324c: e3a03000 mov r3, #0
116942
while
(nbytes >1)
...// 此處省略若干行
116975
43e43294
: e6ff0070 uxth r0, r0
116976
43e43298
: e28dd00c add sp, sp, #12
116977
43e4329c: e49df004 pop
;(ldr pc,
[sp]
, #4
)116978 sum +
=*ptr++
;// 此處為出異常處對應的指令位址
116979
43e432a0: e0d2c0b2 ldrh ip,
[r2]
, #2
116980
43e432a4: e083300c add r3, r3, ip
116981
43e432a8: eaffffe8 b 43e43250
0x10
>
116982
116983
43e432ac
:116984
116985
return
(~checksum)
&0xffff
;116986
}116987
通過上述操作,我們發現導致異常的指令為43e432a0: e0d2c0b2 ldrh ip, [r2], #2
。
解決辦法如下:
+
intdm9601_eth_recv
(struct udevice *udev,
int flags, uchar *
*packetp)++
仔細查閱資料crc校驗出錯的原因,查閱uimage的頭,發現讀取到記憶體的64位元組uboot的header完全和檔案一模一樣,那麼就只會有資料不一樣才會出現這個錯誤問題。
70 #define pad_count
(s, pad)((
(s)-1)
/(pad)+1
)71 #define pad_size
(s, pad)
(pad_count
(s, pad)
* pad)
72 #define alloc_align_buffer_pad
(type, name, size, align, pad) \
73char __##name[
round
(pad_size
((size)
*sizeof
(type)
, pad)
, align) \
74+(align -1)
]; \
75 \
76 type *name =
(type *
)align
((uintptr_t)__##name, align)
77 #define alloc_align_buffer
(type, name, size, align) \
78alloc_align_buffer_pad
(type, name, size, align,1)
79 #define alloc_cache_align_buffer_pad
(type, name, size, pad) \
80alloc_align_buffer_pad
(type, name, size, arch_dma_minalign, pad)
81 #define alloc_cache_align_buffer
(type, name, size) \
82alloc_align_buffer
(type, name, size, arch_dma_minalign)
解決辦法如下:73
char __##name[
round
(pad_size
((size)
*sizeof
(type)
, pad)
, align) \
74+(align -1)
]; \
75 \
76 type *name =
(type *
)align
((uintptr_t)__##name, align)
+
intdm9601_eth_recv
(struct udevice *udev,
int flags, uchar *
*packetp)
++
在解決上述問題後,網絡卡移植便順利的結束了,這裡只簡單的介紹了解決思路與辦法,其實博主遇到的時候也差了不少資料,走了不少彎路,甚至還用wireshark抓包對比,也增加了除錯用的static void dump_msg(uint8_t *ptr, int len)
介面來實現對互動資料的跟蹤。遇到問題的時候不妨多想一下可能導致該問題的相關因素,在利用合適的除錯方法,便可以解決絕大部分問題;當然還是解決不了的,只有找大神幫忙咯。 uboot網絡卡驅動移植
官方的uboot預設是不使能網絡卡相關的 的,既在配置標頭檔案中config cmd net預設是沒有被定義的 要使能網絡卡相關 就要在配置標頭檔案中新增config cmd net這個巨集,切記還要去掉 undef config cmd net這個定義 ping命令在官方uboot中也沒有使能,所...
u boot1 1 6的移植 網絡卡支援
注 藍色為修改部分!driver dm9000x.c中修改 inteth init bd t bd hj end www.embedsky.net printf mac 02x 02x 02x 02x 02x 02x n bd bi enetaddr 0 bd bi enetaddr 1 bd bi...
uclinux移植遇到的問題
但是遇到了一些問題 重起後,導致了出現 檔案的錯誤,不能用我的使用者名稱進行登入,搜尋網路後發現這個問題經常有人遇到,解決方法是登入到 然後執行 命令。或者 home username 我試了這兩種方法,不知道到底是哪個起作用了,再重啟的時候不再出現 dmrc 的錯誤,但是出現了更嚴重的 持續不到 ...