第二阶段:修改初始化代码

  代码运行到了第二阶段代码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;
}

 

  到这里第二阶段的初始化主线代码就修改完了,下面是各子系统和功能代码的修改。

posted @ 2016-07-04 13:51  pingfandfy  阅读(710)  评论(0编辑  收藏  举报