U-BOOT介绍以及disk模块源码分析

来源:互联网 发布:翻译日文的软件 编辑:程序博客网 时间:2024/05/04 21:10
一. BootLoader简介
在专用的嵌入式板子运行GNU/Linux系统已经变得越来越流行。一个嵌入式Linux系统从软件的角度看通常可以分为四个层次:
1、 引导加载程序。包括固化在固件(firmware)中的boot代码(可选),和BootLoader两大部分。
2、 Linux内核。特定于嵌入式板子的定制内核以及内核的启动参数。
3、 文件系统。包括根文件系统和建立于Flash内存设备之上文件系统。通常用ramdisk来作为rootfs。
4、 用户应用程序。特定于用户的应用程序。有时在用户应用程序和内核层之间可能还会包括一个嵌入式图形用户界面。常用的嵌入式GUI有:MicroWindows和MiniGUI懂。
引导加载程序是系统加电后运行的第一段软件代码。PC机中的引导加载程序由BIOS(其本质就是一段固件程序)和位于硬盘MBR中的OS BootLoader(比如,LILO和GRUB等)一起组成。BIOS在完成硬件检测和资源分配后,将硬盘MBR中的BootLoader读到系统的RAM中,然后将控制权交给OS BootLoader。BootLoader的主要运行任务就是将内核映象从硬盘上读到 RAM 中,然后跳转到内核的入口点去运行,也即开始启动操作系统。
而在嵌入式系统中,通常并没有像BIOS那样的固件程序(注,有的嵌入式CPU也会内嵌一段短小的启动程序),因此整个系统的加载启动任务就完全由BootLoader来完成。比如在一个基于ARM7TDMI core的嵌入式系统中,系统在上电或复位时通常都从地址0x00000000处开始执行,而在这个地址处安排的通常就是系统的BootLoader程序。
简单地说,BootLoader就是在操作系统内核运行之前运行的一段小程序。通过这段小程序,我们可以初始化硬件设备、建立内存空间的映射图,从而将系统的软硬件环境带到一个合适的状态,以便为最终调用操作系统内核准备好正确的环境。
通常,BootLoader是严重地依赖于硬件而实现的,特别是在嵌入式世界。因此,在嵌入式世界里建立一个通用的BootLoader几乎是不可能的。尽管如此,我们仍然可以对BootLoader归纳出一些通用的概念来,以指导用户特定的BootLoader设计与实现。
二.U-BOOT介绍
uboot是一个庞大的公开源码的软件。他支持一些系列的arm体系,包含常见的外设的驱动,是一个功能强大的板极支持包。其代码可以从http://sourceforge.net/projects/u-boot下载
U-BOOT是由PPCBOOT发展起来的,是PowerPC、ARM9、Xscale、X86等系统通用的Boot方案,从官方版本0.3.2开始全面支持SC系列单板机。u-boot是一个open source的bootloader,目前版本是0.4.0。u-boot是在ppcboot以及armboot的基础上发展而来,虽然宣称是0.4.0版本,却相当的成熟和稳定,已经在许多嵌入式系统开发过程中被采用。由于其开发源代码,其支持的开发板众多。唯一遗憾的是并不支持我们现在学习所用samsung 44B0X的开发板。
为什么我们需要u-boot?显然可以将ucLinux直接烧入flash,从而不需要额外的引导装载程序(bootloader)。但是从软件升级的角度以及程序修补的来说,软件的自动更新非常重要。事实上,引导装载程序(bootloader)的用途不仅如此,但仅从软件的自动更新的需要就说明我们的开发是必要的。
同时,u-boot移植的过程也是一个对嵌入式系统包括软硬件以及操作系统加深理解的一个过程。
三.disk模块分析
part.c:输出设备信息
part_amiga.c:处理amiga分区
part_dos.c:处理dos分区
part_iso.c:处理iso分区
part_mac.c:处理mac分区

