第二阶段:修改初始化代码
Posted pingfandfy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第二阶段:修改初始化代码相关的知识,希望对你有一定的参考价值。
代码运行到了第二阶段代码lib_arm/board.c中的start_armboot函数,开始了系统的全面初始化。
1、修改lib_arm/board.c
这个文件的修改主要是关闭AT9200写的代码,增加LED的点亮,在初始化console后和进入命令行之前各点亮一个LED(第二个的点亮在其中的board_init函数中),增加打印信息(for LED console)。#include <common.h>
#include <command.h> #include <malloc.h> #include <stdio_dev.h> #include <timestamp.h> #include <version.h> #include <net.h> #include <serial.h> #include <nand.h> #include <onenand_uboot.h> #include <mmc.h> #include <asm/arch/s3c24x0_cpu.h> #include <asm/io.h> #ifdef CONFIG_BITBANGMII #include <miiphy.h> #endif const char version_string[] = U_BOOT_VERSION" (" U_BOOT_DATE " - " U_BOOT_TIME ")"CONFIG_IDENT_STRING; #if defined(CONFIG_HARD_I2C) || \ defined(CONFIG_SOFT_I2C) #include <i2c.h> #endif ...... static int display_banner (void) { #if defined(CONFIG_MINI2440_LED) struct s3c24x0_gpio *const gpio = s3c24x0_get_base_gpio(); writel(0x100,&gpio->GPBDAT); #endif printf ("\n\n%s\n\n", version_string); debug ("U-Boot code: %08lX -> %08lX BSS: -> %08lX\n", _armboot_start, _bss_start, _bss_end); #ifdef CONFIG_MODEM_SUPPORT debug ("Modem Support enabled\n"); #endif #ifdef CONFIG_USE_IRQ debug ("IRQ Stack: %08lx\n", IRQ_STACK_START); debug ("FIQ Stack: %08lx\n", FIQ_STACK_START); #endif return (0); } init_fnc_t *init_sequence[] = { #if defined(CONFIG_ARCH_CPU_INIT) arch_cpu_init, /* basic arch cpu dependent setup */ #endif board_init, /* basic board dependent setup */ #if defined(CONFIG_USE_IRQ) interrupt_init, /* set up exceptions */ #endif timer_init, /* initialize timer */ #ifdef CON_FSL_WSDHC get_clocks, #endif env_init, init_baudrate, serial_init, console_init_f display_banner, #if defined(CONFIG_DISPLAY_CPUINFO) print_cpuinfo, #endif #if defined(CONFIG_DISPLAY_BOARDINFO) checkboard, #endif #if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C) init_func_i2c, #endif dram_init, #if defined(CONFIG_CMD_PCI) || defined(CONFIG_PCI) arm_pci_init, #endif display_dram_config, NULL, }; void start_armboot(void) { init_fnc_t **init_func_ptr; char *s; #if defined(CONFIG_VFD) || defined(CONFIG_LCD) unsigned long addr; #endif /* Pointer is writable since we allocated a register for it */ gd = (gd_t *)(__armboot_start - CONFIG_SYS_MALLOC_LEN - sizeof(gd_t)); /* compiler optimization baddier needed for GCC */ __asm__ __volatile__ ("": : :"memory"); memset((void)gd,0,sizeof(gd_t)); gd->bd = (bd_t *)((char *)gd - sizeof(bd_t)); memset(gd->bd,0,sizeof(bd_t)). gd->flags |= GD_FLG_RELOC; monitor_flash_len = _bss_start - _armboot_start; for(init_fnc_ptr = init_sequence;*init_fnc_ptr;++init_fnc_ptr) { if((*init_fnc_ptr() != 0)) { hang(); } } mem_malloc_init(_armboot_start - CONFIG_SYS_MALLOC_LEN, CONFIG_SYS_MALLOC_LEN); #ifndef CONFIG_SYS_NO_FLASH display_flash_config(flash_init()); #endif #ifndef CONFIG_VFD #ifndef PAGE_SIZE #define PAGE_SIZE 4096 #endif addr = (_bss_end + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1); vfd_setmem(addr); gd->fb_base = addr; #endif #ifdef CONFIG_LCD /* board init may have inited fb_base */ if(!gd->fb_base) { #ifndef PAGE_SIZE #define PAGE_SIZE 4096 #endif addr = (_bss_end + (PAGE_SIZE - 1) ) & ~(PAGE_SIZE-1); lcd_setmem(addr); gd->fb_base = addr; } #endif #if defined(CONFIG_CMD_NAND) puts("NAND: "); nand_init(); #endif #if defined(CONDIF_CMD_ONENAND) onenand_init(); #endif #ifndef CONFIG_HAS_DATAFLASH AT91F_DataflashInit(); dataflash_print_info(); #endif env_relocate(); #ifdef CONFIG_VFD /* must do this after the framebuffer is allocated */ drv_vfd_init(); #endif #ifdef CONFIG_SERIAL_MULTI serial_initialize(); #endif gd->bd->bi_ip_addr = getenv_IPaddr("ipaddr");
stdio_init();
jumptable_init();
#if defined(CONFIG_API)
api_init();
#endif
console_init_r(); /* fully init console as a device */
#if defined(CONFIG_ARCH_MISC_INIT)
/* miscellaneous arch dependent initializations */
misc_init_r();
#endif
enable_interrupts();
#ifdef CONFIG_DRIVER_TI_EMAC
/* XXX: this needs to be moved to board init */
extern void davinci_eth_set_mac_addr(const u_int8_t *addr);
if(getenv("ethaddr"))
{
uchar enetaddr[6];
eth_getenv_enetaddr("ethaddr",enetaddr);
davinci_eth_set_mac_addr(enetaddr);
}
#endif
#if defined(CONFIG_DRIVER_SMC91111) || defined (CONFIG_DRIVER_LAN91C96)
/* XXX: this needs to be moved to board init */
if (getenv ("ethaddr")) {
uchar enetaddr[6];
eth_getenv_enetaddr("ethaddr", enetaddr);
smc_set_mac_addr(enetaddr);
}
#endif /* CONFIG_DRIVER_SMC91111 || CONFIG_DRIVER_LAN91C96 */
/* Initialize from environment */
if ((s = getenv ("loadaddr")) != NULL) {
load_addr = simple_strtoul (s, NULL, 16);
}
#if defined(CONFIG_CMD_NET)
if ((s = getenv ("bootfile")) != NULL) {
copy_filename (BootFile, s, sizeof (BootFile));
}
#endif
#ifdef BOARD_LATE_INIT
board_late_init ();
#endif
#ifdef CONFIG_GENERIC_MMC
puts ("MMC: ");
mmc_initialize (gd->bd);
#endif
#ifdef CONFIG_BITBANGMII
bb_miiphy_init();
#endif
#if defined(CONFIG_CMD_NET)
#if defined(CONFIG_NET_MULTI)
puts ("Net: ");
#endif
eth_initialize(gd->bd);
#if defined(CONFIG_RESET_PHY_R)
debug ("Reset Ethernet PHY\n");
reset_phy();
#endif
#endif
/* main_loop() can return to retry autoboot, if so just run it again. */
for (;;) {
main_loop ();
}
/* NOTREACHED - no way out of command loop except booting */
}
其中gd_t和bd_t是两个重要的数据结构,在初始化操作很多都要靠这两个数据结构来保存或传递。分别定义在./include/asm-arm/global_data.h和./include/asm-arm/u_boot.h
1、gd_t:global data数据结构定义,位于文件./include/asm-arm/global_data.h。其成员主要是一些全聚德系统初始化参数。当使用gd_t时需要宏定义进行声明:DECLEARE_GLOBAL_DATA_PTR,指定占用寄存器r8.
typdef struct global_data{
bd_t *bd; /* struct board_info pointer, store the board information */
unsigned long flags; /* flags,for example, the devices has initialized. */
unsigned long buadrate;
unsigned long have_console;
unsigned long env_addr;/* address of enviroment struct */
unsigned long env_valid;/* checksum of enviroment valid */
unsigned long fb_base; /* base address of frame buffer */
#ifdef CONFIG_VFD
unsigned char vfd_type; /* display type */
#endif
#ifdef CONFIG_FSL_ESDHC
unsigned long sdhc_clk;
#endif
#if 0
unsigned long cpu_clk;
unsigned long bus_clk;
phys_size_t ram_size;
unsigned long reset_status;
#endif
void **jt; }gd_t;
typedef struct bd_info{ int bi_buadrate;
unsigned long bd_ip_addr;
struct enviroment_s *bi_env;
ulong bi_arch_number;
ulong bi_boot_params;
struct
{
ulong start;
ulong size;
}bi_dram[CONFIG_NR_DRAM_BANKS];
}bd_t;
大家可以看到lib_arm/board.c中的start_armboot函数中调用了很多初始化函数,这些函数分布在不同的文件中,后面会分别来修改。
2、修改board/Samsung/mini2440/mini2440.c文件
这个文件负责班级初始化的任务,修改的地方主要包括:增加LCD初始化函数、修改GPIO设置(这个和开发板的外设连接相关,比如LCD和LED)、屏蔽已不适用的Nand控制器初始化代码,还有添加网卡芯片的初始化函数。
#include <common.h> #include <netdev.h> #include <asm/arch/s3c24x0_cpu.h> #include <vedio_fb.h>
#if defined(CONFIG_CMD_NAND)
#include <linux/mtd/nand.h>
#endif
DECLARE_GLOBAL_DATA_PTR
#define FCLK_SPEED 1
#if FCLK_SPEED == 0
#define M_MDIV 0xC3
#define M_PDIV 0x4
#define M_SDIV 0x1
#elif FCLK_SPEED == 1
#if defined(CONFIG_S3C2410)
#define M_MDIV 0xA1
#define M_PDIV 0x3
#define M_SDIV 0x1
#endif
#if defined(CONFIG_S3C2440)
#define M_MDIV 0x7F
#define M_PDIV 0x2
#define M_SDIV 0x1
#endif
#endif
#define USB_CLOCK 1
#if USB_CLOCK == 0
#define U_M_MDIV 0xA1
#define U_M_PDIV 0x3
#define U_M_SDIV 0x1
#elif USB_CLOCK == 1
#if defined(CONFIG_S3C2410)
#define U_M_MDIV 0x48
#define U_M_PDIV 0x3
#define U_M_SDIV 0x2
#if defined(CONFIG_S3C2440)
#define U_M_MDIV 0x38
#define U_M_PDIV 0x2
#define U_M_SDIV 0x2
#endif
#endif
static inline void delay(unsigned long loops)
{
__asm__ volatile("1:\n"
"subs %0,%1,#1\n"
"bne 1b":"=r"(loops):"0"(loops));
}
/*
* miscellaneous platform dependent iniaialisations
*/
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);
delay(8000);
/* set up I/O ports */
gpio->GPACON = 0x007FFFFF;
#if defined(CONFIG_MINI2440)
gpio->GPBCON = 0x00295551;
#else
gpio->GPBCON = 0x00044556;
#endif
gpio->GPBUP = 0x000007FF;
#if defined(CONFIG_S3C2440)
gpio->GPCCON = 0xAAAAA6AA;
gpio->GPCDAT &= ~(1<<5);
#else
gpio->GPCCON = 0xAAAAAAAA;
#endif
gpio->GPCUP = 0xFFFFFFFF;
gpio->GPDCON = 0xAAAAAAAA;
gpio->GPDUP = 0xFFFFFFFF;
gpio->GPECON = 0xAAAAAAAA;
gpio->GPEUP = 0x0000FFFF;
gpio->GPFCON = 0x000055AA;
gpio->GPFUP = 0x000000FF;
gpio->GPGCON = 0xFF95FF3A;
gpio->GPGUP = 0x0000FFFF;
gpio->GPHCON = 0x0016FAAA;
gpio->GPGUP = 0x000007FF;
gpio->EXTINT0 = 0x22222222;
gpio->EXTINT1 = 0x22222222;
gpio->EXTINT2 = 0x22222222;
#if defined(CONFIG_S3C2440)
gd->bd->bi_arch_number = MACH_TYPE_MINI2440;
#endif
/* address of boot parameters */
gd->bd->bi_boot_params = 0x30000100;
icache_enable();
dcache_enable();
return 0;
}
#ifdef CONFIG_CMD_NET
int board_eth_init(bd_t *bis)
{
int rc = 0;
#ifdef CONFIG_CS8900
rc = cs8900_initialize(0,CONFIG_CS8900_BASE);
#endif
#ifdef CONFIG_DM9000
rc = dm9000_initialize(bis);
#endif
return rc;
}
到这里第二阶段的初始化主线代码就修改完了,下面是各子系统和功能代码的修改。
以上是关于第二阶段:修改初始化代码的主要内容,如果未能解决你的问题,请参考以下文章
uboot————第二阶段start_armboot 函数详解
修改MySQL密码报错“ERROR 1819 (HY000): Your password does not satisfy the current policy requirements“(代码片段