/* Load a binary file into memory via the UART If its an elf file, copy it into the correct memory areas and execute it. */ void load_run( int type, unsigned int address ) { int file_size; /* testing tyhe boot loader itself in simulation */ if ( type == 2 ) { print_help(); _core_status(); print_spaces(16); _testpass(); } /* Load a file but don't run it */ else if ( type == 1 ) { /* Load a file using the xmodem protocol */ printf ("Send file w/ 1K Xmodem protocol from terminal emulator now...\n"); /* Destination, Destination Size */ file_size = xmodemReceive((char *) FILE_LOAD_BASE, FILE_MAX_SIZE); if (file_size < 0 || file_size > FILE_MAX_SIZE) { printf ("Xmodem error file size 0x%x \n", file_size); return; } printf("\nelf split\n"); elfsplitter(FILE_LOAD_BASE, file_size); } /* Hello world special start address - simulations only */ else if ( type == 4 ) { _jump_to_program(0x0080e400); } /* Load a binary file into memory */ else if ( type == 5 ) { /* Destination, Destination Size */ file_size = xmodemReceive((char *) address, FILE_MAX_SIZE); if (file_size < 0 || file_size > FILE_MAX_SIZE) { printf ("Xmodem error file size 0x%x \n", file_size); return; } } /* Run the program */ else { printf("j 0x%08x\n", JUMP_ADR); /* Flush the uart tx buffer with spaces */ print_spaces(16); printf("\n"); /* pc jump */ _jump_to_program(JUMP_ADR); _testpass(); } }
void cmd_xmodem(void) { int rcv, fnbr; char *fname, *errorreturn; getargs(&cmdline, 3, " "); if(argc != 3) error("Invalid syntax"); if(toupper(*argv[0]) == 'R') rcv = true; else if(toupper(*argv[0]) == 'S') rcv = false; else error("Invalid syntax"); fname = getCstring(argv[2]); fnbr = FindFreeFileNbr(); if(!fnbr) error("Too many files open"); MMfopen(fname, rcv?"w":"r", fnbr); FileXfr = true; if(rcv) errorreturn = xmodemReceive(fnbr); else errorreturn = xmodemTransmit(fnbr); FileXfr = false; MMfclose(fnbr); if(*errorreturn) error(errorreturn); }
int main(void) { int rx_len; irq_initialize_vectors(); cpu_irq_enable(); unsigned char ch; // Initialize the sleep manager sleepmgr_init(); #if !SAM0 sysclk_init(); board_init(); #else system_init(); #endif configure_console(); printf("\nUSB CDC\n"); printf("CPU:%dHz\n", sysclk_get_cpu_hz()); printf("sysclk_get_peripheral_hz:%dHz\n", sysclk_get_peripheral_hz()); printf("sysclk_get_main_hz:%dHz\n", sysclk_get_main_hz()); ui_init(); ui_powerdown(); // Start USB stack to authorize VBus monitoring udc_start(); port_interrupt_disible(); // The main loop manages only the power mode // because the USB management is done by interrupt unsigned long input_count=0; while (true) { ch = port_inbyte(1); if(! port_in_is_error()) { if('c'== ch) { port_outbyte('C'); xmodemReceive((unsigned char *)0x2000, 0x100000); } else if('x'== ch) { port_outbyte('X'); xmodemTransmit((unsigned char *)0x2000, 0x100000); } else if('u'== ch) { port_outbyte('U'); } else if('m'== ch) { for(int j=0; j<20; j++) { //printf("S 64MB"); port_outbyte('+'); for(int i=0; i <1024*1024/4; i++) { memcpy((void *)(0x60000000), (void *)0x60010000, 1024*4); } //printf("E 64MB "); } } else if('T'== ch) { while(1) { //delay_us(1); rx_len = port_read(test_rx_buf, rx_block_len, 1); //crc16_ccitt(test_rx_buf,rx_block_len); memcpy(&test_rx_buf[rx_block_len], &test_rx_buf[0], rx_block_len); if(rx_len != rx_block_len) break; #if 0 for(int i=0;i<rx_bulk_len; i++) { if('T'!=test_rx_buf[i]) break; } #endif input_count += rx_block_len; if(0==(input_count&(1024-1))) { //port_outbyte('K'); } if(0==(input_count&(1024*1024-1))) { port_outbyte('M'); } } } } else { delay_us(10); } //sleepmgr_enter_sleep(); } }
void main(void) { u32 rootfs; char *rfs_txt; u32 image = 0; struct jffs2_raw_inode *node, *mfg_node; char *cmdline = 0, *altcmdline = 0; u32 kernel_nand_addr = 0, alt_kernel_nand_addr = 0; int board_id; int done = 0; u32 ret = 0; #ifdef CPU_LF1000 /* disable the USB controller */ BIT_SET(REG16(LF1000_UDC_BASE+UDC_PCR), PCE); #endif adc_init(); board_id = load_board_id(); display_backlight(board_id); clock_init(); db_init(); display_init(); fbcon_init(); db_displaytee(1); db_puts("************************************************\n"); db_puts("* *\n"); db_puts("* OpenDidj lightning-boot 1.1 / 12 Mar 2010 *\n"); db_puts("* *\n"); db_puts("************************************************\n"); db_puts("\n\n"); #ifdef CONFIG_MACH_LF_LF1000 /* now that backlight is on, see if we have enough battery to boot */ if(gpio_get_val(LOW_BATT_PORT, LOW_BATT_PIN) == 0 && ADC_TO_MV(adc_get_reading(LF1000_ADC_VBATSENSE)) < BOOT_MIN_MV){ db_puts("PANIC: battery voltage too low!\n"); die(); } #endif /* CONFIG_MACH_LF_LF1000 */ #ifdef UBOOT_SUPPORT if(((REG32(LF1000_GPIO_BASE+GPIOCPAD) & BUTTON_MSK) == BUTTON_MSK)) { do { db_puts("xmodem download mode\n"); timer_init(); offset = 0; xmodemInit(db_putchar,db_getc_async); tmr_poll_start(2000); db_puts("Switch to 115200 baud and press any button\n"); db_puts("to start XModem download...\n"); /* set the baud rate */ #define UART16(r) REG16(LF1000_SYS_UART_BASE+r) UART16(BRD) = 1; /* FIXME (for now "1" sets 115200 baud , "11" sets 19200 baud) */ UART16(UARTCLKGEN) = ((UARTDIV-1)<<UARTCLKDIV)|(UART_PLL<<UARTCLKSRCSEL); if(tfs_load_summary(sum_buffer, BOOT0_ADDR) != 0) { db_puts("trying BOOT1\n"); if(tfs_load_summary(sum_buffer, BOOT1_ADDR)) { db_puts("u-boot not found\n"); break; } } while (!done) { if (tmr_poll_has_expired()){ if(((REG32(LF1000_GPIO_BASE+GPIOCPAD) & BUTTON_MSK) != BUTTON_MSK)) { db_displaytee(0); ret = xmodemReceive(ubcopy); db_displaytee(1); if ( ret >= 0 ) break; } if (ret == -1) db_puts("XMODEM_ERROR : REMOTECANCEL\n"); if (ret == -2) db_puts("XMODEM_ERROR : OUTOFSYNC\n"); if (ret == -3) db_puts("XMODEM_ERROR : RETRYEXCEED\n"); if ( ret < 0 ) continue; /* db_puts("Loaded : "); db_int(ret); db_puts("bytes\n"); */ } } db_puts("\n\nXModem download complete.\n"); db_puts("Transferring control to U-Boot.\n"); /* jump to u-boot */ ((void (*)( int r0, int r1, int r2))UBOOT_ADDR) (0, MACH_TYPE_LF1000, 0); /* never get here! */ die(); } while(0); } #endif /* UBOOT_SUPPORT */ /* Set up the kernel command line */ /* read entire /flags partition */ nand_read(fs_buffer, BOOT_FLAGS_ADDR, BOOT_FLAGS_SIZE); /* find rootfs file */ node = jffs2_cat((char *)fs_buffer, BOOT_FLAGS_SIZE, "rootfs"); rootfs = RFS0; if(node == 0) { db_puts("warning: failed to find rootfs flags!\n"); } else { rfs_txt = (char*)node+sizeof(struct jffs2_raw_inode)-4; if(!strncmp(rfs_txt, "RFS1", 4)) { db_puts("booting RFS1\n"); rootfs = RFS1; } #ifdef NFS_SUPPORT else if(!strncmp(rfs_txt, "NFS0", 4)) { db_puts("booting NFS0\n"); rootfs = NFS0; } else if(!strncmp(rfs_txt, "NFS1", 4)) { db_puts("booting NFS1\n"); rootfs = NFS1; } #endif /* NFS_SUPPORT */ else { db_puts("booting RFS0\n"); } } /* Find the mfcart file */ mfg_node = jffs2_cat((char *)fs_buffer, BOOT_FLAGS_SIZE, "mfcart"); if(mfg_node != 0) { db_puts("Booting with mfg cartridge layout.\n"); } /* construct the command line */ if(mfg_node == 0) { if(rootfs == RFS0) { cmdline = CMDLINE_BASE CMDLINE_RFS0 CMDLINE_UBI; altcmdline = CMDLINE_BASE CMDLINE_RFS1 CMDLINE_UBI; kernel_nand_addr = BOOT0_ADDR; alt_kernel_nand_addr = BOOT1_ADDR; } else if(rootfs == RFS1) { cmdline = CMDLINE_BASE CMDLINE_RFS1 CMDLINE_UBI; altcmdline = CMDLINE_BASE CMDLINE_RFS0 CMDLINE_UBI; kernel_nand_addr = BOOT1_ADDR; alt_kernel_nand_addr = BOOT0_ADDR; } #ifdef NFS_SUPPORT else if(rootfs == NFS0) { cmdline = CMDLINE_BASE CMDLINE_NFS CMDLINE_UBI; altcmdline = CMDLINE_BASE CMDLINE_NFS CMDLINE_UBI; kernel_nand_addr = BOOT0_ADDR; alt_kernel_nand_addr = BOOT1_ADDR; } else if(rootfs == NFS1) { cmdline = CMDLINE_BASE CMDLINE_NFS CMDLINE_UBI; altcmdline = CMDLINE_BASE CMDLINE_NFS CMDLINE_UBI; kernel_nand_addr = BOOT1_ADDR; alt_kernel_nand_addr = BOOT0_ADDR; } #endif /* NFS_SUPPORT */ } else { if(rootfs == RFS0) { cmdline = CMDLINE_BASE CMDLINE_RFS0 CMDLINE_MFG CMDLINE_UBI; altcmdline = CMDLINE_BASE CMDLINE_RFS1 CMDLINE_MFG CMDLINE_UBI; kernel_nand_addr = BOOT0_ADDR; alt_kernel_nand_addr = BOOT1_ADDR; } else if(rootfs == RFS1) { cmdline = CMDLINE_BASE CMDLINE_RFS1 CMDLINE_MFG CMDLINE_UBI; altcmdline = CMDLINE_BASE CMDLINE_RFS0 CMDLINE_MFG CMDLINE_UBI; kernel_nand_addr = BOOT1_ADDR; alt_kernel_nand_addr = BOOT0_ADDR; } #ifdef NFS_SUPPORT else if(rootfs == NFS0) { cmdline = CMDLINE_BASE CMDLINE_NFS CMDLINE_MFG CMDLINE_UBI; altcmdline = CMDLINE_BASE CMDLINE_NFS CMDLINE_MFG CMDLINE_UBI; kernel_nand_addr = BOOT0_ADDR; alt_kernel_nand_addr = BOOT1_ADDR; } else if(rootfs == NFS1) { cmdline = CMDLINE_BASE CMDLINE_NFS CMDLINE_MFG CMDLINE_UBI; altcmdline = CMDLINE_BASE CMDLINE_NFS CMDLINE_MFG CMDLINE_UBI; kernel_nand_addr = BOOT1_ADDR; alt_kernel_nand_addr = BOOT0_ADDR; } #endif /* NFS_SUPPORT */ } if(tfs_load_summary(sum_buffer, kernel_nand_addr)) { db_puts("warning: booting alternative kernel!\n"); if(tfs_load_summary(sum_buffer, alt_kernel_nand_addr)) { db_puts("PANIC: unable to load alt summary\n"); die(); } } db_stopwatch_start("LOAD KERNEL"); image = load_kernel(cmdline); db_stopwatch_stop(); if(image == 0) { db_puts("Warning: booting alternative kernel!\n"); if(tfs_load_summary(sum_buffer, alt_kernel_nand_addr) != 0) { die(); } image = load_kernel(altcmdline); if(image == 0) { db_puts("PANIC: nothing to boot\n"); die(); } } #ifdef DISPLAY_SUPPORT db_stopwatch_start("SPLASH"); db_puts("Loading bootsplash\n"); tfs_load_file("bootsplash.rgb", (u32 *)FRAME_BUFFER_ADDR); display_init(); db_stopwatch_stop(); #endif load_cart_id(); db_puts("Starting the kernel...\n"); cleanup_for_linux(); /* jump to image (void, architecture ID, atags pointer) */ ((void(*)(int r0, int r1, unsigned int r2))image) (0, MACH_TYPE_LF1000, (unsigned int)params_buffer); /* never get here! */ die(); }
int main(void) { u32 rootfs; u8 *load_address; char *rfs_txt; u32 image = 0; struct jffs2_raw_inode *node, *mfg_node; char *cmdline = 0, *altcmdline = 0; u32 kernel_nand_addr = 0, alt_kernel_nand_addr = 0; int board_id; u32 ret = 0; u32 ret2 = 0; u8 selection = 0; u8 displayOn = 0; unsigned char cSel; #ifdef CPU_LF1000 /* disable the USB controller */ BIT_SET(REG16(LF1000_UDC_BASE+UDC_PCR), PCE); #endif adc_init(); board_id = load_board_id(); display_backlight(board_id); clock_init(); db_init(); #ifdef CONFIG_MACH_LF_LF1000 /* now that backlight is on, see if we have enough battery to boot */ if(gpio_get_val(LOW_BATT_PORT, LOW_BATT_PIN) == 0 && ADC_TO_MV(adc_get_reading(LF1000_ADC_VBATSENSE)) < BOOT_MIN_MV){ display_init(); db_puts("PANIC: battery voltage too low!\n"); guru_med(0xBA77DEAD,0x0BAD0BAD); // die(); } #endif /* CONFIG_MACH_LF_LF1000 */ #ifdef UBOOT_SUPPORT if(((REG32(LF1000_GPIO_BASE+GPIOCPAD) & BUTTON_MSK) == BUTTON_MSK)) { display_init(); displayOn = 1; fbinit(); fbclear(); renderString(5,2,"OpenDidj lightning-boot " LB_VERSION " / " __DATE__ ); renderString(5,4,"Select an option:"); db_puts("OpenDidj lightning-boot " LB_VERSION " / " __DATE__ ); db_puts("\n"); make_crc_table(); timer_init(); offset = 0; // tmr_poll_start(2000); db_puts("Switch to 115200 baud\n"); /* set the baud rate */ UART16(BRD) = 1; /* FIXME (for now "1" sets 115200 baud , "11" sets 19200 baud) */ UART16(UARTCLKGEN) = ((UARTDIV-1)<<UARTCLKDIV)|(UART_PLL<<UARTCLKSRCSEL); // Reggie added for julspower, autoboot if zimage is present on the SD card. ret2 = check_autoboot(&cSel); if ( ret2 == 0 ) { selection=cSel; db_puts("\nAutobooting zImage from SD\n"); goto selection_section; } selection = do_menu(); selection_section: load_address = (u8 *)(UBOOT_ADDR); switch ( selection ) { case 0: goto normal_boot; case 1: goto normal_boot; case 2: goto normal_boot; case 3: xmodemInit(db_putchar,db_getc_async); ret = xmodemReceive(ubcopy); break; case 4: ret = sd_load("u-boot.bin",load_address); break; case 5: ret = sd_load("zImage",load_address); break; case 6: // Reggie added, feature to load lightning-boot.bin from SD // filename *must* be 8.3 or it will fail to load, so lets // make it easy on ourselves and name it lb.bin on the sd load_address = (u8 *)(UBOOT_ADDR2); ret = sd_load("lb.bin",load_address); db_puts("\nLoading Lightning Boot from SD\n"); break; } if ( ret != 0 ) guru_med(selection,ret); db_puts("\nboot jmp\n"); /* jump to u-boot */ ((void (*)( int r0, int r1, int r2))load_address) (0, MACH_TYPE_LF1000, 0); /* never get here! */ guru_med(0x000000F0,0); // die(); } #endif /* UBOOT_SUPPORT */ normal_boot: /* Set up the kernel command line */ /* read entire /flags partition */ nand_read(fs_buffer, BOOT_FLAGS_ADDR, BOOT_FLAGS_SIZE); /* find rootfs file */ node = jffs2_cat((char *)fs_buffer, BOOT_FLAGS_SIZE, "rootfs"); rootfs = RFS0; if(node == 0) { db_puts("warning: failed to find rootfs flags!\n"); } else { rfs_txt = (char*)node+sizeof(struct jffs2_raw_inode)-4; if(!strncmp(rfs_txt, "RFS1", 4)) { db_puts("booting RFS1\n"); // this should be made to use RFS2? rootfs = RFS1; } // Reggie added to check cmdline options, if /flags/rootfs has been set to > RFS1 if (selection==1){ // set to the default SD config just in case the rootfs flag is set for didj(RFS0/1) rootfs = RFS2; db_puts("nand/SD boot\n"); { // if(!strncmp(rfs_txt, "RFS2", 4)) { // db_puts("booting SDRFS\n"); // rootfs = RFS2; // } // else if(!strncmp(rfs_txt, "RFS3", 4)) { if(!strncmp(rfs_txt, "RFS3", 4)) { db_puts("booting nand/SD DEBUG\n"); rootfs = RFS3; } } } #ifdef NFS_SUPPORT else if(!strncmp(rfs_txt, "NFS0", 4)) { db_puts("booting NFS0\n"); rootfs = NFS0; } else if(!strncmp(rfs_txt, "NFS1", 4)) { db_puts("booting NFS1\n"); rootfs = NFS1; } #endif /* NFS_SUPPORT */ else { db_puts("booting RFS0\n"); } } /* Find the mfcart file */ mfg_node = jffs2_cat((char *)fs_buffer, BOOT_FLAGS_SIZE, "mfcart"); if(mfg_node != 0) { db_puts("Booting with mfg cartridge layout.\n"); } else { // Reggie added, setup for custom command line read from /flags/cmdline // try and keep some sanity for the mfcart flag to trump everything, not // sure we really need to worry about the carts at all and could remove // the code? same with the NFS support, although that might come with // future developments if (selection == 2){ rootfs = RFS4; } } /* construct the command line */ if(mfg_node == 0) { if(rootfs == RFS0) { cmdline = CMDLINE_BASE CMDLINE_RFS0 CMDLINE_UBI; altcmdline = CMDLINE_BASE CMDLINE_RFS1 CMDLINE_UBI; kernel_nand_addr = BOOT0_ADDR; alt_kernel_nand_addr = BOOT1_ADDR; } else if(rootfs == RFS1) { cmdline = CMDLINE_BASE CMDLINE_RFS1 CMDLINE_UBI; altcmdline = CMDLINE_BASE CMDLINE_RFS0 CMDLINE_UBI; // Reggie changed, we want to boot the kernel from // kernel0 but the rootfs from RFS1 kernel_nand_addr = BOOT0_ADDR; alt_kernel_nand_addr = BOOT0_ADDR; } // Reggie added, just a copy of the RFS1 boot commands. // the kernel that boots the SD rootfs should be burnt // to kernel1 partition, this way if the SD kernel fails // it will fall back to booting the original kernel0/RFS0 // well, in theory // both RFS2/3 functions boot from the same kernel parition(kernel1) // and the same SD partition (mmcpblk0p2, ext3) // so alt_/kernel_nand_addr are set to BOOT1_ADDR, altcmdline falls // back to the other SD based RFS option else if(rootfs == RFS2) { cmdline = CMDLINE_BASE CMDLINE_RFS2 CMDLINE_UBI; altcmdline = CMDLINE_BASE CMDLINE_RFS3 CMDLINE_UBI; kernel_nand_addr = BOOT1_ADDR; alt_kernel_nand_addr = BOOT1_ADDR; } else if(rootfs == RFS3) { cmdline = CMDLINE_BASE CMDLINE_RFS3 CMDLINE_UBI; altcmdline = CMDLINE_BASE CMDLINE_RFS2 CMDLINE_UBI; kernel_nand_addr = BOOT1_ADDR; alt_kernel_nand_addr = BOOT1_ADDR; } // Reggie also added this, code to read custom cmdline from // a file called "cmdline" on the vfat SD partition, mmcblk0p1 else if (rootfs == RFS4){ // look for cmdline in the root of the vfat partition on the // uSD card and load the contents into cmdline_txt cmdline_load("cmdline", (u8 *)cmdline_txt); db_puts(cmdline_txt); cmdline = (char *)cmdline_txt; altcmdline = CMDLINE_BASE CMDLINE_RFS2 CMDLINE_UBI; // always boot the explorer kernel (BOOT1_ADDR) no matter // how the cmdline is constructed kernel_nand_addr = BOOT1_ADDR; alt_kernel_nand_addr = BOOT1_ADDR; } #ifdef NFS_SUPPORT else if(rootfs == NFS0) { cmdline = CMDLINE_BASE CMDLINE_NFS CMDLINE_UBI; altcmdline = CMDLINE_BASE CMDLINE_NFS CMDLINE_UBI; kernel_nand_addr = BOOT0_ADDR; alt_kernel_nand_addr = BOOT1_ADDR; } else if(rootfs == NFS1) { cmdline = CMDLINE_BASE CMDLINE_NFS CMDLINE_UBI; altcmdline = CMDLINE_BASE CMDLINE_NFS CMDLINE_UBI; kernel_nand_addr = BOOT1_ADDR; alt_kernel_nand_addr = BOOT0_ADDR; } #endif /* NFS_SUPPORT */ } if(tfs_load_summary(sum_buffer, kernel_nand_addr)) { db_puts("warning: booting alternative kernel!\n"); if(tfs_load_summary(sum_buffer, alt_kernel_nand_addr)) { db_puts("PANIC: unable to load alt summary\n"); guru_med(0xA0000000,1); //die(); } } db_stopwatch_start("LOAD KERNEL"); if (rootfs==RFS4){ db_puts("RFS4 loading\n"); image = load_kernel(cmdline); } else{ db_puts("normal cmdline\n"); db_puts(cmdline); image = load_kernel(cmdline); } db_stopwatch_stop(); if(image == 0) { db_puts("Warning: booting alternative kernel!\n"); if(tfs_load_summary(sum_buffer, alt_kernel_nand_addr) != 0) { guru_med(0xA0000000,2); //die(); } image = load_kernel(altcmdline); if(image == 0) { db_puts("PANIC: nothing to boot\n"); guru_med(0xA0000000,3); //die(); } } #ifdef DISPLAY_SUPPORT db_stopwatch_start("SPLASH"); db_puts("Loading bootsplash\n"); tfs_load_file("bootsplash.rgb", (u32 *)FRAME_BUFFER_ADDR); if ( !displayOn ) display_init(); mlc_set_video_mode(); //display_init(); db_stopwatch_stop(); #endif load_cart_id(); db_puts("Starting kernel...\n"); cleanup_for_linux(); /* jump to image (void, architecture ID, atags pointer) */ ((void(*)(int r0, int r1, unsigned int r2))image) (0, MACH_TYPE_LF1000, (unsigned int)params_buffer); /* never get here! */ guru_med(0x000000F0,0); //die(); }