五、基础初始化(init_sequence)

news/2024/5/5 2:46:32/文章来源:https://blog.csdn.net/liutit/article/details/130034442

初始化序列数组

# < lib_arm\board.c >

init_fnc_t *init_sequence[] = {

board_init, /* basic board dependent setup */

timer_init, /* initialize timer */

env_init, /* initialize environment */

init_baudrate, /* initialze baudrate settings */

serial_init, /* serial communications setup */

console_init_f, /* stage 1 init of console */

display_banner, /* say that we are here */

dram_init, /* configure available RAM banks */

arm_pci_init,

display_dram_config,

NULL,

};

初始化函数

board_init(基础板级初始化)

# < board\vbird\mini2440\mini2440.c >

int board_init (void)

{

struct s3c24x0_clock_power * const clk_power = s3c24x0_get_base_clock_power();

struct s3c24x0_gpio * const gpio = s3c24x0_get_base_gpio();

/* to reduce PLL lock time, adjust the LOCKTIME register */

clk_power->LOCKTIME = 0xFFFFFF;

/* configure MPLL */

clk_power->MPLLCON = ((M_MDIV << 12) + (M_PDIV << 4) + M_SDIV);

/* some delay between MPLL and UPLL */

delay (4000);

/* configure UPLL */

clk_power->UPLLCON = ((U_M_MDIV << 12) + (U_M_PDIV << 4) + U_M_SDIV);

/* some delay between MPLL and UPLL */

delay (8000);

/* set up the I/O ports */

gpio->GPACON = 0x007FFFFF;

gpio->GPBCON = 0x00044555;

gpio->GPBUP = 0x000007FF;

gpio->GPCCON = 0xAAAAAAAA;

gpio->GPCUP = 0x0000FFFF;

gpio->GPDCON = 0xAAAAAAAA;

gpio->GPDUP = 0x0000FFFF;

gpio->GPECON = 0xAAAAAAAA;

gpio->GPEUP = 0x0000FFFF;

gpio->GPFCON = 0x000055AA;

gpio->GPFUP = 0x000000FF;

gpio->GPGCON = 0xFF95FFBA;

gpio->GPGUP = 0x0000FFFF;

gpio->GPHCON = 0x002AFAAA;

gpio->GPHUP = 0x000007FF;

/* arch number of SMDK2410-Board */

gd->bd->bi_arch_number = MACH_TYPE_MINI2440;

/* adress of boot parameters */

gd->bd->bi_boot_params = 0x30000100;

icache_enable();

dcache_enable();

return 0;

}

获取时钟设置结构体

# < include\s3c2410.h >

#define S3C24X0_CLOCK_POWER_BASE 0x4C000000

static inline struct s3c24x0_clock_power *s3c24x0_get_base_clock_power(void)

{

return (struct s3c24x0_clock_power *)S3C24X0_CLOCK_POWER_BASE;

}

说明:

LOCKTIME 0x4C000000    //MPLL设置之后频率不稳定影响FCLK,所有会将FCLK锁定一地段时间

MPLLCON 0x4C000004    //MPLL锁相环控制器,控制着FCLK的频率

UPLLCON 0x4C000008    //UPLL锁相环控制器,控制着UCKL频率,USB的时钟频率

CLKCON 0x4C00000C    //不同模块的时钟使能控制器

CLKSLOW 0x4C000010  

CLKDIVN 0x4C000014

CAMDIVN 0x4C000018

初始化序列数组

# < lib_arm\board.c >

init_fnc_t *init_sequence[] = {

board_init, /* basic board dependent setup */

timer_init, /* initialize timer */

env_init, /* initialize environment */

init_baudrate, /* initialze baudrate settings */

serial_init, /* serial communications setup */

console_init_f, /* stage 1 init of console */

display_banner, /* say that we are here */

dram_init, /* configure available RAM banks */

arm_pci_init,

display_dram_config,

NULL,

};

初始化函数

board_init(基础板级初始化)

# < board\vbird\mini2440\mini2440.c >

int board_init (void)

