Use B-core (3) in uClinux for bf561: Implementation of corebld

Source: Internet
Author: User

After/dev/coreb is available, uClinux also provides corebld. It is used to read elf files as common files and extract executable code, call the functions provided by/dev/coreb to write the executable code to L1 instruction memory or SDRAM of the B-core, and then call the driver function to execute the code. It is implemented in user/blkfin-apps/corebld. C. Currently, corebld can only analyze files in ELF format, but after proper modification, it should also be able to analyze executable code generated under vdsp. 1 , Elf Format OverviewThe executable and linking format (ELF) file is a common object file format in x86 Linux. For convenience and efficiency, the content of the ELF file has two parallel perspectives: one is the program connection angle, and the other is the program running angle, as shown in. The elf header describes the organization of the entire file at the beginning of the file. The section provides information about the target file (such as commands, Data, symbol tables, and relocation information ), the program header table specifies how to create a process image, which contains the entries of each program header. The section header table contains the entries of each section, including the names, sizes, and other information. The following struct provides information available for the elf header: typedef struct {unsigned char e_ident [ei_nident];/* File identification. */elf32_half e_type;/* file type. */elf32_half e_machine;/* machine architecture. */elf32_word e_version;/* ELF format version. */elf32_addr e_entry;/* entry point. */elf32_off e_phoff;/* program header file offset. */elf32_off e_shoff;/* section header file offset. */elf32_word e_fla GS;/* architecture-specific flags. */elf32_half e_ehsize;/* size of ELF header in bytes. */elf32_half e_phentsize;/* size of program header entry. */elf32_half e_phnum;/* Number of program header entries. */elf32_half e_shentsize;/* size of section header entry. */elf32_half e_shnum;/* Number of section header entries. */elf32_half e_shstrndx;/* section name strings section. */} elf32 _ EHDR; the struct below provides information available for each section: typedef struct {elf32_word sh_name;/* section name (index into the section header string table ). */elf32_word sh_type;/* section type. */elf32_word sh_flags;/* Section flags. */elf32_addr sh_addr;/* address in memory image. */elf32_off sh_offset;/* offset in file. */elf32_size sh_size;/* size in bytes. */elf32_word sh_link;/* index of a related section. */Elf32_word sh_info;/* depends on section type. */elf32_size sh_addralign;/* alignment in bytes. */elf32_size sh_entsize;/* size of each entry in section. */} elf32_shdr; because our goal is to extract executable code from each section and place it in the proper position of core B, it is enough to use these two struct. For more detailed information about elf, refer to the elf manual or documentation. 2 , Corebld ImplementationThe implementation of corebld is actually very simple. It is to extract the executable code in each section and then write it to the sh_addr location specified in the elf32_shdr struct. Finally, call the function provided by/dev/coreb to start the B-core. The following code illustrates this process: # define compiler_vdsp 0 # define compiler_gcc 1 int elf_load (const char * BUF) {elf32_ehdr * EHDR = (elf32_ehdr *) BUF; int compiler; if (! Is_elf (* EHDR) {printf ("file is not an elf file. /n "); Return-1;} If (EHDR-> e_flags = 4 & EHDR-> e_machine = 0x6a) compiler = compiler_vdsp; else if (EHDR-> e_flags = 0 & EHDR-> e_machine = 0x6a) compiler = compiler_gcc; else {printf ("file is not a Blackfin ELF File/N"); Return-1 ;} {// take the offset of the first section, the number of sections in this file, and the size of each section unsigned int section_ptr = (unsigned INT) BUF + EHDR-> e_sho Ff; unsigned int section_cnt = EHDR-> e_shnum; unsigned int section_sz = EHDR-> e_shentsize; int I; // write the executable code in each section to the specified region for (I = 0; I <section_cnt; ++ I) {elf32_shdr * shdr = (elf32_shdr *) (char *) section_ptr + I * section_sz); unsigned long ADDR = shdr-> sh_addr; unsigned long size = shdr-> sh_size; if (compiler = compiler_vdsp & (shdr-> sh_flags & 0x408000) = 0x8000) | (compiler = compile R_gcc & (shdr-> sh_flags & 0x0003) = 0x0003) {printf ("write % Zi bytes to 0x % P/N", size, (void *) ADDR); put_region (char *) ADDR, BUF + shdr-> sh_offset, size) ;}} return 0 ;} next, let's take a look at how the code in each section is written to the specified region: static void put_region (char * DST, const char * SRC, size_t count) {int F = open ("/dev/coreb", o_rdwr); int Index = 0, ret = 0; unsigned long seek = 0; // specify the command and parameter if (unsigne D long) DST> = 0xff600000) & (unsigned long) DST <0xff604000) {If (unsigned long) DST + count <0xff604000) {Index = 0; seek = (unsigned long) DST & 0x3fff ;}} else if (unsigned long) DST >=0xff610000) & (unsigned long) DST <0xff614000 )) {If (unsigned long) DST + count <0xff614000) {Index = 1; Seek = (unsigned long) DST & 0x3fff ;}} else if (unsigned long) DST> = 0xff500000) & (unsig Ned long) DST <0xff508000) {If (unsigned long) DST + count <0xff508000) {Index = 2; Seek = (unsigned long) DST & 0x7fff ;}} else if (unsigned long) DST >=0xff400000) & (unsigned long) DST <0xff408000) {If (unsigned long) DST + count <0xff408000) {Index = 3; Seek = (unsigned long) DST & 0x7fff;}/* Copy SDRAM Code */} else if (unsigned long) DST> = 0x3c00000) & (unsigned long) DST <0x4000000) {memcpy (DST, SRC, count);} else {printf ("cowardly refusing to load an incorrectly linked binary. /n "" Please make sure the binary you are trying to load is linked for bf561 core B. /n "" you will need a specially crafted linker definition file to do this for you. /n "); close (f); return;} // call the function to set the base address of the region to be written later if (ret = IOCTL (F, 1, & Index ))! = 0) printf ("IOCTL return % d/N", RET); // you can specify the offset if (seek) if (ret = lseek (F, seek, seek_set) <0) printf ("Seek failed! /N "); If (write (F, SRC, count )! = Count) printf ("Write failed! /N "); close (f); printf (" wrote % Zi bytes to 0x % P/N ", Count, DST );}

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.