




已阅读5页,还剩13页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
一 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体系,包含常见的外设的驱动,是一个功能强大的板极支持包。其代码可以从/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 availablen);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 availablen);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分区#endifint 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分区,以下略#endifdefault:break;return (-1);static void print_part_header (const char *type, block_dev_desc_t * dev_desc)/输出设备、分区类型,如IDE, SCSI, ATAPI, USB, DOC, UNKNOWNputs (nPartition Map for );switch (dev_desc-if_type) case IF_TYPE_IDE: puts (IDE);break;default: puts (UNKNOWN);break;printf ( device %d - Partition Type: %snn,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#endifputs (# Unknown partition tablen);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 summed_longs; i+)sum += *block+; return (sum != 0);static void print_disk_type(u32 disk_type)/输出amigaOS 磁盘类型,一般由四个字节表示,例如DOS0表示original file system,SFS0表示SmartFileSystem,DOS1表示FFS. char buffer6; buffer0 = (disk_type & 0xFF000000)24; buffer1 = (disk_type & 0x00FF0000)16; buffer2 = (disk_type & 0x0000FF00)8; buffer3 = ; buffer4 = (disk_type & 0x000000FF) + 0; buffer5 = 0; printf(%s, buffer);static void print_part_info(struct partition_block *p)/输出给定分区块内的信息 bstr_print(p-drive_name); printf(%6dt%6dt, 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%5dn, 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 checksumn,i);if (sum_block(struct block_header *)block_buffer) = 0) PRINTF(FOUNDn); memcpy(&rdb, trdb, sizeof(struct rigid_disk_block); return (struct rigid_disk_block *)&rdb; PRINTF(Done scanning, no RDB foundn); return NULL;struct bootcode_block *get_bootcode(block_dev_desc_t *dev_desc)/寻找启动代码,它必须在块设备前16个块中,或者在Ridgid块中 PRINTF(Scanning for BOOT from 0 to %dn, limit); for (i = 0; i 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 checksumn, i);if (sum_block(struct block_header *)block_buffer) = 0) PRINTF(Found valid bootcode blockn); memcpy(&bootcode, boot, sizeof(struct bootcode_block); return &bootcode; PRINTF(No boot code found on diskn); return 0;int test_part_amiga(block_dev_desc_t *dev_desc)/测试给定分区是否有amiga分区表/rigid块 PRINTF(test_part_amiga: Testing for an Amiga RDB partitionn); rdb = get_rdisk(dev_desc); if (rdb) bootcode = get_bootcode(dev_desc);if (bootcode) PRINTF(test_part_amiga: bootable Amiga diskn);else PRINTF(test_part_amiga: non-bootable Amiga diskn);return 0; else PRINTF(test_part_amiga: no RDB foundn);return -1; static struct partition_block *find_partition(block_dev_desc_t *dev_desc, int partnum)/寻找指定分区号的分区 PRINTF(Trying to find partition block %dn, 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 checksumn,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-type0 = (disk_type & 0xFF000000)24; info-type1 = (disk_type & 0x00FF0000)16; info-type2 = (disk_type & 0x0000FF00)8; info-type3 = ; info-type4 = (disk_type & 0x000000FF) + 0; info-type5 = 0; return 0;void print_part_amiga (block_dev_desc_t *dev_desc)/输出分区信息 PRINTF(print_part_amiga: Scanning partition listn); block = rdb-partition_list; PRINTF(print_part_amiga: partition list at 0x%xn, block); printf(Summary: DiskBlockSize: %dn Cylinders : %dn Sectors/Track: %dn Heads : %dnn, rdb-block_bytes, rdb-cylinders, rdb-sectors, rdb-heads); printf( First Num. n Nr. Part. Name Block Block Type Boot Priorityn); boot = get_bootcode(dev_desc); if (boot) printf(Disk is bootablen); 待续.static void print_one_part (dos_partition_t *p, int ext_part_sector, int part_num)/打印一个分区信息printf (%5dtt%10dt%10dt%2x%sn,part_num, lba_start, lba_size, p-sys_ind,(is_extended (p-sys_ind) ? Extd : );static int test_block_type(unsigned char *buffer)/测试块类型if(bufferDOS_PART_MAGIC_OFFSET + 0 != 0x55) | (bufferDOS_PART_MAGIC_OFFSET + 1 != 0xaa) ) return (-1);/不是dos块if(strncmp(&bufferDOS_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 bufferDEFAULT_SECTOR_SIZE;if (dev_desc-block_read(dev_desc-dev, 0, 1, (ulong *) buffer) != 1) | (bufferDOS_PART_MAGIC_OFFSET + 0 != 0x55) | (bufferDOS_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 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 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: %08lXn,bootaddr);if (dev_desc-block_read (dev_desc-dev, bootaddr, 1, (ulong *) tmpbuf) != 1) if(verb)printf (* Cant 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%dn, a + dev_desc-dev, part_num);break;default:sprintf (info-name, xx%c%dn, a + dev_desc-dev, part_num);break;/bootcatalog (including validation Entry) 必须小于 2048Byteswhile(offsetboot_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 %lxn,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 Typen);i=0;do printf ( %2d %8ld %8ld %6ld %.32sn,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; iblock_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 GBnDeviceType=0x%x, DeviceId=0x%xnn #: 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; isignature != MAC_DRIVER_MAGIC) #if 0printf (* Bad Signature: expected 0x%04x, got 0x%04xn,MAC_DRIVER_MAGIC, ddb_p-signature);#endifreturn (-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 (* Cant 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%04xn,dev_desc-dev, n, MAC_PARTITION_MAGIC, pdb_p-signature);return (-1);if (n = part)return (0);if (part pdb_p-map_count) printf (* Invalid partition %d:%d %d:1.%d:%d onlyn,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_d
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 时间的脚步课件
- 时间沈从文句子课件
- 小学语文板书培训
- 2025版农业科技孵化基地入驻项目合作协议
- 二零二五版法人股份转让与员工激励计划协议
- 二零二五年度城市轨道交通截桩施工合同
- 二零二五版农业科技推广与应用服务合同
- 2025版办公室装修工程合同范本
- 二零二五年度矿山地质勘查服务合同汇编
- 二零二五年度金融理财产品购销合同范本
- GB/T 13477.6-2002建筑密封材料试验方法第6部分:流动性的测定
- 产程干预医学指征相关考核试题及答案
- 语文文学常识
- 医院消毒供应中心外来器械管理流程教材44课件
- 土地估价基础知识与估价方法课件
- 污水处理厂运行成本分析
- 配货员绩效考核表
- 商品和服务税收分类编码表
- 数形结合论文参考文献
- 破壁灵芝孢子粉产品介绍课件
- DB32-T 2710-2014堤坝道路施工质量检验与评定规范-(高清现行)
评论
0/150
提交评论