{

struct s3c24x0_clock_power * const clk_power = s3c24x0_get_base_clock_power();

struct s3c24x0_gpio * const gpio = s3c24x0_get_base_gpio();

/* to reduce PLL lock time, adjust the LOCKTIME register */

clk_power->LOCKTIME = 0xFFFFFF;

/* configure MPLL */

clk_power->MPLLCON = ((M_MDIV << 12) + (M_PDIV << 4) + M_SDIV);

/* some delay between MPLL and UPLL */

delay (4000);

/* configure UPLL */

clk_power->UPLLCON = ((U_M_MDIV << 12) + (U_M_PDIV << 4) + U_M_SDIV);

/* some delay between MPLL and UPLL */

delay (8000);

/* set up the I/O ports */

gpio->GPACON = 0x007FFFFF;

gpio->GPBCON = 0x00044555;

gpio->GPBUP = 0x000007FF;

gpio->GPCCON = 0xAAAAAAAA;

gpio->GPCUP = 0x0000FFFF;

gpio->GPDCON = 0xAAAAAAAA;

gpio->GPDUP = 0x0000FFFF;

gpio->GPECON = 0xAAAAAAAA;

gpio->GPEUP = 0x0000FFFF;

gpio->GPFCON = 0x000055AA;

gpio->GPFUP = 0x000000FF;

gpio->GPGCON = 0xFF95FFBA;

gpio->GPGUP = 0x0000FFFF;

gpio->GPHCON = 0x002AFAAA;

gpio->GPHUP = 0x000007FF;

/* arch number of SMDK2410-Board */

gd->bd->bi_arch_number = MACH_TYPE_MINI2440;

/* adress of boot parameters */

gd->bd->bi_boot_params = 0x30000100;

icache_enable();

dcache_enable();

return 0;

}

获取时钟设置结构体

# < include\s3c2410.h >

#define S3C24X0_CLOCK_POWER_BASE 0x4C000000

static inline struct s3c24x0_clock_power *s3c24x0_get_base_clock_power(void)

{

return (struct s3c24x0_clock_power *)S3C24X0_CLOCK_POWER_BASE;

}

说明:

LOCKTIME 0x4C000000    //MPLL设置之后频率不稳定影响FCLK,所有会将FCLK锁定一地段时间

MPLLCON 0x4C000004    //MPLL锁相环控制器,控制着FCLK的频率

UPLLCON 0x4C000008    //UPLL锁相环控制器,控制着UCKL频率,USB的时钟频率

CLKCON 0x4C00000C    //不同模块的时钟使能控制器

CLKSLOW 0x4C000010  

CLKDIVN 0x4C000014

CAMDIVN 0x4C000018

 

设置MPLL锁相环,将FCLK设置为406MHz

# < board\vbird\mini2440\mini2440.c >

#define M_MDIV 0x7F

#define M_PDIV 0x2

#define M_SDIV 0x1

clk_power->MPLLCON = ((M_MDIV << 12) + (M_PDIV << 4) + M_SDIV);

FCLK = (2*(7F+8)*12MHz)/( (4+2)*2^1 ) = 406MHz

 

设置UPLL锁相环

    /* some delay between MPLL and UPLL */        

    delay (4000);

    /* configure UPLL */

    clk_power->UPLLCON = ((U_M_MDIV << 12) + (U_M_PDIV << 4) + U_M_SDIV);

    /* some delay between MPLL and UPLL */

    delay (8000);

GPIO初始化

    /* set up the I/O ports */

gpio->GPACON = 0x007FFFFF;

gpio->GPBCON = 0x00044555;

gpio->GPBUP = 0x000007FF;

gpio->GPCCON = 0xAAAAAAAA;

gpio->GPCUP = 0x0000FFFF;

gpio->GPDCON = 0xAAAAAAAA;

gpio->GPDUP = 0x0000FFFF;

gpio->GPECON = 0xAAAAAAAA;

gpio->GPEUP = 0x0000FFFF;

gpio->GPFCON = 0x000055AA;

gpio->GPFUP = 0x000000FF;

gpio->GPGCON = 0xFF95FFBA;

gpio->GPGUP = 0x0000FFFF;

gpio->GPHCON = 0x002AFAAA;

gpio->GPHUP = 0x000007FF;

设置ArchNumber,后续内核引导也需要这个参数

    gd->bd->bi_arch_number = MACH_TYPE_MINI2440;

说明:内核引导第二个参数会使用

# < lib_arm\bootm.c > - do_bootm_linux

void (*theKernel)(int zero, int arch, uint params);  //第二个参数

设置uboot向内核传递参数的地址参数

    gd->bd->bi_boot_params = 0x30000100;