Part.c
文件:
void dev_print (block_dev_desc_t *dev_desc)
{//主要用来向用户报告设备信息
……
    if (dev_desc->type==DEV_TYPE_UNKNOWN) {//设备未知
        puts ("not available/n");
        return;
    }
    ……
    puts ("            Type: ");
    if (dev_desc->removable)    //设备可移除
        puts ("Removable ");
    switch (dev_desc->type & 0x1F) {    //输出设备类型
        case DEV_TYPE_HARDDISK: puts ("Hard Disk");
                    break;
        case DEV_TYPE_CDROM:    puts ("CD ROM");
                    break;
        case DEV_TYPE_OPDISK:  puts ("Optical Device");
                    break;
        case DEV_TYPE_TAPE:     puts ("Tape");
                    break;
        default:        printf ("# %02X #", dev_desc->type & 0x1F);
                    break;
    }
    puts ("/n");
    if ((dev_desc->lba * dev_desc->blksz)>0L) {
        ulong mb, mb_quot, mb_rem, gb, gb_quot, gb_rem;
        lbaint_t lba;
        lba = dev_desc->lba;
        lba512 = (lba * (dev_desc->blksz/512));
        mb = (10 * lba512) / 2048; /* 2048 = (1024 * 1024) / 512 MB */
        /* round to 1 digit */
        mb_quot = mb / 10;
        mb_rem = mb - (10 * mb_quot);
        gb = mb / 1024;
        gb_quot = gb / 10;
        gb_rem = gb - (10 * gb_quot);
……
    }
else { puts ("            Capacity: not available/n");   }
}
……
void init_part (block_dev_desc_t * dev_desc)    //对分区iso,mac,dos,amiga进行初始化
{
#ifdef CONFIG_ISO_PARTITION //对应iso分区
    ……
#endif
#ifdef CONFIG_MAC_PARTITION //对应mac分区
    ……
#endif
#ifdef CONFIG_DOS_PARTITION //对应dos分区
    ……
#endif
#ifdef CONFIG_AMIGA_PARTITION//对应amiga分区
    ……
#endif
}
int get_partition_info (block_dev_desc_t *dev_desc, int part, disk_partition_t *info)
{   //获得不同分区的分区信息
        switch (dev_desc->part_type) {
#ifdef CONFIG_MAC_PARTITION //对应mac分区,以下略
    ……
#endif
……
    default:
        break;
    }
    return (-1);
}
static void print_part_header (const char *type, block_dev_desc_t * dev_desc)
{   //输出设备、分区类型,如IDE, SCSI, ATAPI, USB, DOC, UNKNOWN
    puts ("/nPartition Map for ");
    switch (dev_desc->if_type) {
        case IF_TYPE_IDE: puts ("IDE");
                    break;
        ……
        default:        puts ("UNKNOWN");
                    break;
    }
    printf (" device %d --   Partition Type: %s/n/n",
            dev_desc->dev, type);
}
void print_part (block_dev_desc_t * dev_desc)
{   //输出分区信息
        switch (dev_desc->part_type) {
#ifdef CONFIG_MAC_PARTITION
    ……
#endif
#ifdef CONFIG_DOS_PARTITION
    ……
#endif
#ifdef CONFIG_ISO_PARTITION
    ……
#endif
#ifdef CONFIG_AMIGA_PARTITION
    ……
#endif
    }
    puts ("## Unknown partition table/n");
}
Part_amiga文件:
static void bcpl_strcpy(char *to, char *from)
{   //将bcpl转换成c string
    int len = *from++;
    while (len)
    {    *to++ = *from++;    len--;    }
    *to = 0;
}
static void bstr_print(char *string)
{   //输出一个bcpl字符串。Bcpl字符串第一个byte保存了该字符串的长度
    ……
}
int sum_block(struct block_header *header)
{   //计算一个块的大小,块以0结束
……
    for (i = 0; i < header->summed_longs; i++)
    sum += *block++;
    return (sum != 0);
}
static void print_disk_type(u32 disk_type)
{   //输出amigaOS 磁盘类型,一般由四个字节表示,例如DOS/0表示original file system,SFS/0表示SmartFileSystem,DOS/1表示FFS.
    char buffer[6];
    buffer[0] = (disk_type & 0xFF000000)>>24;
    buffer[1] = (disk_type & 0x00FF0000)>>16;
    buffer[2] = (disk_type & 0x0000FF00)>>8;
    buffer[3] = '//';
    buffer[4] = (disk_type & 0x000000FF) + '0';
    buffer[5] = 0;
    printf("%s", buffer);
}
static void print_part_info(struct partition_block *p)
{   //输出给定分区块内的信息
……
    bstr_print(p->drive_name);
    printf("%6d/t%6d/t",
       g->low_cyl * g->block_per_track * g->surfaces ,
       (g->high_cyl - g->low_cyl + 1) * g->block_per_track * g->surfaces - 1);
    print_disk_type(g->dos_type);
    printf("/t%5d/n", g->boot_priority);
}
struct rigid_disk_block *get_rdisk(block_dev_desc_t *dev_desc)
{   //寻找Rigid Disk块。该块必须位于设备的最前面的16个块中
    ……
   if (res == 1)
    {
        struct rigid_disk_block *trdb = (struct rigid_disk_block *)block_buffer;
        if (trdb->id == AMIGA_ID_RDISK)
        {
        PRINTF("Rigid disk block suspect at %d, checking checksum/n",i);
        if (sum_block((struct block_header *)block_buffer) == 0)
        {
            PRINTF("FOUND/n");
            memcpy(&rdb, trdb, sizeof(struct rigid_disk_block));
            return (struct rigid_disk_block *)&rdb;
        }
        }
    }
    }
    PRINTF("Done scanning, no RDB found/n");
    return NULL;
}
struct bootcode_block *get_bootcode(block_dev_desc_t *dev_desc)
{   //寻找启动代码,它必须在块设备前16个块中,或者在Ridgid块中
    ……
    PRINTF("Scanning for BOOT from 0 to %d/n", limit);
    for (i = 0; i < limit; i++)
    {
    ulong res = dev_desc->block_read(dev_desc->dev, i, 1, (ulong *)block_buffer);
    if (res == 1)
    {
        struct bootcode_block *boot = (struct bootcode_block *)block_buffer;
        if (boot->id == AMIGA_ID_BOOT)
        {
        PRINTF("BOOT block at %d, checking checksum/n", i);
        if (sum_block((struct block_header *)block_buffer) == 0)
        {
            PRINTF("Found valid bootcode block/n");
            memcpy(&bootcode, boot, sizeof(struct bootcode_block));
            return &bootcode;
        }
        }
    }
    }
    PRINTF("No boot code found on disk/n");
    return 0;
}
int test_part_amiga(block_dev_desc_t *dev_desc)
{   //测试给定分区是否有amiga分区表/rigid块
    ……
    PRINTF("test_part_amiga: Testing for an Amiga RDB partition/n");
    rdb = get_rdisk(dev_desc);
    if (rdb)
    {
    bootcode = get_bootcode(dev_desc);
    if (bootcode)
        PRINTF("test_part_amiga: bootable Amiga disk/n");
    else
        PRINTF("test_part_amiga: non-bootable Amiga disk/n");
    return 0;
    }
    else
    {
    PRINTF("test_part_amiga: no RDB found/n");
    return -1;
    }
}
static struct partition_block *find_partition(block_dev_desc_t *dev_desc, int partnum)
{   //寻找指定分区号的分区
   ……
    PRINTF("Trying to find partition block %d/n", partnum);
    ……
    while (block != 0xFFFFFFFF)
    {
    ulong res = dev_desc->block_read(dev_desc->dev, block, 1,
                     (ulong *)block_buffer);
    if (res == 1)
    {
        p = (struct partition_block *)block_buffer;
        if (p->id == AMIGA_ID_PART)
        {
        PRINTF("PART block suspect at 0x%x, checking checksum/n",block);
        if (sum_block((struct block_header *)p) == 0)
        {
            if (partnum == 0) break;
            else
            {
            partnum--;
            block = p->next;
            }
        }
        } else block = 0xFFFFFFFF;
    } else block = 0xFFFFFFFF;
    }
……
    return (struct partition_block *)block_buffer;
}
int get_partition_info_amiga (block_dev_desc_t *dev_desc, int part, disk_partition_t *info)
{   //获取一个分区的信息
    ……
    if (!p) return -1;
    g = (struct amiga_part_geometry *)&(p->environment);
    info->start = g->low_cyl * g->block_per_track * g->surfaces;
    info->size = (g->high_cyl - g->low_cyl + 1) * g->block_per_track * g->surfaces - 1;
    info->blksz = rdb.block_bytes;
    bcpl_strcpy(info->name, p->drive_name);
    disk_type = g->dos_type;
    info->type[0] = (disk_type & 0xFF000000)>>24;
    info->type[1] = (disk_type & 0x00FF0000)>>16;
    info->type[2] = (disk_type & 0x0000FF00)>>8;
    info->type[3] = '//';
    info->type[4] = (disk_type & 0x000000FF) + '0';
    info->type[5] = 0;
    return 0;
}
void print_part_amiga (block_dev_desc_t *dev_desc)
{   //输出分区信息
    ……
    PRINTF("print_part_amiga: Scanning partition list/n");
    block = rdb->partition_list;
    PRINTF("print_part_amiga: partition list at 0x%x/n", block);
    printf("Summary: DiskBlockSize: %d/n"
       "          Cylinders    : %d/n"
       "          Sectors/Track: %d/n"
       "          Heads        : %d/n/n",
       rdb->block_bytes, rdb->cylinders, rdb->sectors,
       rdb->heads);
    printf("                 First   Num. /n"
       "Nr. Part. Name Block   Block Type        Boot Priority/n");
    ……
    boot = get_bootcode(dev_desc);
    if (boot)
    {    printf("Disk is bootable/n");    }
}

static void print_one_part (dos_partition_t *p, int ext_part_sector, int part_num)

{//打印一个分区信息

    ……

    printf ("%5d/t/t%10d/t%10d/t%2x%s/n",

        part_num, lba_start, lba_size, p->sys_ind,

        (is_extended (p->sys_ind) ? " Extd" : ""));

}

static int test_block_type(unsigned char *buffer)

{   //测试块类型

    if((buffer[DOS_PART_MAGIC_OFFSET + 0] != 0x55) ||

        (buffer[DOS_PART_MAGIC_OFFSET + 1] != 0xaa) ) {

        return (-1);

    }   //不是dos

    if(strncmp(&buffer[DOS_PBR_FSTYPE_OFFSET],"FAT",3)==0)

        return DOS_PBR; /* is PBR */

    return DOS_MBR;     /* Is MBR */

}

int test_part_dos (block_dev_desc_t *dev_desc)

{   //测试是否为dos

    unsigned char buffer[DEFAULT_SECTOR_SIZE];

    if ((dev_desc->block_read(dev_desc->dev, 0, 1, (ulong *) buffer) != 1) ||

        (buffer[DOS_PART_MAGIC_OFFSET + 0] != 0x55) ||

        (buffer[DOS_PART_MAGIC_OFFSET + 1] != 0xaa) ) {

        return (-1);

    }

    return (0);

}

