mips架构uboot 启动流程分析

1, uboot启动的第一个阶段 :bootcode/btcode_vg/start.h

复制代码
#ifdef CONFIG_NONO_COMPRESS
        #define	BOOT_ADDR		0xA0000000    // no compress
#else
        #define	BOOT_ADDR		0x80100000	//compress
#endif

// Using register: t6, t7           //wei add this code
#define IF_EQ(a,b,lab)          or t6,zero,a;\
                                or t7,zero,b;\
                                beq t6,t7,lab;\
                                nop;

#define IF_NEQ(a,b,lab)         or t6,zero,a;\
                                or t7,zero,b;\
                                bne t6,t7,lab;\
                                nop;

#define  ADDR   0xA0380000
	#define  PATT0  0x5a0000a5
	#define  PATT1  0xA5A55A5A
	#define  PATT2  0x005AA500
	#define  PATT3  0xA5A55A5A
	#define  PATT4  0xAAAAAAAA
	#define  PATT5  0xffffffff
	#define  PATT6  0x00000000
	#define  PATT7  0x00000000
	#define  PATT8  0xffffffff
	#define CLK_MANAGER 0xb8000010
	#define DCR 0xb8001004


#define DRAM_DDR2 1
	#define DRAM_DDR3 2

	#define GET_BITVAL(v,bitpos,pat) ((v& ((unsigned int)pat<<bitpos))>>bitpos)
	#define RANG1 1
	#define RANG2 3
	#define RANG3  7
	#define RANG4 0xf		
	#define RANG5 0x1f	
	
	#define SYS_HW_STRAP   (0xb8000000 +0x08)	

#define SRAM_REG_SET_SIZE	(0x10)
#define SRAM_REG_SET_NUM	(4)
#define SRAM_REG_BASE_ADDR	(0xB8004000)

#define C0SRAMSAR_REG_ADDR	(SRAM_REG_BASE_ADDR + 0x0)
#define C0SRAMSSR_REG_ADDR	(SRAM_REG_BASE_ADDR + 0x4)
#define C0SRAMSBR_REG_ADDR	(SRAM_REG_BASE_ADDR + 0x8)

#define C1SRAMSAR_REG_ADDR	(SRAM_REG_BASE_ADDR + 0x40)
#define C1SRAMSSR_REG_ADDR	(SRAM_REG_BASE_ADDR + 0x44)
#define C1SRAMSBR_REG_ADDR	(SRAM_REG_BASE_ADDR + 0x48)

#define SRAM_SEG_ENABLE		(0x1)

#define SRAM_SIZE_256B		(0x1)
#define SRAM_SIZE_512B		(0x2)
#define SRAM_SIZE_1KB		(0x3)
#define SRAM_SIZE_2KB		(0x4)
#define SRAM_SIZE_4KB		(0x5)
#define SRAM_SIZE_8KB		(0x6)
#define SRAM_SIZE_16KB		(0x7)
#define SRAM_SIZE_32KB		(0x8)
#define SRAM_SIZE_64KB		(0x9)
#define SRAM_SIZE_128KB		(0xA)
#define SRAM_SIZE_256KB		(0xB)
#define SRAM_SIZE_512KB		(0xC)
#define SRAM_SIZE_1MB		(0xD)

bootcode/btcode_vg/start.S

复制代码
#include <asm/asm.h>
#include <regdef.h>
#include <asm/mipsregs.h>
#include "start.h"
#include "../autoconf.h"

#define CONFIG_CACHE_INIT

#define CONFIG_SYS_ROM_CACHE_BASE_ADDR      0x9FD00000
#define CONFIG_SYS_SRAM_CACHE_BASE_ADDR     0x9FE00000
#define CONFIG_SYS_ROM_NONCACHE_BASE_ADDR   0xBFD00000
#define CONFIG_SYS_SRAM_NONCACHE_BASE_ADDR  0xBFE00000
#define CONFIG_SYS_ROM_PHY_BASE_ADDR        0x1FD00000
#define CONFIG_SYS_SRAM_PHY_BASE_ADDR       0x1FE00000