iCache和dCache的使能(指令/数据高速缓存)

    icache_enable();

    dcache_enable();

说明:

CR_I:icache

CR_C:dcache

static void cache_enable(uint32_t cache_bit)

{

uint32_t reg;

reg = get_cr(); /* get control reg. */

cp_delay();

set_cr(reg | cache_bit);

}

static inline unsigned int get_cr(void)

{

unsigned int val;

asm("mrc p15, 0, %0, c1, c0, 0 @ get CR" : "=r" (val) : : "cc");

return val;

}

#define isb() __asm__ __volatile__ ("" : : : "memory")

static inline void set_cr(unsigned int val)

{

asm volatile("mcr p15, 0, %0, c1, c0, 0 @ set CR"

 : : "r" (val) : "cc");

isb();

}

timer_init(定时器初始化)

int timer_init(void)

{

struct s3c24x0_timers *timers = s3c24x0_get_base_timers();

ulong tmr;

/* use PWM Timer 4 because it has no output */

/* prescaler for Timer 4 is 16 */

writel(0x0f00, &timers->TCFG0);

if (timer_load_val == 0) {

/*

* for 10 ms clock period @ PCLK with 4 bit divider = 1/2

* (default) and prescaler = 16. Should be 10390

* @33.25MHz and 15625 @ 50 MHz

*/

timer_load_val = get_PCLK() / (2 * 16 * 100);

timer_clk = get_PCLK() / (2 * 16);

}

/* load value for 10 ms timeout */

lastdec = timer_load_val;

writel(timer_load_val, &timers->TCNTB4);

/* auto load, manual update of Timer 4 */

tmr = (readl(&timers->TCON) & ~0x0700000) | 0x0600000;

writel(tmr, &timers->TCON);

/* auto load, start Timer 4 */

tmr = (tmr & ~0x0700000) | 0x0500000;

writel(tmr, &timers->TCON);

timestamp = 0;

return (0);

}

获取定时器设置结构体

#define S3C24X0_TIMER_BASE 0x51000000

static inline struct s3c24x0_timers *s3c24x0_get_base_timers(void)

{

return (struct s3c24x0_timers *)S3C24X0_TIMER_BASE;

}

struct s3c24x0_timers {

S3C24X0_REG32 TCFG0;

S3C24X0_REG32 TCFG1;

S3C24X0_REG32 TCON;

struct s3c24x0_timer ch[4];

S3C24X0_REG32 TCNTB4;

S3C24X0_REG32 TCNTO4;

};

struct s3c24x0_timer {

S3C24X0_REG32 TCNTB;

S3C24X0_REG32 TCMPB;

S3C24X0_REG32 TCNTO;

};

TCFG0 0x51000000    //定时器配置(配置两个8位预分频器)

TCFG1 0x51000004    //定时器配置(5个MUX和DMA模式选择)

TCON 0x51000008    //定时器控制器

TCNTB0 0x5100000C    //定时器0计数缓冲区

TCMPB0 0x51000010    //定时器0比较缓冲区

TCNTO0 0x51000014    //定时器0计数观察寄存器

TCNTB1 0x51000018

TCMPB1 0x5100001C

TCNTO1 0x51000020

TCNTB2 0x51000024

TCMPB2 0x51000028

TCNTO2 0x5100002C

TCNTB3 0x51000030

TCMPB3 0x51000034

TCNTO3 0x51000038

TCNTB4 0x5100003C

TCNTO4 0x51000040

 设置定时器配置0为0x0f00

writel(0x0f00, &timers->TCFG0);

Prescaler 1 = 0x0f

Prescaler 0 = 0x00

clock = 50MHz / (15+1) / (1/2)

 

设置定时器超时10ms

        /* load value for 10 ms timeout */

lastdec = timer_load_val;

writel(timer_load_val, &timers->TCNTB4);

/* auto load, manual update of Timer 4 */

tmr = (readl(&timers->TCON) & ~0x0700000) | 0x0600000;

writel(tmr, &timers->TCON);

/* auto load, start Timer 4 */

tmr = (tmr & ~0x0700000) | 0x0500000;

writel(tmr, &timers->TCON);

timestamp = 0;

env_init(环境变量初始化)

init_baudrate(波特率初始化)

static int init_baudrate (void)

