在VDSP中编译uclinux(2):内存布局

来源:互联网 发布:vb excel编程实例 编辑:程序博客网 时间:2024/05/05 15:46
 
1   uclinux的内存布局
在uclinux启动时,有一段空间利用的提示:
Memory map:
 text      = 0x00001000-0x000b0db0
 init      = 0x000b1000-0x000bd23c
 data      = 0x000bf1b8-0x000e5588
 stack     = 0x000c0000-0x000c2000
 bss       = 0x000e5590-0x000f14d8
 available = 0x000f14d8-0x03500000
 rootfs    = 0x03500000-0x03f00000
 DMA Zone = 0x03f00000-0x04000000
其中text代表这段空间中存储的是uclinux内核的代码;init中存放的也是uclinux内核的代码,但是这一段空间在内核启动完成后是可以回收的,即它可以供内核重新分配;DATA段是 uClinux 未被初始化的数据空间;BSS段是 uClinux初始化的数据空间,它的初始化操作将在head.s中完成。此外从0到text开始的这一段空间也会被初始化为0。
2   VDSP中的空间分配
uclinux的空间定位是由链接器完成的,由arch/blackfin/kernel/vmlinux.lds.s控制完成。而VDSP的空间定位则是由ldf文件完成的,而ldf文件的语法与vmlinux.lds.s相似。我们所要做的就是将vmlinux.lds.s中的相关定义转移到ldf文件中。
1、定义一块uclinux使用的内存空间:
MEM_SDRAM_UCLINUX    { TYPE(RAM) START(0x00010000) END(0x001fffff) WIDTH(8) }       在这里,空间的结束使用了一个较大的数值,实际上在uclinux内核中会从代码实际结束的地方开始管理存储空间。
2、将uclinux内核的入口函数写入到0xFFA00000,即a核的启动地址。
       RESOLVE(__start, 0xFFA00000)
       KEEP(__start,_main)