#define CONFIG_SYS_INIT_SP_OFFSET	        0x4000

/* cache */
#define INDEX_INVALIDATE_I      			0x00
#define INDEX_WRITEBACK_INV_D   			0x01
#define START_ADDR 							0x80000000
#define CONFIG_SYS_CACHELINE_SIZE 			32
#define _ICACHE_SIZE						(64 * 1024)		
#define _DCACHE_SIZE						(32 * 1024)		

		.text
		.set noreorder
		.globl __start
__start:

		j 	reset
		nop     
		nop

reset:
	nop
	nop
	nop                                 
 	REG32_ANDOR(0xb8000010,~(1<<11),0); 
 	nop                                 
 	nop                                 
	nop
	nop
	REG32_W(0xb8000014, ((1<<8)|(1<<4))); //enable uart
	nop
	
#ifndef CONFIG_DECREASE_BOOTSIZE
	#if 1
		jal uart_show    //show boot msg
		nop
	#endif
#endif
	
	/* Clear watch registers */
	mtc0	zero, CP0_WATCHLO
	mtc0	zero, CP0_WATCHHI

	/* WP(Watch Pending), SW0/1 should be cleared */
	mtc0	zero, CP0_CAUSE

	mfc0	t0, CP0_STATUS
	or	t0, ST0_CU0 | 0x1f  
	xor	t0, 0x1f 
	mtc0	t0, CP0_STATUS
	.set	noreorder
	sll	zero, 3				# ehb

	/* Init Timer */
	mtc0	zero, CP0_COUNT
	mtc0	zero, CP0_COMPARE

#ifdef CONFIG_CACHE_INIT
	nop
	li	t7, 0xb8000008
	lw	t6, 0(t7)
	and	t6,t6,0x0F
	li	t7, 0x01
	beq	t6,t7, cache_init_end
	nop

	/* CONFIG0 register */
	mfc0 t0, CP0_CONFIG
	li	t1,~CONF_CM_CMASK
	and	t0,t0,t1
	ori	t0,t0,CONF_CM_UNCACHED
	mtc0	t0,CP0_CONFIG

	/* processor ID */
	mfc0		k1, C0_PRId
	li      t0, M_PRIdImp | M_PRIdCoID
	and     k1, t0

	/* Initialize caches... */
	la	t9, sys_init_cache
	jalr	t9
	 nop

	/* ... and enable them */
	mfc0 t0, CP0_CONFIG
	li	t1,~CONF_CM_CMASK
	and	t0,t0,t1
	ori	t0,t0,CONF_CM_CACHABLE_NONCOHERENT
	mtc0	t0,CP0_CONFIG
	
cache_init_end:
#endif

//------------------------------------------------	 	

//============================================================================
	//UART_WRITE('G');
#ifndef CONFIG_NAND_FLASH_BOOTING
	/* Set up temporary stack */
	/* spi flash do ddr init here */
	li  sp, (CONFIG_SYS_SRAM_CACHE_BASE_ADDR + CONFIG_SYS_INIT_SP_OFFSET - 0x20)
	nop
	jal start_c
#endif
	nop
    nop

//--------------------------------------------------------------------------------
flash2ram:
// Load to 80100000 for compress
// Load to 80000000 for non-compress

		la		k0, __boot_start
		la		k1, (__boot_end + 4)
		la		t1, BOOT_ADDR
1:
		#if 0
		jal SPI_show    //show SPI msg
		nop
		#endif
		
		lw		t0, 0(k0)
		nop
		sw		t0, 0(t1)	//*(t1)=*(t0)   t1+=4;  t0+=4;   t1=BOOT_ADDR, t0=__boot_start, run loop
		nop
		addu	t1, 4
		addu	k0, 4
		bne		k1, k0, 1b
		nop

//		UART_PRINT_DELAY(SPI_done_msg);
		/* flush dcache */
		li a0,	(START_ADDR+_DCACHE_SIZE)
		li a1,	START_ADDR
