日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

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

發(fā)布時(shí)間:2025/4/16 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 U-BOOT介绍以及disk模块源码分析 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
一. BootLoader簡(jiǎn)介 在專用的嵌入式板子運(yùn)行GNU/Linux系統(tǒng)已經(jīng)變得越來(lái)越流行。一個(gè)嵌入式Linux系統(tǒng)從軟件的角度看通常可以分為四個(gè)層次: 1、 引導(dǎo)加載程序。包括固化在固件(firmware)中的boot代碼(可選),和BootLoader兩大部分。 2、 Linux內(nèi)核。特定于嵌入式板子的定制內(nèi)核以及內(nèi)核的啟動(dòng)參數(shù)。 3、 文件系統(tǒng)。包括根文件系統(tǒng)和建立于Flash內(nèi)存設(shè)備之上文件系統(tǒng)。通常用ramdisk來(lái)作為rootfs。 4、 用戶應(yīng)用程序。特定于用戶的應(yīng)用程序。有時(shí)在用戶應(yīng)用程序和內(nèi)核層之間可能還會(huì)包括一個(gè)嵌入式圖形用戶界面。常用的嵌入式GUI有:MicroWindows和MiniGUI懂。 引導(dǎo)加載程序是系統(tǒng)加電后運(yùn)行的第一段軟件代碼。PC機(jī)中的引導(dǎo)加載程序由BIOS(其本質(zhì)就是一段固件程序)和位于硬盤MBR中的OS BootLoader(比如,LILO和GRUB等)一起組成。BIOS在完成硬件檢測(cè)和資源分配后,將硬盤MBR中的BootLoader讀到系統(tǒng)的RAM中,然后將控制權(quán)交給OS BootLoader。BootLoader的主要運(yùn)行任務(wù)就是將內(nèi)核映象從硬盤上讀到 RAM 中,然后跳轉(zhuǎn)到內(nèi)核的入口點(diǎn)去運(yùn)行,也即開始啟動(dòng)操作系統(tǒng)。 而在嵌入式系統(tǒng)中,通常并沒(méi)有像BIOS那樣的固件程序(注,有的嵌入式CPU也會(huì)內(nèi)嵌一段短小的啟動(dòng)程序),因此整個(gè)系統(tǒng)的加載啟動(dòng)任務(wù)就完全由BootLoader來(lái)完成。比如在一個(gè)基于ARM7TDMI core的嵌入式系統(tǒng)中,系統(tǒng)在上電或復(fù)位時(shí)通常都從地址0x00000000處開始執(zhí)行,而在這個(gè)地址處安排的通常就是系統(tǒng)的BootLoader程序。 簡(jiǎn)單地說(shuō),BootLoader就是在操作系統(tǒng)內(nèi)核運(yùn)行之前運(yùn)行的一段小程序。通過(guò)這段小程序,我們可以初始化硬件設(shè)備、建立內(nèi)存空間的映射圖,從而將系統(tǒng)的軟硬件環(huán)境帶到一個(gè)合適的狀態(tài),以便為最終調(diào)用操作系統(tǒng)內(nèi)核準(zhǔn)備好正確的環(huán)境。 通常,BootLoader是嚴(yán)重地依賴于硬件而實(shí)現(xiàn)的,特別是在嵌入式世界。因此,在嵌入式世界里建立一個(gè)通用的BootLoader幾乎是不可能的。盡管如此,我們?nèi)匀豢梢詫?duì)BootLoader歸納出一些通用的概念來(lái),以指導(dǎo)用戶特定的BootLoader設(shè)計(jì)與實(shí)現(xiàn)。 二.U-BOOT介紹 uboot是一個(gè)龐大的公開源碼的軟件。他支持一些系列的arm體系,包含常見的外設(shè)的驅(qū)動(dòng),是一個(gè)功能強(qiáng)大的板極支持包。其代碼可以從http://sourceforge.net/projects/u-boot下載 U-BOOT是由PPCBOOT發(fā)展起來(lái)的,是PowerPC、ARM9、Xscale、X86等系統(tǒng)通用的Boot方案,從官方版本0.3.2開始全面支持SC系列單板機(jī)。u-boot是一個(gè)open source的bootloader,目前版本是0.4.0。u-boot是在ppcboot以及armboot的基礎(chǔ)上發(fā)展而來(lái),雖然宣稱是0.4.0版本,卻相當(dāng)?shù)某墒旌头€(wěn)定,已經(jīng)在許多嵌入式系統(tǒng)開發(fā)過(guò)程中被采用。由于其開發(fā)源代碼,其支持的開發(fā)板眾多。唯一遺憾的是并不支持我們現(xiàn)在學(xué)習(xí)所用samsung 44B0X的開發(fā)板。 為什么我們需要u-boot?顯然可以將ucLinux直接燒入flash,從而不需要額外的引導(dǎo)裝載程序(bootloader)。但是從軟件升級(jí)的角度以及程序修補(bǔ)的來(lái)說(shuō),軟件的自動(dòng)更新非常重要。事實(shí)上,引導(dǎo)裝載程序(bootloader)的用途不僅如此,但僅從軟件的自動(dòng)更新的需要就說(shuō)明我們的開發(fā)是必要的。 同時(shí),u-boot移植的過(guò)程也是一個(gè)對(duì)嵌入式系統(tǒng)包括軟硬件以及操作系統(tǒng)加深理解的一個(gè)過(guò)程。 三.disk模塊分析 part.c:輸出設(shè)備信息 part_amiga.c:處理amiga分區(qū) part_dos.c:處理dos分區(qū) part_iso.c:處理iso分區(qū) part_mac.c:處理mac分區(qū)
Part.c
文件:
void dev_print (block_dev_desc_t *dev_desc) {//主要用來(lái)向用戶報(bào)告設(shè)備信息 …… if (dev_desc->type==DEV_TYPE_UNKNOWN) {//設(shè)備未知 puts ("not available/n"); return; } …… puts ("??????????? Type: "); if (dev_desc->removable)??? //設(shè)備可移除 puts ("Removable "); switch (dev_desc->type & 0x1F) {??? //輸出設(shè)備類型 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)??? //對(duì)分區(qū)iso,mac,dos,amiga進(jìn)行初始化 { #ifdef CONFIG_ISO_PARTITION //對(duì)應(yīng)iso分區(qū) …… #endif #ifdef CONFIG_MAC_PARTITION //對(duì)應(yīng)mac分區(qū) …… #endif #ifdef CONFIG_DOS_PARTITION //對(duì)應(yīng)dos分區(qū) …… #endif #ifdef CONFIG_AMIGA_PARTITION//對(duì)應(yīng)amiga分區(qū) …… #endif } int get_partition_info (block_dev_desc_t *dev_desc, int part, disk_partition_t *info) {?? //獲得不同分區(qū)的分區(qū)信息 switch (dev_desc->part_type) { #ifdef CONFIG_MAC_PARTITION //對(duì)應(yīng)mac分區(qū),以下略 …… #endif …… default: break; } return (-1); } static void print_part_header (const char *type, block_dev_desc_t * dev_desc) {?? //輸出設(shè)備、分區(qū)類型,如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) {?? //輸出分區(qū)信息 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轉(zhuǎn)換成c string int len = *from++; while (len) {??? *to++ = *from++;??? len--;??? } *to = 0; } static void bstr_print(char *string) {?? //輸出一個(gè)bcpl字符串。Bcpl字符串第一個(gè)byte保存了該字符串的長(zhǎng)度 …… } int sum_block(struct block_header *header) {?? //計(jì)算一個(gè)塊的大小,塊以0結(jié)束 …… for (i = 0; i < header->summed_longs; i++) sum += *block++; return (sum != 0); } static void print_disk_type(u32 disk_type) {?? //輸出amigaOS 磁盤類型,一般由四個(gè)字節(jié)表示,例如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) {?? //輸出給定分區(qū)塊內(nèi)的信息 …… 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塊。該塊必須位于設(shè)備的最前面的16個(gè)塊中 …… 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) {?? //尋找啟動(dòng)代碼,它必須在塊設(shè)備前16個(gè)塊中,或者在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) {?? //測(cè)試給定分區(qū)是否有amiga分區(qū)表/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) {?? //尋找指定分區(qū)號(hào)的分區(qū) …… 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) {?? //獲取一個(gè)分區(qū)的信息 …… 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) {?? //輸出分區(qū)信息 …… 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)

{//打印一個(gè)分區(qū)信息

??? ……

??? 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)

{?? //測(cè)試塊類型

??? 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)

{?? //測(cè)試是否為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)

{?? //輸出與其擴(kuò)展分區(qū)表有關(guān)的分區(qū)信息

??? ……

??? //輸出所有主要/邏輯分區(qū)

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

??? for (i = 0; i < 4; i++, pt++) {//文件系統(tǒng)不顯示MBR以外的分區(qū)

??????? 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++;

??????? }

??? }

??? //處理擴(kuò)展分區(qū)

??? 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)

{?? //獲取與其擴(kuò)展分區(qū)表有關(guān)的分區(qū)信息

??? ……

}

……

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設(shè)備塊的分區(qū)信息

??? ……

??? //第一部分必須是主要卷

??? 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);

