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

📄 lboot.c

📁 完整的Bell实验室的嵌入式文件系统TFS
💻 C
📖 第 1 页 / 共 2 页
字号:
            bip->bi_memsize = strtoul(optarg,0,0);            break;        case 'o':            offset = strtoul(optarg,0,0);            break;        case 'r':            comma = strchr(optarg,',');            if (!comma)                return(CMD_PARAM_ERROR);            *comma = 0;            rdb = strtoul(optarg,0,0);            rds = strtoul(comma+1,0,0);            rde = rdb + rds;            break;        case 'v':            verbose++;            break;        default:            return(CMD_PARAM_ERROR);        }    }    /* If the filename is specified, then we must load the file     * from TFS to memory.  Note that the relocation addresses     * may not be correct because it should be loaded to address zero.     * We will depend on the -o option to tell us if we need to      * adjust for this.      */    if (argc == optind+1) {        struct boot_block *bb;        char *fbase, *fname;        fname = argv[optind];        tfp = tfsstat(fname);        if (!tfp) {            printf("%s: file not found\n",fname);            return(CMD_FAILURE);        }        if (TFS_USRLVL(tfp) > getUsrLvl()) {            printf("Permission denied\n");            return(CMD_FAILURE);        }        fbase = TFS_BASE(tfp);        if (memcmp(fbase,xmagic,4) == 0) {            err = tfsloadlelf(tfp,verbose > 1 ? 1 : 0,(long *)&entry);            if (err != TFS_OKAY) {                printf("%s: %s\n",fname,tfserrmsg(err));                return(CMD_FAILURE);            }        }        else if (memcmp(fbase,zmagic,4) == 0) {            bb = (struct boot_block *)fbase;            memcpy((char *)bb->dest, fbase + sizeof(struct boot_block),                TFS_SIZE(tfp) - sizeof(struct boot_block));            entry = (void(*)())bb->entry_point;        }        else {            printf("File %s, not vmlinux or vmlinuz!!??\n",fname);            return(CMD_FAILURE);        }        entryset = 1;    }    /* Yanking comments from arch/ppc/kernel/ppc4xx_setup.c of linux,     * registers r3 thru r7 are as follows...     *     * r3 - Optional pointer to a board information structure.     * r4 - Optional pointer to the physical starting address of the init RAM     *      disk.     * r5 - Optional pointer to the physical ending address of the init RAM     *      disk.     * r6 - Optional pointer to the physical starting address of any kernel     *      command-line parameters.     * r7 - Optional pointer to the physical ending address of any kernel     *      command-line parameters.     *     * Registers r4-r7 can be established locally with this command through     * the -b and -r options.  The structure pointed to by r3 appears to     * be different for different targets, so this will be an external     * function.      * NOTE: the comments in the linux code say "Optional".  Don't beleive     * it!  They are not optional!  At a minimum, the board information     * pointer must point to a valid board information structure, and the     * other registers must be NULL.     */    if (verbose) {        printf("entry(0x%lx,0x%lx,0x%lx,0x%lx,0x%lx)\n",            (ulong)bip,rdb,rde,(ulong)bpb,(ulong)bpe);    }    if (entryset) {        if (verbose)            printf("Branching to entrypoint 0x%lx...\n",(ulong)entry);        entry(bip,rdb,rde,bpb,bpe);         /* Branch to entrypoint */    }    return(CMD_SUCCESS);}/* tfsloadlelf(): * This function is VERY similar to the TFS_EBIN_ELF version of tfsloadebin() * in tfsloader.c.  Originally I put a few changes to the standard stuff in * tfsloader.c; but then I decided to leave that stuff work in the standard * way only and put any hacks of the standard here in the lboot.c file.  This * will avoid future hacking of the loader functions just to support the * non-standard way in which the ELF file is loaded for linux. */static inttfsloadlelf(TFILE *fp,int verbose,long *entrypoint){    Elf32_Word  size, notproctot;    ulong       delta;    int         i, err, no_sections_loaded;    char        *shname_strings;    ELFFHDR     *ehdr;    ELFSHDR     *shdr;    delta = 0;    no_sections_loaded = 1;    /* Establish file header pointers... */    ehdr = (ELFFHDR *)(TFS_BASE(fp));    shdr = (ELFSHDR *)((int)ehdr + ehdr->e_shoff);    err = 0;    /* Store the section name string table base: */    shname_strings = (char *)ehdr + shdr[ehdr->e_shstrndx].sh_offset;    notproctot = 0;    /* For each section header, relocate or clear if necessary... */    for (i=0;!err && i<ehdr->e_shnum;i++,shdr++) {        if ((size = shdr->sh_size) == 0)            continue;        if ((verbose) && (ehdr->e_shstrndx != SHN_UNDEF))            printf("%-10s: ", shname_strings + shdr->sh_name);        if (!(shdr->sh_flags & SHF_ALLOC)) {            notproctot += size;            if (verbose)                printf("     %7ld bytes not processed (tot=%ld)\n",                    size,notproctot);            continue;        }        /* This linux binary always wants to be loaded at zero.  The load         * address in the header of the first section is used as a delta         * for all sections so that the first section is loaded at zero         * and all remaining sections are loaded with the same delta as         * the first section.  The initial linux code is address independent         * and it quickly turns on the MMU and adjusts it's "virtual"         * memory space to look like it is running at the actual address         * space specified by the elf header.         */        if (no_sections_loaded) {            delta = (ulong)shdr->sh_addr;            no_sections_loaded = 0;        }        if (shdr->sh_type == SHT_NOBITS) {            if (tfsmemset((char *)(shdr->sh_addr - delta),0,size,                verbose,0) != 0)                err++;        }        else {            if (TFS_ISCPRS(fp)) {                int     outsize;                outsize = decompress((char *)(ehdr)+shdr->sh_offset,size,                    (char *)shdr->sh_addr - delta);                if (outsize == -1) {                    err++;                    continue;                }                if (verbose)                    printf("dcmp %7d bytes from 0x%08lx to 0x%08lx\n",outsize,                        (ulong)(ehdr)+shdr->sh_offset,shdr->sh_addr);            }            else {                if (tfsmemcpy((char *)(shdr->sh_addr - delta),                    (char *)((int)ehdr+shdr->sh_offset),                    size,verbose,0) != 0)                    err++;            }            /* Flush caches for each loadable section... */            flushDcache((char *)shdr->sh_addr - delta,size);            invalidateIcache((char *)shdr->sh_addr - delta,size);        }    }    if (err)        return(TFSERR_MEMFAIL);    if (verbose) {        printf("entrypoint: 0x%lx, linux-delta: 0x%lx\n",            ehdr->e_entry, delta);    }    /* Store entry point: */    if (entrypoint)        *entrypoint = (long)(ehdr->e_entry) - delta;    return(TFS_OKAY);}

⌨️ 快捷键说明

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