2:		
		cache 	INDEX_WRITEBACK_INV_D,0(a1)
		nop
		addu	a1,	CONFIG_SYS_CACHELINE_SIZE
		bne		a1,a0,2b
		nop


		/* invalid icache */
		li a0,	(START_ADDR+_ICACHE_SIZE)
		li a1,	START_ADDR
3:
		cache	INDEX_INVALIDATE_I,0(a1)
		nop
		addu 	a1,CONFIG_SYS_CACHELINE_SIZE
		bne		a1,a0,3b
		nop

		//		Jump to booting
		li		k0, BOOT_ADDR
		jr		k0
		nop 
              //all END
	
//--------------------------------------------------------------------------------	

boot_msg:	.ascii "\r\nBooting...\r\n\0"
SPI_done_msg:  .ascii "\r\nSPI image move done ->Jump to DRAM\r\n\0"
SPI_msg:  .ascii "\r\n.\0"
#endif

//==========================================================================

CPU上电 (0xBFCO0000)

reset: 基本硬件初始化,CPU初始化

缓存初始化,初始化DDR

设置栈指针,从SPI Flash拷贝代码到DDR,刷新缓存

jal start_c ← 调用第二阶段C代码

(第二阶段代码执行DDR初始化等)

返回后执行flash2ram, 更完整的外设初始化;

从Flash复制到RAM

跳转到RAM执行

bootcode\btcode_vg\start_c.c

