内核运行编译问题集中注意

问题1 

readl和writel的定义

之前由于自己定义了一个readl出现的错误

#define readl(addr)       *(unsigned int*)(addr)

while(readl(xxxx));

也就是不停读取xxx地址的值。如果不是0.那么跳出循环,一般用于读取物理硬件寄存器


由于编译器认为读取的xxx的地址没有变化以及优化的问题。可能最终会优化成

  ldr r3,[xxxx]

1:

  tst r3,0

  beq 1b

导致死循环并且不再读取xxx地址里面的值

所以必须要用一些编译语句让他不优化,或者变成

1:

  ldr r3,[xxxx]

  tst r3,0

  beq 1b


比如

#define __arch_getl(a) (*(volatile unsigned int *)(a))

#define __arch_putl(v,a) (*(volatile unsigned int *)(a) = (v))


#define mb() asm volatile("dsb sy" : : : "memory")
#define dmb() __asm__ __volatile__ ("" : : : "memory")
#define __iormb() dmb()
#define __iowmb() dmb()


#define writel(v,c) ({ u32 __v = v; __iowmb(); __arch_putl(__v,c); __v; })

#define readl(c) ({ u32 __v = __arch_getl(c); __iormb(); __v; })


问题2

由于编译地址导致的访问问题

在内核开启mmu之前访问的一直是物理地址

如果在输出打印为puts("aaaaaaaaaaaaaaaaaa")

那么aaaaaaaaaaaaa可能存放在虚拟地址的0XC0100000

编译以后就会变成

ldr r0,=0XC0100000

bl puts

但是没有开启mmu,代码此时可能在物理地址0x20000000

puts里面去访问0xc01000000就会崩溃了


所以要使得这个aaaaaaaaaaa的地址是相对的。要在编译时加上-fpic指令。也就是代码地址无关。

编译后会变成

LDR             R0, =(0xc0100000 - 0xc00accccd)
 ADD             R0, PC, R0

通过使用pc来定位。避免地址相关

这个-fpic指令可以在MakeFile中通过添加

ccflags-y := -fpic 或者找到对应的位置来添加



问题3

特别注意不要将所有的寄存器都当做标准寄存器使用,在start_kernel汇编的阶段,不一定是标准用法。

比如SP寄存器 不一定是可以用的堆栈寄存器。

我想在汇编阶段语句A和语句B之间执行一些打印。所以使用了下列方式

语句A

push {xxxxxxxxxxx}

打印

pop{xxxxxxxxx}

语句B

结果崩溃了。原因是开启mmu前后

ldr r13, =__mmap_switched @ address to jump to after
@ mmu has been enabled
badr lr, 1f @ return (PIC) address

使用了r13也就是sp寄存器保存__mmap_switched地址

并且修改了lr寄存器

一直到

__mmap_switched:
adr r3, __mmap_switched_data
ldmia r3!, {r4, r5, r6, r7}
cmp r4, r5 @ Copy data segment if needed
1: cmpne r5, r6
ldrne fp, [r4], #4
strne fp, [r5], #4
bne 1b

mov fp, #0 @ Clear BSS (and zero fp)
1: cmp r6, r7
strcc fp, [r6],#4
bcc 1b


 ARM( ldmia r3, {r4, r5, r6, r7, sp})

最后才从r3中恢复了sp寄存器

要到这里以后才能正常使用sp 寄存器。(调试了5天)








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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值