{

char tmp[64]; /* long enough for environment variables */

int i = getenv_r ("baudrate", tmp, sizeof (tmp));

gd->bd->bi_baudrate = gd->baudrate = (i > 0)

? (int) simple_strtoul (tmp, NULL, 10)

: CONFIG_BAUDRATE;

return (0);

}

serial_init(串口初始化)

int serial_init(void)

{

return serial_init_dev(UART_NR); //UART_NR = 0

}

struct s3c24x0_uart {

S3C24X0_REG32 ULCON;

S3C24X0_REG32 UCON;

S3C24X0_REG32 UFCON;

S3C24X0_REG32 UMCON;

S3C24X0_REG32 UTRSTAT;

S3C24X0_REG32 UERSTAT;

S3C24X0_REG32 UFSTAT;

S3C24X0_REG32 UMSTAT;

S3C24X0_REG8 UTXH;

S3C24X0_REG8 res1[3];

S3C24X0_REG8 URXH;

S3C24X0_REG8 res2[3];

S3C24X0_REG32 UBRDIV;

};

static int serial_init_dev(const int dev_index)

{

struct s3c24x0_uart *uart = s3c24x0_get_base_uart(dev_index);  //dev_index = 0

/* FIFO enable, Tx/Rx FIFO clear */

writel(0x07, &uart->UFCON);    //使能FIFO

writel(0x0, &uart->UMCON);    //取消使能自动流量控制

/* Normal,No parity,1 stop,8 bit */

writel(0x3, &uart->ULCON);    // 0个停止位,8位数据

/*

* tx=level,rx=edge,disable timeout int.,enable rx error int.,

* normal,interrupt or polling

*/

writel(0x245, &uart->UCON);

_serial_setbrg(dev_index);

return (0);

}

#define S3C24X0_UART_BASE 0x50000000

static inline struct s3c24x0_uart *s3c24x0_get_base_uart(enum s3c24x0_uarts_nr n)

{

return (struct s3c24x0_uart *)(S3C24X0_UART_BASE + (n * 0x4000));

}

 

 

 console_init_f(控制台初始化,第一阶段)

int console_init_f(void)

{

gd->have_console = 1;

return 0;

}

display_banner(打印信息,Uboot终端第一条信息)

static int display_banner (void)

{

printf ("\n\n%s\n\n", version_string);

debug ("U-Boot code: %08lX -> %08lX  BSS: -> %08lX\n",

      _armboot_start, _bss_start, _bss_end);

return (0);

}

const char version_string[] =

U_BOOT_VERSION" (" U_BOOT_DATE " - " U_BOOT_TIME ")"CONFIG_IDENT_STRING;

#define U_BOOT_VERSION "U-Boot 2009.11"

#define U_BOOT_DATE " 4月 24 2012"

#define U_BOOT_TIME "10:35:44"

 

dram_init(配置RAM块)

int dram_init (void)

{

gd->bd->bi_dram[0].start = PHYS_SDRAM_1;

gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;

return 0;

}

#define PHYS_SDRAM_1 0x30000000 /* SDRAM Bank #1 */

#define PHYS_SDRAM_1_SIZE 0x04000000 /* 64 MB */

arm_pci_init(好像没调用)

display_dram_config(打印RAM配置,主要为大小)

static int display_dram_config (void)

{

int i;

ulong size = 0;

for (i=0; i<CONFIG_NR_DRAM_BANKS; i++) {

size += gd->bd->bi_dram[i].size;

}

puts("DRAM:  ");

print_size(size, "\n");

return (0);

}

#define CONFIG_NR_DRAM_BANKS 1   /* we have 1 bank of DRAM */

设置MPLL锁相环,将FCLK设置为406MHz

# < board\vbird\mini2440\mini2440.c >

#define M_MDIV 0x7F

#define M_PDIV 0x2

#define M_SDIV 0x1

clk_power->MPLLCON = ((M_MDIV << 12) + (M_PDIV << 4) + M_SDIV);

FCLK = (2*(7F+8)*12MHz)/( (4+2)*2^1 ) = 406MHz

 

设置UPLL锁相环

    /* some delay between MPLL and UPLL */        

    delay (4000);

    /* configure UPLL */

    clk_power->UPLLCON = ((U_M_MDIV << 12) + (U_M_PDIV << 4) + U_M_SDIV);

    /* some delay between MPLL and UPLL */

    delay (8000);

GPIO初始化

    /* set up the I/O ports */

gpio->GPACON = 0x007FFFFF;