VDSP默认的入口是start,在*_basiccrt.s中实现。经过这样处理后,A核就将从head.s中的__start开始,而B核仍将从*_basiccrt.s中的start开始执行。
3、移植.text段的内容。
              // uclinux的代码部分
              uclinux_text
              {
                     INPUT_SECTION_ALIGN(4)
 
                     __stext__ = .;
                     __stext = .;
                     INPUT_SECTIONS($LIBRARIES_SML3_CM(.text))
                     INPUT_SECTION_ALIGN(8)
                     __sched_text_start = .;               
                     INPUT_SECTIONS($LIBRARIES_SML3_CM(.sched.text))
                     __sched_text_end = .;
                     INPUT_SECTIONS($LIBRARIES_SML3_CM(.text.lock))
 
                     INPUT_SECTION_ALIGN(16)
                     ___start___ex_table = .;
                     INPUT_SECTIONS($LIBRARIES_SML3_CM(__ex_table))
                     ___stop___ex_table = .;
 
                     // 原先放在L1_Code中的内容
                     INPUT_SECTION_ALIGN(4)
                     __CORE = 0;
                     INPUT_SECTIONS($OBJECTS_CORE_A(L1_code) $LIBRARIES_CORE_A(L1_code))
                     INPUT_SECTIONS($OBJECTS_CORE_A(VDK_ISR_code) $LIBRARIES_CORE_A(VDK_ISR_code))
                     INPUT_SECTIONS($OBJECTS_CORE_A(cplb) $LIBRARIES_CORE_A(cplb))
                     INPUT_SECTIONS($OBJECTS_CORE_A(cplb_code) $LIBRARIES_CORE_A(cplb_code))
                     INPUT_SECTIONS($OBJECTS_CORE_A(noncache_code) $LIBRARIES_CORE_A(noncache_code))
                     INPUT_SECTIONS($OBJS_LIBS_INTERNAL_CORE_A(program))
                     INPUT_SECTIONS($OBJS_LIBS_NOT_EXTERNAL_CORE_A(program))
                     INPUT_SECTIONS($OBJECTS_CORE_A(program) $LIBRARIES_CORE_A(program))
 
                     // SDRAM Bank0的内容
                     INPUT_SECTION_ALIGN(4)
                     INPUT_SECTIONS($LIBRARIES_SML3_CM(sdram_data_bank0))
                     INPUT_SECTIONS($LIBRARIES_SML3_CM(sdram_bank0))
                     INPUT_SECTIONS($LIBRARIES_SML3_CM(data1))
                     INPUT_SECTIONS($LIBRARIES_SML3_CM(voldata))
                     INPUT_SECTIONS($LIBRARIES_SML3_CM(constdata))
                    
                     // SDRAM Bank1的内容
                     INPUT_SECTION_ALIGN(4)
                     INPUT_SECTIONS($LIBRARIES_SML3_CM(sdram0))
                     INPUT_SECTIONS($LIBRARIES_SML3_CM(sdram_data_bank1))
                     INPUT_SECTIONS($LIBRARIES_SML3_CM(sdram_bank1))
                     INPUT_SECTIONS($LIBRARIES_SML3_CM(program))
                     INPUT_SECTIONS($LIBRARIES_SML3_CM(noncache_code))
                                         
                     // uclinux代码
                     INPUT_SECTIONS($LIBRARIES_SML3_CM(program))
                     INPUT_SECTIONS($LIBRARIES_SML3_CM(.rodata))
                     INPUT_SECTIONS($LIBRARIES_SML3_CM(.rodata.*))
                     INPUT_SECTIONS($LIBRARIES_SML3_CM(__vermagic))           // Kernel version magic
                     INPUT_SECTIONS($LIBRARIES_SML3_CM(.rodata1))
                     INPUT_SECTIONS($LIBRARIES_SML3_CM(.fixup))
 
                     // Kernel symbol table: Normal symbols
                     INPUT_SECTION_ALIGN(4)
                     ___start___ksymtab = .;
                     INPUT_SECTIONS($LIBRARIES_SML3_CM(__ksymtab))
                     ___stop___ksymtab = .;
 
                     // Kernel symbol table: GPL-only symbols
                     ___start___ksymtab_gpl = .;
                     INPUT_SECTIONS($LIBRARIES_SML3_CM(__ksymtab_gpl))
                     ___stop___ksymtab_gpl = .;
 
                     // Kernel symbol table: Normal unused symbols
                     ___start___ksymtab_unused = .;
                     INPUT_SECTIONS($LIBRARIES_SML3_CM(__ksymtab_unused))
                     ___stop___ksymtab_unused = .;
 
                     // Kernel symbol table: GPL-only unused symbols
                     ___start___ksymtab_unused_gpl = .;
                     INPUT_SECTIONS($LIBRARIES_SML3_CM(__ksymtab_unused_gpl))
                     ___stop___ksymtab_unused_gpl = .;
 
 
                     // Kernel symbol table: GPL-future symbols
                     ___start___ksymtab_gpl_future = .;
                     INPUT_SECTIONS($LIBRARIES_SML3_CM(__ksymtab_gpl_future))
                     ___stop___ksymtab_gpl_future = .;
 
                     // Kernel symbol table: Normal symbols
                     ___start___kcrctab = .;
                     INPUT_SECTIONS($LIBRARIES_SML3_CM(__kcrctab))
                     ___stop___kcrctab = .;
 
                     // Kernel symbol table: GPL-only symbols
                     ___start___kcrctab_gpl = .;
                     INPUT_SECTIONS($LIBRARIES_SML3_CM(__kcrctab_gpl))
                     ___stop___kcrctab_gpl = .;
 
                     // Kernel symbol table: GPL-future symbols
                     ___start___kcrctab_gpl_future = .;
                     INPUT_SECTIONS($LIBRARIES_SML3_CM(__kcrctab_gpl_future))
                     ___stop___kcrctab_gpl_future = .;
 
                     // Kernel symbol table: strings
                     INPUT_SECTIONS($LIBRARIES_SML3_CM(__ksymtab_strings))
 
              INPUT_SECTION_ALIGN(4)
                     __etext = .;
              } > MEM_SDRAM_UCLINUX