static void print_partition_extended (block_dev_desc_t *dev_desc, int ext_part_sector, int relative, int part_num)

{   //输出与其扩展分区表有关的分区信息

    ……

    //输出所有主要/逻辑分区

    pt = (dos_partition_t *) (buffer + DOS_PART_TBL_OFFSET);

    for (i = 0; i < 4; i++, pt++) {//文件系统不显示MBR以外的分区

        if ((pt->sys_ind != 0) &&

            (ext_part_sector == 0 || !is_extended (pt->sys_ind)) ) {

            print_one_part (pt, ext_part_sector, part_num);

        }

        /* Reverse engr the fdisk part# assignment rule! */

        if ((ext_part_sector == 0) ||

            (pt->sys_ind != 0 && !is_extended (pt->sys_ind)) ) {

            part_num++;

        }

    }

    //处理扩展分区

    pt = (dos_partition_t *) (buffer + DOS_PART_TBL_OFFSET);

    for (i = 0; i < 4; i++, pt++) {

        if (is_extended (pt->sys_ind)) {

            int lba_start = le32_to_int (pt->start4) + relative;

            print_partition_extended (dev_desc, lba_start,

                          ext_part_sector == 0  ? lba_start

                                    : relative,

                          part_num);

        }

    }

    return;

}

