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

📄 bootcd.c

📁 em86xx 完整启动程序,支持网络下载与串通下载
💻 C
字号:
/***************************************** Copyright (c) 2002-2004 Sigma Designs, Inc. All Rights Reserved Proprietary and Confidential *****************************************//* This file is part of the boot loader *//* * bootcd.c * * Bootable CD-ROM format support * * Based on "El Torito" Bootable CD-ROM Format Specification v1.0 * Modified from jasper boot loader by Ho Lee 03/24/2004 */#include "config.h"#include "uart.h"#include "io.h"#include "system.h"#include "util.h"#include "hardware.h"#include "em86xxapi.h"#include "ide.h"#include "atapi.h"#include "bootcd.h"// function protoytypesstatic unsigned int check_boot_record(unsigned char *buf);static int check_validation_entry(unsigned char *buf);static int get_initial_entry(unsigned char *buf, unsigned int *psector, unsigned int *pnsector);// return 0 if error// return 4 bytes integer starting from buf + 0x47unsigned int check_boot_record(unsigned char *buf){    /*      * Boot Record Volume Descriptor      *     * 0x00 : Boot record indicator, must be 0     * 0x01 - 0x05 : "CD001"     * 0x06 : Version of this descriptor, must be 1     * 0x07 - 0x26 : "EL TORITO SPECIFICATION" padded with 0's     * 0x27 - 0x46 : Unused, must be 0     * 0x47 - 0x4a : Absolute pointer to first sector of Boot Catalog     * 0x4b - 0x7ff : Unused, must be 0     */    uart_puts("CD-ROM Boot Sector :\n");    if (buf[0] != 0) {        uart_puts("  No boot sector found\n");        return 0;    }        if (strncmp(buf + 1, "CD001", 5) != 0) {        buf[1 + 5] = 0;        uart_printf("  Wrong ISOID %s\n", buf + 1);        return 0;    }    if (buf[6] != 1) {        uart_puts("  Wrong version\n");        return 0;    }    if (strncmp(buf + 7, "EL TORITO SPECIFICATION", 24) != 0) {        buf[7 + 24] = 0;        uart_printf("  Wrong ELTORITOID %s\n", buf + 7);        return 0;    }    uart_printf("  Found Booting Catalog at sector %d\n", __read32(buf + 0x47));    return __read32(buf + 0x47);}// return 0 if OKint check_validation_entry(unsigned char *buf){    /*     * Validation Entry     *     * 0x00 : Header ID, must be 1     * 0x01 : Platform ID     * 0x02 - 0x03 : Reserved, must be 0     * 0x04 - 0x1b : ID string     * 0x1c - 0x1d : checksum     * 0x1e : Key byte, must be 0x55     * 0x1f : Key byte, must be 0xaa     */    uart_puts("CD-ROM Booting Catalog :\n");    if (buf[0x00] != 1 || buf[0x02] != 0 || buf[0x03] != 0 || buf[0x1e] != 0x55 || buf[0x1f] != 0xaa) {        uart_puts("  Invalid validation entry\n");        return 1;    }#ifdef ELTORITO_PLATFORM_ID    if (buf[1] != ELTORITO_PLATFORM_ID) {        uart_printf("  Wrong Platform ID 0x%02x\n", buf[1]);        return 2;    }#endif#ifdef ELTORITO_ID_STRING    if (strncmp(buf + 4, ELTORITO_ID_STRING, 26) != 0) {        buf[4 + 26] = 0;        uart_printf("  Wrong ID string %s\n", buf + 4);        return 3;    }#endif    uart_puts("  Validation entry is OK\n");    return 0;}// return 0 if OKint get_initial_entry(unsigned char *buf, unsigned int *psector, unsigned int *pnsector){    /*     * Initial/Default Entry     *     * 0x00 : Boot indicator, 0x88 = bootable, 0x00 = not bootable     * 0x01 : Boot media type     *        0x00 = no emulation     *        0x01 : 1.2M diskette     *        0x02 : 1.44M diskette     *        0x04 : 2.88M diskette     *        0x08 : harddisk     * 0x02 - 0x03 : Load segment     * 0x04 : System type     * 0x05 : Unused, must be 0     * 0x06 - 0x07 : Sector count     * 0x08 - 0x0b : Load RBA     */    if (buf[0] != 0x88) {        uart_puts("  Not bootable\n");        return 1;    }    if (buf[1] != 0)        uart_printf("  Boot media = %02x\n", buf[1]);    *psector = *(unsigned int *) (buf + 8);    *pnsector = *(unsigned short *) (buf + 6);    uart_printf("  Image starts from sector %d, size is %d sectors\n", *psector, *pnsector);    return 0;}int bootcd_load_image(int drive, unsigned long addr, unsigned long *image_size){    unsigned char buffer[CDSECTOR_SIZE];    unsigned int catalog_sector;    unsigned int image_sector, image_nsector;    unsigned int i;    unsigned long loadaddr;#ifdef CONFIG_ENABLE_NETWORK    extern int net_dev_down(void);#endif    if (atapi_waitready(drive, 20000) != 0) {        uart_puts("No disc detected\n");        return 1;    }    // Read boot record volume descriptor (sector 17)    if (atapi_readsector(drive, buffer, 17, 1) != 0) {        uart_puts("Can't read boot record\n");        return 2;    }    // Get booting catalog sector address    if ((catalog_sector = check_boot_record(buffer)) == 0)        return 3;    // Read booting catalog    if (atapi_readsector(drive, buffer, catalog_sector, 1) != 0) {        uart_puts("Can't read booting catalog\n");        return 5;    }    // Check validation entry    if (check_validation_entry(buffer) != 0)        return 6;    // Get initial image sector and number of sectors    if (get_initial_entry(buffer + 0x20, &image_sector, &image_nsector) != 0)        return 7;#ifdef CONFIG_ENABLE_NETWORK    net_dev_down();#endif    // Load the image    uart_puts("Loading");    for (i = 0, loadaddr = addr; i < image_nsector; ++i) {        atapi_readsector(drive, (void *) loadaddr, image_sector, 1);        loadaddr += CDSECTOR_SIZE;        ++image_sector;        // shows dot at every 64KB        if ((i & 0x1f) == 0)            uart_putc('.');    }    uart_puts("\n");    uart_printf("Loaded kernel to 0x%08lx from CD-ROM, size = %dKB\n",        addr, (image_nsector * CDSECTOR_SIZE) >> 10);    if (image_size)	    *image_size = image_nsector * CDSECTOR_SIZE;    return 0;}

⌨️ 快捷键说明

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