Hi3559AV100 himm报错,引起了其他进程没有启动,下面分析原因。
内核打印信息
# [ 1734.516062] himm[26471]: unhandled level 2 translation fault (11) at 0x00000000, esr 0x92000006
[ 1734.524788] pgd = ffffffc03c231000
[ 1734.528180] [00000000] *pgd=000000007d2b8003[ 1734.532278] , *pud=000000007d2b8003
, *pmd=0000000000000000[ 1734.537759]
[ 1734.539248]
[ 1734.540739] CPU: 0 PID: 26471 Comm: himm Tainted: P O 4.9.37 #1
[ 1734.547983] Hardware name: Hisilicon HI3559AV100 DEMO Board (DT)
[ 1734.553994] task: ffffffc03c3d3c00 task.stack: ffffffc03c1f0000
[ 1734.559910] PC is at 0x40537c
[ 1734.562867] LR is at 0x405374
[ 1734.565826] pc : [<000000000040537c>] lr : [<0000000000405374>] pstate: 60000000
[ 1734.573216] sp : 0000007fefb6a100
[ 1734.576524] x29: 0000007fefb6a100 x28: 0000000000000000
[ 1734.581838] x27: 0000000000000000 x26: 0000000000000000
[ 1734.587146] x25: 0000000000000000 x24: 0000000000000000
[ 1734.592464] x23: 0000000000000000 x22: 0000000000000000
[ 1734.597771] x21: 0000000000401a30 x20: 0000000000000000
[ 1734.603088] x19: 00000000004090f8 x18: 0000000000000000
[ 1734.608395] x17: 0000007fa9e14b60 x16: 0000000000000000
[ 1734.613712] x15: 0000000000000000 x14: 000000000000001d
[ 1734.619039] x13: 0a21726f72726520 x12: 6d656d2f7665642f
[ 1734.624358] x11: 0000000000000020 x10: 0000000000000000
[ 1734.629676] x9 : ffffff80ffffffd0 x8 : 0000000000000040
[ 1734.634984] x7 : 642f206e65706f3a x6 : 0000000000000001
[ 1734.640301] x5 : 0000000000000000 x4 : 0000000000000000
[ 1734.645608] x3 : 0000000000000000 x2 : 0000000000000001
[ 1734.650925] x1 : 0000000000000000 x0 : 0000000000000000
反汇编himm
由于strip过,所以看不到符号表函数名:
405368: f9401fa0 ldr x0, [x29, #56]
40536c: d2801001 mov x1, #0x80 // #128
405370: 97fffac4 bl 403e80 <ioctl@plt+0x2460>
405374: f90027a0 str x0, [x29, #72]
405378: f94027a0 ldr x0, [x29, #72]
40537c: b9400000 ldr w0, [x0]
405380: 2a0003e0 mov w0, w0
405384: f90023a0 str x0, [x29, #64]
405388: f9400ba0 ldr x0, [x29, #16]
40538c: 91002000 add x0, x0, #0x8
405390: f9400001 ldr x1, [x0]
405394: f9401ba2 ldr x2, [x29, #48]
405398: b0000020 adrp x0, 40a000 <ioctl@plt+0x85e0>
40539c: 91054000 add x0, x0, #0x150
4053a0: aa0203e3 mov x3, x2
4053a4: f94023a2 ldr x2, [x29, #64]
4053a8: 97fff17a bl 401990 <printf@plt>
4053ac: f9401ba0 ldr x0, [x29, #48]
4053b0: 2a0003e1 mov w1, w0
4053b4: f94027a0 ldr x0, [x29, #72]
4053b8: b9000001 str w1, [x0]
4053bc: 14000004 b 4053cc <ioctl@plt+0x39ac>
4053c0: b0000020 adrp x0, 40a000 <ioctl@plt+0x85e0>
4053c4: 9105c000 add x0, x0, #0x170
4053c8: 97fff11e bl 401840 <puts@plt>
4053cc: d2800000 mov x0, #0x0 // #0
4053d0: a8c57bfd ldp x29, x30, [sp], #80
4053d4: d65f03c0 ret
4053d8: a9ba7bfd stp x29, x30, [sp, #-96]!
4053dc: 910003fd mov x29, sp
4053e0: b9001fa0 str w0, [x29, #28]
4053e4: f9000ba1 str x1, [x29, #16]
4053e8: f9001fbf str xzr, [x29, #56]
4053ec: f9002bbf str xzr, [x29, #80]
4053f0: b9005fbf str wzr, [x29, #92]
4053f4: b9401fa0 ldr w0, [x29, #28]
4053f8: 7100081f cmp w0, #0x2
重新编译himm
不要strp,反汇编如下:
405368: f9401fa0 ldr x0, [x29, #56]
40536c: d2801001 mov x1, #0x80 // #128
405370: 97fffac4 bl 403e80 <memmap>
405374: f90027a0 str x0, [x29, #72]
405378: f94027a0 ldr x0, [x29, #72]
40537c: b9400000 ldr w0, [x0]
405380: 2a0003e0 mov w0, w0
405384: f90023a0 str x0, [x29, #64]
405388: f9400ba0 ldr x0, [x29, #16]
40538c: 91002000 add x0, x0, #0x8
405390: f9400001 ldr x1, [x0]
40537c: b9400000 ldr w0, [x0]
405380: 2a0003e0 mov w0, w0
405384: f90023a0 str x0, [x29, #64]
405388: f9400ba0 ldr x0, [x29, #16]
40538c: 91002000 add x0, x0, #0x8
405390: f9400001 ldr x1, [x0]
405394: f9401ba2 ldr x2, [x29, #48]
405398: b0000020 adrp x0, 40a000 <dev+0x7b0>
40539c: 91054000 add x0, x0, #0x150
4053a0: aa0203e3 mov x3, x2
4053a4: f94023a2 ldr x2, [x29, #64]
4053a8: 97fff17a bl 401990 <printf@plt>
4053ac: f9401ba0 ldr x0, [x29, #48]
4053b0: 2a0003e1 mov w1, w0
4053b4: f94027a0 ldr x0, [x29, #72]
4053b8: b9000001 str w1, [x0]
查看himm源码
#define DEFAULT_MD_LEN 128
HI_RET himm(int argc , char* argv[])
{
unsigned long ulAddr = 0;
unsigned long ulOld, ulNew;
char strNew[16];
VOID* pMem = NULL;
if (argc <= 1)
{
printf("usage: %s <address> <Value>. sample: %s 0x80040000 0x123\n", argv[0], argv[0]);
EXIT("", -1);
}
if (argc == 2)
{
if( StrToNumber(argv[1], &ulAddr) == HI_SUCCESS)
{
printf("====dump memory %#lX====\n", ulAddr);
#ifdef PC_EMULATOR
#define SHAREFILE "../shm"
printf("**** is Emulator, use share file : %s ****\n", SHAREFILE);
pMem = mmapfile(SHAREFILE , DEFAULT_MD_LEN);
if (NULL == pMem)
{
EXIT("Memory Map error.", -1);
}
pMem += ulAddr;
#else
pMem = memmap(ulAddr, DEFAULT_MD_LEN);
if (pMem == NULL) {
printf("memmap failed!\n");
return -1;
}
#endif
ulOld = *(unsigned int*)pMem;
/*hi_hexdump(STDOUT, pMem, DEFAULT_MD_LEN, 16);*/
printf("%s: 0x%08lX\n", argv[1], ulOld);
printf("NewValue:");
scanf("%s", strNew);
if (StrToNumber(strNew, &ulNew) == HI_SUCCESS)
{
*(unsigned int*)pMem = ulNew;
}
else
{
printf("Input Error\n");
}
}
else
{
printf("Please input address like 0x12345\n");
}
}
else if (argc == 3)
{
if( StrToNumber(argv[1], &ulAddr) == HI_SUCCESS &&
StrToNumber(argv[2], &ulNew) == HI_SUCCESS)
{
pMem = memmap(ulAddr, DEFAULT_MD_LEN);
ulOld = *(unsigned int*)pMem;
/*hi_hexdump(STDOUT, pMem, DEFAULT_MD_LEN, 16);*/
printf("%s: 0x%08lX --> 0x%08lX \n", argv[1], ulOld, ulNew);
*(unsigned int*)pMem = ulNew;
}
}
else
{
printf("xxx\n");
}
return 0;
}
原因分析
加载x0寄存器里面的地址数据到w0引发了错误
40537c: b9400000 ldr w0, [x0]
查看x0寄存器存储的地址是多少
[ 1734.650925] x1 : 0000000000000000 x0 : 0000000000000000
可以看见地址0,所以是非法内存访问出错
查看memmap函数对应源码,可知argc == 3时,memmap函数没有做空指针判断,可能在某种情况下内存映射返回空指针
405370: 97fffac4 bl 403e80 <memmap>
所以需要增加空指针容错处理