⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 疑难解答.txt

📁 三星公司关于 4510的 bootloader的实现与分析。 里面包含有4510 bootloader的源代码
💻 TXT
字号:
问:
你好,首先很感谢你写这些东西,看了你写的bootloader,对我很有启发。但我还是有几个问题不是很明白,想请教一下。

首先是对于part5这块儿有点儿疑问,这段代码主要是把bootloader由flash拷贝到sdram中去,我的理解是只要把RO代码段拷贝过去就可以了啊,为什么要拷贝(RO+RW)长度的代码呢,而且我的理解是虽说拷贝了(RO+RW)长度的代码,但是RW段的内容并没有被拷贝到sdram中去,这么做是为什么呢?另外这里RWBase的地址是多少呢,是在ads中设置的0xA00000这个吗?RW段代码在flash中的地址是如何确定的呢?如果是0xA00000的话,已经超过2Mflash的大小了啊?

;Part 5
;***************************************************************
;Self copy from FLASH to SDRAM

 LDR r0, =|Image$$RO$$Base|      
 LDR r1, =|Image$$RO$$Limit|      
 LDR r2, =|Image$$RW$$Base|      
 LDR r3, =|Image$$RW$$Limit|     

 SUB r1, r1, r0
 SUB r3, r3, r2
 ADD r1, r1, r3
 
 LDR r2, =0x200000   ;@2M

 
COPY
 LDR r3, [r0], #4
 STR r3, [r2], #4
 SUBS r1, r1,   #4
 BNE COPY

还有一个问题就是你是把image.ram转换成一个数组了,那么在把bootloader烧到flash里这个数组是存在哪里的呢,是放在RW段吗?如果是放在RW段的话,那在映射后是不是先把RW段的数据由flash拷贝到sdram中,再把位于sdram中RW段的image.ram数组拷贝到0x8000处,然后运行uclinux。

答:
part5这部分代码的目的就是要把整个bootlaoder拷贝到sdram里去,包括RW段和RO段。在程序里,RO BASE = 0X0, RW BASE = 0XA00000, 这里需要注意一个问题:在编译链接好的程序里面,RW段是放置在RO段后面的,所以|Image$$RO$$Limit|既是RO段的结束位置也是RW段的起始地址。 而RW BASE是指在运行的时候RW段的地址,因为运行时我们需要把RW段拷贝到memory里可读写的存储介质上去,所以RW BASE 被设置为 0XA00000. 所以,RW BASE 大于2M并不是个问题。

其实你也可以开始指把RO段拷贝到SDRAM里去,回头在从flash里把RW段拷贝到合适的位置上去,但为了使得实现更简单和直接,我没有这样做,而是一口气就把整个bootloader拷贝到sdram里去了,回头就不用在管flash了。在remap后再把RW段从SDRAM里拷贝到SDRAM合适的位置去。

因为kernel[]这个数组是一个全局变量,所以肯定是被放到RW段去了。所以,在remap后,先把RW段拷贝到RW_BASE的位置上去,设置好堆栈指针,就可以调用loadkernel函数了,这个函数会把knerle[]这个数组(其实就是内核image.ram)拷贝到0x8000的位置上去,然后跳转过去就可以启动了。

希望能够解释清楚,如果有问题请发贴继续讨论。

问:
编译出来有1M多,怎么会如此大呢?

答:
是的,大概有1M多。为了简单起见,在把image.ram转化为char数组前并没有把image.ram先压缩一下,所以编译出来比较大。如果你感兴趣的话,可以自己把压缩和解压缩添加进去,网上找的到压缩和解压缩的源代码,应该挺容易实现的。

问:
非常清楚的說明。另外有個問題想請教,在 load kernal 完成後,uClinux kernal 會在位址 0x0 重設中斷向量嗎? thks

答:
bootloader里不用管中断。但在kernel起来后,kernel自己肯定会设置中断向量的。 

呵呵,一个BootLoader的最小系统,简洁、高效!真是好人! 

问:
现在有一个问题:

在loadkernel.c中2097152你是怎么计算出来的呢?也就是uclinux内核字节的大小。

for(i = 0; i < 2097152; i++){
  *to = *from;
  to++;
  from++;
 }

我通过ultraEdit计算出来的是:2732523,好像差别蛮大呀?敢问大侠如何计算?

再次谢谢了!

答:
其实在这个地方我偷了个懒,呵呵,直接设置成2M了,因为flash的大小就是2M。

请问在源代码中在管理模式下设置堆栈指针0x800000,有什么讲究吗?为什么不启用内部RAM,将堆栈设置在3FE0000呢?

是uclinux要求必须设置在0x800000吗?请指教。

;Part 8
;***********************************************************************
;Set stack pointer & jump to c function

 LDR  sp, =0x800000

 IMPORT loadkernel
 LDR  pc, =loadkernel
这里设置的堆栈指针只是bootloader用的,可以随便设置在那里(SDRAM or SRAM),只要不占用0x8000开始的那块SDRAM就可以了。 因为必须把kernel转载到0x8000处,所以我把堆栈指针设置在了SDRAM的高端。

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -