?? main.c
字號(hào):
#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;}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -