main.c

来自「这是上月」· C语言 代码 · 共 491 行

C
491
字号
#define COMMAND_LINE_SIZE         1024#define SZ_64M                  0x04000000#define DRAM_SIZE		     SZ_64M/*#define DRAM_BASE               0x30000000 */#define KERNEL_ROM_ADDR				0x00030000       /*kernel zImage 在  nand flash 中的位置.  */#define KERNEL_SIZE       0x001d0000#define MACH_TYPE 193#define MT_SMC_S3C2410 3#define LINUX_KERNEL_OFFSET	0x8000#define LINUX_PARAM_OFFSET	0x100#define SZ_4K                           0x00001000#define LINUX_PAGE_SIZE		SZ_4K#define LINUX_PAGE_SHIFT	12#define LINUX_ZIMAGE_MAGIC	0x016f2818int printk(const char *fmt, ...);/* This is the old deprecated way to pass parameters to the kernel */struct param_struct {union {struct {unsigned long page_size; /* 0 */unsigned long nr_pages; /* 4 */unsigned long ramdisk_size; /* 8 */unsigned long flags; /* 12 */#define FLAG_READONLY 1#define FLAG_RDLOAD 4#define FLAG_RDPROMPT 8unsigned long rootdev; /* 16 */unsigned long video_num_cols; /* 20 */unsigned long video_num_rows; /* 24 */unsigned long video_x; /* 28 */unsigned long video_y; /* 32 */unsigned long memc_control_reg; /* 36 */unsigned char sounddefault; /* 40 */unsigned char adfsdrives; /* 41 */unsigned char bytes_per_char_h; /* 42 */unsigned char bytes_per_char_v; /* 43 */unsigned long pages_in_bank[4]; /* 44 */unsigned long pages_in_vram; /* 60 */unsigned long initrd_start; /* 64 */unsigned long initrd_size; /* 68 */unsigned long rd_start; /* 72 */unsigned long system_rev; /* 76 */unsigned long system_serial_low; /* 80 */unsigned long system_serial_high; /* 84 */unsigned long mem_fclk_21285; /* 88 */} s;char unused[256];} u1;union {char paths[8][128];struct {unsigned long magic;char n[1024 - sizeof(unsigned long)];} s;} u2;char commandline[COMMAND_LINE_SIZE];};#define UART_CTL_BASE		0x50000000#define oUTRSTAT		0x10	#define oUTXHL			0x20	#define __REGl(x)	(*(volatile unsigned long *)(x))#define __REGb(x)	(*(volatile unsigned char *)(x))#define bUART(x, Nb)		__REGl(UART_CTL_BASE + (x)*0x4000 + (Nb))#define bUARTb(x, Nb)		__REGb(UART_CTL_BASE + (x)*0x4000 + (Nb))#define UTRSTAT0		bUART(0, oUTRSTAT)#define UTXH0			bUARTb(0, oUTXHL)#define UTRSTAT_TX_EMPTY	(1 << 2)#define SERIAL_WRITE_READY()	((UTRSTAT0) & UTRSTAT_TX_EMPTY)#define SERIAL_WRITE_CHAR(c)	((UTXH0) = (c))#define PROC_SERIAL_PUTC(c)	\	({ while (!SERIAL_WRITE_READY()); \	   SERIAL_WRITE_CHAR(c); })void putc(char c){	PROC_SERIAL_PUTC(c);} void putnstr(const char *str, int n){	if (str == "")		return;	while (n && *str != '\0') {		putc(*str);		str++;		n--;	}}int strlen(const char* str){int i=0;while(*str++) i++;return i;} void putstr(const char *str){	putnstr(str, strlen(str));}   #define MAX_PART_NAME             16typedef struct mtd_partiton {        char name[MAX_PART_NAME];       /* partition name */        unsigned long offset;        unsigned long size;        unsigned long flag;} mtd_partition_t;#define MF_BONFS          0x00000004mtd_partition_t default_mtd_partitions[] = {        {                name:           "vi",                offset:         0,                size:           0x00020000,                flag:           0        }, {                name:           "param",                offset:         0x00020000,                size:           0x00010000,                flag:           0        }, {                name:           "kernel",                offset:         0x00030000,                size:           0x001d0000,                flag:           0        }, {                name:           "root",                offset:         0x00200000,                size:           0x02300000,                flag:           MF_BONFS        },{					 name:				"yaffs",					 offset:				0x02500000,					 size:				0x01b00000,					 flag:				0}};#define SZ_1M                           0x00100000#define SZ_16K                          0x00004000#define SZ_64M                          0x04000000#define DRAM_BASE0		0x30000000      /* base address of dram bank 0 */#define DRAM_BASE		DRAM_BASE0#define DRAM_SIZE		SZ_64M#define VIVI_RAM_SIZE		SZ_1M#define VIVI_RAM_BASE		(DRAM_BASE + DRAM_SIZE - VIVI_RAM_SIZE)#define HEAP_SIZE		SZ_1M#define HEAP_BASE		(VIVI_RAM_BASE - HEAP_SIZE)#define MMU_TABLE_SIZE		SZ_16K#define MTD_PART_SIZE		SZ_16K#define PARAMETER_TLB_SIZE	SZ_16K#define LINUX_CMD_SIZE		SZ_16K#define MMU_TABLE_BASE		(HEAP_BASE - MMU_TABLE_SIZE)#define VIVI_PRIV_SIZE		(MTD_PART_SIZE + PARAMETER_TLB_SIZE + LINUX_CMD_SIZE)#define VIVI_PRIV_RAM_BASE        (MMU_TABLE_BASE - VIVI_PRIV_SIZE)#define MTD_PART_OFFSET		0x00000000#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))int default_nb_part = ARRAY_SIZE(default_mtd_partitions);int *nb_mtd_parts = (int *)(VIVI_PRIV_RAM_BASE + MTD_PART_OFFSET + 8);const char mtd_part_magic[8] = {'V', 'I', 'V', 'I', 'M', 'T', 'D', 'P'};int get_default_mtd_partition(void){     		char *src_parts = (char *)&default_mtd_partitions;	char *dst_parts = (char *)(VIVI_PRIV_RAM_BASE + MTD_PART_OFFSET);	int num = default_nb_part;		putstr("begin to transfer mtd partition table \n");	if (src_parts == "") return -1;	/* printk("number of mtd partitions: %d\n", num); */	*(nb_mtd_parts) = num;	if ((sizeof(mtd_partition_t)*num + 16) > MTD_PART_SIZE) {		/*printk("too large mtd partition table\n"); */		return -1;	}	memcpy(dst_parts, mtd_part_magic, 8);	/* copy mtd magic */	dst_parts += 16;	/* copy partition table */	memcpy(dst_parts, src_parts, (sizeof(mtd_partition_t)*num));		return 0;}#include <config.h>#define __REGb(x)	(*(volatile unsigned char *)(x))#define __REGi(x)	(*(volatile unsigned int *)(x))#define NF_BASE		0x4e000000#define NFCONF		__REGi(NF_BASE + 0x0)#define NFCMD		__REGb(NF_BASE + 0x4)#define NFADDR		__REGb(NF_BASE + 0x8)#define NFDATA		__REGb(NF_BASE + 0xc)#define NFSTAT		__REGb(NF_BASE + 0x10)#define BUSY 1inline void wait_idle(void) {    int i;    while(!(NFSTAT & BUSY))      for(i=0; i<10; i++);}#define NAND_SECTOR_SIZE	512#define NAND_BLOCK_MASK		(NAND_SECTOR_SIZE - 1)/* low level nand read function */intnand_read_ll(unsigned char *buf, unsigned long start_addr, int size){    int i, j;    if ((start_addr & NAND_BLOCK_MASK) || (size & NAND_BLOCK_MASK)) {        return -1;	/* invalid alignment */    }    /* chip Enable */    NFCONF &= ~0x800;    for(i=0; i<10; i++);    for(i=start_addr; i < (start_addr + size);) {      /* READ0 */      NFCMD = 0;      /* Write Address */      NFADDR = i & 0xff;      NFADDR = (i >> 9) & 0xff;      NFADDR = (i >> 17) & 0xff;      NFADDR = (i >> 25) & 0xff;      wait_idle();      for(j=0; j < NAND_SECTOR_SIZE; j++, i++) {	*buf = (NFDATA & 0xff);	buf++;      }    }    /* chip Disable */    NFCONF |= 0x800;	/* chip disable */    return 0;}static inline void cpu_arm920_cache_clean_invalidate_all(void){__asm__(	"	mov	r1, #0\n"	"	mov	r1, #7 << 5\n"		  /* 8 segments */	"1:	orr	r3, r1, #63 << 26\n"	  /* 64 entries */	"2:	mcr	p15, 0, r3, c7, c14, 2\n" /* clean & invalidate D index */	"	subs	r3, r3, #1 << 26\n"	"	bcs	2b\n"			  /* entries 64 to 0 */	"	subs	r1, r1, #1 << 5\n"	"	bcs	1b\n"			  /* segments 7 to 0 */	"	mcr	p15, 0, r1, c7, c5, 0\n"  /* invalidate I cache */	"	mcr	p15, 0, r1, c7, c10, 4\n" /* drain WB */	);}void cache_clean_invalidate(void){	cpu_arm920_cache_clean_invalidate_all();}static inline void cpu_arm920_tlb_invalidate_all(void){	__asm__(		"mov	r0, #0\n"		"mcr	p15, 0, r0, c7, c10, 4\n"	/* drain WB */		"mcr	p15, 0, r0, c8, c7, 0\n"	/* invalidate I & D TLBs */		);}void tlb_invalidate(void){	cpu_arm920_tlb_invalidate_all();}void  call_linux(long a0, long a1, long a2){	cache_clean_invalidate();	tlb_invalidate();__asm__(	"mov	r0, %0\n"	"mov	r1, %1\n"	"mov	r2, %2\n"	"mov	ip, #0\n"	"mcr	p15, 0, ip, c13, c0, 0\n"	/* zero PID */	"mcr	p15, 0, ip, c7, c7, 0\n"	/* invalidate I,D caches */	"mcr	p15, 0, ip, c7, c10, 4\n"	/* drain write buffer */	"mcr	p15, 0, ip, c8, c7, 0\n"	/* invalidate I,D TLBs */	"mrc	p15, 0, ip, c1, c0, 0\n"	/* get control register */	"bic	ip, ip, #0x0001\n"		/* disable MMU */	"mcr	p15, 0, ip, c1, c0, 0\n"	/* write control register */	"mov	pc, r2\n"	"nop\n"	"nop\n"	: /* no outpus */	: "r" (a0), "r" (a1), "r" (a2)	);}/* * pram_base: base address of linux paramter */static void setup_linux_param(long param_base){	struct param_struct *params = (struct param_struct *)param_base; 	char *linux_cmd;	/*printk("Setup linux parameters at 0x%08lx\n", param_base);*/	memset(params, 0, sizeof(struct param_struct));	/* 部坷苛 秦拎具 瞪 巴甸.. 抄叼啊 版氰利栏肺 措面 嘛篮 巴.. */	params->u1.s.page_size = LINUX_PAGE_SIZE;	params->u1.s.nr_pages = (DRAM_SIZE >> LINUX_PAGE_SHIFT);#if 0	params->u1.s.page_size = LINUX_PAGE_SIZE;	params->u1.s.nr_pages = (dram_size >> LINUX_PAGE_SHIFT);	params->u1.s.ramdisk_size = 0;	params->u1.s.rootdev = rootdev;	params->u1.s.flags = 0;	/* TODO */	/* If use ramdisk */	/*	params->u1.s.initrd_start = ?;	params->u1.s.initrd_size = ?;	params->u1.s.rd_start = ?;	*/#endif	/* set linux command line */	/*linux_cmd = get_linux_cmd_line();*/	linux_cmd= "noinitrd root=/dev/mtdblock/1 init=/linuxrc confole=ttyS0";		if (linux_cmd == "") {			putstr("boot args is null");	} else {		memcpy(params->commandline, linux_cmd, strlen(linux_cmd) + 1);			putstr("loading linux boot args is ok !"); 	}       }int boot_kernel(void){		unsigned long boot_mem_base;		unsigned long mach_type;unsigned long dst;boot_mem_base = 0x30000000;dst = 0x30008000;mach_type = MACH_TYPE;			setup_linux_param(boot_mem_base + LINUX_PARAM_OFFSET);/*	get_default_mtd_partition(); */	putstr ("MACH_TYPE = 193  \n");		putstr("NOW, Booting Linux......\n");  	call_linux(0, mach_type, dst);	return 0;	}	/*static void error(void){	putstr("Sorry. We can not run vivi\n"); 	for (;;) } */int main(int argc, char *argv[]){	boot_kernel();			return 0;}

⌨️ 快捷键说明

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