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

📄 romfs.c

📁 em86xx 完整启动程序,支持网络下载与串通下载
💻 C
字号:
/***************************************** Copyright (c) 2002-2004 Sigma Designs, Inc. All Rights Reserved Proprietary and Confidential *****************************************//* This file is part of the boot loader *//* * romfs.c * * Extract linux kernel binary from romfs */#include "config.h"#include "uart.h"#include "util.h"#include "kunzip.h"#include "bootconfig.h"/*  extract from linux's romfs.txt :The layout of the filesystem is the following:offset      content    +---+---+---+---+  0 | - | r | o | m |  \    +---+---+---+---+   The ASCII representation of those bytes  4 | 1 | f | s | - |  /    (i.e. "-rom1fs-")    +---+---+---+---+  8 |   full size   |   The number of accessible bytes in this fs.    +---+---+---+---+ 12 |    checksum   |   The checksum of the FIRST 512 BYTES.    +---+---+---+---+ 16 | volume name   |   The zero terminated name of the volume,    :               :   padded to 16 byte boundary.    +---+---+---+---+ xx |     file  |    :    headers    :[...] The following bytes are now part of the file system; each file header must begin on a 16 byte boundary. offset     content    +---+---+---+---+  0 | next filehdr|X|   The offset of the next file header    +---+---+---+---+     (zero if no more files)  4 |   spec.info   |   Info for directories/hard links/devices    +---+---+---+---+  8 |     size      |   The size of this file in bytes    +---+---+---+---+ 12 |   checksum    |   Covering the meta data, including the file    +---+---+---+---+     name, and padding 16 | file name     |   The zero terminated name of the file,    :               :   padded to 16 byte boundary    +---+---+---+---+ xx | file data |    :       :Notes:+ Values are big endian. (ie NOT intel)+ Checksum : simple sum of the first 512 bytes (or the number of bytes  accessible, whichever is smaller).  The applied algorithm is the same  as in the AFFS filesystem, namely a simple sum of the longwords  (assuming bigendian quantities again).  For details, please consult  the source.*/typedef struct {    unsigned int next;    unsigned int info;    unsigned int size;    unsigned int crc;} file_hdr;static const char *romfs_found_msg = "ROMFS found at 0x%p, Volume name = %s\n";static const char *romfs_none_msg = "ROMFS not found\n";static const char *romfs_chk_msg = "ROMFS Check failed\n";extern unsigned loadaddr_heap_unzip;// Lookup file in romfs and return file  address (or 0 if no such file)file_hdr *romfs_lookup(unsigned int *romfs, char *name, file_hdr *hdrprev){    char *filename;    char *volume;    file_hdr *hdr;    unsigned int next;        if (hdrprev == NULL) {        volume = (char *)(romfs + 4); // +4 32bits words        while (*volume)            volume++;	volume += 1; /* must account for the terminating null character */        hdr = (file_hdr *)(((unsigned int) volume + 15) & ~0xF);    } else {        next = (swapl(hdrprev->next) & ~0xF) >> 2;        if (next == 0)            return NULL;        hdr = (file_hdr *) (romfs+next);    }    while (1) {        filename = ((char *) hdr) + 16;        next = (swapl(hdr->next) & ~0xF) >> 2;        // uart_printf("%08x : %s\n", (void *) hdr - (void *) romfs, filename);        if (name == NULL)             return hdr;        else if (strcmp(name, filename) == 0) {            uart_printf("File %s found\n", name);            return hdr;        } else if (next == 0) {            uart_printf("File %s not found\n", name);            return NULL;        }        hdr = (file_hdr *) (romfs+next);    }}#define ROMFS_MAGIC_1 ('-' + ('r'<<8) + ('o'<<16) + ('m'<<24))#define ROMFS_MAGIC_2 ('1' + ('f'<<8) + ('s'<<16) + ('-'<<24))// Check the romfs starting at 'addr' (with -romfs- marker)unsigned int romfs_check(unsigned int *addr){    return (((*addr) == ROMFS_MAGIC_1) && ((*(addr + 1)) == ROMFS_MAGIC_2)) ? 1 : 0;}/** * Get the full size of a ROMFS (without padding) * @param addr - beginning address of the ROMFS * @return > 0 on success, 0 on error */unsigned int romfs_size(unsigned int *addr){	if (romfs_check(addr))		return swapl(*(addr + 2));	return 0;}// Find the romfs in flash starting from 'addr'// Return the first file_hdrunsigned int find_romfs(unsigned int addr, unsigned int to){    while (!romfs_check((unsigned int *) addr) && addr <= to)        addr += 0x1000;    return (addr > to) ? 0 : addr;}#undef ROMFS_MAGIC_1#undef ROMFS_MAGIC_2static unsigned int load_gz(file_hdr *hdr, unsigned int addr){    unsigned char *filename = (unsigned char *)hdr;    unsigned int *fileaddr;    unsigned int *loadaddr = (unsigned int *)addr;    int count = swapl(hdr->size);    int res;#ifdef CONFIG_ENABLE_NETWORK    extern int net_dev_down(void);    net_dev_down();#endif    filename += 16; // point to beginning of file name    do {        filename += 16;    } while (*(filename - 1));         fileaddr = (unsigned int *) filename;    uart_printf("Unzipping image from 0x%p to 0x%p, size = %d\n", fileaddr, loadaddr, count);    res = kunzip((char *)fileaddr, (char *)loadaddr, loadaddr_heap_unzip);    return res;}static unsigned int load_bin(file_hdr *hdr, unsigned int addr){           unsigned char *filename = (unsigned char *)hdr;    unsigned int *fileaddr;    unsigned int *loadaddr = (unsigned int *)addr;    unsigned int count = swapl(hdr->size);#ifdef CONFIG_ENABLE_NETWORK    extern int net_dev_down(void);    net_dev_down();#endif    filename += 16; // point to beginning of file name    do {        filename += 16;    } while (*(filename - 1));         fileaddr = (unsigned int *) filename;    uart_printf("Copying image from 0x%p to 0x%p, size = %d\n", fileaddr, loadaddr, count);    memcpy(loadaddr, fileaddr, count);    // verification    if (memcmp(loadaddr, fileaddr, count) != 0)        uart_puts("Data mismatch after copying\n");    return count;}unsigned int boot_romfs(unsigned int kload, unsigned int addr, unsigned int to) {    unsigned int *romfs_addr;    file_hdr *hdr;     // Look for romfs starting after 8K    romfs_addr = (unsigned int *) find_romfs(addr, to);    if (romfs_addr == 0) {        uart_puts(romfs_none_msg);        return 0; //romfs not found           }    uart_printf(romfs_found_msg, romfs_addr, (char *) romfs_addr + 16);        if (!romfs_check(romfs_addr)) {        uart_puts(romfs_chk_msg);        return 0; //romfs corrupted    }        if ((hdr = romfs_lookup(romfs_addr, DEFAULT_KERNELGZ_FILENAME, NULL)) && load_gz(hdr, kload))        return 1;    if ((hdr = romfs_lookup(romfs_addr, DEFAULT_KERNEL_FILENAME, NULL)) && load_bin(hdr, kload))        return 1;    uart_puts("ROMFS load failed\n");        return 0;}unsigned int load_romfs_file(char *name, unsigned int load_addr, 			unsigned int addr, unsigned int to, int autoexpand){    unsigned int *romfs_addr;    file_hdr *hdr;    unsigned int count = 0;    char fname[64];                                                                                    // Look for romfs starting after 8K    romfs_addr = (unsigned int *) find_romfs(addr, to);    if (romfs_addr == 0) {        uart_puts(romfs_none_msg);        return 0; //romfs not found    }                                                                                    uart_printf(romfs_found_msg, romfs_addr, (char *) romfs_addr + 16);                                                                                    if (!romfs_check(romfs_addr)) {        uart_puts(romfs_chk_msg);        return 0; //romfs corrupted    }                                                                                    if ((hdr = romfs_lookup(romfs_addr, name, NULL)) && (count = load_bin(hdr, load_addr)))        return count;     if (autoexpand) {        strcpy(fname, name);        strcat(fname, ".gz");        if ((hdr = romfs_lookup(romfs_addr, fname, NULL)) && (count = load_gz(hdr, load_addr)))            return count;    }                                                                                    uart_puts("ROMFS load failed\n");                                                                                    return 0;}int dump_romfs(unsigned int addr, unsigned int to){    static char *s_filetype[] = {        "hard link", "dir", "file", "symbolic link", "block dev", "char dev", "socket", "fifo" };            unsigned int *romfs_addr;    file_hdr *hdr = NULL;    int type, size, next;    // Look for romfs starting after 8K    romfs_addr = (unsigned int *) find_romfs(addr, to);    if (romfs_addr == 0) {        uart_puts(romfs_none_msg);        return 0; //romfs not found           }    uart_printf(romfs_found_msg, romfs_addr, (char *) romfs_addr + 16);        if (!romfs_check(romfs_addr)) {        uart_puts(romfs_chk_msg);        return 0; //romfs corrupted    }        while ((hdr = romfs_lookup(romfs_addr, NULL, hdr)) != NULL) {        size = swapl(hdr->size);        type = swapl(hdr->next);        next = type & ~0x0f;        type &= 0x07;        uart_printf("%p : Name = %s, Type = %s, Size = %08x, Next = %08x\n",             hdr, ((char *) hdr) + 16, s_filetype[type], size, next);    }     return 0;}

⌨️ 快捷键说明

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