JLink + Vmware调试linux内核

JLink + Vmware调试linux内核 2012-06-28 15:10:49

分类: 嵌入式

Jlink 版本:  V4.34d

交叉编译: arm-none-linux-gnueabi-gcc

 

Boot Loader 调用 Linux 内核的方法是直接跳转到内核的第一条指令处,也即直接跳转到 MEM_START+0x8000 地址处。在跳转时,下列条件要满足:
1. CPU 寄存器的设置:
    * R0=0;
    * R1=机器类型 ID;关于 Machine Type Number,可以参见 linux/arch/arm/tools/mach-types。
    * R2=启动参数标列表在 RAM 中起始基地址;
2. CPU 模式:
    * 必须禁止中断(IRQs和FIQs);
    * CPU 必须 SVC 模式;

3. Cache 和 MMU 的设置:
    * MMU 必须关闭;
    * 指令 Cache 可以打开也可以关闭;
    * 数据 Cache 必须关闭;

 

4. 设备DMA必须关闭状态

 

要满足以上条件有两种方法

1. 通过初始化脚本

这些内容就是初始化代码所要做的事情,

贴一段gdb + j-link on s3c244x的, 主要就是要配置一下MMU。

#memory init
mon MemU32 0x48000000 = 0x22111100
mon MemU32 0x4800001c = 0x18001
mon MemU32 0x48000024 = 0x8c0514
mon MemU32 0x48000028 = 0x91
mon MemU32 0x4800002c = 0x30

#setup mmu
mon MemU32 0x33f03000 = 0x30000c12
mon MemU32 0x33f03004 = 0x30100c12
mon MemU32 0x33f03008 = 0x30200c12
mon MemU32 0x33f0300c = 0x30300c12
mon MemU32 0x33f03010 = 0x30400c12
mon MemU32 0x33f03014 = 0x30500c12
mon MemU32 0x33f03018 = 0x30600c12
mon MemU32 0x33f0301c = 0x30700c12
mon MemU32 0x33f00cfc = 0x33f00c12
monitor cp15 2 0 0 0 = 0x33f00000

#enable mmu
monitor cp15 1 0 0 0 = 0x7171
#wce 0, c1, c0, 0 ,0x7171

#load kernel vmlinux
load vmlinux
file vmlinux

#reset kernel boot env
monitor cp15 1 0 0 0 = 0x7170
monitor reg pc = 0x30008000
monitor reg r0 = 0x00000000  #0x00000000
monitor reg r1 = your_machine_id_here

 

2. 借助uboot

借助uboot初始化寄存器,cpu模式,MMU等

我们用gdb在内核开始函数设置一个硬件断点,hbreak start_kernel

然后利用uboot启动引导内核,调试器将会停止在内核开始的地方

 

硬件断点和软件断点

硬件断点检测的是地址,一旦监视到指定的地址装入PC就会停下;

软件断点则是首先在指定的内存位置插入特征值,当调试器检测到特征值后就会停下.(这里记不太清楚了)

bootloader软件断点可以正常工作,但是在跳到kernel后,内核链接地址0xc...,这些都是不存在的物理地址,没有打开MMU前,
这些无法访问,软件断点是不能正常工作的,显然MMU开启前,软件断点并不能在0xC...地址处插入特征值,这时只能使用硬件断点。

 

linux内核一般是运行在3G以上的虚拟地址空间,而且对于每个进程地址是相同的.

如果我们在3G以下地址设置硬件断点,可能影响多个用户进程,但是如果硬件断点设置在3G以上,就只影响内核,因为kernel地址唯一。

跟内核不一样,用户的应用软件用同样的虚拟地址(是被MMU转移的不同的物理地址)。这就意味着,如果我们设置硬件中断,所有

用户程序运行到相应的地址会被中断。

这就是为什么当调试用户程序的时候只有用软件中断。这种方式它们就专注于已经调试过的进程,保证没有其它的进程干扰它们。
一旦开启mmu就不应当使用硬件断点,如果系统有两个任务在运行,硬件断点会对这两个任务产生影响。

uboot 链接后地址是实际物理地址,软断点可以在相应位置插入特征值。
因为内核链接后的地址是虚拟地址,软断点不能被正确设置,只能用硬件断点

 

这里只说开启MMU,start_kernel之后的代码

(gdb) connect_2440 #自己定义的宏 
(gdb) set $pc = 0x33f80000 ; assuming the u-boot starts at 0x33f80000

(gdb) mon reset
(gdb) hbreak start_kernel ; hardware breakpoint is used because the MMU is still not active
(gdb) c #之后开发板会从nor flash 位置0处执行uboot
The board is running (u-boot, then the kernel) and will stop at the start_kernel function.

开发板串口:

#tftp 0x30008000  uImage

#bootm 0x30008000

(gdb) delete ; delete the hardware breakpoint
Now you can use the software breakpoints. We can put break and watch points anywhere we want the target to break and debug it and start it again.
If some break is hit the target will stop and gdb will show the corresponding source file. You can step-in step-over function calls, add/remove breaks, watch variables, examine target’s memory and so on.

3B{22U]H(J(~_QF{}]UQ5JU

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值