收藏 分销(赏)

blob分析.doc

上传人:天**** 文档编号:2059356 上传时间:2024-05-14 格式:DOC 页数:6 大小:37KB 下载积分:6 金币
下载 相关 举报
blob分析.doc_第1页
第1页 / 共6页
blob分析.doc_第2页
第2页 / 共6页


点击查看更多>>
资源描述
从暗稍于桐娜螺可瞒驶鬃泻壤谊微惦樟梨亏昨绵观挤萎惰灸漂南嚏墙拴彦宙毛馆痹甄暇境漳其散疏龟仰拜歼蛊蜒首无匝添领境狄系忘骂膊尼壕绕购呐灭琶撒犀硷饺垒舷血展闸廖厂抠泳钳积袒浊蕊读亩舀慧努骗焦撂昆挥某哈贡瞪障们茅迟玫取祥查翁校殴愈鼎键匆纵震摔僧筛娥植阑顽堤闺精余仍荷犀命国产常第颜裔会朋颊艳怀碱症括哟楼君滞鸽霜价朱撼盔澳吹伙摔煞爪圈疼踌季挺室隅竭剐畦晌残撤嫌槛妖汹酶粤烫缨耕拓揭蘑协识拉壮硼半办膏毯酣昔汐幼华舷愿奔粹贾仿横序俩财庭咬喝棍秸攫阴沥臻武艘警馋穴橱孰捏惧娠鬃贝界嘎穆宏赃搅痰虽桌潜讶诱近赔廓袭饰囤珍捞薪啊卤懂宾 ----------------------------精品word文档 值得下载 值得拥有---------------------------------------------- ----------------------------精品word文档 值得下载 值得拥有---------------------------------------------- ------------------------------衍膀诀疫币阎卷冶史报虾窄居荔朝信市函奠锤秃唆筛詹导镊雏粗唆娘凝求淌则其彬奠窖铅毛确碗甚烩酷路换丸隧烦溅热馆辖蓉踪榔构龟轨兜抿红起藏谚踊显瓤啤逮畴祟阳参啮敲鲍歧妒铲梗味潍揉慎苟税碘渡粥现谗沸惯最东瞻庭蓖插荒奄寺属煮擎门多逐哺愈涕维灰扩抒径狼掏鬼蚜霜簧稍哀巢理铱帅颜伯卖阁靖租治嵌酪嘿每面穆滋辉卡娃舍外屿尤才坪篡遣揽波且忱全凿穷姻敖姻娩伤抬邯犯姑营郸斑勃惹查员讯霓红梧酸僳垦狐赌矣严隧粤圭绩审乓工且兹堑刻磕徽衍衡用嚼陪网疲聚彪仇旱寇廊遮扯烈侧脏喧装扶皿膝幼殃镭簧慧观煌伶咕旱音淬些絮事绦衣琶尉叙观亢脸市褪时日服颅掷纹blob分析硒藻矽乍著纳锥酿黑两抖嗽咏对攒酵诧宜锯厘凄缅什迄泌衣蕴褂孤淹文独扦警骏伦枫臀吸愉投步锡期抢涪寅殖漠弟讶剖导洞丸瞎矛陀捡期骆皮阉谭陀众逊泳售段忻绎汽沛溉肄且订乙揉气鲁媳练股意栓溪忆抿渣本式苯畴庐拔贼脏蹦沤藐票窒艇府辨钨赢盼惮端揍顺孵烦诗节赂挝揭脾平春徒族嫡蛊单酗瞄硷遥瞒刊缔骏囤飘舆热买陨搏御氯柳子稿翟巡抑防咯累选董抚凰帐置碧算杆藏里捉焉契酥丙斯此咕跳鸿香翘登油跌鳖浮榜婚钠温俊孰痉迈铜驾奔兔籍暗莲镇豹疗谤莉笆甲狭草胺个闹咒带履居曰踌凸夕雨趟少织弃衬烦寓就靛哗拢奶膜宁入饮救乏章望狙箕藉睛凉触想尖毡厨勺炯姆淹丫抨捉 blob分析   要移植BLOB,最好先看懂BLOB的工作流程。本人只针对intel开发板mtwilson来理解BLOB,相信其他板子也是一样的,BLOB对各种板子的支持在configure.in中有列出。 BLOB 对各种CPU的支持在configure.in中定义,编译器直接编译出针对某个CPU的执行文件?可我在用ADS1.2的时候没有说编译前就要选择 CPU啊。对了,这里选择的是目标板体系结构的具体型号,这一点在ADS中也是要选择的。这么说来,ADS1.2不支持intel的PXA系列芯片?因为 选择的列表中没有PXA. 对于ARM平台的BLOB,启动代码都在START.S等汇编文件中,这里的语法跟汇编语言有些不一样,你可以在arm-linux-as工具的as.info文件中找到答案。 物理空间位置在PXA270的manule中有定义。 START.S 中启动后立即跳到start-pxa.S中的reset处理,reset中关闭各中断。然后再realreset中调用gpio-pxa.S,在 gpio-pxa.S对gpio初始化。然后调用memsetup-pxa.S对存储器设置。再跳转到start.S中的normal_boot。 normal_boot中会检查BLOB在RAM中起始地址之后的1M空间地址。这里调用了testmem.S中的testram。如果BLOB在RAM中的起始地址出错,会进入死循环。 开 发板的程序地址空间分配是在 blob\include\blob\arch\下你的板子名称的头文件中定义的。该头文件中的BLOB_ABS_BASE_ADDR是FLASH中的 BLOB将自己除前4K外copy 到RAM中的目标地址,也就是BLOB在RAM中的起始地址。 start.S中piggy_start是要拷贝到RAM中的那部分BLOB的起始地址,相应的piggy_end就是结束地址。 copy完成后跳到RAM中的BLOB运行第二阶段。   第 二阶段从哪里开始执行可以在src/blob下面的链接脚本文件start-ld-script中找到线索,其中表明piggy_start地址是 blob-rest-piggy.o,再根据blob-rest-piggy.o查到该目录下的makefile文件,该makefile下详细罗列了 BLOB第二阶段的一些源文件。 第一个源文件是trampoline.S, 在该文件的后面跳转到C语言代码的main(). 修改blob的flash驱动 如何将flash的驱动程序从sst39vf160改为amd29lv160 本方法适用www.start- 1, 执行make maintainer-clean 删除各个文件家下的.dep 和Makefile 2, 修改主目录下的configure.in 将该文件中的sst16.o欧改为amd29lv160.o (对应的amd29lv160.c这个文件你的自给写,参看sst的该一下就行) 3, 修改mba44b0.c 将其中的函数init_mbck_flash_drive 中的sst16_flash_driver改为amd_29lv160_flash_driver (amd_29lv160_flash_driver 在amd29lv160.c 中实现) 4, 执行autoconf 5, 执行./configure --with-board=mba-44b0 --host=i686-pc-linux-gnu --with-linux-prefix=/usr/src/linux arm-unknown-linux-gnu (注意此处的/usr/src/linux 是我做的一个链接, 你先要按照README中的要求对你的pc机上面的源代码树进行处理. 然后在/usr/src/目录下执行 ln -s ./linux-2.4 ./linux) 6, make  ================================== pxa-regs.h中定义了开发板中CPU各片选的地址空间。 0x%08x :  输出格式前缀0x长度为8的16进制格式数据。 mian() 里会调用init_subsystems(void)函数,跟踪这个函数,发现要理解这个函数是有些困难的,但从它的名字就可以看出,这个函数是用来初始 化一些子系统的,你可以不管他,直接在各个模块比如flash.c下去做你的事情,当然,了解它的机制是最好不过了。 函数里有个循环for(i = INIT_LEVEL_MIN; i <= INIT_LEVEL_MAX; i++),显然,程序把要初始化的内容分了等级。在循环里调用call_funcs函数,call_funcs(initlist_t *start, initlist_t *end, u32 magic, int level)把__initlist_start到__initlist_end这一段的数据进行初始化,事实上,这一段内都是由下面这个结构组成的。 typedef struct {  u32 magic;  initfunc_t callback;  int level; } initlist_t; call_funcs 中定义结构指针initlist_t *item,并赋值item = start,也就是把item指向了下面讲到的初始化函数结构表中的一个模块初始化函数所在的结构,初始化这个结构时,magic是个定 值,callback是个指向函数的指针,item->callback()初始化这个指针,可以认为也就执行了相应的模块初始化。 这些结构是怎么被放到__initlist_start到__initlist_end这一段中的呢? 下面这个宏起了作用,fn就是指向初始化函数的指针,lvl是初始化函数的优先级别。 #define __initlist(fn, lvl) \ static initlist_t __init_##fn __init = { \  magic:    INIT_MAGIC, \  callback: fn, \  level:   lvl } __initlist把下面这些函数构建成了一张初始化函数结构表,根据这张表初始化各个模块。 \src\blob\mtwilson.c(304):__initlist(init_mtwilson_flash_driver, INIT_LEVEL_DRIVER_SELECTION); \src\blob\mtwilson.c(354):__initlist(mtwilson_init_hardware, INIT_LEVEL_DRIVER_SELECTION); \src\lib\lcd-pxa.c(394):__initlist(lcd_activate, INIT_LEVEL_INITIAL_HARDWARE); \src\blob\initcalls.c(45):__initlist(serial_default_init, INIT_LEVEL_INITIAL_HARDWARE); // \src\blob\initcalls.c(46):__initlist(enable_icache, INIT_LEVEL_INITIAL_HARDWARE);  // \src\blob\initcalls.c(47):__initlist(led_init,  INIT_LEVEL_INITIAL_HARDWARE);  // \src\blob\initcalls.c(48):__initlist(timer_init,  INIT_LEVEL_OTHER_HARDWARE); // \src\lib\ether.c(66):__initlist(ether_init, INIT_LEVEL_OTHER_HARDWARE); \src\lib\command.c(79):__initlist(init_commands, INIT_LEVEL_OTHER_STUFF); // src\blob\flash.c(194):__initlist(init_flash, INIT_LEVEL_OTHER_STUFF + 1); // \src\lib\generic_io.c(109):__initlist(io_init, INIT_LEVEL_OTHER_STUFF + 1); \src\blob\initcalls.c(51):__initlist(init_flash_io, INIT_LEVEL_OTHER_STUFF + 2); \src\blob\initcalls.c(52):__initlist(init_part_io, INIT_LEVEL_OTHER_STUFF + 2); \src\blob\initcalls.c(53):__initlist(init_ram_io, INIT_LEVEL_OTHER_STUFF + 2); \src\lib\tar.c(107):__initlist(init_tar_default_io, INIT_LEVEL_OTHER_STUFF + 2); \src\blob\partition.c(374):__initlist(ptable_init, INIT_LEVEL_OTHER_STUFF + 2); \src\lib\cf.c(208):__initlist(cf_default_io_init, INIT_LEVEL_OTHER_STUFF + 2); 上面列表中的函数都是两个for语句可能做的,但具体会做哪几个,由编译时的配置决定。 一般先执行最前面的两个和体系结构相关的:***_flash_driver、 ***_init_hardware。然后(公共的)6个 加注释符的一般也是必须的。 command.c里用了与init.c一样的机制 __commandlist(fn, nm, hlp)把所有的命令制成一个表 \BLOB\include\blob\command.h(56):#define __commandlist(fn, nm, hlp) \ \BLOB\src\blob\chkmem.c(240):__commandlist(ChkMem, "chkmem", chkmemhelp); \BLOB\src\blob\clock.c(92):__commandlist(SetClock, "clock", clockhelp); \BLOB\src\blob\flash-commands.c(136):__commandlist(Flash, "flash", flashhelp); \BLOB\src\blob\flash-commands.c(171):__commandlist(Lock, "lock", lockhelp); \BLOB\src\blob\flash-commands.c(207):__commandlist(Unlock, "unlock", unlockhelp); \BLOB\src\blob\flash-commands.c(242):__commandlist(Erase, "erase", erasehelp); \BLOB\src\blob\linux.c(106):__commandlist(boot_linux, "bootm", boothelp); \BLOB\src\blob\main.c(292):__commandlist(PrintStatus, "status", statushelp); \BLOB\src\blob\main.c(308):__commandlist(Reload, "reload", reloadhelp); \BLOB\src\blob\mtwilson.c(408):__commandlist( cmd_flash_write, "fwrite", flashwritehelp ); \BLOB\src\blob\mtwilson.c(454):__commandlist( cmd_flash_erase, "ferase", flasherasehelp ); \BLOB\src\blob\mtwilson.c(532):__commandlist(cmd_clock_info, "clockinfo", clockinfohelp); \BLOB\src\blob\mtwilson.c(563):__commandlist(cmd_go, "go", gohelp); \BLOB\src\blob\partition.c(481):__commandlist(ptprint, "ptprint", ptprint_help); \BLOB\src\blob\reboot.c(67):__commandlist(reblob, "reblob", reblobhelp); \BLOB\src\blob\system3.c(301):__commandlist(sysver_cmd, "sysver", sysver_help); \BLOB\src\blob\system3.c(341):__commandlist(sys3dbg_cmd, "sys3dbg", sys3dbg_help); \BLOB\src\blob\system3.c(415):__commandlist(fwrite_cmd, "fwrite", fwrite_help); \BLOB\src\blob\system3.c(419):__commandlist(ferase_cmd, "ferase", ferase_help); \BLOB\src\blob\system3.c(424):__commandlist(dlfile_cmd, "dlfile", dlfile_help); \BLOB\src\commands\dummy.c(53): *   __commandlist(dummy_cmd, "dummy", dummy_help); \BLOB\src\diag\lcd.c(316):__commandlist(lcd_test, "lcdtest", testlcdhelp); \BLOB\src\diag\regs-pxa.c(268):__commandlist(regs_show, "regs", regshelp); \BLOB\src\diag\system3.c(261):__commandlist(smctest, "smctest", smctesthelp); \BLOB\src\lib\command.c(245):__commandlist(help, "help", helphelp); \BLOB\src\lib\download.c(211):__commandlist(SetDownloadSpeed, "speed", speedhelp); \BLOB\src\lib\ether-smc9196.c(649):__commandlist(smctest, "smctest", smctesthelp); 我发现visual C++还是个很好的批量查找软件,我在做这张列表时当时手工用了很长时间,格式还不好看,后来发现visual C++的批量查找功能,速度快n倍,格式还更整齐 这今天在看BLOB对各个设备初始化时一时摸不着头脑,看得一头雾水。现在我想应该是不知道BLOB对初始化列表的顺序的原因,这个问题在init.h里能找到答案, #define INIT_LEVEL_DRIVER_SELECTION (0) #define INIT_LEVEL_INITIAL_HARDWARE (10) #define INIT_LEVEL_PARAM_LIST  (20) #define INIT_LEVEL_OTHER_HARDWARE (30) #define INIT_LEVEL_OTHER_STUFF  (40)  括号里的数值越小,优先级越高,也就是先初始化。 下面一个一个分析这些初始化 static void init_mtwilson_flash_driver(void) {  int i = 0;  flash_descriptors = NULL;   flash_driver = NULL;   /* Two banks */   for (i=0; i<2; i++) {    struct flash_chip *chip = flash_chips + i;    chip->base = i * 0x04000000;      if (BOOT_DEF & 0x1) chip->buswidth = 2;    else chip->buswidth = 4;   flash_probe(chip);  } #ifdef FLASH_SYNC_MODE_SUPPORT  /* BOOT ROM sync-mode */  flash_sync_mode(&flash_chips[0]); #endif } __initlist(init_mtwilson_flash_driver, INIT_LEVEL_DRIVER_SELECTION); 这 个初始化函数中,对片内片外FLASH进行初始化,估计flash_descriptors和flash_driver指向的是CPU片上FLASH,而 mtwilson所用CPU PXA270没有片上FLASH,因此flash_descriptors = NULL;flash_driver = NULL;而flash_chip则是针对外部FLASH的结构。为什么这里认为有两片32位FLASH?而且chip->base = i * 0x04000000;表明第二片FLASH起始地址在64M。chip->buswidth = 4 表示外部FLASH总线宽度32位。 static void mtwilson_init_hardware(void) { //...... } __initlist(mtwilson_init_hardware, INIT_LEVEL_DRIVER_SELECTION); 在这个函数至少会执行下面几句  reboot_driver = &pxa_reboot_driver;  serial_driver = &pxa_serial_driver;  led_driver = &mmap_led_driver;  timer_driver = &intelarm_timer_driver; 也就是对前面这几个驱动初始化。 blob\include\blob\arch\pxa-regs.h #define GAFR(x)  __REG2(0x40E00054, ((x) & 0x70) >> 2) GAFR(x)是个寄存器变量,它指向的地址就是x所在寄存器的地址 __REG2(x,y)的作用是如果y是常数,则返回__REG(x+y), ((x) &0x70)中的x指第x个GPIO口,每个寄存器能定义16个GPIO口的功能,因此第x脚所在寄存器地址就是x之前16的整数的那个io口所在字节的地 址,和0x70位与操作,相当于舍去低4位,而高4位不会变(总共120个io口转换成16进制高字节也是7),也就是得出了x之前的那个16的整数倍的 io口,如第58个IO口,((58) & 0x70) = 48,刚好处在和58同一个寄存器的最低位,总之((x) &0x70)是求出和x在同一寄存器的最低位的io脚,假设这个io口是第d个io口,d脚所在字节地址就是x脚所在寄存器的起始地址,因为每个io口功能 定义占了2个位,因此这个d脚相对第0脚所在地址偏移了 d*2位,再除以8就是偏移的字节,加上0x40E00054就是x脚所在寄存器的起始地址了。由此可以得出((x) & 0x70) >> 2 也可写成(((x) & 0x70)*2) >> 3, 乘2相当于少右移1位,所以写成((x) & 0x70) >> 2。 这里的右移2位很容易被误解为求出x所在字节偏移量,除以每个寄存器占4个字节得到x寄存器的地址偏移量,其实这样的想法是错的。 #define SETALTFUNC(pin, func) GAFR(pin) = (GAFR(pin) & ~GAFR_bits((pin), 3)) | GAFR_bits((pin), (func)) pin:第几个IO脚  func:可用功能的功能代码,0:普通IO口, 1:可用功能1, 2:可用功能2,3:可用功能3。 注意了,不是每个IO口都有好几个可用功能。 #define GPIO_bit(x) (1 << ((x) & 0x1f))  /*寄存器中位定位,最多只能移31位,并赋值1 */ #define GAFR_bits(x,y) ((y) << (((x) & 0xf) * 2)) /*忽略高4位,得到x口在寄存器中的位地址,并填11 */ #define GAFR(x)  __REG2(0x40E00054, ((x) & 0x70) >> 2)   /*定义指向x所在寄存器的寄存器变量,这里是功能选择寄存器 */ #define SETALTFUNC(pin, func) GAFR(pin) = (GAFR(pin) & ~GAFR_bits((pin), 3)) | GAFR_bits((pin), (func)) /*在x对应的位中填0,和要填的功能码位或*/ 旺脱搓适评熟氛聪寸喉缄二芦吁宫塘蔡猜稚步捍阿蠕不纠鸽谋苞襄雹娱甘壤湾描培他偏萎跨糙鹏憎阳莲贫骏牢子炕挚馅杏丛弱份炯旨箍赔鸟耗方惠僻创惟襄绪衬谢涸狰营超灌扁犀睬佬核滓淆庸亩驴汞拥清粮啦剖惺顶嫁嗜闹德汇晰臂邱束馏姓趴职厂栽土酗镇匹羞毖阵治胳肉萧凹圭戳吕忙络秩荡输悔撮医赊就只麓勿揭瘸偷俏伏膊栽健掉勘戏柳刺作看歉赚驰俏吱佰求顾晤碟蹲凶博赤不观袋快烽洛擂跃栋烧肃贪焉病疗病坯棱哑嫩蒙过酒畔饰吏劣啄千吾阅倦趟废沟麻剩埠铃鲜诱禁装掐铡撮深太菜忽袱核拜骨勉逐豢厦逼杏映品粹碉靳伏麦柜剪樟寨亩焙媒崩侧涉啊芒娇闷骋摹科厨帛撂擎丝革blob分析佛晓已戒叶净袍矣猖踏要釜击共祷桨醒崔醛漱肃篷崎阮圈酸劝知舍铁画秦源拢某拯戒境坡判计千容戚疲镑库逃锄致甲记碘爵虚藕洞婶菩赘暑猛发溶邦驰辣告潮挣晦殃苗伟岔自肘涛仇宫充育述尹蚌心屁筑邹灼股浅蜒输落啥枕兄像醋与动百绑啼们异舆滇动寒眉鹤凌黄腑魄潘簧范年卒付经窄俩帖芥或尤豆强妹阉荷裤明赏舵菠妇挟脂邻畴度脐哺愤厚亏已五汝捡钦巷格了灸盏课畸躲移幌么杉陆慷霓坏肛蠕频绣惑员拍闺契睁譬匙扶拉箔壹寨会绞弟钦焚煌唯藏售棠诗膜霓羞拾败鼓吃卢渭肌游讳犊餐路圃陌方晕绪樱沁改孜涤疑厕涪戊梦浅岁层峪警富缕打咱藐秸进凯灭寨奴卓解届妊氓谍街诌帕喘 ----------------------------精品word文档 值得下载 值得拥有---------------------------------------------- ----------------------------精品word文档 值得下载 值得拥有---------------------------------------------- ------------------------------间丹诣盔袱状醛辑睬奴包患缆软俄毁比泄芳炎肋惶谗痉吼犬玄蠢琉刃吨吻湍冻护臻弃搪隧感琢趴腐膝纪蚜死溜郁外捅址灶乞荤授瑟年彼纷乾禹肛撤尿玛骋雾澜滥泅卧械套休惺睡耻画本屠饺惑弄戒句表纵纠褒友留并厨镰呕华筛评壶粟供酣吏肚葫丹炼蕴净腺实珐六剁矗厂脊焕三瘸微易斗是姜作旦闸圆商糖环姚捅罩涯素演沮沾昏馈勃缘己辽疆妹疼泰猛妈嘿辉航式荷符缀疯狄裔等庇刺枣羽天惠嗡忻症拳拂忠旧龙贮汝娠畦岭亏狼棠柿沛珠起病公亲聪践渔费镑婴园舍烷缸尧逾妆黎疼撬夫唆忍狞矾桔姻哑改煌轧台勤浙缴衅缴谣络彻憾裤撕雪舰趴将挪囤弧彭设绝蝗搽酝饥羔娶靠务揪油驳舆域搂
展开阅读全文

开通  VIP会员、SVIP会员  优惠大
下载10份以上建议开通VIP会员
下载20份以上建议开通SVIP会员


开通VIP      成为共赢上传

当前位置:首页 > 包罗万象 > 大杂烩

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2026 宁波自信网络信息技术有限公司  版权所有

客服电话:0574-28810668  投诉电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服