gpio->GPBCON = 0x00044555;

gpio->GPBUP = 0x000007FF;

gpio->GPCCON = 0xAAAAAAAA;

gpio->GPCUP = 0x0000FFFF;

gpio->GPDCON = 0xAAAAAAAA;

gpio->GPDUP = 0x0000FFFF;

gpio->GPECON = 0xAAAAAAAA;

gpio->GPEUP = 0x0000FFFF;

gpio->GPFCON = 0x000055AA;

gpio->GPFUP = 0x000000FF;

gpio->GPGCON = 0xFF95FFBA;

gpio->GPGUP = 0x0000FFFF;

gpio->GPHCON = 0x002AFAAA;

gpio->GPHUP = 0x000007FF;

设置ArchNumber,后续内核引导也需要这个参数

    gd->bd->bi_arch_number = MACH_TYPE_MINI2440;

说明:内核引导第二个参数会使用

# < lib_arm\bootm.c > - do_bootm_linux

void (*theKernel)(int zero, int arch, uint params);  //第二个参数

设置uboot向内核传递参数的地址参数

    gd->bd->bi_boot_params = 0x30000100;

iCache和dCache的使能(指令/数据高速缓存)

    icache_enable();

    dcache_enable();

说明:

CR_I:icache

CR_C:dcache

static void cache_enable(uint32_t cache_bit)

{

uint32_t reg;

reg = get_cr(); /* get control reg. */

cp_delay();

set_cr(reg | cache_bit);

}

static inline unsigned int get_cr(void)

{

unsigned int val;

asm("mrc p15, 0, %0, c1, c0, 0 @ get CR" : "=r" (val) : : "cc");

return val;

}

#define isb() __asm__ __volatile__ ("" : : : "memory")

static inline void set_cr(unsigned int val)

{

asm volatile("mcr p15, 0, %0, c1, c0, 0 @ set CR"

 : : "r" (val) : "cc");

isb();

}

timer_init(定时器初始化)

int timer_init(void)

{

struct s3c24x0_timers *timers = s3c24x0_get_base_timers();

ulong tmr;

/* use PWM Timer 4 because it has no output */

/* prescaler for Timer 4 is 16 */

writel(0x0f00, &timers->TCFG0);

if (timer_load_val == 0) {

/*

* for 10 ms clock period @ PCLK with 4 bit divider = 1/2

* (default) and prescaler = 16. Should be 10390

* @33.25MHz and 15625 @ 50 MHz

*/

timer_load_val = get_PCLK() / (2 * 16 * 100);

timer_clk = get_PCLK() / (2 * 16);

}

/* load value for 10 ms timeout */

lastdec = timer_load_val;

writel(timer_load_val, &timers->TCNTB4);

/* auto load, manual update of Timer 4 */

tmr = (readl(&timers->TCON) & ~0x0700000) | 0x0600000;

writel(tmr, &timers->TCON);

/* auto load, start Timer 4 */

tmr = (tmr & ~0x0700000) | 0x0500000;

writel(tmr, &timers->TCON);

timestamp = 0;

return (0);

}

获取定时器设置结构体

#define S3C24X0_TIMER_BASE 0x51000000

static inline struct s3c24x0_timers *s3c24x0_get_base_timers(void)

{

return (struct s3c24x0_timers *)S3C24X0_TIMER_BASE;

}

struct s3c24x0_timers {

S3C24X0_REG32 TCFG0;

S3C24X0_REG32 TCFG1;

S3C24X0_REG32 TCON;

struct s3c24x0_timer ch[4];

S3C24X0_REG32 TCNTB4;

S3C24X0_REG32 TCNTO4;

};

struct s3c24x0_timer {

S3C24X0_REG32 TCNTB;

S3C24X0_REG32 TCMPB;

S3C24X0_REG32 TCNTO;

};

TCFG0 0x51000000    //定时器配置(配置两个8位预分频器)

TCFG1 0x51000004    //定时器配置(5个MUX和DMA模式选择)

TCON 0x51000008    //定时器控制器

TCNTB0 0x5100000C    //定时器0计数缓冲区

TCMPB0 0x51000010    //定时器0比较缓冲区

TCNTO0 0x51000014    //定时器0计数观察寄存器

TCNTB1 0x51000018

TCMPB1 0x5100001C

TCNTO1 0x51000020

TCNTB2 0x51000024

TCMPB2 0x51000028