复制代码
void start_c(void)
{
	EFUSE_DATA efuse_data;
	u1Byte dram_type_idx, dram_freq_idx;
	u4Byte strap_pin;
	u4Byte dram_val, cpu_freq;
	// (dram_type, dram_freq)
	// 0,0 => DDR2 400 MHz
	// 0,1 => DDR2 533 MHz
	// 1,0 => DDR1 200 MHz
	// 1,1 => DDR1 250 MHz
	u4Byte dram_table[2][2] = {{400, 533}, {200, 250}};

	//modify OCP_L to 0x000 1170mA
	REG32(0xb8000260) = REG32(0xb8000260) & (~(1<<31));
	REG32(0xb8000264) = REG32(0xb8000264) & (~3);
	REG32(0xb80002c8) = ( REG32(0xb80002c8) & (~3)| 0x2 );
#ifdef CONFIG_RTL_8197F_VG
	REG32(0xb800311c) = 0xa5600000;  //disable watcdog
#endif

#ifdef CONFIG_ESD_SUPPORT
	REG32(BSP_CDBR)=(BSP_DIVISOR) << BSP_DIVF_OFFSET;
        REG32(BSP_TC0DATA) = (((BSP_SYS_CLK_RATE/BSP_DIVISOR)/HZ)) << 4;
        REG32(0xb800311c)=0x00600000;
	/*For DDR3 must , for DDR2 safe*/
#endif
#if defined(CONFIG_SW_8367R) || defined(CONFIG_SW_83XX)
       REG32(BSP_PIN_MUX_SEL3) = (REG32(BSP_PIN_MUX_SEL3) & ~(3<<30)) | (0x3<<30);
        REG32(BSP_PEFGH_CNR) &= (~(0x00000040));
        REG32(BSP_PEFGH_DIR) |= (0x00000040);
                        REG32(BSP_PEFGH_DAT) &= (~(0x00000040));
#endif

	_memctl_debug_printf("\n8197F Cstart\n");

	timer_init();
	strap_pin = REG32(REG_HW_STRAP);
	cpu_freq = get_cpu_freq(strap_pin);
	// dram_type:  0: DDR2, 1:DDR1
	dram_type_idx = BIT_GET_STRAP_PIN_DRAM_TYPE_INV(strap_pin);
	//printf("*pdram_type_idx:%d\n",*pdram_type_idx);
	if ((strap_pin & BIT_STRAP_PIN_HW_DBG_DISABLE) == BIT_STRAP_PIN_HW_DBG_DISABLE) {
		dram_freq_idx = BIT_GET_STRAP_PIN_DRAM_FEQ(strap_pin);
		//printf("1111 *pdram_freq_idx:%d\n",*pdram_freq_idx);
	} else { // HW_DBG_DISABLE == 0
		dram_freq_idx = 0;
	}

	switch (REG32(0xB800000C) & 0x0F) {
                case 0x06:
                case 0x0C:
                        dram_val =  32;
                        break;
                case 0x04:
                case 0x0A:
                        dram_val =  64;
                        break;
                case 0x05:
                case 0x0B:
                        dram_val =  128;
                        break;
                default:
#ifdef CONFIG_DRAM_SIZE
                        dram_val = CONFIG_DRAM_SIZE_IN_MB;
#else
                        //dram_val = 32;
        //                dram_val = REG32(0xB8000F00); // auto detect
			dram_val = 0;
#endif
		break;
        }
        REG32(0xB8000F00) = dram_val;


	memset(&efuse_data, 0, sizeof(EFUSE_DATA));
#ifdef CONFIG_RTL_8197F_VG
	rtl8197f_vg_calibration();
#endif
	init_ram(strap_pin, dram_type_idx, dram_freq_idx, &efuse_data);

	dram_val = REG32(0xB8000F00);

	if (dram_type_idx == 0)
		printf("\nDRAM Type: DDR2\n");
	else
		printf("\nDRAM Type: DDR1\n");

	/*#ifdef CONFIG_CPU_1G_DDR2_533M
	printf("\tDRAM frequency: 533MHz\n");
	#elif defined(CONFIG_CPU_800M_DDR2_400M)
	printf("\tDRAM frequency: 400MHz\n");
	#elif defined(CONFIG_CPU_600M_DDR2_200M)
	printf("\tDRAM frequency: 200MHz\n");
	#else*/
	printf("\tDRAM frequency: %dMHz\n", dram_table[dram_type_idx][dram_freq_idx]);
	//#endif

/*	switch (REG32(0xB800000C) & 0x0F) {
		case 0x06:
		case 0x0C:
			dram_val =  32;
			break;
		case 0x04:
		case 0x0A:
			dram_val =  64;
			break;
		case 0x05:
		case 0x0B:
			dram_val =  128;
			break;
		default:
#ifdef CONFIG_DRAM_SIZE
			dram_val = CONFIG_DRAM_SIZE_IN_MB;
#else
			//dram_val = 32;
			dram_val = REG32(0xB8000F00); // auto detect
#endif
	}
	REG32(0xB8000F00) = dram_val;*/
	printf("\tDRAM Size: %dMB\n", dram_val);
	REG32(0xb8000850) =  REG32(0xb8000850) & (~(1<<7));
}

2,uboot启动的第二个阶段,编译后查看head.o->boot/arch/mips/kernel/head.S

复制代码
1:
        sw zero, 0(t0)
        addi t0, 4
        bne t0, s1, 1b
        nop
        nop

        jal     init_arch                                                 
        nop  
        nop

init_arch ->boot\arch\mips\kernel\setup.c

复制代码
asmlinkage void init_arch(int argc, char **argv, char **envp, int *prom_vec)
{
	//init_icache();
	//init_icache();		
	
	init_cpu_config();	

   // start_kernel();
	jmp_func_t *jmp;
   	extern void start_kernel(void);

	//jmp=((int)start_kernel)& ~UNCACHE_MASK;
	jmp = (jmp_func_t *)(((int)start_kernel)& ~UNCACHE_MASK);
	jmp();
}

直接uboot跳转kernel的代码:

复制代码
void start_kernel(void)
{
	int ret;

	gCHKKEY_HIT = 0;
	gCHKKEY_CNT = 0;

	IMG_HEADER_T header;
	SETTING_HEADER_T setting_header;
#ifdef MTN_NORMAL_IPV6_Haier
        RTL_W32(BSP_LED_R_PIN_MUX_SEL, 
			(RTL_R32(BSP_LED_R_PIN_MUX_SEL) 
			& ~(BSP_LED_R_PIN_MASK) | (BSP_LED_R_PIN_MUX)));
    
    // RTL_W32(BSP_LED_R_PIN_MUX_SEL,1); 
	/* turn on gpio pin */
	RTL_W32(BSP_GPIO_CNR_REG(BSP_LED_R_PIN), 
			(RTL_R32(BSP_GPIO_CNR_REG(BSP_LED_R_PIN)) 
			& (~(1 << BSP_GPIO_BIT(BSP_LED_R_PIN)))));
	/* set gpio as output */
	RTL_W32(BSP_GPIO_DIR_REG(BSP_LED_R_PIN), (RTL_R32(BSP_GPIO_DIR_REG(BSP_LED_R_PIN)) | (1 << BSP_GPIO_BIT(BSP_LED_R_PIN))));


    RTL_W32(BSP_LED_G_PIN_MUX_SEL, 
			(RTL_R32(BSP_LED_G_PIN_MUX_SEL) 
			& ~(BSP_LED_G_PIN_MASK) | (BSP_LED_G_PIN_MUX))); 
	/* turn on gpio pin */
	RTL_W32(BSP_GPIO_CNR_REG(BSP_LED_G_PIN), 
			(RTL_R32(BSP_GPIO_CNR_REG(BSP_LED_G_PIN)) 
			& (~(1 << BSP_GPIO_BIT(BSP_LED_G_PIN)))));
	/* set gpio as output */
	RTL_W32(BSP_GPIO_DIR_REG(BSP_LED_G_PIN), (RTL_R32(BSP_GPIO_DIR_REG(BSP_LED_G_PIN)) | (1 << BSP_GPIO_BIT(BSP_LED_G_PIN))));

    RTL_W32(BSP_LED_R_PIN_MUX_SEL, 
			(RTL_R32(BSP_LED_R_PIN_MUX_SEL) 
			& ~(BSP_LED_R_PIN_MASK) | (BSP_LED_R_PIN_MUX)));
    
    // RTL_W32(BSP_LED_R_PIN_MUX_SEL,1); 
	/* turn on gpio pin */
	RTL_W32(BSP_GPIO_CNR_REG(BSP_LED_R_PIN), 
			(RTL_R32(BSP_GPIO_CNR_REG(BSP_LED_R_PIN)) 
			& (~(1 << BSP_GPIO_BIT(BSP_LED_R_PIN)))));
	/* set gpio as output */
	RTL_W32(BSP_GPIO_DIR_REG(BSP_LED_R_PIN), (RTL_R32(BSP_GPIO_DIR_REG(BSP_LED_R_PIN)) | (1 << BSP_GPIO_BIT(BSP_LED_R_PIN))));


    RTL_W32(BSP_LED_G_PIN_MUX_SEL, 
			(RTL_R32(BSP_LED_G_PIN_MUX_SEL) 
			& ~(BSP_LED_G_PIN_MASK) | (BSP_LED_G_PIN_MUX))); 
	/* turn on gpio pin */
	RTL_W32(BSP_GPIO_CNR_REG(BSP_LED_G_PIN), 
			(RTL_R32(BSP_GPIO_CNR_REG(BSP_LED_G_PIN)) 
			& (~(1 << BSP_GPIO_BIT(BSP_LED_G_PIN)))));
	/* set gpio as output */
	RTL_W32(BSP_GPIO_DIR_REG(BSP_LED_G_PIN), (RTL_R32(BSP_GPIO_DIR_REG(BSP_LED_G_PIN)) | (1 << BSP_GPIO_BIT(BSP_LED_G_PIN))));   
    
    Set_LED_R_ON();
    Set_LED_G_OFF();
    
    mdelay(1000);
    
    Set_LED_R_OFF();
    Set_LED_G_ON();
    mdelay(1000);

    Set_LED_R_ON();
    Set_LED_G_OFF();
    mdelay(1000);

    Set_LED_R_OFF();
    Set_LED_G_ON();
    mdelay(1000);

    Set_LED_G_ON();
    Set_LED_R_OFF();
#else
	/* set pin mux as gpio */
	RTL_W32(BSP_POWER_LED_PIN_MUX_SEL, 
			(RTL_R32(BSP_POWER_LED_PIN_MUX_SEL) 
			& ~(BSP_POWER_LED_PIN_MASK) | (BSP_POWER_LED_PIN_MUX))); 
	/* turn on gpio pin */
	RTL_W32(BSP_GPIO_CNR_REG(BSP_POWER_LED_PIN), 
			(RTL_R32(BSP_GPIO_CNR_REG(BSP_POWER_LED_PIN)) 
			& (~(1 << BSP_GPIO_BIT(BSP_POWER_LED_PIN)))));
	/* set gpio as output */
	RTL_W32(BSP_GPIO_DIR_REG(BSP_POWER_LED_PIN), 
			(RTL_R32(BSP_GPIO_DIR_REG(BSP_POWER_LED_PIN)) 
			| (1 << BSP_GPIO_BIT(BSP_POWER_LED_PIN))));
	/* set data */
	/* led on */
	RTL_W32(BSP_GPIO_DAT_REG(BSP_POWER_LED_PIN), 
			(RTL_R32(BSP_GPIO_DAT_REG(BSP_POWER_LED_PIN)) 
			| (0 << BSP_GPIO_BIT(BSP_POWER_LED_PIN))));
	mdelay(1000);
	/* led off */
	RTL_W32(BSP_GPIO_DAT_REG(BSP_POWER_LED_PIN), 
			(RTL_R32(BSP_GPIO_DAT_REG(BSP_POWER_LED_PIN)) 
			| (~(0 << BSP_GPIO_BIT(BSP_POWER_LED_PIN)))));
	mdelay(1000);
	/*second led on */
	RTL_W32(BSP_GPIO_DAT_REG(BSP_POWER_LED_PIN), 
			(RTL_R32(BSP_GPIO_DAT_REG(BSP_POWER_LED_PIN)) 
			& (0 << BSP_GPIO_BIT(BSP_POWER_LED_PIN))));
    #endif
//-------------------------------------------------------
	setClkInitConsole();

	initHeap();
		
	initInterrupt();

	initFlash();
	
	#ifdef CONFIG_I2C_POLLING
	initI2C();
	#endif

	#ifdef CONFIG_PCIE_INIT
	initPCIE();
	#endif

#ifdef CONFIG_CRYPTO_DEV_REALTEK
	rtl_crypto_init();
#endif
	//Init_GPIO();				
	//MxSpdupThanLexra();  //wei add

#if defined(CONFIG_POST_ENABLE)
	ret = POSTRW_API();
#endif
  	/*
	FullAndSemiReset();
        rtl8651_restartAsicEthernetPHYNway(1,1);
        rtl8651_restartAsicEthernetPHYNway(2,2);
        rtl8651_restartAsicEthernetPHYNway(3,3);
        rtl8651_restartAsicEthernetPHYNway(4,4);
	*/

	showBoardInfo();

#if defined(CONFIG_POST_ENABLE)
	if(ret == 0)
		return;
#endif

#ifdef CONFIG_BOOT_RESET_ENABLE	
	/* set pin mux as gpio */
	RTL_W32(BSP_RESET_BTN_PIN_MUX_SEL, 
			(RTL_R32(BSP_RESET_BTN_PIN_MUX_SEL) 
			& ~(BSP_RESET_BTN_PIN_MASK) | (BSP_RESET_BTN_PIN_MUX))); 
	/* turn on gpio pin */
	RTL_W32(BSP_GPIO_CNR_REG(BSP_RESET_BTN_PIN), 
			(RTL_R32(BSP_GPIO_CNR_REG(BSP_RESET_BTN_PIN)) 
			& (~(1 << BSP_GPIO_BIT(BSP_RESET_BTN_PIN)))));
	/* set gpio as input */
	RTL_W32(BSP_GPIO_DIR_REG(BSP_RESET_BTN_PIN), 
			(RTL_R32(BSP_GPIO_DIR_REG(BSP_RESET_BTN_PIN)) 
			& (~(1 << BSP_GPIO_BIT(BSP_RESET_BTN_PIN)))));
#endif

	#if 0
	DDR_short_ZQ();
	#endif

	#if 0
	#define REG32(reg)		(*(volatile unsigned int   *)(reg))
	REG32(0xb8010000)|=(3<<28); //set b8010000 bit 29-28=0b11 (burst size = 128 bytes)//0xf4000000
	#endif

#if 1 //defined(CONFIG_RTL8197F) && (defined (CONFIG_SW_8367R) || defined (CONFIG_SW_83XX)) && defined(CONFIG_LAN_WAN_ISOLATION)
	//init_97f_8367r();
	if (swCore_init()) {  	
		dprintf("\nSwitch core initialization failed!\n");        
		return;
	}
#elif defined(CONFIG_RTL8197F) && (defined (CONFIG_SW_8367R) || defined (CONFIG_SW_83XX))
	//pull low for 8367R
	#define GPIO_RESET				26		// GPIO_H2
	REG32(PIN_MUX_SEL14) = (REG32(PIN_MUX_SEL14) & ~(0xF<<28)) | (2<<28);
	REG32(PEFGHCNR) &= ~(1<<GPIO_RESET);
	REG32(PEFGHDIR) |= (1<<GPIO_RESET);
	// for 8367r h/w reset pin	
	REG32(PEFGHDAT) &= ~(1<<GPIO_RESET);	
#endif	

#ifdef SUPPORT_TFTP_CLIENT
	extern volatile unsigned int last_sent_time;
	extern unsigned int tftp_from_command;
	extern int retry_cnt;
	retry_cnt = 0;
	tftp_from_command  = 0;
	last_sent_time  = 0;
	eth_startup(0); 
	sti();			
	tftpd_entry(1);
#endif

	return_addr=0;
	//ret=check_image	(&header,&setting_header);
	ret = 1;		//do check_image() after detect ESC!!!

#if defined(CONFIG_NAND_FLASH_BOOTING)
 	#define MAX_MOUNT_ROOTFS_TIMES	5
	if(REG32(0xb8019004) > MAX_MOUNT_ROOTFS_TIMES){
		REG32(0xb8019004) = 0;
		ret = 0;
	}
#endif

#ifdef CONFIG_SD_CARD_BOOTING
	ret=1;
#endif
	
	doBooting(ret, return_addr, &header);
}
相关推荐
陌上花开缓缓归以9 小时前
W25N01KVZEIR flash烧写
arm开发
牛奶10 小时前
《前端架构设计》:除了写代码,我们还得管点啥
前端·架构·设计
苏渡苇11 小时前
Java + Redis + MySQL:工业时序数据缓存与持久化实战(适配高频采集场景)
java·spring boot·redis·后端·spring·缓存·架构
麦聪聊数据11 小时前
如何用 B/S 架构解决混合云环境下的数据库连接碎片化难题?
运维·数据库·sql·安全·架构
2的n次方_12 小时前
CANN HCOMM 底层架构深度解析:异构集群通信域管理、硬件链路使能与算力重叠优化机制
架构
技术传感器12 小时前
大模型从0到精通:对齐之心 —— 人类如何教会AI“好“与“坏“ | RLHF深度解析
人工智能·深度学习·神经网络·架构
小北的AI科技分享13 小时前
万亿参数时代:大语言模型的技术架构与演进趋势
架构·模型·推理
一条咸鱼_SaltyFish16 小时前
从零构建个人AI Agent:Node.js + LangChain + 上下文压缩全流程
网络·人工智能·架构·langchain·node.js·个人开发·ai编程
码云数智-园园16 小时前
解决 IntelliJ IDEA 运行 Spring Boot 测试时“命令行过长”错误
架构
AC赳赳老秦17 小时前
虚拟化技术演进:DeepSeek适配轻量级虚拟机,实现AI工作负载高效管理
人工智能·python·架构·数据挖掘·自动化·数据库架构·deepseek