📄 bootdisc.c
字号:
/***************************************** Copyright (c) 2001-2002 Sigma Designs, Inc. All Rights Reserved Proprietary and Confidential *****************************************//* This is file is part of the Jasper DVD boot loader */#include "config.h"#ifdef SUPPORT_BOOT_FROM_CD#include "atapi.h"#include "errors.h"#include "uart.h"#include "fipuser.h"unsigned char sector_buffer[2048]; static int stringcmp(const char *s1, const char *s2, int n){ int i=0; while(s1[i] == s2[i]) { if(s2[i]==0 || i>=n-1) { return 1; // same string } i++; } // different strings return 0;}static void set_disc_boot_status(int st){ if(st == BOOT_STATUS_ATAPIERROR) boot_status |= st; else boot_status = (boot_status & ~BOOT_STATUS_DISC_MASK) | st;}// Read a (possibly unaligned) 32 bit valueunsigned int read_dword(unsigned char *buf){ unsigned int r; r= (unsigned int)( (buf[0] )| (buf[1] << 8)| (buf[2] << 16)| (buf[3] << 24) ); return r;}// Read a (possibly unaligned) 16 bit valueunsigned short read_word(unsigned char *buf){ return (unsigned short)( (buf[0] )| (buf[1] >> 8) );}// Read 'count' sectors starting from 'addr' into 'buffer'unsigned int read_sectors(unsigned char *buffer, unsigned int addr, unsigned short count){ PrintLong(addr); PrintUart(" : read_sectors\r\n",25); if(IdeReadSectors(buffer, addr, count)){ PrintUart("Read Sectors FAILED\r\n",30); return 0; } else { PrintUart("Read Sectors OK\r\n",30); return 1; }}// Detect if we have a valid disc hereunsigned int detect_disc(){ if(IdeWaitReady(5000000)!=0) return 0; // failed else return 1;}// Check boot record validity and return boot catalog addressunsigned int read_boot_record(unsigned char *buf){ if(buf[0]!=0 || buf[6]!=1) { PrintUart("BOOT RECORD: Wrong ID or Version\r\n",40); return 0; // wrong Id or version } if(!stringcmp(buf+1, "CD001",5)) { PrintUart("BOOT RECORD: Wrong ISOID\r\n",40); PrintUart(buf+1,6); PrintUart("\r\n",6); return 0; // wrong isoid } if(!stringcmp(buf+7, "EL TORITO SPECIFICATION",24)) { PrintUart("BOOT RECORD: Wrong ELTORITOID\r\n",40); return 0; // wrong el torito id } return read_dword(buf+0x47); }// check validation entryunsigned int check_validation_entry(unsigned char *buf){ if(buf[0]!=1) return 0;#ifdef ELTORITO_PLATFORM_ID if(buf[1]!=ELTORITO_PLATFORM_ID) { // check platform ID PrintUart("WRONG PLATFORM ID\r\n",40); return 0; }#endif#ifdef ELTORITO_ID_STRING if(!stringcmp(buf+4,ELTORITO_ID_STRING,26)) { PrintUart("WRONG ID STRING",40); PrintUart(buf+4,40); return 0; }#endif if((buf[0x1e]!=0x55) || (buf[0x1f]!=0xaa)) return 0;// FIXME - need to check more - crc and stuff return 1;}// read initial entry and get image addr and sizeunsigned int get_initial_entry(unsigned char *buf, unsigned int *addr, unsigned int *count){ if(buf[0]!=0x88) { PrintUart("DEFAULT ENTRY: Not bootable\r\n",40); return 0; // Non bootable or wrong indicator }/* Optionnal: check the emulation type */ if(buf[1]!=0) // Emulation shoudl be set to No Emulation return 0; // Unsupported emulation? *count=read_word(buf+6); *addr=read_dword(buf+8); /* Optionnal: return the load segment value return ((unsigned int)read_word(buf+2))<<4)*/ return 1;}// Load the image from disc into sdram// XXX FIXME - Sector size ? When to use 2048 and when to use 512 (logical)unsigned int load_image(unsigned int image_addr, unsigned int kload, unsigned short image_count){ return read_sectors((char *)kload, image_addr, image_count);}// Main routine to boot from CD// Try to locate a bootable image on the CD and load it at 'kload'unsigned int try_boot_disc(unsigned int kload) { unsigned int catalog_addr; unsigned int image_addr; unsigned int image_count; PrintUart("Detect the disc\r\n",30); // Is there an ISO disc ? if(!detect_disc()) { fip_display_text(FIP_TEXT_NO_DISC); PrintUart("No disc\r\n",30); set_disc_boot_status(BOOT_STATUS_NODISC); return 0; } PrintUart("Disc Present\r\n",20); fip_display_text(FIP_TEXT_LOADING); // Read Boot Record Volume Descriptor (sector 17) if(!read_sectors(sector_buffer, 17, 1)){ set_disc_boot_status(BOOT_STATUS_BOOTRECORD | BOOT_STATUS_ATAPIERROR); return 0; } PrintUart("Boot Record Sector Read\r\n",30); // Get booting catalog address catalog_addr=read_boot_record(sector_buffer); PrintUart("\r\n",4); PrintLong(catalog_addr); PrintUart("\r\n",4); if(!catalog_addr) { set_disc_boot_status(BOOT_STATUS_BOOTRECORD); return 0; } PrintUart("Boot Record OK\r\n",20); // Read booting catalog if(!read_sectors(sector_buffer, catalog_addr, 1)){ set_disc_boot_status(BOOT_STATUS_BOOTCATALOG | BOOT_STATUS_ATAPIERROR); return 0; } PrintUart("Read Boot Catalog sector\r\n",40); // Check validation entry if(!check_validation_entry(sector_buffer)) { set_disc_boot_status(BOOT_STATUS_VALIDATION); return 0; } PrintUart("Validation Entry OK\r\n",30); // Get initial image address and size if(!get_initial_entry(sector_buffer+0x20,&image_addr, &image_count)) { set_disc_boot_status(BOOT_STATUS_ENTRY); return 0; } PrintUart("Found Initial Entry\r\n",30); PrintLong(image_addr); PrintUart(" address to load\r\n",30); PrintLong(image_count); PrintUart(" sectors to load (but using 512)\r\n",40); image_count=512; // Copy the image from CD to SDRAM if(!load_image(image_addr, kload, image_count)) set_disc_boot_status(BOOT_STATUS_DISCLOAD); PrintUart("Loaded Image\r\n",30); set_disc_boot_status(BOOT_STATUS_OK); return 1;}#endif // SUPPORT_BOOT_FROM_CD
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -