AT91RM9200引导程序的建立(三)--------U-Boot1.1.4在AT91RM9200上的移植

    技术2022-05-11  64

     

    BootLoader概述        Boot Loader就是在操作系统内核运行之前运行的一段小程序。通过这段BootLoader,我们来初始化硬件设备,为硬件设备准备地址空间,中断号等,建立内存空间的映射,从而将系统的软硬件环境带到一个合适的状态。 AT91RM9200处理器启动有两种情况,一种是从外部启动,如Flash,EEPROM,DATAFLASH等;一种是从内部的BOOTROM固化代码引导。我们的ARM板是直接通过JTAG接口从主机下载到目标板的flash中直接启动。        系统上电后,我们的CPU从0x00000000取它的第一条指令,而我们的flash就是被映射到这个地址上。CPU就首先执行我们烧在flash上的BootLoader 程序,通过它来引导Linux系统。 U-Boot是一个通用的Bootloader,可以方便地移植到其他硬件平台。现在已经成为ARM平台事实上的标准。 U-Boot的源码包可以从sourceforge网站下载。我们使用U-Boot1.1.4来作为我们移植的Bootloader。   U-Boot1.1.4 移植 u-boot修改。 由于我们的板子和atmel的DK板不同,所以针对我们的硬件,要重新修改u-boot代码,特别是flash驱动部分。   1)修改 board/at91rm9200dk/config.mk TEXT_BASE=0x21f00000 将U-Boot载入32MSDRAM的高端部分,即最高端1M的空间留给U-Boot代码。   2)修改include/configs/at91rm9200dk.h  修改Flash和SDRAM的大小:      #define PHYS_SDRAM_SIZE 0x2000000 /* 32 megs */     #define PHYS_FLASH_SIZE 0x200000 /* 2 megs main flash */ 同时定义如下环境变量: #define CONFIG_DEFAULT_ENVIRONMENT #define CONFIG_BOARDNAME "AT91RM9200DK" #define CONFIG_ETHADDR "00:11:22:33:44:55" #define CONFIG_IPADDR "192.168.1.100" #define CONFIG_SERVERIP "192.168.1.1" //#define CONFIG_GATEWAYIP "192.168.18.1" #define CONFIG_BOOTCOMMAND "tftp 0x20008000 zImage; tftp 0x20410000 ramdisk;go 0x20008000" #define CONFIG_DEFAULT_KERNEL "2.6.17" 从上面可以看出,我们板子的IP地址是192.168.1.100,而我们的宿主机IP地址为192.168.1.1 ,我们的网卡Mac为:00:11:22:33:44:55。 3)修改flash驱动 borad/at91rm9200dk/flash.c 这个文件修改的部分比较的多。 1.     首先是 OrgDef 的定义,加上目前的 flash     OrgDef OrgSSTvF6401B[]= {                                      {2048,4*1024},   /*2048*64KBytes sectors*/ }; 修改 函数 flash_identification(flash_info_t * info), 显示正确的信息。 void flash_identification (flash_info_t * info) {        volatile u16 manuf_code, device_code, add_device_code;          MEM_FLASH_ADDR1 = FLASH_CODE1;        MEM_FLASH_ADDR2 = FLASH_CODE2;        MEM_FLASH_ADDR1 = ID_IN_CODE;          manuf_code = *(volatile u16 *) CFG_FLASH_BASE;        device_code = *(volatile u16 *) (CFG_FLASH_BASE + 2);        add_device_code = *(volatile u16 *) (CFG_FLASH_BASE + (3 << 1));          MEM_FLASH_ADDR1 = FLASH_CODE1;        MEM_FLASH_ADDR2 = FLASH_CODE2;        MEM_FLASH_ADDR1 = ID_OUT_CODE;          /* Vendor type */        /*        if(info->flash_id = ATM_MANUFACT & FLASH_VENDMASK)        {                  printf ("Atmel: ");        }        */        if(info->flash_id=SST_MANUFACT & FLASH_VENDMASK)    //zzl061206        {                  printf("SST:");        } /*atmel identify*/        if ((device_code & FLASH_TYPEMASK) == (ATM_ID_BV1614 & FLASH_TYPEMASK)) {                    if ((add_device_code & FLASH_TYPEMASK) ==                             (ATM_ID_BV1614A & FLASH_TYPEMASK)) {                             info->flash_id |= ATM_ID_BV1614A & FLASH_TYPEMASK;                             printf ("AT49BV1614A (16Mbit)/n");                  } else {                                 /* AT49BV1614 Flash */                             info->flash_id |= ATM_ID_BV1614 & FLASH_TYPEMASK;                             printf ("AT49BV1614 (16Mbit)/n");                  }          } else if ((device_code & FLASH_TYPEMASK) == (ATM_ID_BV6416 & FLASH_TYPEMASK)) {                    info->flash_id |= ATM_ID_BV6416 & FLASH_TYPEMASK;                  printf ("AT49BV6416 (64Mbit)/n");        }        /*sst identify*/       else if((device_code & FLASH_TYPEMASK) == (SST_ID_xF6401B & FLASH_TYPEMASK)) //zzl061206       {                info->flash_id |= SST_ID_xF6401B & FLASH_TYPEMASK;                printf("vF6401B(64Mbit)/n");       } }   2. 修改初始化Flash函数ulong flash_init (void)ulong flash_init (void) {        int i, j, k;        unsigned int flash_nb_blocks, sector;        unsigned int start_address;        OrgDef *pOrgDef;          ulong size = 0;          for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) {                  ulong flashbase = 0;                    flash_identification (&flash_info[i]);                    if ((flash_info[i].flash_id & FLASH_TYPEMASK) ==                             (ATM_ID_BV1614 & FLASH_TYPEMASK)) {                               pOrgDef = OrgAT49BV16x4;                             flash_nb_blocks = sizeof (OrgAT49BV16x4) / sizeof (OrgDef);                  } else if ((flash_info[i].flash_id & FLASH_TYPEMASK) ==                             (ATM_ID_BV1614A & FLASH_TYPEMASK)){      /* AT49BV1614A Flash */                               pOrgDef = OrgAT49BV16x4A;                             flash_nb_blocks = sizeof (OrgAT49BV16x4A) / sizeof (OrgDef);                  } else if ((flash_info[i].flash_id & FLASH_TYPEMASK) ==                             (ATM_ID_BV6416 & FLASH_TYPEMASK)){       /* AT49BV6416 Flash */                               pOrgDef = OrgAT49BV6416;                             flash_nb_blocks = sizeof (OrgAT49BV6416) / sizeof (OrgDef);                  }                  /*zzl*/                else if((flash_info[i].flash_id & FLASH_TYPEMASK)==                         (SST_ID_xF6401B & FLASH_TYPEMASK))                {                         pOrgDef=OrgSSTvF6401B;                         flash_nb_blocks = sizeof (OrgSSTvF6401B) / sizeof (OrgDef);                }                  else {                             flash_nb_blocks = 0;                             pOrgDef = OrgAT49BV16x4;                  }                    flash_info[i].sector_count = flash_number_sector(pOrgDef, flash_nb_blocks);                  memset (flash_info[i].protect, 0, flash_info[i].sector_count);                    if (i == 0)                             flashbase = PHYS_FLASH_1;                  else                             panic ("configured too many flash banks!/n");                    sector = 0;                  start_address = flashbase;                  flash_info[i].size = 0;                    for (j = 0; j < flash_nb_blocks; j++) {                             for (k = 0; k < pOrgDef[j].sector_number; k++) {                                       flash_info[i].start[sector++] = start_address;                                       start_address += pOrgDef[j].sector_size;                                       flash_info[i].size += pOrgDef[j].sector_size;                             }                  }                    size += flash_info[i].size;                    if ((flash_info[i].flash_id & FLASH_TYPEMASK) ==                             (ATM_ID_BV6416 & FLASH_TYPEMASK)){       /* AT49BV6416 Flash */   /*zzl*/                               /* Unlock all sectors at reset */                             for (j=0; j<flash_info[i].sector_count; j++){                                       flash_unlock_sector(&flash_info[i], j);                             }                  }        }          /* Protect binary boot image */        flash_protect (FLAG_PROTECT_SET,                         CFG_FLASH_BASE,                         CFG_FLASH_BASE + CFG_BOOT_SIZE - 1, &flash_info[0]);          /* Protect environment variables */        flash_protect (FLAG_PROTECT_SET,                         CFG_ENV_ADDR,                         CFG_ENV_ADDR + CFG_ENV_SIZE - 1, &flash_info[0]);          /* Protect U-Boot gzipped image */        flash_protect (FLAG_PROTECT_SET,                         CFG_U_BOOT_BASE,                         CFG_U_BOOT_BASE + CFG_U_BOOT_SIZE - 1, &flash_info[0]);          return size;   3.修改 函数flash_erase(),将检测flash类型注释掉,因为先前已经检测过         /* first look for protection bits */ /*zzl 20061206        if (info->flash_id == FLASH_UNKNOWN)                  return ERR_UNKNOWN_FLASH_TYPE;          if ((s_first < 0) || (s_first > s_last)) {                  return ERR_INVAL;        }          if ((info->flash_id & FLASH_VENDMASK) !=                  (ATM_MANUFACT & FLASH_VENDMASK)) {                  return ERR_UNKNOWN_FLASH_VENDOR;        } */ 但是这里出现了一个问题,编译后IP地址为0.192.168.1,serverip也是0.192.168.1。修改net/net.c中获得IP地址的函数。 IPaddr_t getenv_IPaddr (char *var) {        /*zzl*/        char tmp_str[64];        strcpy(tmp_str,getenv(var)); if(isxdigit(*tmp_str))      /*测试环境变量字符是否是16进制,如果是,从第一个字符开始取4个字节,如果不是,则从第二个字符开始取4个字节。*/                  return (string_to_ip(tmp_str));        else                  return(string_to_ip(tmp_str+1));        /*old code        return (string_to_ip(getenv(var)));        */ } 重新编译 #make distclean #make at91rm9200dk_config #make all 编译成功后得到u-boot.bin的二进制文件,即为需要的可执行映象文件,将其用仿真器通过JTAG烧进flash中。板子重新上电,U-Boot启动成功。(注:U-Boot1.1.4已经不需要将其压缩为u-boot.gz。直接烧入flash的0地址后,便能启动,进入u-boot下。)

    最新回复(0)