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

📄 boot.c

📁 bootloader源代码
💻 C
字号:
/***************************************** Copyright (c) 2002-2004 Sigma Designs, Inc. All Rights Reserved Proprietary and Confidential *****************************************//* This file is part of the EM86XX boot loader */#include "config.h"#include "util.h"#include "uart.h"#include "hardware.h"#include "em86xxapi.h"#include "io.h"#include "romfs.h"#include "flash.h"#include "ide.h"#include "bootcd.h"#include "net.h"#include "net_ipv4.h"#include "bootmenu.h"#include "bootconfig.h"#include "memcfg.h"#ifdef CONFIG_ENABLE_FIP#include "fip.h"extern const char *fiptext;#endif#ifdef CONFIG_ENABLE_DVI#define ALLOW_OS_CODE 1#include "../../rmdef/rmdef.h"#include "../../emhwlib_hal/i2c/include/i2c_hal.h"#endifextern unsigned long dram0_size;extern memcfg_t *memcfg_ptr;extern void do_boot_prog(unsigned int) __attribute__ ((noreturn));//// function prototypes// // every functions return 0 if failed. otherwise they don't return control to caller. //int doboot_romfs_rom(unsigned int loadaddr);int doboot_romfs_ram(unsigned int loadaddr);int doboot_ide(int drive, int part, int subpart, unsigned int loadaddr);int doboot_idedisk(unsigned int loadaddr);int doboot_cd(int drive, unsigned int loadaddr);int doboot_idecd(unsigned int loadaddr);int doboot_net(unsigned int loadaddr, char *filename);void do_boot(unsigned int addr) __attribute__ ((noreturn));extern unsigned long loadaddr_kernel, loadaddr_kernelfs, loadaddr_romfs;static const char *copy_msg = "Copying binary from 0x%08x to 0x%08x, size %d(0x%x)\n";void do_boot(unsigned int addr) {#if defined(CONFIG_ENABLE_FIP) && defined(CONFIG_ENABLE_IDE)    unsigned long key;#endif#ifdef CONFIG_ENABLE_NETWORK    extern int net_dev_down(void);    net_dev_down();#endif#if defined(CONFIG_ENABLE_FIP) && defined(CONFIG_ENABLE_IDE)    key = fip_readkey(); /* See if any buttons is pressed */    if (key == FIP_KEY_EJECT)  /* Ejecting the CD */	ide_cdrom_eject(0, key);    fip_write_text(0, fiptext = "BOOT", FIP_CENTER);#endif    do_boot_prog(addr);}//// Boot from ROMFS//int doboot_romfs_rom(unsigned int loadaddr){    unsigned int addr = loadaddr ? loadaddr : loadaddr_kernel;    if (boot_romfs(addr, LOADER_FLASH_ROMFSADDR, LOADER_FLASH_ROMFSADDR + 0x00040000)) {        uart_printf("Boot kernel at 0x%08x with ROMFS at 0x%08x\n", addr, LOADER_FLASH_ROMFSADDR);        do_boot(addr);    }    return 0;}int doload_installablefile(unsigned int loadaddr, unsigned int len, int docksum, int doadj){    unsigned int checksum = 0;    if (docksum != 0)	checksum = binfile_crc_check((void *)loadaddr, len);    if (checksum != 0)	return 0;    else {        unsigned int dest = *((unsigned int *)loadaddr);	uart_printf(copy_msg, loadaddr + 2 * sizeof(unsigned long), dest, len - sizeof(void *), len - sizeof(void *));	/* Strip off the header 8 bytes: 4 = dest addr, 4 = checksum */        memcpy((void *)UNCACHED(dest), (void *)(loadaddr + 2 * sizeof(unsigned long)), len - 2 * sizeof(unsigned long));	/* If adjustment of memcfg need to be made */	if (doadj != 0) {            memcfg_ptr->dram0_fixed_topreserved = memcfg_ptr->dram0_size						+ DRAM0_BASE - dest;            if (memcfg_ptr->dram0_removable_topreserved != 0)                memcfg_ptr->dram0_removable_topreserved -=			memcfg_ptr->dram0_fixed_topreserved;	    gen_memcfg_checksum(memcfg_ptr); /* Compute and set the checksum value */        }    }    return 1;}int doload_romfs_installablefile(char *name, unsigned int loadaddr, int doadj){    unsigned int len = load_romfs_file(name, loadaddr, LOADER_FLASH_ROMFSADDR, LOADER_FLASH_ROMFSADDR + 0x00040000, 1);    if (len == 0)	return 0;    return(doload_installablefile(loadaddr, len, 1, doadj));}#if defined(CONFIG_ENABLE_FLASH) && defined(CONFIG_ENABLE_VSYNCPARAM)int doload_vsyncparam(unsigned int dest, int docksum){    unsigned int checksum = 0;    unsigned int startaddr;    flash_probe(LOADER_FLASHBASE, 1, 0); /* In case the flash hasn't been probed */    startaddr = LOADER_FLASHBASE + flash_getsize() - (MAX_USERPREF_SIZE / 2); /* Last 32KB of flash */    if (docksum != 0)        checksum = binfile_crc_check((void *)startaddr, MAX_USERPREF_SIZE / 2);     if ((checksum == 0) && (dest != 0)) {	    uart_printf(copy_msg, startaddr, dest, MAX_USERPREF_SIZE / 2, MAX_USERPREF_SIZE / 2);	memcpy((void *)dest, (void *)startaddr, MAX_USERPREF_SIZE / 2);	return 1;    }     return 0;}#endif#ifdef CONFIG_ENABLE_IRQHANDLERextern const char *irqhandler_init_msg;int doload_irqhandler(unsigned int loadaddr, unsigned int len, int docksum){    unsigned int checksum = 0;    if (docksum != 0)	checksum = binfile_crc_check((void *)loadaddr, len);    if (checksum == 0) {	typedef void (*FUNCPTR)(void);	unsigned long dest = *(unsigned int *)(loadaddr + sizeof(unsigned int));        FUNCPTR irqhandler_entry = (FUNCPTR)dest;       /* Offset by 4 */	if (dest == 0)	    return 0;	uart_printf(irqhandler_init_msg, (unsigned long)irqhandler_entry);        (*irqhandler_entry)();	return 1;    }    return 0;}int doload_romfs_irqhandler(unsigned int loadaddr){    unsigned int len = load_romfs_file(DEFAULT_IRQHANDLER_FILENAME, loadaddr, LOADER_FLASH_ROMFSADDR, LOADER_FLASH_ROMFSADDR + 0x00040000, 1);    if (len == 0)	return 0;    return(doload_irqhandler(loadaddr, len, 1));}#endif#ifdef CONFIG_ENABLE_BITMAPSint doload_bitmap(unsigned int loadaddr, unsigned int len, int docksum){    unsigned int checksum = 0;    if (docksum != 0)	checksum = binfile_crc_check((void *)loadaddr, len);    if (checksum != 0)	return 0;    else {	unsigned int *newaddr = (unsigned int *)(loadaddr);	unsigned int i;	unsigned int top_removable_size = 0;	while (newaddr < (unsigned int *)(loadaddr + len) - sizeof(unsigned int)) {	    unsigned long dest, len, type;	    type = (unsigned long)*newaddr;	    newaddr++; 	    dest = (unsigned long)*newaddr; 	    newaddr++; 	    len = (unsigned long)*newaddr;  	    newaddr++;			    if (dest > UNCACHED(DRAM0_BASE)) {		unsigned int dram0_base = UNCACHED(DRAM0_BASE);		if (dest > DRAM0_BASE)		    dram0_base = DRAM0_BASE;					if (dram0_base + memcfg_ptr->dram0_size - dest > top_removable_size) 		    top_removable_size = UNCACHED(DRAM0_BASE) + memcfg_ptr->dram0_size - dest;	    }	    switch(type) {	        case 0x44454c52:  //RLED			uart_printf("Decompressing RLED section to 0x%08lx, from 0x%08lx, size %d (0x%x)\n", dest, newaddr, len, len);			uart_printf("Decompressed size of RLED section is 0x%08lx\n", bmp_inflate((unsigned char*)newaddr, (unsigned char*)dest, len));			newaddr += ((len+sizeof(unsigned int)-1) / sizeof(unsigned int));			break;		case 0x44574152: //RAWD			uart_printf("Copying RAWD section to 0x%08lx, from 0x%08lx, size %d (0x%x)\n", dest, newaddr, len, len);			    			if (dest < UNCACHED(DRAM0_BASE)) {				for (i = 0; i < len/sizeof(unsigned int); i++) {					__raw_writel(*newaddr, dest);					newaddr++;					dest+=sizeof(unsigned int);				}			} else {				if ((UNCACHED(dest) + len) > (UNCACHED(DRAM0_BASE) + memcfg_ptr->dram0_size - 					memcfg_ptr->dram0_fixed_topreserved)) {					uart_puts("Warning: section too big (");					if (memcfg_ptr->dram0_fixed_topreserved)						uart_puts("override top fixed reserved area).\n");					else						uart_puts("beyond DRAM0 boundary).\n");				}				memcpy((void *)dest, (void *)newaddr, len);				newaddr += len/sizeof(unsigned int);			}			break;		default:			uart_printf("Inavalid section identifier found at 0x%08lx\n", newaddr-3);			return 0; 	    }	}	memcfg_ptr->dram0_removable_topreserved = top_removable_size;	gen_memcfg_checksum(memcfg_ptr); /* Compute and set the checksum value */    }    return 1;}int doload_romfs_bitmap(char *name, unsigned int loadaddr){    unsigned int len = load_romfs_file(name, loadaddr, LOADER_FLASH_ROMFSADDR, LOADER_FLASH_ROMFSADDR + 0x00040000, 1);    if (len == 0)	return 0;    return(doload_bitmap(loadaddr, len, 1));}#endif#ifdef CONFIG_ENABLE_UCODESint doload_ucode(unsigned int loadaddr, unsigned int len, int docksum){	unsigned int checksum = 0;	unsigned int dest;		if (docksum != 0)		checksum = binfile_crc_check((void *)loadaddr, len);		if (checksum != 0)		return 0;	dest = DRAM0_BASE + memcfg_ptr->dram0_size - len;	uart_printf(copy_msg, loadaddr, dest, len, len);        memcpy((void *)UNCACHED(dest), (void *)(loadaddr), len);		memcfg_ptr->dram0_fixed_topreserved = len;	gen_memcfg_checksum(memcfg_ptr); /* Compute and set the checksum value */			return 1;}int doload_romfs_ucode(char *name, unsigned int loadaddr){    unsigned int len = load_romfs_file(name, loadaddr, LOADER_FLASH_ROMFSADDR, LOADER_FLASH_ROMFSADDR + 0x00040000, 1);    if (len == 0)	return 0;    return(doload_ucode(loadaddr, len, 1));}#endif#ifdef CONFIG_ENABLE_DVIint doload_dvi(unsigned int loadaddr, unsigned int len, int docksum){	unsigned int checksum = 0;	unsigned int *newaddr = (unsigned int *)(loadaddr);	struct i2c i2c_info;	RMstatus err;		if (docksum != 0)		checksum = binfile_crc_check((void *)loadaddr, len);		if (checksum != 0)		return 0;	i2c_info.pGBus = (struct gbus *) 1;	i2c_info.RegBase = REG_BASE_SYSTEM;	i2c_info.PioClock = (unsigned char)*newaddr; newaddr++;	i2c_info.PioData = (unsigned char)*newaddr; newaddr++;	i2c_info.DelayUs = (unsigned long)*newaddr; newaddr++; 	i2c_info.WrAddr = (unsigned char)*newaddr; newaddr++;	i2c_info.RdAddr = (unsigned char)*newaddr; newaddr++;		while (newaddr  < (unsigned int *) (loadaddr + len - 4)) {		unsigned char addr, val;		addr = (unsigned char)*newaddr; newaddr++;		val = (unsigned char)*newaddr; newaddr++;		err = I2C_Write(&i2c_info, addr, &val, 1);		if (RMFAILED(err)) {			uart_printf("I2C_Write fails: addr: 0x%02x, val: 0x%02x\n", addr, val);			return 0;		}	}	return 1;}int doload_romfs_dvi(char *name, unsigned int loadaddr){    unsigned int len = load_romfs_file(name, loadaddr, LOADER_FLASH_ROMFSADDR, LOADER_FLASH_ROMFSADDR + 0x00040000, 1);    if (len == 0)	return 0;    return(doload_dvi(loadaddr, len, 1));}#endif#ifdef CONFIG_ENABLE_FULLFUNCTIONint doboot_romfs_ram(unsigned int loadaddr){    unsigned int addr = loadaddr ? loadaddr : loadaddr_kernelfs;    if (boot_romfs(addr, loadaddr_romfs, loadaddr_kernelfs)) {        uart_printf("Boot kernel at 0x%08x with ROMFS at 0x%08lx\n", addr, loadaddr_romfs);        do_boot(addr);    }    return 0;}#endif#ifdef CONFIG_ENABLE_IDE//// Boot from IDE device//int doboot_ide(int drive, int part, int subpart, unsigned int loadaddr){    unsigned int addr = loadaddr ? loadaddr : 0;    int doboot = 0, type;    image_infoblock_t info;    type = ide_check_image(drive, part, subpart, &info);    switch (type) {    case IMAGE_TYPE_NONE :        uart_puts("No bootable image found\n");        break;    case IMAGE_TYPE_KERNEL :        if (addr == 0)            addr = loadaddr_kernel;        uart_printf("Loading kernel from IDE device, size = %dKB\n", info.u.len >> 10);        if (ide_read_image(type, drive, part, subpart, (unsigned char *) addr))             uart_puts("Failed to load kernel image\n");        else {            doboot = 1;            uart_printf("Boot kernel at 0x%08x with IDE\n", addr);        }        break;    case IMAGE_TYPE_ROMFS :        if (addr == 0)            addr = loadaddr_kernelfs;        uart_printf("Loading ROMFS from IDE device, size = %dKB\n", info.u.len >> 10);        if (ide_read_image(type, drive, part, subpart, (unsigned char *) loadaddr_romfs))            uart_puts("Failed to load romfs image\n");        else {            if (boot_romfs(addr, loadaddr_romfs, addr)) {                doboot = 1;                uart_printf("Boot kernel at 0x%08x with ROMFS at 0x%08lx\n", addr, loadaddr_romfs);            }        }        break;    }    if (doboot)        do_boot(addr);    return doboot;}int doboot_idedisk(unsigned int loadaddr){    int drive, drives, part;    if ((drives = ide_found(IDE_ATA)) == 0) {        ide_probe(0x03, 0);        drives = ide_found(IDE_ATA);    }    if (drives == 0) {        uart_puts("No IDE device found\n");        return 0;    }        for (drive = 0; drive < MAX_DRIVES; ++drive) {        if (drives & (1 << drive)) {            if (ide_probe_image(drive, &part, NULL) != IMAGE_TYPE_NONE) {                uart_printf("Found bootable image at drive %d partition %d\n", drive, part);                doboot_ide(drive, part, 0, loadaddr);            }        }    }    uart_puts("No bootable image found\n");    return 0;}int doboot_cd(int drive, unsigned int loadaddr){	if (loadaddr == 0)		loadaddr = loadaddr_kernel;	if (bootcd_load_image(drive, loadaddr, NULL) == 0)		do_boot(loadaddr);    return 0;}int doboot_idecd(unsigned int loadaddr){	int drive, drives;    if ((drives = ide_found(IDE_ATAPI)) == 0) {        ide_probe(IDE_ALL, 0);        drives = ide_found(IDE_ATAPI);    }    if (drives == 0) {        uart_puts("No ATAPI device found\n");        return 0;    }        for (drive = 0; drive < MAX_DRIVES; ++drive) {        if (drives & (1 << drive)) {			if (doboot_cd(drive, loadaddr))				break;		}	}	return 0;}#endif#ifdef CONFIG_ENABLE_NETWORK//// Boot from Network//int doboot_net(unsigned loadaddr, char *filename){    extern int bootmenu_net_up(int force);    int len;    char *fname;    if (loadaddr == 0)        loadaddr = loadaddr_kernel;    if (bootmenu_net_up(0) != 0)        return 0;    if (!ipv4_ipaddr_valid(g_bootconfig.server)) {        uart_puts("Server address is invalid\n");        return 0;    }    if (filename != NULL)	fname = filename;    else	fname = g_bootconfig.kernel_filename;	    if (ipv4_tftp(g_bootconfig.server, fname, loadaddr, &len) == 0) {        uart_printf("Loaded kernel to 0x%08x, size = %d bytes\n", loadaddr, len);        do_boot(loadaddr);    }        return 0;}#endif

⌨️ 快捷键说明

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