??? }

……

??? //找到有效入口,現(xiàn)在尋找分區(qū)

??? 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)) {??? //默認(rèn)入口的id

??????????? if(entry_num==part_num) { //找到分區(qū)

??????????????? goto found;

??????????? }

??????????? entry_num++; //記錄分區(qū)入口數(shù)

??????????? 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; //跳過(guò)不使用的入口

??????? }

??????? 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)

{?? //打印分區(qū)信息

??? 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)

{?? 測(cè)試是否為iso分區(qū)

??? 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分區(qū)

??? ……

??? if (part_mac_read_ddb (dev_desc, &ddesc)) {//讀塊錯(cuò)誤,或無(wú)有效信息

??????? return (-1);??? }

??? n = 1;? //假設(shè)最少有一個(gè)分區(qū)

??? 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;更新分區(qū)數(shù)

??? }

??? return (0);

}

void print_part_mac (block_dev_desc_t *dev_desc)

{?? //輸出mac分區(qū)信息

??? ……

??? 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;? //假設(shè)最少有一個(gè)分區(qū)

??? 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)

{?? //讀取設(shè)備描述塊信息

??? ……

??? 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)

{?? //讀取分區(qū)描述塊信息

??? int n = 1;

??? for (;;) {? //必須從第一個(gè)分區(qū)開始讀描述塊,只有這樣才能知道一共有多少個(gè)分區(qū)

??????? 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;?? //更新分區(qū)數(shù)

??? }

}

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