TCNTO2 0x5100002C

TCNTB3 0x51000030

TCMPB3 0x51000034

TCNTO3 0x51000038

TCNTB4 0x5100003C

TCNTO4 0x51000040

 设置定时器配置0为0x0f00

writel(0x0f00, &timers->TCFG0);

Prescaler 1 = 0x0f

Prescaler 0 = 0x00

clock = 50MHz / (15+1) / (1/2)

 

设置定时器超时10ms

        /* load value for 10 ms timeout */

lastdec = timer_load_val;

writel(timer_load_val, &timers->TCNTB4);

/* auto load, manual update of Timer 4 */

tmr = (readl(&timers->TCON) & ~0x0700000) | 0x0600000;

writel(tmr, &timers->TCON);

/* auto load, start Timer 4 */

tmr = (tmr & ~0x0700000) | 0x0500000;

writel(tmr, &timers->TCON);

timestamp = 0;

env_init(环境变量初始化)

init_baudrate(波特率初始化)

static int init_baudrate (void)

{

char tmp[64]; /* long enough for environment variables */

int i = getenv_r ("baudrate", tmp, sizeof (tmp));

gd->bd->bi_baudrate = gd->baudrate = (i > 0)

? (int) simple_strtoul (tmp, NULL, 10)

: CONFIG_BAUDRATE;

return (0);

}

serial_init(串口初始化)

int serial_init(void)

{

return serial_init_dev(UART_NR); //UART_NR = 0

}

struct s3c24x0_uart {

S3C24X0_REG32 ULCON;

S3C24X0_REG32 UCON;

S3C24X0_REG32 UFCON;

S3C24X0_REG32 UMCON;

S3C24X0_REG32 UTRSTAT;

S3C24X0_REG32 UERSTAT;

S3C24X0_REG32 UFSTAT;

S3C24X0_REG32 UMSTAT;

S3C24X0_REG8 UTXH;

S3C24X0_REG8 res1[3];

S3C24X0_REG8 URXH;

S3C24X0_REG8 res2[3];

S3C24X0_REG32 UBRDIV;

};

static int serial_init_dev(const int dev_index)

{

struct s3c24x0_uart *uart = s3c24x0_get_base_uart(dev_index);  //dev_index = 0

/* FIFO enable, Tx/Rx FIFO clear */

writel(0x07, &uart->UFCON);    //使能FIFO

writel(0x0, &uart->UMCON);    //取消使能自动流量控制

/* Normal,No parity,1 stop,8 bit */

writel(0x3, &uart->ULCON);    // 0个停止位,8位数据

/*

* tx=level,rx=edge,disable timeout int.,enable rx error int.,

* normal,interrupt or polling

*/

writel(0x245, &uart->UCON);

_serial_setbrg(dev_index);

return (0);

}

#define S3C24X0_UART_BASE 0x50000000

static inline struct s3c24x0_uart *s3c24x0_get_base_uart(enum s3c24x0_uarts_nr n)

{

return (struct s3c24x0_uart *)(S3C24X0_UART_BASE + (n * 0x4000));

}

 

console_init_f(控制台初始化,第一阶段)

int console_init_f(void)

{

gd->have_console = 1;

return 0;

}

display_banner(打印信息,Uboot终端第一条信息)

 

static int display_banner (void)

{

printf ("\n\n%s\n\n", version_string);

debug ("U-Boot code: %08lX -> %08lX  BSS: -> %08lX\n",

      _armboot_start, _bss_start, _bss_end);

return (0);

}

const char version_string[] =

U_BOOT_VERSION" (" U_BOOT_DATE " - " U_BOOT_TIME ")"CONFIG_IDENT_STRING;

#define U_BOOT_VERSION "U-Boot 2009.11"

#define U_BOOT_DATE " 4月 24 2012"

#define U_BOOT_TIME "10:35:44"

 

dram_init(配置RAM块)

int dram_init (void)

{

gd->bd->bi_dram[0].start = PHYS_SDRAM_1;

gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;

return 0;

}

#define PHYS_SDRAM_1 0x30000000 /* SDRAM Bank #1 */

#define PHYS_SDRAM_1_SIZE 0x04000000 /* 64 MB */

arm_pci_init(好像没调用)

display_dram_config(打印RAM配置,主要为大小)

static int display_dram_config (void)

