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

📄 bios.c

📁 Compex BIOS for SAMSUNG S3C4510B v1.20-lt
💻 C
字号:
#include "types.h"#include "bios.h"#include "bioscall.h"#include "board.h"#include "config.h"#include "console.h"#include "utils.h"#include "bootloader.h"extern const unsigned long _rom_base;extern const unsigned long system_table_offset;extern const unsigned long default_table_offset;extern const unsigned char sysinit_data[];extern const unsigned char biosapi_data[];extern const unsigned char setup_data[];extern const unsigned char fdisk_data[];extern const unsigned char tftp_data[];extern const unsigned char gunzip_data[];#define gunzip(inbuf, insize, outbuf, outsize)	\	((GUNZIP *)GUNZIP_ADDR)(inbuf, insize, outbuf, outsize)int sys_init(struct system_table_struct *system_table, unsigned long rom_base, unsigned long dram_base){	typedef int (SYSINIT)(struct system_table_struct *, unsigned long, unsigned long);	SYSINIT *sys_init_ptr;	memcpy((char *)SRAM_BASE, sysinit_data, 1024 * 3);	sys_init_ptr = (SYSINIT *)SRAM_BASE;	sys_init_ptr(system_table, rom_base, dram_base);	return 0;}int biosapi_init(struct system_table_struct *system_table){	unsigned char *inbuf;	unsigned long insize;	unsigned char *outbuf;	unsigned long outsize;	struct biosapi_init_struct init_param;	BIOSCALL *fp;	/* load gunzip */	memcpy((char *)GUNZIP_ADDR, gunzip_data, 1024 * 10);		inbuf = (unsigned char *)biosapi_data;	outbuf = (unsigned char *)BIOS_API_ADDR;	insize = 0x7fffffff;	outsize = 0x7fffffff;	gunzip(inbuf, &insize, outbuf, &outsize);	init_param.rom_base = _rom_base;	init_param.dram_base = DRAM_BASE;	init_param.system_table_offset = system_table_offset;	init_param.system_table = system_table;	fp = (BIOSCALL *)outbuf;	return (*fp)(BIOSCALL_INIT, (unsigned long)&init_param);  // Init BIOS call}int load_setup(void){	typedef int (SETUP)(void);	unsigned char *inbuf;	unsigned long insize;	unsigned char *outbuf;	unsigned long outsize;	SETUP *setup_ptr;	inbuf = (unsigned char *)setup_data;	outbuf = (unsigned char *)SETUP_ADDR;	insize = 0x7fffffff;	outsize = 0x7fffffff;	gunzip(inbuf, &insize, outbuf, &outsize);	setup_ptr = (SETUP *)SETUP_ADDR;	setup_ptr();	return 0;}int load_fdisk(void){	typedef int (FDISK)(void);	unsigned char *inbuf;	unsigned long insize;	unsigned char *outbuf;	unsigned long outsize;	FDISK *fdisk_ptr;	inbuf = (unsigned char *)fdisk_data;	outbuf = (unsigned char *)FDISK_ADDR;	insize = 0x7fffffff;	outsize = 0x7fffffff;	gunzip(inbuf, &insize, outbuf, &outsize);	fdisk_ptr = (FDISK *)FDISK_ADDR;	fdisk_ptr();	return 0;}int load_tftp(unsigned long mode, unsigned long param){	typedef int (TFTP)(unsigned long, unsigned long);	unsigned char *inbuf;	unsigned long insize;	unsigned char *outbuf;	unsigned long outsize;	TFTP *tftp_ptr;	inbuf = (unsigned char *)tftp_data;	outbuf = (unsigned char *)TFTP_ADDR;	insize = 0x7fffffff;	outsize = 0x7fffffff;	gunzip(inbuf, &insize, outbuf, &outsize);	tftp_ptr = (TFTP *)TFTP_ADDR;		return tftp_ptr(mode, param);}int check_partition(struct partition_struct *partition){	if (partition->flag == PART_FLAG_NONE) {		printf("Non-exist Partition!\r\n");		return -1;	}	if (partition->flag == PART_FLAG_NET) {		printf("Network Partition!\r\n");		return -1;	}		if (partition->type == PART_TYPE_RO) {		printf("Read-only Partition!\r\n");		return -1;	}	return 0;}struct partition_struct *select_partition(struct partition_table_struct *partition_table){	struct partition_struct *partition;	int i;	printf("\r\n");	for (i = 0; i < PART_MAX_NUM; i++) {		partition = &partition_table->partition[i];		printf("Partition %d : ", i + 1);		if (partition->flag == PART_FLAG_NONE) {			printf("None");		} else {			printf("0x%08lx - 0x%08lx" , partition->offset,				partition->offset + partition->size - 1);		}		printf("\r\n");	}	do {		printf("\r\nUpdate image on which partition (1 - 8) ");		i = get_select('1', '8');		printf("\r\n");		if (i < 0)			return NULL;					partition = &partition_table->partition[i];	} while (check_partition(partition));	return partition;}int setup_uclinux_cmdline(struct partition_struct *partition){	struct tag *tag;	char *s;	tag = (struct tag *)(partition->param_addr);	tag->hdr.tag = ATAG_CORE;	tag->hdr.size = 2;	if (partition->command_line[0] != '\0') {		tag = (struct tag *)((u32 *)tag + tag->hdr.size);		tag->hdr.tag = ATAG_CMDLINE;		tag->hdr.size = 2 + CMD_LENGTH/sizeof(u32);				s = (char *)&(tag->u);		memcpy(s, partition->command_line, CMD_LENGTH);		s[CMD_LENGTH - 1] = '\0';	}		tag = (struct tag *)((u32 *)tag + tag->hdr.size);	tag->hdr.tag = ATAG_NONE;	tag->hdr.size = 0;	return 0;}unsigned char *load_image(struct partition_table_struct *partition_table,		struct boot_param_struct *boot_param){	char *inbuf;	char *outbuf;	char *exec_addr;	unsigned long insize;	unsigned long outsize;	struct partition_struct *partition;	int i;	i = partition_table->boot_partition;	if (i < 0 || i > PART_MAX_NUM) {		printf("\r\nNo BOOT partition found!\r\n");		return NULL;	}		/* prepare buffers */	partition = &partition_table->partition[i];	exec_addr = (char *)(partition->exec_addr);	if (partition->flag == PART_FLAG_NET) {		printf("\r\nLoading Image From Net ................ \r\n");		insize = load_tftp(BOOT_LOAD_IMAGE, 0);		insize = ((insize + 3) & ~0x00000003);		if (insize == 0) {			printf("\r\nCancel\r\n");			return NULL;		}		outsize = 0x7fffffff;		inbuf = (char *)BUF_ADDR;		outbuf = inbuf + insize;		if (outbuf < (char *)exec_addr)			outbuf = (char *)exec_addr;	} else if (partition->flag == PART_FLAG_DISK) {		printf("\r\nLoading Image From Disk ............... ");		insize = partition->size;		if (insize == 0) {			printf("Cancel\r\n");			return NULL;		}		outsize = 0x7fffffff;		inbuf = (char *)(_rom_base + partition->offset);		outbuf = (char *)BUF_ADDR;		if (outbuf < (char *)exec_addr)			outbuf = (char *)exec_addr;	} else {		printf("\r\nNo BOOT partition found!\r\n");		return NULL;	}	/* load image to ram */	if (partition->gzipped_image) {		if (!gunzip(inbuf, &insize, outbuf, &outsize)) {			outsize = ((outsize + 3) & ~0x00000003);			if (outbuf != (char *)exec_addr)				memmove((char *)exec_addr, outbuf, outsize);		} else {			printf("Gunzip error!\r\n");			return NULL;		}	} else {		if (inbuf != (char *)exec_addr)			memmove((char *)exec_addr, inbuf, insize);	}	printf("Done\r\n");	/* setup boot parameters */	if (partition->image_type == IMAGE_UCLINUX) {		boot_param->r0 = 0;		boot_param->r1 = MACH_TYPE_SAMSUNG;		boot_param->r2 = partition->param_addr;		boot_param->r3 = 0;		setup_uclinux_cmdline(partition);	} else {		boot_param->r0 = 0;		boot_param->r1 = 0;		boot_param->r2 = 0;		boot_param->r3 = 0;	}	return (unsigned char *)(partition->exec_addr);}int main_menu(const char *password){	int list[] = {		BOOT_BIOS_SETUP,		BOOT_RUN_FDISK,		BOOT_LOAD_IMAGE,		BOOT_UPDATE_IMAGE,		BOOT_REBOOT	};	int select;	if ((password != NULL) && (password[0] != '\0')) {		char s[PASSWD_LENGTH];		printf("\r\n");		do {			printf("Password: ");			getpass(s, PASSWD_LENGTH, '*');			printf("\r\n");		} while (strncmp(password, s, PASSWD_LENGTH));	}	printf("\r\n\r\nMain Menu\r\n\r\n");	printf("1 - BIOS Setup\r\n");	printf("2 - Run Fdisk\r\n");	printf("3 - Load Image\r\n");	printf("4 - Update Image\r\n");	printf("5 - Reboot\r\n");	printf("\r\nPlease Select ");		while ( (select = get_select('1', '5')) < 0);	printf("\r\n");	return list[select];}/* *  Main BIOS functions */unsigned char *bios_main(struct boot_param_struct *boot_param){	struct system_table_struct *system_table;	struct partition_table_struct *partition_table;	struct partition_struct *partition;	unsigned char *exec_addr;	unsigned long startup_mode;	int i, ch, first_menu;		console_init();	printf("\r\n\r\n");	printf("Compex BIOS for SAMSUNG S3C4510B v1.20-lt72\r\n\r\n");	system_table = (struct system_table_struct *)		(_rom_base + system_table_offset);		printf("Press Enter for Menu, Esc for Safe Mode\r\n");	startup_mode = 0;	for (i = 0; i < 10000; i++) {		if (!kbhit())			continue;		ch = getch();		if (ch == KEY_ENTER) {			startup_mode = 1;			break;		} else if (ch == KEY_ESC) {			system_table = (struct system_table_struct *)				(_rom_base + default_table_offset);			printf("Chosen Safe Mode\r\n");			break;		}	}		partition_table = (struct partition_table_struct *)		(_rom_base + system_table->partition_table_offset);	printf("\r\nInitializing system .... ");	sys_init(system_table, _rom_base, DRAM_BASE);	printf("Done\r\n");	biosapi_init(system_table);	if (startup_mode)		startup_mode = BOOT_MENU;	else		startup_mode = bios_startup_mode();	first_menu = 1;	while (1) {		bios_set_userflag(USERFLAG_NONE);		switch (startup_mode) {		case BOOT_MENU:			if (first_menu) {				first_menu = 0;				startup_mode = main_menu(system_table->password);			} else				startup_mode = main_menu(NULL);			break;		case BOOT_BIOS_SETUP:			load_setup();			startup_mode = BOOT_MENU;			break;		case BOOT_RUN_FDISK:			load_fdisk();			startup_mode = BOOT_MENU;			break;		case BOOT_LOAD_IMAGE:			exec_addr = load_image(partition_table, boot_param);			if (exec_addr != NULL) {				/* setup CPU parameters */				boot_param->reg_clkcon = system_table->cpu.reg_clkcon;				boot_param->reg_syscfg = system_table->cpu.reg_syscfg;				return exec_addr;			}			startup_mode = BOOT_MENU;			break;		case BOOT_UPDATE_IMAGE:			partition = select_partition(partition_table);			if (partition != NULL)				load_tftp(startup_mode, (unsigned long)partition);			startup_mode = BOOT_MENU;			break;		case BOOT_REBOOT:			bios_reboot();			startup_mode = BOOT_MENU;			break;		default:			startup_mode = BOOT_MENU;			break;		}		switch (bios_get_userflag()) {		case USERFLAG_MEMORY:			printf("\r\nMemory configuration changed, reboot? (Y/n) ");			if (get_yes_no(1)) {				printf("\r\n");				bios_reboot();			} else				printf("\r\n");			break;		case USERFLAG_BIOS:			printf("\r\nBIOS default loaded, reboot? (Y/n) ");			if (get_yes_no(1)) {				printf("\r\n");				bios_reboot();			} else				printf("\r\n");			break;		default:			break;		}	}	return (unsigned char *)_rom_base;}

⌨️ 快捷键说明

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