{?? //獲取mac分區(qū)的信息

??? 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功能的使用說(shuō)明
3.ping:注:只能開發(fā)板PING別的機(jī)器
4.setenv: 設(shè)置互環(huán)境變量:
5.setenv serverip 192.168.0.1
6.setenv ipaddr 192.168.0.56
7.setenv bootcmd ‘
tftp 32000000 vmlinux; kgo 32000000’
8.saveenv: 保存環(huán)境變量

9.在設(shè)置好環(huán)境變量以后, 保存變量值
10.tftp: tftp 32000000 vmlinux, 把server(IP=環(huán)境變量中設(shè)置的serverip)中/tftpdroot/ 下的vmlinux通過(guò)TFTP讀入到物理內(nèi)存32000000處。
11.kgo: 起動(dòng)沒(méi)有壓縮的linux內(nèi)核,kgo 32000000
12.bootm:起動(dòng)UBOOT? TOOLS制作的壓縮LINUX內(nèi)核
, bootm 3200000
13.protect: 對(duì)FLASH進(jìn)行寫保護(hù)或取消寫保護(hù), protect on 1:0-3(就是對(duì)第一塊FLASH的0-3扇區(qū)進(jìn)行保護(hù)),protect off 1:0-3取消寫保護(hù)

14.erase: 刪除FLASH的扇區(qū), erase 1:0-2(就是對(duì)每一塊FLASH的0-2扇區(qū)進(jìn)行刪除)
15.cp: 在內(nèi)存中復(fù)制內(nèi)容, cp 32000000 0 40000(把內(nèi)存中0x32000000開始的0x40000字節(jié)復(fù)制到0x0處
)
16.mw: 對(duì)RAM中的內(nèi)容寫操作, mw 32000000 ff 10000(把內(nèi)存0x32000000開始的0x10000字節(jié)設(shè)為
0xFF)
17.md: 修改RAM中的內(nèi)容, md 32000000(內(nèi)存的起始地址)

18.usb:
lusb start:
起動(dòng)usb 功能
lusb info: 列出設(shè)備
lusb scan: 掃描usb storage(u 盤)設(shè)備
19.fatls:列出DOS FAT文件系統(tǒng), 如:fatls usb 0列出第一塊U盤中的文件
20.fatload: 讀入FAT中的一個(gè)文件,如:fatload usb 0:0 32000000 aa.txt
21.把USB中的aa.txt 讀到物理內(nèi)存0x32000000處!

22.flinfo: 列出flash的信息
23.loadb: 準(zhǔn)備用KERMIT協(xié)議接收來(lái)自kermit或超級(jí)終端傳送的文件。
24.nfs: nfs 32000000 192.168.0.2:aa.txt , 把192.168.0.2(LINUX 的NFS文件系統(tǒng))中的NFS文件系統(tǒng)中的aa.txt 讀入內(nèi)存0x32000000處。

總結(jié)

以上是生活随笔為你收集整理的U-BOOT介绍以及disk模块源码分析的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。