{

int i;

ulong size = 0;

for (i=0; i<CONFIG_NR_DRAM_BANKS; i++) {

size += gd->bd->bi_dram[i].size;

}

puts("DRAM:  ");

print_size(size, "\n");

return (0);

}

#define CONFIG_NR_DRAM_BANKS 1   /* we have 1 bank of DRAM */

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_283725.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

VUE3 学习笔记(七)动态样式 class 实现

目录 一、绑定 HTML class 1. 绑定对象 2. 绑定数组 3. 在组件上使用 二、绑定内联样式 1. 绑定对象 2. 绑定数组 3. 自动前缀 4. 样式多值 数据绑定的一个常见需求场景是操纵元素的 CSS class 列表和内联样式。因为 class 和 style 都是 attribute&#xff0c;我们可…

一道小学题,解答了我与学霸的差距

目录一、背景二、题目三、过程1.形式转换2.个位数相加只能向前进一位嘛&#xff1f;进两位可以吗&#xff1f;进三位呢&#xff1f;3.十位数上要填写的内容&#xff0c;可以是0嘛&#xff1f;你想到了吗&#xff1f;4.如何下意识的去做结构化&#xff1f;四、总结五、升华一、背…

讲一下dns过程:给一个网址www.google.com,dns服务器如何逐级解析的?

DNS 中的域名都是用句点来分隔的&#xff0c;比如 www.server.com&#xff0c;这里的句点代表了不同层次之间的界限。在域名中&#xff0c;越靠右的位置表示其层级越高。域名最后还有一个点&#xff0c;比如 www.server.com.&#xff0c;这个最后的一个点代表根域名。 根DNS服…

UDP套接字

大家好,又见面了,&#x1f389;&#x1f389;&#x1f389;&#x1f338;&#x1f338;&#x1f338; 今天为大家带来UDP套接字的相关知识 文章目录认识socketUDP和TCP认识UDPAPI有关方法基于UDP实现回显服务器UDP的方法基于UDP实现回显程序认识socket UDP和TCP 认识UDPAPI有…

腾讯空降测试工程师,绩效次次拿S,真是砂纸擦屁股,给我露了一手啊

​上周我们公司的绩效面谈全部结束了&#xff0c;每年到这个时间点就是打绩效的时候了&#xff0c;对于职场打工人来说绩效绝对是最重要的事情之一&#xff0c;原因也很简单&#xff1a;奖金、晋升、涨薪都和它有关系。 比如下面这个美团员工在脉脉上的自曝就很凄凉&#xff1…

多种方法解决VS在创建多个源文件后运行时出现的重定义错误:main已经在1.obj中定义

名人说&#xff1a;博学之&#xff0c;审问之&#xff0c;慎思之&#xff0c;明辨之&#xff0c;笃行之。——《中庸》 创作者&#xff1a;Code_流苏(CSDN) 本篇文章收录于&#xff1a;各类问题记录专栏 记录一、原因经过二、解决方法1️⃣方法一 注释2️⃣方法二 生成排除3️⃣…

学习Python的一些知识点记录

一、对象比较 Python中有两种对象比较方式&#xff1a; 值比较。使用比较符号&#xff08;、>、<等&#xff09;标识符比较。使用 is、not 关键字。标识符就是对象在内存中的有效地址&#xff0c;使用 id() 函数可以得到对象的标识符。二、None 对象 这是一个特殊对象…

【Python】数学 - 用 Python 自动化求解函数 f(x) 的值

目录 1、缘起 2、求以下函数的值 3、代码清单 3.1、求解 f(0)、f(1)、 f(​编辑)、f(​编辑) 3.2、求解 g(0)、g(1)、g(​编辑)、g(​编辑) 3.3、求解 h(0)、h(1)、h(​编辑)、h(​编辑) 4、总结 1、缘起 Python 是一种强大的编程语言&#xff0c;它具有广泛的应用领域。…

四、第二阶段

全局数据 声明 # < lib_arm\board.c > DECLARE_GLOBAL_DATA_PTR; 定义 # < include\asm\global_data.h > typedef struct global_data { bd_t *bd; unsigned long flags; unsigned long baudrate; unsigned long have_console; /* serial_init() was calle…

使用adb 命令删除手机预装app

1. 手机开启开发者选项&#xff0c;允许usb调试&#xff1b; 2.pc 安装adb&#xff0c; 1&#xff09;Windows版本&#xff1a;https://dl.google.com/android/repository/platform-tools-latest-windows.zip 2&#xff09;按键windowsr打开运行&#xff0c;输入sysdm.cpl&a…