在这里,除了uclinux的代码外,还插入了VDSP库的代码,因为我们希望尽可能使用VDSP提供的库函数。中间还有一部分代码和数据段混合在一起了,以后再进行细调。
还有一个特殊的符号__stext__,这个符号原来是放在head.s中的,表示uclinux内核第一行代码的起始位置,因为我们将第一行代码写到了0xffa00000,因此在head.s中的符号取消,转而在ldf文件中进行定义。
4、移植.init段定义。
              // 初始化代码部分,可回收
              uclinux_init
              {
                     INPUT_SECTION_ALIGN(4096)
 
                     ___init_begin = .;
                     __sinittext = .;
                     INPUT_SECTIONS($LIBRARIES_SML3_CM(.init.text))
                     __einittext = .;
                     INPUT_SECTIONS($LIBRARIES_SML3_CM(.init.data))
                    
                     INPUT_SECTION_ALIGN(16)
                     ___setup_start = .;
                     INPUT_SECTIONS($LIBRARIES_SML3_CM(.init.setup))
                     ___setup_end = .;
                     ___start___param = .;
                     INPUT_SECTIONS($LIBRARIES_SML3_CM(__param))
                     ___stop___param = .;
                     ___initcall_start = .;
                     INPUT_SECTIONS($LIBRARIES_SML3_CM(.initcall1.init))
                     INPUT_SECTIONS($LIBRARIES_SML3_CM(.initcall2.init))
                     INPUT_SECTIONS($LIBRARIES_SML3_CM(.initcall3.init))
                     INPUT_SECTIONS($LIBRARIES_SML3_CM(.initcall4.init))
                     INPUT_SECTIONS($LIBRARIES_SML3_CM(.initcall5.init))
                     INPUT_SECTIONS($LIBRARIES_SML3_CM(.initcall6.init))
                     INPUT_SECTIONS($LIBRARIES_SML3_CM(.initcall7.init))
                     ___initcall_end = .;
                     ___con_initcall_start = .;
                     INPUT_SECTIONS($LIBRARIES_SML3_CM(.con_initcall.init))
                     ___con_initcall_end = .;
                     ___security_initcall_start = .;
                     INPUT_SECTIONS($LIBRARIES_SML3_CM(.security_initcall.init))
                     ___security_initcall_end = .;
                    
              INPUT_SECTION_ALIGN(4)
                     ___initramfs_start = .;
                     INPUT_SECTIONS($LIBRARIES_SML3_CM(.init.ramfs))
                     ___initramfs_end = .;
                    
               INPUT_SECTION_ALIGN(4)
                     ___init_end = .;
              } > MEM_SDRAM_UCLINUX
5、移植的.text.l1,即需要放在L1中的部分。
              uclinux_text_l1
              {
                     INPUT_SECTION_ALIGN(4)
                     __l1_lma_start = .;
                     __stext_l1 = .;
                     INPUT_SECTIONS($LIBRARIES_SML3_CM(.l1.text))
 
                     INPUT_SECTION_ALIGN(4)
                     __etext_l1 = .;
              } > MEM_A_L1_CODE
6、移植.data.l1数据段。
              uclinux_data_l1
              {
                     INPUT_SECTION_ALIGN(4)
                     __sdata_l1 = .;
                     INPUT_SECTIONS($LIBRARIES_SML3_CM(.l1.data))
              INPUT_SECTIONS(corea.dlb(data1))
                     __edata_l1 = .;
 
                     INPUT_SECTION_ALIGN(4)
                     __sbss_l1 = .;
                     INPUT_SECTIONS($LIBRARIES_SML3_CM(.l1.bss))
 
                     INPUT_SECTION_ALIGN(4)
                     __ebss_l1 = .;
              } > MEM_A_L1_DATA_A
7、移植.data.b.l1。
              uclinux_data_b_l1
              {
                     INPUT_SECTION_ALIGN(4)
                     __sdata_b_l1 = .;
                     INPUT_SECTIONS($LIBRARIES_SML3_CM(.l1.data.B))
                     __edata_b_l1 = .;
 
                     INPUT_SECTION_ALIGN(4)
                     __sbss_b_l1 = .;
                     INPUT_SECTIONS($LIBRARIES_SML3_CM(.l1.bss.B))
 
                     INPUT_SECTION_ALIGN(4)
                     __ebss_b_l1 = .;
              } > MEM_A_L1_DATA_B
