Question

We are trying to load a linux image into our DRAM at a specific location ,DRAM end address is 0x80000000 which we come to know from boot log which says "mem device ending address is 0x80000000".We are loading our image at address "0x5000000" and before that variuos section in image getting loaded at some address which is greater than "0x80000000",for eaxmple again from boot logs

 loading section to address 0xc5000000 from file position 0x1000, size is 0x5ac13e

Whats meaning of "from file position 0x1000" in above line.

first section that loaded is .text section ,below is our vmlinux image dump of section header

[Nr]      Name           Type            Addr     Off    Size   ES Flg Lk Inf Al

[ 0]                     NULL            00000000 000000 000000 00      0   0  0

 [ 1]   .text            PROGBITS        c5000000 001000 5ac13e 00  AX  0   0 4096

 [ 2]      .notes           NOTE            c55ac140 5ad140 000168 00  AX  0   0  4

 [ 3]    __ex_table        PROGBITS        c55ac2b0 5ad2b0 000fe0 00   A  0   0  4

 [ 4]   .rodata           PROGBITS        c55ae000 5af000 20a930 00   A  0   0 64

 [ 5]   __bug_table       PROGBITS        c57b8930 7b9930 0075fc 00   A  0   0  1

 [ 6]   .pci_fixup        PROGBITS        c57bff2c 7c0f2c 001a90 00   A  0   0  4

 [ 7]    .builtin_fw       PROGBITS        c57c19bc 7c29bc 0000cc 00   A  0   0  4

Its quite a big list, so didn't post full .But one thing we can see here .text section is greater than DRAM end address ,so image should not be loded properly though we are not getting any error after loading first section it keeps on loading other sections but after this message it hangs.

    program load complete, entry point: 0x5000000, size: 0x92e7fc

My question is how can I align these different sections address to our DRAM address, Is objcopy utility could be used here to change address of these Different sections.

Is there any way to set these section addresses before compilation?? Second thing what could be reason for this Hang afer program load complete.

Was it helpful?

Solution

from file position 0x1000 means what it says. You have it in the dump:

[Nr]      Name           Type            Addr     Off    Size   ES Flg Lk Inf Al
...
[ 1]   .text            PROGBITS        c5000000 001000 5ac13e 00  AX  0   0 4096

It's where the .text section starts in the file, at offset 0x1000.

But one thing we can see here .text section is greater than DRAM end address

Nope, it's not greater (not in the sense of bigger, at least), it's compiled in the expectation that it'll be loaded at address 0xc5000000 in the memory.

so image should not be loded properly though we are not getting any error after loading first section it keeps on loading other sections

The image can be loaded anywhere, it's just data for the purpose of loading.

OTOH, if loading section to address 0xc5000000 means what it says, the file gets loaded into nowhere since your RAM ends at 0x7fffffff.

but after this message it hangs.

And that's expected. Machine code is rarely position-independent and so if you load it at a location different from where it's supposed to be loaded, it'll not work. Or if it doesn't even get loaded, then what are you going to execute? Garbage.

Is there any way to set these section addresses before compilation??

Depending on the system you may have one of the two below options or both:

  • set up page translation in such a way that virtual addresses from 0xc5000000 and up map to physical addresses from 0x5000000 and up for the entire program
  • find the linker script that your compiler is using and change the initial section address from 0xc5000000 to 0x5000000, google this up, see compiler/linker documentation

Also, it's a bit odd that the entry point is at 0x5000000. Not that this is necessarily wrong, it's just that it's rarely the case. I'd make sure that the start label (or _start or whatever it is) indeed receives the same address as the beginning of the .text section. If, for some reason, it's not the case, there's something wrong either with the linker script or the compiler/linker command-line options or with the loader.

OTHER TIPS

What loader do you use? What is the form of the "image"? U-boot image, raw one, vmlinux ELF file? I guess the last one judging by the existence of sections, etc. From ELF file you should load not sections but rather so called program headers. For example this is the OpenRISC linux kernel program headers listing (obtained using readelf -l):

Elf file type is EXEC (Executable file)
Entry point 0xc0000000
There are 2 program headers, starting at offset 52

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  LOAD           0x002000 0xc0000000 0x00000000 0x231728 0x232000 RWE 0x2000
  LOAD           0x234000 0xc0232000 0x00232000 0x17c78c 0x18bfcc RWE 0x2000

 Section to Segment mapping:
  Segment Sections...
   00     .text .rodata __ksymtab __ksymtab_gpl __ksymtab_strings __param __modver 
   01     .data __ex_table .head.text .init.text .init.data .bss 

See the difference between VirtAddr and PhysAddr (dropped c due to usual Linux kernel mapping). Naturally, the physical address should be used for loading.

The reason kernel is using virtual addresses for symbols, sections etc is that during boot you quickly enter the moment when the MMU is initialized, the virtual addresses are then the only valid ones.

And finally, about changing those addresses. Indeed, as pointed by Alexey, linker script is the key. You can find these in arch/(your arch)/kernel/vmlinux.lds.S. But the point is this is IMO not your problem, the problem lies probably in the loader or its options.

Check your arch/arm/mach-xxx/Makefile.boot ( You use arm board right ? )

  zreladdr-y        += 0x80008000
params_phys-y       := 0x80000100
initrd_phys-y       := 0x80800000

This is from Ti omap3 chip .

As I think you will need the same

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top