Go 语言安装部署,两分钟让你写`上Hello World`(包含 goland 开发工具)

Go 语言安装部署&#xff0c;两分钟让你写上Hello World&#xff08;包含 goland 开发工具&#xff09; 第一步下载 Go 安装包 官网 https://golang.google.cn/dl/ 根据自己使用电脑平台选择安装版本 第二步 安装 GO 打开安装包直接点击next下一步 勾选协议&#xff0c;继…

10 kafka生产者发送消息的原理

1.发送原理&#xff1a; 在消息发送的过程中&#xff0c;涉及到了两个线程——main 线程和 Sender 线程。在 main 线程 中创建了一个双端队列 RecordAccumulator。main 线程将消息发送给 RecordAccumulator&#xff0c; Sender 线程不断从 RecordAccumulator 中拉取消息发送到…

CTFHub | 00截断

0x00 前言 CTFHub 专注网络安全、信息安全、白帽子技术的在线学习&#xff0c;实训平台。提供优质的赛事及学习服务&#xff0c;拥有完善的题目环境及配套 writeup &#xff0c;降低 CTF 学习入门门槛&#xff0c;快速帮助选手成长&#xff0c;跟随主流比赛潮流。 0x01 题目描述…

IDEA修改主题 设置背景图片

IDEA修改主题 设置背景图片 目录IDEA修改主题 设置背景图片1.修改IDEA默认主题2.修改IDEA背景图片2.1 打开设置界面2.2 下载插件很多小白在刚刚使用IDEA的时候还不是很熟练本文主要给大家提供一些使用的小技巧&#xff0c;希望能帮助到你1.修改IDEA默认主题 IDEA的默认主题是黑…

Jmeter 工具测试 websocket

WebSocket 是一种基于在单个 TCP 连接上进行全双工通信的协议&#xff0c;是从HTML5开始提供的一种浏览器与服务器之间进行全双工通讯的网络技术。相较于 HTTP 协议&#xff0c;WebSocket 协议实现了持久化网络通信&#xff0c;可以实现客户端和服务端的长连接&#xff0c;能够…

对Javascript中作用域的理解?

一、作用域 作用域&#xff0c;即变量&#xff08;变量作用域又称上下文&#xff09;和函数生效&#xff08;能被访问&#xff09;的区域或集合 换句话说&#xff0c;作用域决定了代码区块中变量和其他资源的可见性 举个例子 function myFunction() {let inVariable "…

C/C++中文参考手册离线最新版

最近又用回C/C刷题&#xff0c;回想上一年还在用Java&#xff0c;C/C才是世界上最好的语言&#xff08;纯属调侃&#xff09;。哼哼&#xff0c;不许反驳。 想分享我正在使用的C/C中文参考手册离线最新版给大家&#xff0c;需要的朋友们可以自行下载&#xff08;free的哦&#…

造型别致的耳夹式耳机,听出新色彩,塞那Z50上手

蓝牙耳机这几年发展很快&#xff0c;市面上的选择特别丰富&#xff0c;其中还有不少设计、音质都特别出彩的产品&#xff0c;像是我最近在用的这款sanag塞那Z50&#xff0c;就采用了一种很新颖的设计&#xff0c;带来了更加舒适的佩戴体验&#xff0c;而且音质表现也很出色。 s…

Redis 如何使用 Sentinel 构建主从复制的高可用架构?

文章目录Redis 如何使用 Sentinel 构建主从复制的高可用架构&#xff1f;什么是 Sentinel 服务&#xff1f;如何配置 Sentinel 集群服务&#xff1f;启动 Sentinel 服务配置说明测试主节点失效查看 Sentinel 主节点服务状态查看 Sentinel 从节点服务状态模拟主节点失效观察各个…

Unity实战篇 | 使Unity打包的exe程序始终保持屏幕最前端【文末送书】

&#x1f3ac; 博客主页&#xff1a;https://xiaoy.blog.csdn.net &#x1f3a5; 本文由 呆呆敲代码的小Y 原创&#xff0c;首发于 CSDN&#x1f649; &#x1f384; 学习专栏推荐&#xff1a;Unity系统学习专栏 &#x1f332; 游戏制作专栏推荐&#xff1a;游戏制作 &…