8、移植数据段。
              // 数据段
              uclinux_data
              {
                     INPUT_SECTION_ALIGN(0x2000)
                     __sdata = .;
                     INPUT_SECTIONS($LIBRARIES_SML3_CM(.data.init_task))
                     INPUT_SECTIONS($LIBRARIES_SML3_CM(.data))
 
                     // 原先放在DATA_A的内容
                     INPUT_SECTION_ALIGN(4)
                     ___l1_data_cache_a = 0;
                     INPUT_SECTIONS($OBJECTS_CORE_A(L1_data_a) $LIBRARIES_CORE_A(L1_data_a))
                     INPUT_SECTIONS($OBJECTS_CORE_A{DualCoreMem("CoreA")}(cplb_data) $LIBRARIES_CORE_A{DualCoreMem("CoreA")}(cplb_data))
                     INPUT_SECTIONS($OBJECTS_CORE_A(cplb_data) $LIBRARIES_CORE_A(cplb_data))
                     INPUT_SECTIONS($OBJECTS_CORE_A(voldata) $LIBRARIES_CORE_A(voldata))
                     INPUT_SECTIONS($OBJECTS_CORE_A(constdata) $LIBRARIES_CORE_A(constdata))
                     INPUT_SECTIONS($OBJS_LIBS_INTERNAL_CORE_A(data1))
                     INPUT_SECTIONS($OBJS_LIBS_NOT_EXTERNAL_CORE_A(data1))
                     INPUT_SECTIONS($OBJECTS_CORE_A(data1) $LIBRARIES_CORE_A(data1))
                     INPUT_SECTIONS($OBJECTS_CORE_A(.edt) $LIBRARIES_CORE_A(.edt))
                     INPUT_SECTIONS($OBJECTS_CORE_A(.cht) $LIBRARIES_CORE_A(.cht))
 
                     // 原先放在data_b的内容
                     INPUT_SECTION_ALIGN(4)
                     ___l1_data_cache_b = 0;
                     INPUT_SECTIONS($OBJECTS_CORE_A(ctor) $LIBRARIES_CORE_A(ctor))
                     INPUT_SECTIONS($OBJECTS_CORE_A(ctorl) $LIBRARIES_CORE_A(ctorl))
                     INPUT_SECTIONS($OBJECTS_CORE_A(vtbl) $LIBRARIES_CORE_A(vtbl))
                     INPUT_SECTIONS($OBJECTS_CORE_A(.gdt) $LIBRARIES_CORE_A(.gdt))
                     INPUT_SECTIONS($OBJECTS_CORE_A(.gdtl) $LIBRARIES_CORE_A(.gdtl))
                     INPUT_SECTIONS($OBJECTS_CORE_A(.frt) $LIBRARIES_CORE_A(.frt))
                     INPUT_SECTIONS($OBJECTS_CORE_A(.rtti) $LIBRARIES_CORE_A(.rtti))
                     INPUT_SECTIONS($OBJECTS_CORE_A(.edt) $LIBRARIES_CORE_A(.edt))
                     INPUT_SECTIONS($OBJECTS_CORE_A(.cht) $LIBRARIES_CORE_A(.cht))
                     INPUT_SECTIONS($OBJS_LIBS_INTERNAL_CORE_A(data1))
                     INPUT_SECTIONS($OBJS_LIBS_NOT_EXTERNAL_CORE_A(data1))
                     INPUT_SECTIONS($OBJECTS_CORE_A(data1) $LIBRARIES_CORE_A(data1))
                     INPUT_SECTIONS($OBJECTS_CORE_A{DualCoreMem("CoreA")}(cplb_data) $LIBRARIES_CORE_A{DualCoreMem("CoreA")}(cplb_data))
                     INPUT_SECTIONS($OBJECTS_CORE_A(cplb_data) $LIBRARIES_CORE_A(cplb_data))
                     INPUT_SECTIONS($OBJECTS_CORE_A(voldata) $LIBRARIES_CORE_A(voldata))
                     INPUT_SECTIONS($OBJECTS_CORE_A(constdata) $LIBRARIES_CORE_A(constdata))
                                                              
                     _jiffies = _jiffies_64;
                    
                     INPUT_SECTION_ALIGN(4)
                     __edata = .;
              } > MEM_SDRAM_UCLINUX
在这里插入了VDSP库中的数据段。
9、移植bss段。
              // bss
              uclinux_bss
              {
                     INPUT_SECTION_ALIGN(4)
                     ___bss_start = .;
                     INPUT_SECTIONS($LIBRARIES_SML3_CM(.bss))
                     INPUT_SECTIONS($LIBRARIES_SML3_CM(COMMON))
                     INPUT_SECTION_ALIGN(4)
                     ___bss_stop = .;
                     __end = . ;
              } > MEM_SDRAM_UCLINUX
 
原创粉丝点击