📄 bootcd.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 + -