static int get_partition_info_extended (block_dev_desc_t *dev_desc, int ext_part_sector,    int relative, int part_num, int which_part, disk_partition_t *info)

{   //获取与其扩展分区表有关的分区信息

    ……

}

……

Part_iso.c文件:

int get_partition_info_iso_verb(block_dev_desc_t * dev_desc, int part_num, disk_partition_t * info, int verb)

{   //获得iso设备块的分区信息

    ……

    //第一部分必须是主要卷

    blkaddr=PVD_OFFSET;

    if (dev_desc->block_read (dev_desc->dev, PVD_OFFSET, 1, (ulong *) tmpbuf) != 1)

   return (-1);

    if(ppr->desctype!=0x01) {

        if(verb)

            printf ("** First descriptor is NOT a primary desc on %d:%d **/n",

                dev_desc->dev, part_num);

        return (-1);

    }

    if(strncmp(ppr->stand_ident,"CD001",5)!=0) {

        if(verb)

            printf ("** Wrong ISO Ident: %s on %d:%d **/n",

                ppr->stand_ident,dev_desc->dev, part_num);

        return (-1);

    }

    ……

    //寻找入口

    if(strncmp(pbr->ident_str,"EL TORITO SPECIFICATION",23)!=0) {

        if(verb)

            printf ("** Wrong El Torito ident: %s on %d:%d **/n",

                pbr->ident_str,dev_desc->dev, part_num);

        return (-1);

    }

    bootaddr=le32_to_int(pbr->pointer);

    PRINTF(" Boot Entry at: %08lX/n",bootaddr);

    if (dev_desc->block_read (dev_desc->dev, bootaddr, 1, (ulong *) tmpbuf) != 1) {

        if(verb)

            printf ("** Can't read Boot Entry at %lX on %d:%d **/n",

                bootaddr,dev_desc->dev, part_num);

        return (-1);

    }

……

    //找到有效入口,现在寻找分区

    entry_num=0;

    offset=0x20;

    sprintf (info->type, "U-Boot");

    switch(dev_desc->if_type) {

        case IF_TYPE_IDE:

        case IF_TYPE_ATAPI:

            sprintf (info->name, "hd%c%d/n", 'a' + dev_desc->dev, part_num);

            break;

        ……

        default:

            sprintf (info->name, "xx%c%d/n", 'a' + dev_desc->dev, part_num);

            break;

    }

    //bootcatalog (including validation Entry)必须小于 2048Bytes

    while(offset<2048) {

        pide=(iso_init_def_entry_t *)&tmpbuf[offset];

        if ((pide->boot_ind==0x88) ||

            (pide->boot_ind==0x00)) {    //默认入口的id

            if(entry_num==part_num) { //找到分区

                goto found;

            }

            entry_num++; //记录分区入口数

            offset+=0x20;

            continue;

        }

        if ((pide->boot_ind==0x90) ||   /* Section Header Entry */

            (pide->boot_ind==0x91) ||    /* Section Header Entry (last) */

            (pide->boot_ind==0x44)) {    /* Extension Indicator */

            offset+=0x20; //跳过不使用的入口

        }

        else {

            if(verb)

                printf ("** Partition %d not found on device %d **/n",

                    part_num,dev_desc->dev);

            return(-1);

        }

    }

    ……

    newblkaddr=le32_to_int(pide->rel_block_addr);

    info->start=newblkaddr;

    PRINTF(" part %d found @ %lx size %lx/n",part_num,newblkaddr,info->size);

    return 0;

}

int get_partition_info_iso(block_dev_desc_t * dev_desc, int part_num, disk_partition_t * info)

{

    return(get_partition_info_iso_verb(dev_desc, part_num, info, 1));

}

void print_part_iso(block_dev_desc_t * dev_desc)

{   //打印分区信息

    disk_partition_t info;

    int i;

    if(get_partition_info_iso_verb(dev_desc,0,&info,0)==-1) {

        printf("** No boot partition found on device %d **/n",dev_desc->dev);

        return;

    }

    printf("Part   Start     Sect x Size Type/n");

    i=0;

    do {

        printf (" %2d %8ld %8ld %6ld %.32s/n",

            i, info.start, info.size, info.blksz, info.type);

        i++;

    } while (get_partition_info_iso_verb(dev_desc,i,&info,0)!=-1);

}

int test_part_iso (block_dev_desc_t *dev_desc)

{   测试是否为iso分区

    disk_partition_t info;

    return(get_partition_info_iso_verb(dev_desc,0,&info,0));

}

Part_mac.c文件:

int test_part_mac (block_dev_desc_t *dev_desc)

{   //检查是否为有效的mac分区

    ……

    if (part_mac_read_ddb (dev_desc, &ddesc)) {//读块错误,或无有效信息

        return (-1);    }

    n = 1;  //假设最少有一个分区

    for (i=1; i<=n; ++i) {

        if ((dev_desc->block_read(dev_desc->dev, i, 1, (ulong *)&mpart) != 1) ||

            (mpart.signature != MAC_PARTITION_MAGIC) ) {

            return (-1);

        }

        n = mpart.map_count;更新分区数

    }

    return (0);

}

void print_part_mac (block_dev_desc_t *dev_desc)

{   //输出mac分区信息

    ……

    if (part_mac_read_ddb (dev_desc, &ddesc)) {

        /* error reading Driver Desriptor Block, or no valid Signature */

        return;

    }

    n  = ddesc.blk_count;

……

    printf ("Block Size=%d, Number of Blocks=%d, "

        "Total Capacity: %ld.%ld MB = %ld.%ld GB/n"

        "DeviceType=0x%x, DeviceId=0x%x/n/n"

        "   #:                 type name"

        "                   length   base       (size)/n",

        ddesc.blk_size,

        ddesc.blk_count,

        mb.quot, mb.rem, gb.quot, gb.rem,

        ddesc.dev_type, ddesc.dev_id

        );

    n = 1;  //假设最少有一个分区

    for (i=1; i<=n; ++i) {

        ……

        printf ("%20.32s %-18.32s %10u @ %-10u (%3ld%c)/n",

            mpart.type,

            mpart.name,

            mpart.block_count,

            mpart.start_block,

            bytes, c

            );

    }

    return;

}

static int part_mac_read_ddb (block_dev_desc_t *dev_desc, mac_driver_desc_t *ddb_p)

{   //读取设备描述块信息

    ……

    if (ddb_p->signature != MAC_DRIVER_MAGIC) {

#if 0

        printf ("** Bad Signature: expected 0x%04x, got 0x%04x/n",

            MAC_DRIVER_MAGIC, ddb_p->signature);

#endif

        return (-1);

    }

    return (0);

}

static int part_mac_read_pdb (block_dev_desc_t *dev_desc, int part, mac_partition_t *pdb_p)

{   //读取分区描述块信息

    int n = 1;

    for (;;) {  //必须从第一个分区开始读描述块,只有这样才能知道一共有多少个分区

        if (dev_desc->block_read (dev_desc->dev, n, 1, (ulong *)pdb_p) != 1) {

            printf ("** Can't read Partition Map on %d:%d **/n",

                dev_desc->dev, n);

            return (-1);

        }

        if (pdb_p->signature != MAC_PARTITION_MAGIC) {

            printf ("** Bad Signature on %d:%d: "

                "expected 0x%04x, got 0x%04x/n",

                dev_desc->dev, n, MAC_PARTITION_MAGIC, pdb_p->signature);

            return (-1);

        }

        if (n == part)

            return (0);

        if ((part < 1) || (part > pdb_p->map_count)) {

            printf ("** Invalid partition %d:%d [%d:1...%d:%d only]/n",

                dev_desc->dev, part,

                dev_desc->dev,

                dev_desc->dev, pdb_p->map_count);

            return (-1);

        }

        n = part;   //更新分区数

    }

}

int get_partition_info_mac (block_dev_desc_t *dev_desc, int part, disk_partition_t *info)

{   //获取mac分区的信息

    mac_driver_desc_t   ddesc;

    mac_partition_t     mpart;

    if (part_mac_read_ddb (dev_desc, &ddesc)) {

        return (-1);

    }

    info->blksz = ddesc.blk_size;

    if (part_mac_read_pdb (dev_desc, part, &mpart)) {

        return (-1);

    }

    info->start = mpart.start_block;

    info->size  = mpart.block_count;

    memcpy (info->type, mpart.type, sizeof(info->type));

    memcpy (info->name, mpart.name, sizeof(info->name));

    return (0);

}

四.常用U-BOOT命令介绍

1.list 得到所有命令列表
2.help: help usb, 列出USB功能的使用说明
3.ping:注:只能开发板PING别的机器
4.setenv: 设置互环境变量:
5.setenv serverip 192.168.0.1
6.setenv ipaddr 192.168.0.56
7.setenv bootcmd ‘
tftp 32000000 vmlinux; kgo 32000000’
8.saveenv: 保存环境变量

9.在设置好环境变量以后, 保存变量值
10.tftp: tftp 32000000 vmlinux, 把server(IP=环境变量中设置的serverip)中/tftpdroot/ 下的vmlinux通过TFTP读入到物理内存32000000处。
11.kgo: 起动没有压缩的linux内核,kgo 32000000
12.bootm:起动UBOOT  TOOLS制作的压缩LINUX内核
, bootm 3200000
13.protect: 对FLASH进行写保护或取消写保护, protect on 1:0-3(就是对第一块FLASH的0-3扇区进行保护),protect off 1:0-3取消写保护

14.erase: 删除FLASH的扇区, erase 1:0-2(就是对每一块FLASH的0-2扇区进行删除)
15.cp: 在内存中复制内容, cp 32000000 0 40000(把内存中0x32000000开始的0x40000字节复制到0x0处
)
16.mw: 对RAM中的内容写操作, mw 32000000 ff 10000(把内存0x32000000开始的0x10000字节设为
0xFF)
17.md: 修改RAM中的内容, md 32000000(内存的起始地址)

18.usb:
lusb start:
起动usb 功能
lusb info: 列出设备
lusb scan: 扫描usb storage(u 盘)设备
19.fatls:列出DOS FAT文件系统, 如:fatls usb 0列出第一块U盘中的文件
20.fatload: 读入FAT中的一个文件,如:fatload usb 0:0 32000000 aa.txt
21.把USB中的aa.txt 读到物理内存0x32000000处!

22.flinfo: 列出flash的信息
23.loadb: 准备用KERMIT协议接收来自kermit或超级终端传送的文件。
24.nfs: nfs 32000000 192.168.0.2:aa.txt , 把192.168.0.2(LINUX 的NFS文件系统)中的NFS文件系统中的aa.txt 读入内存0x32000000处。

原创粉丝点击