免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: compare2000
打印 上一主题 下一主题

linux git常见命令整理 [复制链接]

论坛徽章:
3
天秤座
日期:2013-12-27 13:44:58射手座
日期:2014-05-22 16:52:43天蝎座
日期:2014-08-13 16:03:21
61 [报告]
发表于 2014-07-30 17:03 |只看该作者
console有多种含义,本文仅针对printk输出的设备,驱动使用register_console注册一个console。 console和tty有很大区别:console是个只输出的设备,功能很简单,只能在内核中访问;tty是char设备,可以被用户程序访问。




实际的驱动比如串口对一个物理设备会注册两次,一个是tty,一个是console,并通过在console的结构中记录tty的主次设备号建立了联系。




在内核中,tty和console都可以注册多个。当内核命令行上指定console=ttyS0之类的参数时,首先确定了printk实际使用那个console作为输出,其次由于console和tty之间的对应关系,打开/dev/console时,就会映射到相应的tty上。用一句话说:/dev/console将映射到默认console对应的tty上。







/dev/console是系统控制台,或者说是物理控制台,而/dev/ttyn则是虚拟控制台,你可以传导诸如console=ttyS1的启动参数给内核,使得ttyS1(第二个串口控制台)成为系统控制台。如果没有传导这个参数给内核,内核就会自动寻找可用的设备作为系统控制台,首先是VGA显示卡,其次才是串口。




注册uart_driver 的时候会分配相应的tty_driver结构

这样通过/dev/console和具体的uart驱动联系起来,通过co->index,又和具体的uart设备联系了起来,这样,内核通过/dev/console就可以操作串口,进行内核信息的输出了。

内核使用/dev/console的地方为kernel初始化的时候:







http://developer.51cto.com/art/201209/357501.htm
我做行销这几年  前言

一个下雨的周末,独坐宿舍,出差随身带了本书,很无趣,难怪压在箱底一直没有看完。又一次深刻体会了,“耐劳碌易,安闲散难”。劳碌的时候,比如六月回国准备比电测试,每天凌晨才走回酒店睡觉,但是苦累过了,牢骚过了,觉得日子过得充实。这大概与“只问耕耘,不问收获”的感受类似。闲散时,体会到更多的无聊和寂寞。在欧洲生活,真的是要具备“自己和自己玩的能力”。

趁这个机会总结一下行销七年的体会吧。去年拿到“金牌产品经理”的“大铜牌”时,就想写个总结。结果拖到现在才开始动笔,总是拿“忙”做借口,其实只是个“合理”的理由而已。真实的原因只有自己清楚----还是得承认自己有轻微的拖延症,而且对自己的文字表达能力没有信心。总之,这次真的开始了,想到哪写到哪。



为什么想做行销?

2003年初毕业,在广州做研发,2005年进成都研究所做硬件开发,2007年转行销部门。原计划在行销待三年,现在已经是第七个年头了。谈不上成功,但这七年对自己意义重大,为人处事和自信心至少有了改善。也许,任何一个人不论从事什么职业,七年的时间都会发生很大变化。行销的工作可能只是加速了我的变化。

为什么从研发转行销呢,“成都可是个来了就不想走的城市”?不少人问过我这个问题。我自认为是个“内向”的人,木讷少言,和人沟通常常找不到话题,这样的人似乎不适合去面对客户。我对这个问题的回答一直是“我想改变自己”。是的,这是我发自内心的答案,不是个“听起来合理的答案”。

2007年上半年,看到公司内部招产品经理的通知,马上就有了这个想法。现在想,最主要的原因是对现状不满,感觉按这个性格发展下去,前途无望。**自己到一个必须和人打交道的地方,强迫自己改变。看过一个资料,说每次吃饭都吃完的人有强迫症。好吧,还得承认,我有轻微的强迫症。每次吃饭,不管是自助餐还是在家里,都努力吃到一粒米不剩。当然,实在吃不下除外,还没有强迫到自虐的程度。我儿子正好相反,每次都剩饭,完全继承了他妈的遗传。

总之,为了改变自己,决定转行销。也许有点自私,不记得当时是否考虑了孩子还小。应该是考虑了的,和老婆商量,老婆也支持我出去改变一下,同意出去三年。

好像也犹豫过,担心失去眼前的东西,也担心自己到一线能不能做好?一个工科生,毕业四年多,一直都是做硬件开发工作,和人打交道少。记得当时还约了老专家沟通,老专家最后给的结论是,“其实你内心已经做了决定”。在离开研发之前,有天中午和一个同事同桌吃饭,她和我说,“经常和以前去市场的朋友联系,其实市场和研发的收入差不多”。当时的主管也劝我,市场不像你想象的那么好。这些都没有影响我最终的决定,也许这就是我的性格,决定了的事情拉不回来,很难听进去别人的劝告。



什么样性格的人适合做行销?

我一直都以为,我的性格对做行销工作是个缺陷,很羡慕能在聚会期间谈笑风生、和客户打成一片的高手。记得2007年刚转行销,完成了二营,还在深圳部门培训期间。原部门领导到深圳出差,约了他一起吃饭,他也说“这次部门转行销的四个人,最没有想到的就是你”。

上个月,某产品线领导来比利时,和领导做了深入的沟通。从早上9点开始,边逛街边交流,包括个人的经历、做过的项目、对市场格局的一些看法等。中午一起吃饭,谈到性格的问题,领导很郑重的给了忠告,“我理解你的想法,你可能很羡慕那些能很快和人打成一片,善于搞客户关系的客户经理。你觉得这方面是你的劣势。其实靠做事长期建立起来的信任是真正能产生价值的。我希望你记住我给你的建议,在你以后的职业生涯中,这种性格是你的优势,不是劣势。不要试图去改变它,要利用它。”

这位领导在研发和市场工作多年,可以说阅人无数,很有经验。他是对的,任何性格都有好有坏。确实,在我长期接触的几个客户中,我和关键的架构师都建立了比较好的信任关系,离开了荷兰后还经常有联系,对工作产生了很大帮助。



机缘巧合到荷兰。

决定转行销之后就是和研发领导谈话,行销部门面试。都很顺利,因为研发有输出指标,正发愁没有人愿意去。2007年7月,从成都飞深圳,开始行销培训。在成都双流机场,碰到三个同事,也是这次转行销的,同一班飞机去深圳。

2007年7-10月在机关参加二营培训,看资料、学习产品知识、早起跑步、写总结、百草园门口吃烧烤,周末聚餐、玩杀人游戏。认识了不少各种各样的人,可惜后来分到全球各地后,逐渐疏于联系。10月底分配去向的时候,从成都一起来的兄弟居然都去了自己想去的地方。有个兄弟,受失恋的刺激,要去补助高的地方挣钱,如愿以偿去了非洲;有一个忘记是什么原因了,对南美情有独钟,分配去了智利;我一直定位自己是技术导向的,要求去对技术要求比较高的地方发挥优势,就来了西欧。

10月底,确定了到荷兰做光网产品经理。前任产品经理要马上去其他国家,我去接替她的工作。现在仍然记得那个日期,2007年11月2号,从香港飞荷兰。荷兰的同事很热心,早上7点多,开车到机场接我到有名的540宿舍,放下行李就去了办公室。相信这是会永远留在记忆中的地方,在这里度过了刚刚转行销迷茫的两年。夏天在院子里吃完饭,可以欣赏飞机从头顶很低的飞过,一分钟一架。



最大的障碍是语言。

11月份是荷兰的冬季了,当天是个阴天。第一天上班,开始做KPN国际波分网络设计工作。不记得太多事情了,只记得前任留下的“两个工作日内答复客户问题”的规则。介绍了一下网络设计、报价的规则,带着见了一次客户。两周之后她就离开了,我开始独立工作。

到荷兰之后的第二周,比利时需要一个光网产品经理去和卢森堡的客户做产品交流,不知道什么原因安排了我这个刚来一周的人去支持。记得自己出发前背了几遍波分主打胶片。到比利时很顺利,先从阿姆中心站做火车到比利时中心站,然后打出租车去比利时办事处。晚上,当时的办事处主任把我带到他的宿舍就离开了。宿舍转了一圈,发现没有吃的,只有我一个人在,也没有宿舍钥匙,更不清楚怎么去外面的超市买东西。搜遍宿舍只找到一包挂面,只好拿盐水煮了,没有筷子,只能用叉子。从那以后,每次出差,都要带两包方便面,以防万一。

第二天,一个本地客户经理带着去卢森堡交流。很可惜,讲完胶片之后,经常听不懂客户的问题。现在脑海中还能浮现出额头上渗着油汗,试图听懂客户问题,在白板上给客户解释的画面。带我来的客户经理,最后和我说,“抱歉,我也不懂中文,没有办法给你翻译”。

从比利时回荷兰还出了点问题。在布鲁塞尔做火车,买了票,但是不懂怎么坐车,到了售票员说的那个站台,有趟车停在那里就直接上车了。做了几站之后,发现不对,和来的时候怎么不一样,问了旁边的老外,发现坐错了。下车去问“information”,很可惜,他不会说英语。折腾半天,也不清楚怎么转车。无奈,拦住一个中国的女孩子问她,说我坐反了,她刚好也去布鲁塞尔中央车站转车,可以带我到中央站,并解释了详细的到阿姆转车的过程。本来两个小时的路程,花了五个小时,晚上10点多才到阿姆。记忆中好像还给我留了名片,是一个船务公司的,约了下次到比利时再联系。只是下次到比利时是几年之后的事情了,名片都丢了。

这次失败的出差经历,打击很大。回来之后就开始努力学习英语。其实也没有窍门,从网上下载了新概念英语2-4册,每天晚上听一小时、早上读一小时,努力把每篇文章背下来。可能持续了有小半年时间吧,其实在大学里面还是有点底子的,只是要解决听力的问题。

好在这次交流的客户后来选择了KPN用华为的产品建设他们的网络。



第一次失败的项目。

2008年初,荷兰一个光纤供应商EuroFiber发了个波分标书。据客户经理说,客户是主动找到华为的,好像客户经理还很自豪。那时候还没有投标办,所有的事情要自己搞定。应该是我自己笨,不懂得求助。我、本地客户经理、本地传输主管一起完成了所有工作(不是自豪,是鄙视自己)。我负责答标、网络设计报价、客户交流等。记忆中,从头到尾只是找地区部领导申请了一下价位,对竞争对手、项目运作、汇报求助等一无所知,客户来了问题和需求就马上响应,文档做的很好。

自然这是个失败的项目,客户最后选择了Infinera,Infinera至今在荷兰只有这一个项目。客户给的理由是:“感觉不到华为对他们的**,华为只关注大运营商”。客户经理给的理由是:“我们给客户宣讲时,总是讲我们突破了多少大T,所以给客户留下了这个印象”。觉得很委屈,因为宣讲都是我做的。后来代表处代表参加了客户的会议,问客户不选择华为的理由,客户说:“Infinera拿到这个项目,经常在他们办公室,对他们支持很到位;华为只是被动的响应他们的问题,很少去他们办公室”。记得当时自己终于如释重负----原因不在我这里。

到2012年完成了公司级的ETN-IP项目之后,回顾自己走过的路,才意识到当年自己做的多么失败,难辞其咎。没有项目分析会、竞争分析、商务分析、项目运作等等,可以说是一无所知。也难怪现在回忆以前做过的项目,每个项目都能回忆起来项目分析会、项目组挑灯夜战的场景,这个项目却没有任何感觉,“静悄悄的来,静悄悄的走,不带走一点关注,不留下一丝印象”。



2009年再尝败绩。

2009年初,KPN国际关口局项目发标。忘记为什么我这个光网的产品经理负责了IP的项目,可能是当时荷兰没有IP产品经理吧。我和市场技术的一个同事一起,负责答标工作,用NE5000E。这次项目,仍然没有留下深刻印象,算是学习了一下IP产品知识。项目丢给了思科。



现在想来,从2008年到2009年上半年,我完全没有从研发的思维转变过来,不懂销售项目的运作思路,只关注自己。不知道要关注客户、关注竞争对手,甚至也不明白要调动周边的资源:客户经理、系统部、地区部等。完全是被动的完成任务。

完成从研发到行销的转变,我花了两年的时间,到2010年才逐渐摸到行销的脉络,真够慢的!这和我内向的性格也有关,和其他人沟通太少,认识不到自己的问题。要感谢华为,如果不是有个大平台,允许失败,可能我早已经被扼杀在摇篮里,没有后面的机会了。

这也可能是新手的大忌,要快速的转变思维,牢记“你不是一个人在战斗,你不能一个人去战斗!”。记得曾经和当时部门的老外主管聊,我说缺竞争对手的信息和客户信息,他的直接反应是“我们只需要自己做到最好”。现在我知道了,“自己做到最好”只是个最基础的工作而已。



初尝胜利-荷兰VDF波分项目

2009年下半年,在负责VDF客户PTN和SDH产品交付工作期间,提前发现了现网老旧波分的改造机会(比竞争对手提前)。先后和客户进行了几场交流,包括设备、网管、网络设计、预算分析等。仍然是单打独斗,所有的技术交流都自己搞定。碰到客户的技术问题,首先想到的是自己去查手册,在资料中找答案,找不到才去求助研发。自己完全理解了,才去答复客户。现在还记得,曾经仔细的研读产品手册,列一个大表,把各种单板的性能、主要参数、替代关系都列出来;问过研发的问题,都作为经验记下来。所以在荷兰期间,部门一直拿我作为光网的半个专家。

仍然不懂得求助,但有了点项目运作的概念;交流中注意把对华为有利的技术需求引导给客户。而且只有华为和ALU在VDF集团的短名单里面,ALU还没有发现这个机会,客户一直在和华为交流。从解决方案上,华为当时比较强的关键技术点,ASON、40G、OTN、ROADM、VC和ODU统一交叉等,非常符合客户对现网Sycamore SDH设备改造的需求。项目成功之后,据客户说,ALU收到标书后,曾经和VDF抱怨说这个标书是为华为写的。在投标的关键时候,ALU的客户经理还去休假了,等到客户基本完成决策才回来。我们的前期介入,努力工作和对手的懈怠,是项目成功的一个关键因素。

2010年初的时候,项目已经胜利在望了,已经和客户安排了四月份去国内培训的计划,培训完就开始网络设计和建设。就在此时,VDF集团把爱尔兰、新西兰、荷兰三个波分项目捆绑在一起,“三兰”项目发标。尽管荷兰客户建设在即,要求直接选择华为开始建设,但还是没有阻挡住集团发标。

VDF系统部成立了三个国家组成的项目组,开始统一答标和谈判。集团答标期间,我按原计划在五一期间带客户回国培训。这时候已经由投标办负责答标工作了。

回国之前又出了个小问题,五个客户已经从阿姆飞香港去了深圳。冰岛火山爆发了,导致我要乘坐的航班取消。客户已经到了,而且在答标期间,我必须去啊。在阿姆机场等了很久,最后从赫尔辛基和吉隆坡两次转机,辗转超过24小时,赶上了星期一早上开始的客户培训。为期两周的时间,和这批客户建立了很好的信任关系,他们在评标之前对华为的产品和解决方案已经非常熟悉。

后来又去卢森堡一起参与了集团的谈判。自然,这个项目中标了。这个项目后来写了个案例----《N国V 子网波分项目拓展总结》,可以在3ms上找到。



2010年充分验证了“坚持就是胜利”。那个冬天是荷兰多年不遇的寒冬,圣诞节前一场大雪,导致全线交通瘫痪。我是当天的机票去成都休假,晚上8点多的飞机,下午五点多到火车站,正常情况下15分钟可以到机场。结果火车、公交、出租车全部停运,折腾一个多小时,还在火车站。最后请办公室的同事开车送我去机场,路上又堵车了一个多小时,8点还没有到机场,同事都劝我放弃了。不到黄河不死心啊,坚持到了机场。结果飞机晚点了两个小时,而且大部分乘客都没有赶到机场。这次有幸第一次升舱坐头等舱。

总之,2010年是幸运的一年,第一次作为主力拿项目,第一次做头等舱。



2011年运作成功公司级项目。

2011年初,和KPN交流过程中发现其城域网面临扩容的压力。当时我还是波分的产品经理,主推MS-OTN用ODU广播承载BTV业务。经过上半年多次交流沟通,摸清了现网的大部分信息,认识了IP部门的客户,帮助客户和华为研究MS-OTN标准的专家建立了联系。年中KPN发了承载网架构演进的FCN RFI(Fixed Core Network),由于我们在RFI期间的优异表现,华为和ALU进入下一轮。当年10月份发了BNG和城域的RFQ,我司一举中标。

不详细的介绍这个项目了。这是个公司级项目,运作过程比较复杂。先后总结了两个案例《厚积薄发,从无到有-N国K运营商FCN项目拓展总结》。后来和几位领导一起,完成了关于KPN项目运作思路的案例《从Bottom-up到Top-Down--从单域设备供应商到全面合作伙伴》。这两个案例都能在3ms上看到。

这个项目,投入了将近一年时间,直到圣诞节假期开始的前一天晚上七点,才结束和KPN的谈判,拿到了意向书。我是项目运作和解决方案责任人,用当时一位领导的话说,“你走路的时候都眉头紧锁,目不斜视”。确实投入了很大精力,收获也很大,包括物质的和精神的。

其实2011年初,我已经萌生了离开行销的念头。如果不是因为这个项目,早在三年前已经回研发或者离职了。感谢当年代表处和地区部主管(辛文、冯俊、谭春霞、曾兴云、王德贤等),给予了充分的信任和支持,允许我把所有的精力放在这一个项目上。在这个项目中才真正体会了项目运作、团队合作管理、竞争分析、项目策略、客户关系等等这些概念。个人状态也发生了很大改变,用当时代表辛文的话说,“经过了这个项目,能感觉到你的自信心和幽默感都改变了很多”。

的确如此,2011-2012年是我毕业之后变化最大的阶段,在项目中向这几位优秀的领导学了很多。2011年,我在电脑屏幕的下面贴了个字条“冷静”,提醒自己要心平气和的做事。2012年,开始有了改变,我老婆都感觉到了,说我比以前多了点包容,愿意听别人说话了。

但是说话做事还是很直接,用部门一个本地同事的话说,我的口头禅是“Let’s make a summary”。每次组织会议,听了与会人发表意见后,我总是忍不住要打断漫无边际的讨论,要马上列出行动计划去分配执行。确实性格很难改变,也许永远做不到人情练达。只求以诚待人,简单快乐。用我老婆的话说:“丑也有丑的好处,那张脸一眼看上去至少很真诚;而且心思简单,躺下10分钟就能开始打呼噜”。



2012年带团队做项目。

2012年有幸获得公司金牌产品经理,第一次拿到那么大一个铜牌。开始做部门主管,说是主管,也就十来个人。

2012年带部门两个产品经理(一中一外的配置)一起做电源替换项目。用两个字总结就是“忽悠”:“忽悠”产品经理去做客户关系;“忽悠”服务同事降价;“忽悠”产品线的人来一线做解决方案;“忽悠”地区部给商务;“忽悠”客户同意我们的商务。“忽悠”的还比较成功,这个项目没有发标直接给了华为,后面的交付也比较成功。

2012年6月参加了FLM培训(First Line Manager),自己看了些书,包括德鲁克的几本经典著作、心理学方面的入门知识等;期望自己能做一个好的管理者。仔细想,也实在总结不出来经验。2012年,和一个产品线领导吃饭,他就问了我这个问题。忘记怎么回答了,好像是脱口而出:“开放的心态,以诚待人;多看他人的优点,承担责任,帮助他人成功”。



后记

看到“后记”这两个字,也许你要失望了,没有讲啥“一招制敌”的功夫吗!是的,我还没有练成。我只想把我走过的弯路实事求是的告诉刚入门的产品经理,希望我们不要在同一个坑里花太多时间才能爬出来。

揭开伤疤,解剖自己真心不容易!

论坛徽章:
3
天秤座
日期:2013-12-27 13:44:58射手座
日期:2014-05-22 16:52:43天蝎座
日期:2014-08-13 16:03:21
62 [报告]
发表于 2014-07-30 17:06 |只看该作者
说说wakelock[未结束]  wake_lock_init(struct wakelock *lock, int type, const char *name);


void wake_lock(struct wake_lock *lock);



void wake_lock_timeout(struct wake_lock *lock, long timeout);



void wake_unlock(struct wake_lock *lock);




在/proc/wakelocks中可以查看当前的wakelock.

WAKE_LOCK_SUSPEND 阻止系统进入suspending状态(睡眠状态)。
WAKE_LOCK_IDLE 阻止系统进入low-power idle状态,该状态可能会增加响应时间。(IDLE,要CPU支持,当CPU不支持IDLE时,该选项不起作用)




用户空间通过向

/sys/power/wake_lock

/sys/power/wake_unlock

来上锁和解锁。







》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》

插播一点电源管理:

kernel/power/suspend.c中



c代码
30 const char *const pm_states[PM_SUSPEND_MAX] = {
31 #ifdef CONFIG_EARLYSUSPEND
32         [PM_SUSPEND_ON]         = "on",
33 #endif
34         [PM_SUSPEND_STANDBY]    = "standby",
35         [PM_SUSPEND_MEM]        = "mem",
36 };




手机有这三种状态。

suspend_on,手机正常工作状态

standby,手机休眠状态

mem,手机在休眠态,但数据还在内存中,中断可**。








early_suspend, later_resume,当用户空间请求suspend时,比如按下power键,系统会进入early_suspend,这时,所有early_suspend注册的函数都会逐一调用。当所有的wakelock释放后,系统就会真正休眠。
i2c 如何根据中断号找设备


1, cat /proc/interrupts

76:       1450       GIC  i2c_designware
77:       9089       GIC  i2c_designware
78:       4976       GIC  i2c_designware
79:       2708       GIC  i2c_designware

这里76, 77, 78, 79分别对应哪个设备

2,在注册的地方找代码:
irq = platform_get_irq(pdev, 0);
request_irq(irq, i2c_dw_isr, IRQF_DISABLED | IRQF_NO_THREAD, pdev->name, dev);

int platform_get_irq(struct platform_device *dev, unsigned int num)
{               
         struct resource *r = platform_get_resource(dev, IORESOURCE_IRQ, num);
         
         return r ? r->start : -ENXIO;
}      
EXPORT_SYMBOL_GPL(platform_get_irq);

这里,是通过设备定义的resouce来查找irq.


在:arch/arm/mach-hi6620/dev_i2c.c
126 static struct resource i2c_resource ## chip_id[] = {\
127         [0] = {\
128                 .start = REG_BASE_I2C ## chip_id,\
129                 .end = REG_BASE_I2C ## chip_id + REG_I2C ## chip_id ## _IOSIZE - 1,\
130                 .flags = IORESOURCE_MEM,\
131         },\
132         [1] = {\
133                 .start = IRQ_I2C ## chip_id,\
134                 .end = IRQ_I2C ## chip_id,\
135                 .flags = IORESOURCE_IRQ,\
136         },\
137 };\


也就是说,i2c_designware的irq值是start = IRQ_I2C ## chip_id

在/hisi/platform/hi6620cs_asic/soc_irqs.h

#define IRQ_GIC_START       32

#define IRQ_I2C0        (IRQ_GIC_START + 44)
#define IRQ_I2C1        (IRQ_GIC_START + 45)
#define IRQ_I2C2        (IRQ_GIC_START + 46)
#define IRQ_I2C3        (IRQ_GIC_START + 47)
#define IRQ_I2C4        (IRQ_GIC_START + 4
#define IRQ_I2C5        (IRQ_GIC_START + 49)


通过这里,可以看到这里76, 77, 78, 79分别对应I2C.0~5.



同时,可以在/hisi/platform/hi6620cs_asic/soc_irqs.h,查到其他任意irq是怎么算出来的
查看中断的触发类型,中断是否在执行,是否cpu绑定,是否为wakeup



比如在中断上半部查询当前irq的触发状态,就可以使用struct irq_data::state_use_accessors来查询。在include/linux/irq.h中定义了irqd_set_trigger_type,不过是inline static,在自己的模块无法使用,可以把对应函数代码移动到自己模块使用。



同理,还有其他几种状态,都可以通过state_use_accessors来获取。

中断和中断处理程序的一点总结  今天简单的学习了一下进程调度的东西,总结在下面。

下面代码为内核2.6.34版本。

1,中断分为上半部和下半部
   上半部:中断处理程序,接收到一个中断,立即开始执行,但只做有严格时限的工作,这些工作要求所有中断被禁止。
   下半部:可以稍后完成的工作在下半部完成。
2,中断处理程序注册函数
      request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags,
     const char *name, void *dev)
   irq是分配的中断号,要么提前定死,要么动态获得。
   handler指向处理这个中断的实际中断处理程序。
   flags 可以为0,也可以是下面一个或者多个标志的位掩码
       /*
         * These flags used only by the kernel as part of the
         * irq handling routines.
         *
         * IRQF_DISABLED - keep irqs disabled when calling the action handler
         * IRQF_SAMPLE_RANDOM - irq is used to feed the random generator
         * IRQF_SHARED - allow sharing the irq among several devices
         * IRQF_PROBE_SHARED - set by callers when they expect sharing mismatches to occur
         * IRQF_TIMER - Flag to mark this interrupt as timer interrupt
         * IRQF_PERCPU - Interrupt is per cpu
         * IRQF_NOBALANCING - Flag to exclude this interrupt from irq balancing
         * IRQF_IRQPOLL - Interrupt is used for polling (only the interrupt that is
         *                registered first in an shared interrupt is considered for
         *                performance reasons)
         * IRQF_ONESHOT - Interrupt is not reenabled after the hardirq handler finished.
         *                Used by threaded interrupts which need to keep the
         *                irq line disabled until the threaded handler has been run.
         * IRQF_NO_SUSPEND - Do not disable this IRQ during suspend
         *
         */
    name是与中断相关的设备的ASCII文本表示法。
    dev主要用于共享中断线,如果无需共享,则赋值NULL,否则必须传递唯一的信息。
3,request_irq返回0为成功,返回非0为失败。最常见的是返回-EBUSY,表示给定的中断线已经在使用。
4,request_irq可能会睡眠,因此不能再中断上下文或其他不允许阻塞的代码中调用该函数。之所有会睡眠,是因为在注册过程中会调用kmalloc()来请求分配内存,而该函数是可以睡眠的。
5,释放中断处理程序函数为free_irq(unsigned int irq, void *dev_id),如果指定的中断线是非共享的,则同时禁用该中断线。
6,典型的中断处理程序声明如下:
    irqreturn_t amd_iommu_int_handler(int irq, void *data)
    这里要注意该函数的返回值是一个特殊类型irqreturn_t。
    /**
     * enum irqreturn
     * @IRQ_NONE  interrupt was not from this device
     * @IRQ_HANDLED  interrupt was handled by this device
     * @IRQ_WAKE_THREAD handler requests to wake the handler thread
     */
7,中断处理程序无需重入。当一个给定的中断处理程序正在执行时,相应的中断线在所有处理器上都会被屏蔽,以防止在同一个中断线上接受另一个新的中断。
   但是不同中断线上的其他中断都可以处理。
   
8,共享中断处理程序注册函数的参数flags必须设置IRQF_SHARED标志,而且dev参数必须唯一真实的设备id,否则无法区分是哪个设备发来的中断。
   所有共享中断线的驱动程序都必须满足这些要求。而且注册共享中断处理程序时必须满足:要么该中断线还没有被注册,要么该中断线上的所有已注册的处理程序都设置了IRQF_SHARED标志。
   
9,当执行一个中断处理程序或下半部时,内核处于中断上下文中。中断上下文和进程没有关系,所以中断上下文不可以睡眠,而且不能从中断上下文中调用某些可以睡眠函数。
10,中断栈:中断处理程序早期是没有自己的栈,而是共享所中断进程的内核栈。2.6后,中断处理程序有了自己的栈,每个处理器一个,大小为一页。
11,中断处理机制:硬件设备产生中断,通过总线把电信号发送给中断控制器,如果中断线此时没有被屏蔽,处于激活态,则会把中断发往处理器。
    如果处理器上没有禁止该中断,则立即停止正在做的事,关闭中断系统,跳到中断处理程序的入口点。在内核中,中断处理程序都有一个入口点,这样内核就
    可以知道中断的IRQ号,入口点会在栈中保存IRQ号,并存放当前寄存器的值(这些值属于被中断的任务),然后内核调用函数unsigned int __irq_entry do_IRQ(struct pt_regs *regs)。
    struct pt_regs {
     long ebx;
     long ecx;
     long edx;
     long esi;
     long edi;
     long ebp;
     long eax;
     int  xds;
     int  xes;
     int  xfs;
     int  xgs;
     long orig_eax;
     long eip;
     int  xcs;
     long eflags;
     long esp;
     int  xss;
    };
    do_IRQ会调用handle_irq运行中断处理程序,然后调用irq_exit处理软中断(如果必须且能处理的话,这个软中断是softirqs,下半部实现的一种机制,不同于软件中断),最后将原来寄存器的值恢复。
    然后从入口点跳到ret_from_intr(汇编写的/arch/x86/kernel/entry.s),它会检查重新调度是否正在挂起,如果正在挂起,则分别按照用户抢占和内核抢占处理(具体可参考进程调度http://hi3ms.huawei.com/group/2642/blog_48236.html?uid=9986)。
    ret_from_intr:
     DISABLE_INTERRUPTS(CLBR_NONE)
     TRACE_IRQS_OFF
     decl PER_CPU_VAR(irq_count)
     leaveq
     CFI_DEF_CFA_REGISTER rsp
     CFI_ADJUST_CFA_OFFSET -8
   
12,/proc/interrupts文件中存放的是系统中与中断相关的统计信息。
    第一列是中断线,第二列是接受中断数目的计数器,第三列是处理该中断的中断控制器,最后一列是与这个中断相关的设备名字。
    root@localhost:/proc> vi interrupts

           CPU0       CPU1       CPU2       CPU3       CPU4       CPU5       CPU6       CPU7
  0:         68          0          0          0          0          0          0          0   IO-APIC-edge      timer
  4:          0          0          0        210          0          0          0          0   IO-APIC-edge      serial
  9:          0          0          0          0          0          0          0          0   IO-APIC-fasteoi   acpi
14:          0          0          0       9545          0          0          0          0   IO-APIC-edge      ata_piix
15:          0          0          0          0          0          0          0          0   IO-APIC-edge      ata_piix
16:          0          0    1224941          0          0          0          0          0   IO-APIC-fasteoi   ehci_hcd:usb1, eth0
, eth1
17:          0          0          0          0          0          0          0          0   IO-APIC-fasteoi   uhci_hcd:usb2
18:          0          0          0          0          0          0          0          0   IO-APIC-fasteoi   uhci_hcd:usb3
19:          0          0          0          0          0          0          0          0   IO-APIC-fasteoi   ata_piix
NMI:          0          0          0          0          0          0          0          0   Non-maskable interrupts
LOC:  448397250   81103735   16591016   16421416   16446300   16507987   16086415   16106542   Local timer interrupts
SPU:          0          0          0          0          0          0          0          0   Spurious interrupts
PMI:          0          0          0          0          0          0          0          0   Performance monitoring interrupts
PND:          0          0          0          0          0          0          0          0   Performance pending work
RES:       3836       1491         80         89         53         30         27         20   Rescheduling interrupts
CAL:         30         80         83         67         80         80         81         80   Function call interrupts
TLB:        932       1370       1588       1619       1723       1167         72         47   TLB shootdowns
ERR:          0
MIS:          0

13,一些中断控制函数或者宏
   local_irq_enable  --激活本地中断传递
   local_irq_disable  --禁止本地中断传递
   local_irq_save  --保存本地中断传递的状态,然后禁止本地中断传递
   local_irq_restore  --恢复本地中断传递到指定的状态
   disable_irq  --disable an irq and wait for completion
   disable_irq_nosync  --disable an irq without waiting
   enable_irq  --enable handling of an irq
   irqs_disabled  --return flags == RAW_IRQ_DISABLED;
   in_interrupt  --是否在中断上下文中
   in_irq --是否正在执行中断处理程序
   in_softirq  --是否正在执行软中断程序

论坛徽章:
3
天秤座
日期:2013-12-27 13:44:58射手座
日期:2014-05-22 16:52:43天蝎座
日期:2014-08-13 16:03:21
63 [报告]
发表于 2014-07-30 17:08 |只看该作者
如何在android上编译单个modules  在调试阶段,如果仅仅是单个.ko的反复修改和调试,可以通过单独编译modules的方法进行。



1,增加一个makefile



bash代码
obj-m += xxxx.o

KERNEL_PATH=../../../../../out/target/product/xxxx/obj/KERNEL_OBJ

all:
    make -C $(KERNEL_PATH) M=`pwd` ARCH=arm CROSS_COMPILE=arm-linux-androideabi- modules

clean:
    make -C $(KERNEL_PATH) M=`pwd` ARCH=arm CROSS_COMPILE=arm-linux-androideabi- clean


2, 增加对应的xxxx.o的源文件



3, make CFLAGS_MODULE=-fno-pic



4, push 该模块到手机上


5, insmod

【内核翻译】sysfs,附参考代码  sysfs  The filesystem for exporting kernel objects
Documentation/filesystems/sysfs.txt


Patrick Mochel  <mochel@osdl.org>
Mike Murphy <mamurph@cs.clemson.edu>
Revised:    16 August 2011
Original:   10 January 2003


Translator: Bill Wang(Liang) (w00173980)


What it is:
sysfs是一个ram-based filesystem,基于ramfs。用于导出kernel的数据结构,属性以及kernel space和user space之间的联系。


sysfs和kobject紧密相关。请查阅Documentation/kobject.txt来了解kobject的信息。


Using sysfs
sysfs在CONFIG_SYSFS选项打开后,编译到内核。通过mount来挂载:
        mount -t sysfs sysfs /sys


Directory Creation
每一个注册到系统中的kobject都会有一个sysfs的目录。这个目录是对应Koject的父目录的子目录。【译注:这句话有点绕,有点递归的意思,意思是说,每个kobject都有一个目录,如果kobject有一个parent,那么他的目录就是parent对应的目录的子目录,如果么没有parent,那么就是/sys的子目录】


通过目录结构来标示kobject的层次关系。


Sysfs内部持有一个指针,该指针指向一个在sysfs_dirent对象关联的目录中实现目录的kobject【?】。在过去,Kobject pointer被sysfs用来在kobject 打开或者关闭的时候做引用计数。在现在的sysfs实现中,kobject的引用计数仅仅通过sysfs_schedule_callback()来修改。


Attributes
kobject的属性以文件的形式导出到文件系统中。sysfs将文件I/O操作转换为kobject属性中定义的方法。


属性应该是ASCII文件,建议每个文件只有一个值。不过每个文件只有一个值,效率不是很好,所以也可以有一组相同类型的值。


混合类型,多组数据,或者很复杂的格式化数据不是很恰当。


一个属性对的定义很简单:
        struct attribute {
                char                    * name;
                struct module       *owner;
                umode_t               mode;
                };

        int sysfs_create_file(struct kobject * kobj, const struct attribute * attr);
        void sysfs_remove_file(struct kobject * kobj, const struct attribute * attr);


单单一个属性不能够对属性进行读或者写。各模块需要定义自己的attribute结构,添加对应的读写方法。


比如设备模型使用的strcut device_attribute:
        struct device_attribute {
                struct attribute attr;
                ssize_t (*show)(struct device *dev, struct device_attribute *arr, char *buf);
                ssize_t (*store)(struct device *dev, struct device_attribute *attr, const char *buf, size_t count);


同时也定义了宏来简化定义:
        #define DEVICE_ATTR(_name, _mode, _show, _store)\
        struct device_attribute dev_attr_##_name = __ATTR(_name, _mode, _show, _store)


这样声明一个属性就很简单:
        static DEVICE_ATTR(foo, S_IWUSR | S_IRUGO, show_foo, store_foo);
这句话等同于:
        static struct device_attribute dev_attr_foo = {
                .attr = {
                        .name = "foo",
                        .mode = S_IWUSR | S_IRUGO,
                },
                .show = show_foo,
                .store = store_foo,
        };


Subsystem-Specific Callbacks
当一个模块定义一个新的属性类型,那么就必须实现对应的sysfs操作,这些操作用来读写属性文件。
        struct sysfs_ops {
                ssize_t (*show)(struct kobject*, struct attribute *, char*);
                ssize_t (*store)(struct kobject*, struct attribute *, const char *, size_t);
        }
[子系统应该已经定义了struct kobj_type,这kobj_type中包含了sysfs_ops,参考kobject的文档来查看更多细节]


当一个文件被读写,sysfs就会调用合适的方法。该方法会向通用的struct kobject 和 struct attribute pointers转换为特性的指针类型,然后调用关联的方法。


例子:
drivers/base/core.c


        #define to_dev(obj) container_of(obj, struct device, kobj)
        【译注:返回obj所在的struct device的指针】
        #define to_dev_attr(_attr) container_of(_attr, struct device_attribute, attr)
        【译注:返回attr所在的struct device_attribute的指针】


        static ssize_t dev_attr_show(struct kobject *kobj, struct attribute* attr, char *buf)
        {
                struct device_attribute *dev_attr = to_dev_attr(attr);
                struct device *dev = to_dev(kobj);
                ssize_t ret = -EIO;


                if (dev_attr->show)
                        ret = dev_attr->show(dev, dev_attr, buf);
                if (ret >= (ssize_t)PAGE_SIZE) {
                        print_symbol("dev_attr_show: %s return bad count\n", (unsigned long)dev_attr->show);
                }
                return ret;
        }


【?我的例子里,没有注册设备,只是注册是kobject,为何也能找到对应的show, store,是不是kobject只能用于设备模型,而不能用于其他方面】


Reading/Writing Attribute Data
为了读写属性,show()和store()方法必须在声明属性的时候定义。
        ssize_t (*show)(struct device *dev, struct device_attribute *attr, char *buf);
        ssize_t (*store)(struct device *dev, struct device_attribute *att, const char *buf, size_t count);
换句话说,这两个方法参数只能有一个对象,一个属性和一个buf。


sysfs申请PAGE_SIZE大小的buffer,然后把这个buf传递给方法。每次读写,sysfs只会调用一次方法。这样在方法实现上就有这些特点:
        ---对于read(2),show应该填满整个buffer。由于一个属性只能export一个值,或者一组同类型的值,所以buffer不会太大。
        这个办法也可以让用户空间进行部分读和seek操作。如果用户空间通过seek到0,或者通过pread(2)时用参数0,那么show()多调用一次。
        ---对于write(2),sysfs会将写buffer传入到store()。
        当写sysfs文件时,用户空间应该先读取文件的值,修改成期望的值,然后把整个buf写回。


        属性的读写操作应该操作同一个buf。
        【???】为何写入writehere时,store()方法调用了两次? echo writehere>/sys/hwobj/write_node
其他需要注意的:
        ---【???】写操作会引起show()的位置回到文件开始。
        ---buffer的大小总是PAGE_SIZE。
        ---show()应该返回写入到buf中的长度,返回值和scnprintf()一样。
        【译注】
        scnprintf -- Format a string and place it in a buffer
        int scnprintf(char* buf, size_t size, const char *fmt, ....);
        buf: the buffer to place the result into
        size: the buffer size, including the trailing null space
        【end】
        ---store()应该返回buffer所用的大小。如果所有的buffer都用完了,只需要返回count参数?
        ---show()或者store()方法可以返回错误。如果一个错误的参数传入,那么可以返回一个错误。
        ---show()或者store()传入的对象,会在sysfs引用的object的内存中(?)。所以,物理的设备可能不会存在,所以,如果需要,要检查物理设备是否存在。


简单的实现可以这样:
        static ssize_t show_name(struct device *dev, struct device_attribute *attr, char *buf)
        {
                return scnprintf(buf, PAGE_SIZE, "%s\n", dev->name);
        }
       
        static ssize_t store_name(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
        {
                snprintf(dev->name, sizeof(dev->name, "%.*s", (int)min(count, sizeof(dev->name) - 1), buf);
                return count;
        }


static DEVICE_ATTR(name, S_IRUGO, show_name, store_name);


(注意:真实的应用中,不应该通过userspace来设置device的名字。


Top Level Directory Layout
sysfs的目录结构导出了kernel的数据结构关系。
顶层的sysfs目录结构类似于:
        block/
        bus/
        class/
        dev/
        devices/
        firmware/
        net/
        fs/
devices/用一个文件系统标示了设备树。直接映射了内部的内核设备树,也就是struct device的结构。


bus/用罗列了内核中各种bus类型。每一种bus的目录中的都有两个文件夹:
        devices/
        drivers/


/sys/bus/[bus-type]/devices/ 包含了在系统中发现的设备的链接,指向了/sys/devices下的设备。
/sys/bus/[bus-type]/drivers/ 包含了bus上挂在的设备的驱动。


fs/包含了当前系统的filesystem,子目录时名子文件系统想要导出的属性。


dev/包含了两个文件夹,char/和block/。在各自的目录中,分别时用<major>:<minor>命名的符号链接。


更多关于设备模型的特性可以在/Documentation/driver-model/查看。


TODO: Finish this section


Current Interfaces
- devices (include/linux/device.h)
----------------------------------
Structure:

struct device_attribute {
         struct attribute        attr;
         ssize_t (*show)(struct device *dev, struct device_attribute *attr,
                         char *buf);
         ssize_t (*store)(struct device *dev, struct device_attribute *attr,
                          const char *buf, size_t count);
};

Declaring:

DEVICE_ATTR(_name, _mode, _show, _store);

Creation/Removal:

int device_create_file(struct device *dev, const struct device_attribute * a    ttr);
void device_remove_file(struct device *dev, const struct device_attribute *     attr);


- bus drivers (include/linux/device.h)
--------------------------------------
Structure:

struct bus_attribute {
         struct attribute        attr;
         ssize_t (*show)(struct bus_type *, char * buf);
         ssize_t (*store)(struct bus_type *, const char * buf, size_t count);
};

Declaring:

BUS_ATTR(_name, _mode, _show, _store)

Creation/Removal:

int bus_create_file(struct bus_type *, struct bus_attribute *);
void bus_remove_file(struct bus_type *, struct bus_attribute *);


- device drivers (include/linux/device.h)
-----------------------------------------

Structure:

struct driver_attribute {
         struct attribute        attr;
         struct attribute        attr;
         ssize_t (*show)(struct device_driver *, char * buf);
         ssize_t (*store)(struct device_driver *, const char * buf,
                          size_t count);
};

Declaring:

DRIVER_ATTR(_name, _mode, _show, _store)

Creation/Removal:

int driver_create_file(struct device_driver *, const struct driver_attribute     *);
void driver_remove_file(struct device_driver *, const struct driver_attribut    e *);


Documentation
~~~~~~~~~~~~~
sysfs目录结构和属性定义了kernel和userspace之间的ABI。因此上,这些ABI要稳定和恰当的说明。所有新的sysfs attribute要在Documentation/ABI中说明,查看Docomentation/ABI/README来了解更多。

论坛徽章:
3
天秤座
日期:2013-12-27 13:44:58射手座
日期:2014-05-22 16:52:43天蝎座
日期:2014-08-13 16:03:21
64 [报告]
发表于 2014-07-30 17:10 |只看该作者
本帖最后由 compare2000 于 2014-09-12 16:38 编辑

samp_sysfs.c.txt
/*
* sysfs.example.c - sample code for Documentation/filesystems/sysfs.txt
*
* Copyright (C) 2013  Bill Wang(Liang)
*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA.
*/


#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/kobject.h>
#include <linux/device.h>

static struct kobject *hwobj=NULL;

ssize_t show_node(struct device *dev, struct device_attribute *att, char *buf)
{
        pr_info("%s called\n",__func__);
        return scnprintf(buf, sizeof("show_node", "%s", "show_node";
}

ssize_t store_node(struct device *dev, struct device_attribute *att, const char *buf,
                size_t count)
{
        pr_info("%s store value %s\n",__func__, buf);
        return sizeof(buf);
}


static DEVICE_ATTR(write_node, S_IWUSR | S_IRUGO, NULL, store_node);
static DEVICE_ATTR(read_node, S_IWUSR | S_IRUGO, show_node, NULL);

static int __init samp_sysfs_init(void)
{
        int ret = 0;
        pr_info("%s module init\n", __func__);
        hwobj = kobject_create_and_add("hwobj", NULL);
        if (IS_ERR(hwobj)){
                ret = PTR_ERR(hwobj);
                pr_err("object alloc failed\n";
                goto exit_del_kobject;
        }

        ret = sysfs_create_file(hwobj, &dev_attr_read_node.attr);
        if (ret){
                pr_err("create read node failed %d\n", ret);
                goto exit_del_sysfs_read;
        }

        ret = sysfs_create_file(hwobj, &dev_attr_write_node.attr);
        if (ret){
                pr_err("create write node failed %d\n", ret);
                goto exit_del_sysfs_write_node;
        }
        return ret;

exit_del_sysfs_write_node:
        sysfs_remove_file(hwobj, &dev_attr_write_node.attr);
exit_del_sysfs_read:
        sysfs_remove_file(hwobj, &dev_attr_read_node.attr);
exit_del_kobject:
        kobject_del(hwobj);
        pr_info("%s return %d \n", __func__, ret);

        return ret;
}
static void __exit samp_sysfs_cleanup(void)
{
        sysfs_remove_file(hwobj, &dev_attr_write_node.attr);
        sysfs_remove_file(hwobj, &dev_attr_read_node.attr);
        kobject_del(hwobj);
        printk(KERN_INFO "hell_cleanup\n";
}

module_init(samp_sysfs_init);
module_exit(samp_sysfs_cleanup);

MODULE_AUTHOR("Bill Wang(Liang)";
MODULE_DESCRIPTION("sample code for Documentation/filesystems/sysfs.txt";
MODULE_LICENSE("GPL";

external folder中linux kernel header的作用






在Linux中,有一个external/kernel-headers/original,这个文件夹中有很多linux的头文件,与kernel/include/linux有很多重复的文件。


1、Android external folder


External refers to external open source libraries. That means libraries that the Android platform depend upon but that are not primarily developed and maintained by the Android open source project. Typical examples are webkit for the browser, FreeType for fonts, SqlLite for databases and so on. As more features are added to Android, more of these libraries are included in external.


external folder是外部的open source lib,这些lib是android依赖的,但是主要的开发和维护又不是android来做


http://stackoverflow.com/questio ... older-functionality


2,external/kernel-headers/original
(external/kernel-headers/original/README.TXT)
这个文件夹里的头文件是Bionic来用生成一个干净的user-land(user space)头文件。基于GPL2+。




3、Bionic




Bionic libc是BSD standard C library发展而来,最早是Google为Android开发。作用主要有三个:
a,BSD license: 通过BSD license,Android程序就和GPL分隔开来。
b,Bionic比GNU C Library要小的多。
c,Bionic的速度更快。


Bionic也缺少很多完整的libc的特性,比如宽字符和C++的异常处理。一些函数也没有实现。


(http://discuz-android.blogspot.c ... ve-libc-bionic.html)




HAL层,以及除了kernel意外的任意用到的C头文件,都是bionic中的。
./core/pathmap.mk,pathmap_INCL :=    libc:bionic/libc/include
http://www.linuxidc.com/Linux/2011-03/33672.htm )


Android编译环境所用的交叉编译工具链是prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin/arm-eabi-gcc,-I和-L参数指定了所用的C库头文件和动态库文件路径分别是bionic/libc/include和out/target/product/generic/obj/lib
(http://www.360doc.com/content/09/0624/17/36491_4018938.shtml


kernel中用的头文件在kernel/include中。user space用的头文件在bionic下。


4,Bionic kernel header
(bionic/libc/kernel/README.TXT)
Bionic有一套干净的Linux头文件,这些头文件是通过bionic/libc/kernel/tools解析一份原始的,没有修改过的linux头文件生成的,这份头文件就在external/kernel-headers/original。
干净的头文件只包括类型和宏定义,不过处于效率的考虑,不会生成一些静态内联函数。
这些生成的头文件可以用于编译C++,C,也能够按照ANSI模式编译(linux kernel中用到了大量GNU扩展)。
生成头文件的过程是:
*external/kernel-headers/original
包含通常linux kernel source tree中的include目录。这里仅仅只应该包含android依赖的kernel头文件。


*bionic/libc/kernel/common
包含平台无关的头文件。
TMCC  http://www.broadcast.hc360.com/network/2001-6/35.htm





传输与复用结构控制信号(TMCC)应当包含以下信息:
    ● 用于每一狭槽的调制码组合;
    ● 用于每一狭槽的MPEG-TS识别码;
    ● 其它(例如顺序改变,广播报警、突发事件的旗标比特等)。
    TMCC信号应当比主信号优先传送,因为在没有TMCC信号时,主信号不能解调。TMCC信号恢复的最小间隙应当是一个超级帧的周期时间。接收机应当首先解码每一超级帧的TMCC信号。除了上述信息之外,TMCC信号还应当传送时间基准信号。

repo 备忘  1, repo branch/branches

这两个命令结果和目的一样。显示当前的branch状态和数量。

输出格式:


*P nocolor                   | in repo



输出格式有4列,第一列*显示了当前在用的branch.

第二列,可能是空格,p或者P,取决于upload的状态。

空表示还没有提交发布。

P表示所有提交已经通过repo upload发布。

p表示只有一部分通过repo upload发布。



2,repo diff
查看diff


3,  repo status [<project>...]


比较 工作目录和index,以及HEAD的区别。
结果显示三列,第一列表示index和HEAD的区别,大写。
-表示没有区别。
A:  added         (not in HEAD,     in index                     )
M:  modified      (    in HEAD,     in index, different content  )
D:  deleted       (    in HEAD, not in index                     )
R:  renamed       (not in HEAD,     in index, path changed       )
C:  copied        (not in HEAD,     in index, copied from another)
T:  mode changed  (    in HEAD,     in index, same content       )
U:  unmerged; conflict resolution required


第二列表示working tree和index的区别,小写。
-:  new / unknown (not in index,     in work tree                )
m:  modified      (    in index,     in work tree, modified      )
d:  deleted       (    in index, not in work tree                )




4, repo list
List all projects




5, repo start


Start a new branch for development


Usage: repo start <newbranchname> [--all | <project>...]


'repo start' begins a new branch of development, starting from the
revision specified in the manifest.


一个目录下有一大堆同质或不同质的程序,要测试系统处理并发任务的效率不得不写一个任务分发器(work load manager),用C写对新手来说还是有点大条的,利用make -j可以模拟一个简单的wlm。代码大概如下:
01.binaries := $(foreach ccode, \

02.              $(shell for cfile in `ls *.c`; do echo $cfile; done),\

03.              $(ccode:.c=))

04.$(binaries): %:%.c

05.        @echo BLD        $@

06.        @gcc -o $@       $< >/dev/null 2>&1

07.

08.to_run := $(foreach ccode, \

09.            $(shell for cfile in `ls *.c`; do echo $cfile; done),\

10.            to_run_$(ccode:.c=))

11.

12.run: clean $(to_run)

13.to_run_%: %

14.        @to_run=$@;                         \

15.         echo ${to_run##to_run_};        

16.

17.clean:

18.        @echo -n "-------------------------------- CLEAN "

19.        @echo "--------------------------------"

20.        @echo RMV        $(binaries)

21.        @rm -f                 $(binaries)

22.

23.

24..PHONY: run clean
复制代码运行 make -jN 即可
简而言之就是:
1. default 的 target 是 run,run 依赖于 clean 和 to_run
01.run: clean $(to_run)
复制代码2. to_run 是由一段 shell 产生的
01.to_run := $(foreach ccode, \

02.             $(shell for cfile in `ls *.c`; do echo $cfile; done),\

03.             to_run_$(ccode:.c=))
复制代码3. 假设目录下有 1.c 2.c 3.c 4.c ... 100.c 这100个c程序, 那段 shell 生成的变量 to_run 等于这样的一串: to_run_1 to_run2 ... to_run_100
4. to_run_%: % 那一段 rule 的意思是对于某个目标 to_run_73 依赖于 73,当 73 不存在或者 73.c 被更新过, make 就按照上面声明的 binaries 的规则去(重新)生成它:
01.$(binaries): %:%.c

02.         @echo BLD        $@

03.         @gcc -o $@       $< >/dev/null 2>&1
复制代码5.  73 生成以后就运行它,示例里用的是 echo
01.@to_run=$@;                         \

02.          echo ${to_run##to_run_};   
复制代码实际上可以是
01.@to_run=$@;                         \

02.          ./${to_run##to_run_};   
复制代码这样 73 就在适当的时候被运行了。
假设输入 make -j32 run,结果就是可执行文件 1, 2, 3 ... 32 同时被运行,其中的某个结束后 make 会自动启动后面的 33, 34 ... 直至所有的运行结束,这就模拟了一个简单的本地 work load manager。

这个make脚本的另外一个变种可以是:你有一个程序(假设叫 EXEC0),在一台16核的机器上你希望并行地运行32个带不同参数的 EXEC0 实例,总共运行 1024 个实例来测试系统或者 EXEC0 的运行效率,Makefile大概可以这样写:
01.ifeq ($(MAX),)

02.        MAX=1024

03.endif

04.

05.parameter0=0

06.parameter1=11

07.parameter2=22

08.parameter3=33

09.

10.prerequisites := $(foreach num,                                        \

11.                   $(shell i=0; while [ $$i -lt $(MAX) ];        \

12.                                do                                \

13.                                        echo $$i;                \

14.                                        i=$$((i + 1));                \

15.                                    done),                                \

16.                  target_$(num))

17.run(prerequisites)

18.

19.EXEC0: EXEC0.c

20.        gcc -o $@ $<

21.

22.target_%:EXEC0

23.        @./EXEC0 $(parameter$(shell expr $(subst target_,,$@) % 4))

24.

25..PHONY: run
复制代码一个无聊的EXEC0.c 可以是:
01.int

02.main(int argc, char **argv)

03.{

04.        sleep(atoi(argv[1]));

05.        printf("%s %d\n", argv[0], atoi(argv[1]));

06.

07.        return 0;

08.}
复制代码然后make -j32 MAX=1024

论坛徽章:
3
天秤座
日期:2013-12-27 13:44:58射手座
日期:2014-05-22 16:52:43天蝎座
日期:2014-08-13 16:03:21
65 [报告]
发表于 2014-09-12 16:38 |只看该作者
本帖最后由 compare2000 于 2014-09-12 16:39 编辑

http://bbs.chinaunix.net/thread-1512640-1-1.html
http://blog.chinaunix.net/u/22754/showart_372628.html
=== 1 概述
     === 2 角色分工
     === 3 内核编译文件
        --- 3.1 目标定义
        --- 3.2 内嵌对象 - obj-y
        --- 3.3 可加载模块 - obj-m
        --- 3.4 导出符号
        --- 3.5 库文件 - lib-y
        --- 3.6 目录递归
        --- 3.7 编译标记
        --- 3.8 命令依赖
        --- 3.9 依赖关系
        --- 3.10 特殊规则
     === 4 辅助程序
        --- 4.1 简单辅助程序
        --- 4.2 组合辅助程序
        --- 4.3 定义共享库
        --- 4.4 C++语言使用方法
        --- 4.5 辅助程序编译控制选项
        --- 4.6 何时建立辅助程序
        --- 4.7 使用hostprogs-$(CONFIG_FOO)
     === 5 编译清除机制
     === 6 体系Makefile文件
        --- 6.1 变量设置
        --- 6.2 增加预设置项
        --- 6.3 目录表
        --- 6.4 引导映像
        --- 6.5 编译非内核目标
        --- 6.6 编译引导映像命令
        --- 6.7 定制编译命令
        --- 6.8 预处理连接脚本
        --- 6.9 $(CC)支持功能
     === 7 Kbuild变量
     === 8 Makefile语言
     === 9 Credits
     === 10 TODO
=== 1 概述
Makefile包括五部分:
     Makefile            顶层Makefile文件
     .config                  内核配置文件
     arch/$(ARCH)/Makefile      机器体系Makefile文件
     scripts/Makefile.*      所有内核Makefiles共用规则
     kbuild Makefiles      其它makefile文件
通过内核配置操作产生.config文件,顶层Makefile文件读取该文件的配置。顶层Makefile文件负责产生两个主要的程序:vmlinux (内核image)和模块。顶层Makefile文件根据内核配置,通过递归编译内核代码树子目录建立这两个文件。顶层Makefile文件文本一个名为arch/$(ARCH)/Makefile的机器体系makefile文件。机器体系Makefile文件为顶层makefile文件提供与机器相关的信息。每一个子目录有一个makefile文件,子目录makefile文件根据上级目录makefile文件命令启动编译。这些makefile使用.config文件配置数据构建各种文件列表,并使用这些文件列表编译内嵌或模块目标文件。scripts/Makefile.*包含了所有的定义和规则,与makefile文件一起编译出内核程序。
=== 2 角色分工
人们与内核makefile存在四种不同的关系:
*用户* 用户使用"make menuconfig"或"make"命令编译内核。他们通常不读或编辑内核makefile文件或其他源文件。
*普通开发者* 普通开发者维护设备驱动程序、文件系统和网络协议代码,他们维护相关子系统的makefile文件,因此他们需要内核makefile文件整体性的一般知识和关于kbuild公共接口的详细知识。
*体系开发者* 体系开发者关注一个整体的体系架构,比如sparc或者ia64。体系开发者既需要掌握关于体系的makefile文件,也要熟悉内核makefile文件。
*内核开发者* 内核开发者关注内核编译系统本身。他们需要清楚内核makefile文件的所有方面。
本文档的读者对象是普通开发者和系统开发者。
=== 3 内核编译文件
内核中大多数makefile文件是使用kbuild基础架构的makefile文件。本章介绍kbuild的makefile中的语法。
3.1节“目标定义”是一个快速导引,后面各章有详细介绍和实例。
--- 3.1 目标定义
     目标定义是makefile文件的主要部分(核心)。这些目标定义行定义了如何编译文件,特殊的兼容选项和递归子目录。
      最简单的makefile文件只包含一行:
     Example: obj-y += foo.o
    这行告诉kbuild在该目录下名为foo.o的目标文件(object),foo.o通过编译foo.c或者foo.S而得到。
    如果foo.o编译成一个模块,则使用obj-m变量,因此常见写法如下:
     Example: obj-$(CONFIG_FOO) += foo.o
     $(CONFIG_FOO)可以代表y(built-in对象)或m(module对象)。
      如果CONFIG_FOO不是y或m,那么这个文件不会被编译和链接。
--- 3.2 内嵌对象 - obj-y
    makefile文件将为编译vmlinux的目标文件放在$(obj-y)列表中,这些列表依赖于内核配置。
      Kbuild编译所有的$(obj-y)文件,然后调用"$(LD) -r"合并这些文件到一个built-in.o文件中。built-in.o经过父makefile文件链接到vmlinux。$(obj-y)中的文件顺序很重要。列表中文件允许重复,文件第一次出现将被链接到built-in.o,后续出现该文件将被忽略。
      链接顺序之所以重要是因为一些函数在内核引导时将按照他们出现的顺序被调用,如函数(module_init() / __initcall)。所以要牢记改变链接顺序意味着也要改变SCSI控制器的检测顺序和重数磁盘。
      例如: #drivers/isdn/i4l/Makefile
     # 内核ISDN子系统和设备驱动程序Makefile
     # 每个配置项是一个文件列表
     obj-$(CONFIG_ISDN)         += isdn.o
     obj-$(CONFIG_ISDN_PPP_BSDCOMP) += isdn_bsdcomp.o
--- 3.3 可加载模块 - obj-m
  $(obj-m)表示对象文件(object files)编译成可加载的内核模块。
  一个模块可以通过一个源文件或几个源文件编译而成。makefile只需简单地它们加到$(obj-m)。
      例如:#drivers/isdn/i4l/Makefile
        obj-$(CONFIG_ISDN_PPP_BSDCOMP) += isdn_bsdcomp.o
    注意:在这个例子中$(CONFIG_ISDN_PPP_BSDCOMP)含义是'm'。
      如果内核模块通过几个源文件编译而成,使用以上同样的方法。
      Kbuild需要知道通过哪些文件编译模块,因此需要设置一个$(-objs)变量。
    例如:#drivers/isdn/i4l/Makefile
     obj-$(CONFIG_ISDN) += isdn.o
     isdn-objs := isdn_net_lib.o isdn_v110.o isdn_common.o
     在这个例子中,模块名isdn.o. Kbuild首先编译$(isdn-objs)中的object文件,然后运行"$(LD) -r"将列表中文件生成isdn.o.
  Kbuild使用后缀-objs、-y识别对象文件。这种方法允许makefile使用CONFIG_符号值确定一个object文件是否是另外一个object的组成部分。
     例如: #fs/ext2/Makefile
        obj-$(CONFIG_EXT2_FS)     += ext2.o
        ext2-y := balloc.o bitmap.o
        ext2-$(CONFIG_EXT2_FS_XATTR) += xattr.o
     在这个例子中,如果$(CONFIG_EXT2_FS_XATTR)表示'y',则ext2.o只有xattr.o组成部分。
     注意: 当然,当你将对象文件编译到内核时,以上语法同样有效。因此,如果CONFIG_EXT2_FS=y,Kbuild将先编译ext2.o文件,然后链接到built-in.o。
--- 3.4 导出符号目标
      在makefile文件中没有特别导出符号的标记。
--- 3.5 库文件 - lib-y
      obj-*中的object文件用于模块或built-in.o编译。object文件也可能编译到库文件中--lib.a。
      所有罗列在lib-y中的object文件都将编译到该目录下的一个单一的库文件中。
      包含在0bj-y中的object文件如果也列举在lib-y中将不会包含到库文件中,因为他们不能被访问。但lib-m中的object文件将被编译进lib.a库文件。
      注意在相同的makefile中可以列举文件到buit-in内核中也可以作为库文件的一个组成部分。因此在同一个目录下既可以有built-in.o也可以有lib.a文件。
      例如:#arch/i386/lib/Makefile
        lib-y   := checksum.o delay.o
     这样将基于checksum.o、delay.o创建一个lib.a文件。
      对于内核编译来说,lib.a文件被包含在libs-y中。将“6.3 目录表”。
      lib-y通常被限制使用在lib/和arch/*/lib目录中。
--- 3.6 目录递归
     makefile文件负责编译当前目录下的目标文件,子目录中的文件由子目录中的makefile文件负责编译。编译系统将使用obj-y和obj-m自动递归编译各个子目录中文件。
     如果ext2是一个子目录,fs目录下的makefile将使用以下赋值语句是编译系统编译ext2子目录。
     例如: #fs/Makefile
        obj-$(CONFIG_EXT2_FS) += ext2/
     如果CONFIG_EXT2_FS设置成'y(built-in)或'm'(modular),则对应的obj-变量也要设置,内核编译系统将进入ext2目录编译文件。
      内核编译系统只使用这些信息来决定是否需要编译这个目录,子目录中makefile文件规定那些文件编译为模块那些是内核内嵌对象。
      当指定目录名时使用CONFIG_变量是一种良好的做法。如果CONFIG_选项不为'y'或'm',内核编译系统就会跳过这个目录。
--- 3.7 编译标记
  EXTRA_CFLAGS, EXTRA_AFLAGS, EXTRA_LDFLAGS, EXTRA_ARFLAGS
  所有的EXTRA_变量只能使用在定义该变量后的makefile文件中。EXTRA_变量被makefile文件所有的执行命令语句所使用。
     $(EXTRA_CFLAGS)是使用$(CC)编译C文件的选项。
     例如: # drivers/sound/emu10k1/Makefile
           EXTRA_CFLAGS += -I$(obj)
           ifdef
            DEBUG EXTRA_CFLAGS += -DEMU10K1_DEBUG
            endif
     定义这个变量是必须的,因为顶层makefile定义了$(CFLAGS)变量并使用该变量编译整个代码树。
     $(EXTRA_AFLAGS)是每个目录编译汇编语言源文件的选项。
     例如: #arch/x86_64/kernel/Makefile
           EXTRA_AFLAGS := -traditional
     $(EXTRA_LDFLAGS)和$(EXTRA_ARFLAGS)用于每个目录的$(LD)和$(AR)选项。
     例如: #arch/m68k/fpsp040/Makefile
           EXTRA_LDFLAGS := -x
  CFLAGS_$@, AFLAGS_$@
     CFLAGS_$@和AFLAGS_$@只使用到当前makefile文件的命令中。
     $(CFLAGS_$@)定义了使用$(CC)的每个文件的选项。$@部分代表该文件。
     例如: # drivers/scsi/Makefile
           CFLAGS_aha152x.o =   -DAHA152X_STAT -DAUTOCONF
           CFLAGS_gdth.o   = # -DDEBUG_GDTH=2 -D__SERIAL__ -D__COM2__ \
  -DGDTH_STATISTICS CFLAGS_seagate.o =   -DARBITRATE -DPARITY -DSEAGATE_USE_ASM
     这三行定义了aha152x.o、gdth.o和seagate.o文件的编译选项。
     $(AFLAGS_$@)使用在汇编语言代码文件中,具有同上相同的含义。
     例如: # arch/arm/kernel/Makefile
           AFLAGS_head-armv.o := -DTEXTADDR=$(TEXTADDR) -traditional
           AFLAGS_head-armo.o := -DTEXTADDR=$(TEXTADDR) -traditional
--- 3.9 依赖关系
     内核编译记录如下依赖关系:
      1) 所有的前提文件(both *.c and *.h)
      2) CONFIG_ 选项影响到的所有文件
      3) 编译目标文件使用的命令行
     因此,假如改变$(CC)的一个选项,所有相关的文件都要重新编译。
--- 3.10 特殊规则
      特殊规则使用在内核编译需要规则定义而没有相应定义的时候。典型的例子如编译时头文件的产生规则。其他例子有体系makefile编译引导映像的特殊规则。特殊规则写法同普通的Make规则。
     Kbuild(应该是编译程序)在makefile所在的目录不能被执行,因此所有的特殊规则需要提供前提文件和目标文件的相对路径。
     定义特殊规则时将使用到两个变量:
  $(src): $(src)是对于makefile文件目录的相对路径,当使用代码树中的文件时使用该变量$(src)。
  $(obj): $(obj)是目标文件目录的相对路径。生成文件使用$(obj)变量。
     例如: #drivers/scsi/Makefile
     $(obj)/53c8xx_d.h: $(src)/53c7,8xx.scr $(src)/script_asm.pl
        $(CPP) -DCHIP=810 - -objs)包含了所有的用于链接最终可执行程序的对象。
     例如: #scripts/lxdialog/Makefile
        hostprogs-y   := lxdialog
        lxdialog-objs := checklist.o lxdialog.o
     扩展名.o文件都编译自对应的.c文件。在上面的例子中checklist.c编译成checklist.o,lxdialog.c编译为lxdialog.o。最后两个.o文件链接成可执行文件lxdialog。
     注意:语法-y不能用于定义主机程序。
--- 4.3 定义共享库
     扩展名为.so的对象是共享库文件,并且是位置无关的object文件。内核编译系统提供共享库使用支持,但使用方法有限制。在下面例子中libkconfig.so库文件被链接到可执行文件conf中。
     例如: #scripts/kconfig/Makefile
           hostprogs-y   := conf
           conf-objs     := conf.o libkconfig.so
           libkconfig-objs := expr.o type.o
     共享库文件需要对应的-objs定义, 在上面例子中库libkconfig由两个对象组成:expr.o和type.o。expr.o和type.o将被编译为位置无关代码并被链接如libkconfig.so。共享库不支持C++语言。
--- 4.4 C++语言使用方法
     内核编译系统提供了对C++主机程序的支持以用于内核配置,但不主张其它方面使用这种方法。
     例如: #scripts/kconfig/Makefile
           hostprogs-y   := qconf
           qconf-cxxobjs := qconf.o
     在上面例子中可执行文件由C++文件qconf.cc组成 - 通过$(qconf-cxxobjs)标识。
     如果qconf由.c和.cc文件混合组成,附加行表示这种情况。
     例如: #scripts/kconfig/Makefile
           hostprogs-y   := qconf
           qconf-cxxobjs := qconf.o
           qconf-objs   := check.o
--- 4.5 辅助程序编译控制选项
     当编译主机程序时仍然可以使用$(HOSTCFLAGS)设置编译选项传递给$(HOSTCC)。这些选项将影响所有使用变量HOST_EXTRACFLAG的makefile创建的主机程序。
     例如: #scripts/lxdialog/Makefile
           HOST_EXTRACFLAGS += -I/usr/include/ncurses
     为单个文件设置选项使用下面方式:
     例如: #arch/ppc64/boot/Makefile
     HOSTCFLAGS_piggyback.o := -DKERNELBASE=$(KERNELBASE)
     也可以使用附加链接选项:
     例如: #scripts/kconfig/Makefile
           HOSTLOADLIBES_qconf := -L$(QTDIR)/lib
     当链接qconf时将使用外部选项"-L$(QTDIR)/lib"。
--- 4.6 何时建立辅助程序
     只有当需要时内核编译系统才会编译主机程序。有两种方式:
     (1) 在特殊规则中作为隐式的前提需求
     例如: #drivers/pci/Makefile
     hostprogs-y := gen-devlist
     $(obj)/devlist.h: $(src)/pci.ids $(obj)/gen-devlist
              ( cd $(obj); ./gen-devlist )  产生 .config文件
2) 保存内核版本到include/linux/version.h文件中
3) 符号链接include/asm to include/asm-$(ARCH)
4) 更新所有目标对象的其它前提文件
  - 附加前提文件定义在arch/$(ARCH)/Makefile文件中
5) 递归进入init-* core* drivers-* net-* libs-*中的所有子目录和编译所有的目标对象
  - 上面变量值都引用到arch/$(ARCH)/Makefile文件。
6) 链接所有的object文件生成vmlinux文件,vmlinux文件放在代码树根目录下。
  最开始链接的几个object文件列举在arch/$(ARCH)/Makefile文件的head-y变量中。
7) 最后体系makefile文件定义编译后期处理规则和建立最终的引导映像bootimage。
  - 包括创建引导记录
  - 准备initrd映像和相关处理
--- 6.1 变量设置
  LDFLAGS      $(LD)一般选项
     选项使用于链接器的所有调用中。通常定义emulation就可以了。
     例如: #arch/s390/Makefile
           LDFLAGS   := -m elf_s390
      注意: EXTRA_LDFLAGS和LDFLAGS_$@可以进一步订制使用选项,将第7章。
  LDFLAGS_MODULE       $(LD)链接模块的选项
     LDFLAGS_MODULE通常设置$(LD)链接模块的.ko选项。
     默认为"-r"即可重定位输出文件。
  LDFLAGS_vmlinux   $(LD)链接vmlinux选项
     LDFLAGS_vmlinux定义链接最终vmlinux时链接器的选项。
     LDFLAGS_vmlinux支持使用LDFLAGS_$@。
     例如: #arch/i386/Makefile
           LDFLAGS_vmlinux := -e stext
  OBJCOPYFLAGS      objcopy选项
     当使用$(call if_changed,objcopy)转化a .o文件时,OBJCOPYFLAGS中的选项将被使用。
     $(call if_changed,objcopy)经常被用作为vmlinux产生原始的二进制文件。
     例如: #arch/s390/Makefile
           OBJCOPYFLAGS := -O binary
          #arch/s390/boot/Makefile
           $(obj)/image: vmlinux FORCE $(call if_changed,objcopy)
     在上面例子中$(obj)/image是vmlinux的二进制版本文件。$(call if_changed,xxx)
的使用方法见后。
  AFLAGS   $(AS)汇编选项
     默认值见顶层Makefile文件
     针对每个体系需要另外添加和修改它。
     例如: #arch/sparc64/Makefile
           AFLAGS += -m64 -mcpu=ultrasparc
  CFLAGS      $(CC)编译器选项
     默认值见顶层Makefile文件
     针对每个体系需要另外添加和修改它。
     通常CFLAGS变量值取决于内核配置。
     例如: #arch/i386/Makefile
           cflags-$(CONFIG_M386) += -march=i386
           CFLAGS += $(cflags-y)
     许多体系Makefiles文件动态启动市场目标机器上的C编译器检测支持的选项:
           #arch/i386/Makefile
           ...
           cflags-$(CONFIG_MPENTIUMII)   += $(call cc-option,\
                 -march=pentium2,-march=i686) ...
           # Disable unit-at-a-time mode ...
           CFLAGS += $(call cc-option,-fno-unit-at-a-time)
           ...
     第一个例子当config选项是'y'时将被选中。
  CFLAGS_KERNEL      $(CC)编译built-in对象的选项
     $(CFLAGS_KERNEL)包含外部C编译器选项编译本地内核代码。
  CFLAGS_MODULE      $(CC)编译模块选项
     $(CFLAGS_MODULE)包含外部C编译器选项编译可加载内核代码。
--- 6.2 增加预设置项
     prepare: 这个规则用于列举开始进入子目录编译前需要的前提文件。通常是些包含汇编常量的头文件。
     例如:
     #arch/s390/Makefile
     prepare: include/asm-$(ARCH)/offsets.h
     在这个例子中include/asm-$(ARCH)/offsets.h将在进入子目录前编译。
      详见XXX-TODO文件描述了kbuild如何产生offset头文件。
--- 6.3 目录表
     体系makefile文件和顶层makefile文件共同定义了如何建立vmlinux文件的变量。注意没有体系相关的模块对象定义部分:所有的模块对象都是体系无关的。
  head-y, init-y, core-y, libs-y, drivers-y, net-y
     $(head-y) 列举首先链接到vmlinux的对象文件。
     $(libs-y) 列举了能够找到lib.a文件的目录。
     其余的变量列举了能够找到内嵌对象文件的目录。
     $(init-y) 列举的对象位于$(head-y)对象之后。
     然后是如下位置秩序:
     $(core-y), $(libs-y), $(drivers-y) 和 $(net-y)。
     顶层makefile定义了所有同用目录,arch/$(ARCH)/Makefile文件只需增加体系相关的目录。
     例如: #arch/sparc64/Makefile
           core-y += arch/sparc64/kernel/
           libs-y += arch/sparc64/prom/ arch/sparc64/lib/
           drivers-$(CONFIG_OPROFILE) += arch/sparc64/oprofile/
--- 6.4 引导映像
     体系makefile文件定义了编译vmlinux文件的目标对象,将它们压缩和封装成引导代码,并复制到合适的位置。这包括各种安装命令。如何定义实际的目标对象无法为所有的体系结构提供标准化的方法。
     附加处理过程常位于arch/$(ARCH)/下的boot/目录。
     内核编译系统无法在boot/目录下提供一种便捷的方法创建目标系统文件。因此arch/$(ARCH)/Makefile要调用make命令在boot/目录下建立目标系统文件。建议使用的方法是在arch/$(ARCH)/Makefile中设置调用,并且使用完整路径引用arch/$(ARCH)/boot/Makefile。
     例如: #arch/i386/Makefile
           boot := arch/i386/boot
           bzImage: vmlinux
              $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
     建议使用"$(Q)$(MAKE) $(build)="方式在子目录中调用make命令。
     没有定义体系目标系统文件的规则,但执行"make help"命令要列出所有目标系统文件,因此必须定义$(archhelp)变量。
     例如: #arch/i386/Makefile
     define
        archhelp echo '* bzImage     - Image (arch/$(ARCH)/boot/bzImage)'
      endef
     当执行不带参数的make命令时,将首先编译第一个目标对象。在顶层makefile中第一个目标对象是all:。
     一个体系结构需要定义一个默认的可引导映像。
     "make help"命令的默认目标是以*开头的对象。
     增加新的前提文件给all目标可以设置不同于vmlinux的默认目标对象。
     例如: #arch/i386/Makefile
           all: bzImage
     当执行不带参数的"make"命令时,bzImage文件将被编译。
--- 6.5 编译非内核目标
  extra-y
     extra-y定义了在当前目录下创建没有在obj-*定义的附加的目标文件。
     在extra-y中列举目标是处于两个目的:
      1) 是内核编译系统在命令行中检查变动情况
        - 当使用$(call if_changed,xxx)时
      2) 内核编译系统知道执行"make clean"命令时删除哪些文件
     例如: #arch/i386/kernel/Makefile
           extra-y := head.o init_task.o
     上面例子extra-y中的对象文件将被编译但不会练接到built-in.o中。
--- 6.6 编译引导映像命令
     Kbuild提供了一些编译引导映像有用的宏。
  if_changed
     if_changed是后面命令使用的基础。
     用法:
        target: source(s)
            FORCE $(call if_changed,ld/objcopy/gzip)
     当这条规则被使用时它将检查哪些文件需要更新,或命令行被改变。后面这种情况将迫使重新编译编译选项被改变的执行文件。使用if_changed的目标对象必须列举在$(targets)中,否则命令行检查将失败,目标一直会编译。
     赋值给$(targets)的对象没有$(obj)/前缀。
     if_changed也可以和定制命令配合使用,见6.7"kbuild定制命令"。
     注意: 一个常见错误是忘记了FORCE前导词。
  ld
      链接目标。常使用LDFLAGS_$@作为ld的选项。
  objcopy
      复制二进制文件。常用于arch/$(ARCH)/Makefile中和使用OBJCOPYFLAGS作为选项。
     也可以用OBJCOPYFLAGS_$@设置附加选项。
  gzip
      压缩目标文件。使用最大压缩算法压缩目标文件。
     例如: #arch/i386/boot/Makefile
     LDFLAGS_bootsect := -Ttext 0x0 -s --oformat binary
     LDFLAGS_setup   := -Ttext 0x0 -s --oformat binary -e begtext
     targets += setup setup.o bootsect bootsect.o
     $(obj)/setup $(obj)/bootsect: %: %.o FORCE
            $(call if_changed,ld)
      在上面例子中有两个可能的目标对象,分别需要不同的链接选项。使用LDFLAGS_$@语法为每个目标对象设置不同的链接选项。
     $(targets)包含所有的目标对象,因此内核编译系统知道所有的目标对象并且将:
      1) 检查命令行的改变情况
      2) 执行make clean命令时删除目标对象
     ": %: %.o"是简写方法,减写setup.o和bootsect.o文件。
     注意: 常犯错误是忘记"target :="语句,导致没有明显的原因目标文件被重新编译。
--- 6.7 定制编译命令
     当执行带KBUILD_VERBOSE=0参数的编译命令时命令的简短信息会被显示。要让定制命令具有这种功能需要设置两个变量:
     quiet_cmd_ - 将被显示的内容
      cmd_      - 被执行的命令
     例如: #
           quiet_cmd_image = BUILD   $@
            cmd_image = $(obj)/tools/build $(BUILDFLAGS) \
                    $(obj)/vmlinux.bin > $@
           targets += bzImage
           $(obj)/bzImage: $(obj)/vmlinux.bin $(obj)/tools/build FORCE
                $(call if_changed,image)
                @echo 'Kernel: $@ is ready'
     执行"make KBUILD_VERBOSE=0"命令编译$(obj)/bzImage目标时将显示:
     BUILD   arch/i386/boot/bzImage
--- 6.8 预处理连接脚本
     当编译vmlinux映像时将使用arch/$(ARCH)/kernel/vmlinux.lds链接脚本。
     相同目录下的vmlinux.lds.S文件是这个脚本的预处理的变体。内核编译系统知晓.lds文件并使用规则*lds.S -> *lds。
     例如: #arch/i386/kernel/Makefile
           always := vmlinux.lds
           #Makefile
           export CPPFLAGS_vmlinux.lds += -P -C -U$(ARCH)
     $(always)赋值语句告诉编译系统编译目标是vmlinux.lds。$(CPPFLAGS_vmlinux.lds)赋值语句告诉编译系统编译vmlinux.lds目标的编译选项。
     编译*.lds时将使用到下面这些变量:
     CPPFLAGS      : 定义在顶层Makefile
     EXTRA_CPPFLAGS      : 可以设置在编译的makefile文件中
     CPPFLAGS_$(@F) : 目标编译选项。注意要使用文件全名。
--- 6.9 $(CC)支持功能
     内核可能会用不同版本的$(CC)进行编译,每个版本有不同的性能和选项,内核编译系统提供基本的支持用于验证$(CC)选项。$(CC)通常是gcc编译器,但其它编译器也是可以。
  cc-option cc-option 用于检测$(CC)是否支持给定的选项,如果不支持就使用第二个可选项。
     例如: #arch/i386/Makefile
           cflags-y += $(call cc-option,-march=pentium-mmx,-march=i586)
     在上面例子中如果$(CC)支持-march=pentium-mmx则cflags-y等于该值,否则等于-march-i586。如果没有第二个可选项且第一项不支持则cflags-y没有被赋值。
  cc-option-yn cc-option-yn用于检测gcc是否支持给定的选项,支持返回'y'否则'n'。
     例如: #arch/ppc/Makefile
           biarch := $(call cc-option-yn, -m32)
           aflags-$(biarch) += -a32
           cflags-$(biarch) += -m32
     在上面例子中如果$(CC)支持-m32选项则$(biarch)设置为y。当$(biarch)等于y时,变量$(aflags-y)和$(cflags-y)将分别等于-a32和-m32。
  cc-option-align gcc版本>= 3.0用于定义functions、loops等边界对齐选项。
     gcc = 3.00
        cc-option-align = -falign
     例如:
        CFLAGS += $(cc-option-align)-functions=4
     在上面例子中对于gcc >= 3.00来说-falign-functions=4,gcc ,均为两位数字。例如gcc 3.41将返回0341。
     当一个特定$(CC)版本在某个方面有缺陷时cc-version是很有用的。例如-mregparm=3在一些gcc版本会失败尽管gcc接受这个选项。
     例如: #arch/i386/Makefile
           GCC_VERSION := $(call cc-version)
           cflags-y += $(shell \
           if [ $(GCC_VERSION) -ge 0300 ] ; then echo "-mregparm=3"; fi
     在上面例子中-mregparm=3只使用在版本大于等于3.0的gcc中。
=== 7 Kbuild变量
  顶层Makefile文件导出下面这些变量:
  VERSION, PATCHLEVEL, SUBLEVEL, EXTRAVERSION
     这几个变量定义了当前内核版本号。很少体系体系Makefiles文件直接使用他们,常用$(KERNELRELEASE)代替。
     $(VERSION)、$(PATCHLEVEL)和$(SUBLEVEL)定义了三个基本部分版本号,例如"2", "4",和"0"。这三个变量一直使用数值表示。
     $(EXTRAVERSION)定义了更细的补钉号,通常是短横跟一些非数值字符串,例如"-pre4"。
  KERNELRELEASE
     $(KERNELRELEASE)是一个单一字符如"2.4.0-pre4",适合用于构造安装目录和显示版本字符串。一些体系文件使用它用于以上目的。
  ARCH
     这个变量定义了目标系统体系结构,例如"i386"、“arm"、"sparc". 一些内核编译文件测试$(ARCH)用于确定编译哪个文件。默认情况下顶层Makefile文件设置$(ARCH)为主机相同的系统体系。当交叉编译编译时,用户可以使用命令行改变$(ARCH)值:
        make ARCH=m68k ...
  INSTALL_PATH
     这个变量定义了体系Makefiles文件安装内核映项和System.map文件的路径。
  INSTALL_MOD_PATH, MODLIB
     $(INSTALL_MOD_PATH)定义了模块安装变量$(MODLIB)的前缀。这个变量通常不在Makefile文件中定义,如果需要可以由用户添加。
     $(MODLIB)定义了模块安装目录。
     顶层Makefile定义$(MODLIB)为$(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE)。用户可以使用命令行修改这个值。
=== 8 Makefile语言
  内核Makefiles设计目标用于运行GNU Make程序。Makefiles仅使用GNU Make提到的特性,但使用了较多的GNU扩展部分。
  GNU Make程序支持基本的列表处理功能。内核Makefiles文件结合"if"语句使用了简单的列表建立和维护功能。
  GNU Make程序有两种赋值操作符:":="和"="。 ":="执行时立即计算右值并赋值给左值。"="类似公式定义,当每次使用左值要被使用时计算右值并赋给它。
  一些情况中使用"="合适,而一些情况中使用":="才是正确选择。
=== 9 Credits
  Original version made by Michael Elizabeth Chastain,  Updates
by Kai Germaschewski  Updates by Sam Ravnborg
=== 10 TODO
- Describe how kbuild support shipped files with _shipped.
- Generating offset header files.
- Add more variables to section 7?

论坛徽章:
3
天秤座
日期:2013-12-27 13:44:58射手座
日期:2014-05-22 16:52:43天蝎座
日期:2014-08-13 16:03:21
66 [报告]
发表于 2014-10-23 16:03 |只看该作者
本帖最后由 compare2000 于 2014-10-23 16:08 编辑

根据HR的有关安排,参加了一些社招和校招的面试工作,包括集体面试和业务(专业)面试。

         面试他人的过程,实际也是在面试自己。由己及人,由人及己。

     简单整理下之前到现在的几点零星体会。自勉或他勉,仅供参
【给应聘初试者的几点基本建议】

     今日做了一天的面试官,遇到一些有一定工作经验的求职者,但还是犯了一些低级错误,忍不住给几点建议供参考并与大家探讨。

1、简历要简,一页为好,呈现要点亮点即可;

2、目标岗位要明确,至少要事先研究其名称和职责要求;

3、换岗求职的原因、意愿要清晰,意愿的强烈程度常常是相互的(正/反相关);

4、英语要有所准备,至少要准备下自我介绍与项目类的内容。  



【社招招聘面试随感】

1、工作年限如果不伴随着职位的提升或相应的职业成熟,只能是负分; 简单重复的日历累积(而不是阅历增长)只是平庸的潜台词。年龄亦然。

2、正能量因素在比较中(集面中)效应明显。积极主动、开放进取、团队精神(融入度与合作性)、成就欲......谁都喜欢。等待、保守、沉默、不合群......尽管有时并非坏事,但大部分人更愿意打常规牌。

3、差异性是一把双刃剑,要慎用。可以脱颖而出,可以早夭出局。大家钟爱独特价值,但不敢乱用旁门左道和哗众取宠。

4、留学背景、大公司的历练、专业认证的把关......其影响潜移默化,在日常的表达呈现和解决问题上是可见一斑的。

5、微笑、礼貌……这些简单的待人接物在默默地发挥着作用,影响着受众的感知。  

【今日招聘面试小体悟】  

- 微笑是人际交往永远的利器;自然友好的眼神接触,是最好的见面礼。

- 主动、开放、分享、友善……所有面向他人和团队的优秀习惯,让人们在人群中发现你。这种人一入团队就能凸显。

- 自信、坚韧、沉稳、度量……所有向内修炼的良好特质,让自己散发个性魅力。这种人不需要多表现即可见。

- 面相和气场的差异,带来的不同直觉体验,这种第一感对人的认知影响很大。



【今日招聘面试小体悟】  

- 集体面试是“群殴”或“选秀”,业务面试则是“单挑”或“独角戏”。集面讲究脱颖而出,业面追求单点突破。呈现的侧重点不同。

- 不怕示弱,因为没有全才;

  关键是不忘展示强项所在。

- 不懂没关系,装懂才误事;

  不懂可以学,续航看能力。

- 深进去抓细节和重点(微观),跳出来理结构和逻辑(宏观),如此,才会融会贯通而理解,将知识结构化于脑中。深入浅出,则是理解的最高境界。接下来就是实践转化能力。

- 基础很重要,应该是深入骨髓的。没有人因为学了高数而忘记了123加减乘除,也不应该因为学了经济学而忘了会计要素。



【今日招聘面试小体悟】  

- 人生充满了偶然。 有些偶尔就是单纯的偶然,比如单独事件; 有些偶然中间有必然,比如统计意义下的重复。以平淡心看待偶然,以认真劲对待必然。

- 一个环节的单独面试的成败,在我看来,其中有很大的偶然因素。你的成败可能源于一个很小的原因:一个微笑、一个眼神、一句话、一个正式或随意的打扮、一次积极或消极的发言、一个突发奇想的观点、同伴或对手的一个失误或攻击、一位严苛或随和的考官、一道碰巧的容易或刁钻的考题……从这个意义上来说,大可不必在一个环节的得失上太纠结。尽力而为,成败在天。

- 然,就长远而言,多轮面试乃至后续工作的成功者,确实富有正的能量特质。所谓性格决定命运,这其中就已经包含了众多偶然中蕴藏的必然。从这个意义上来说,正向地修炼自身、打磨性格,是永远不变的必要。

- 招聘考核,确实应该客观评测和主观面试相结合,融科学和艺术于一体,才可能尽量减少偶然的偏差。


- 微笑是人际交往永远的利器;自然友好的眼神接触,是最好的见面礼。

- 主动、开放、分享、友善……所有面向他人和团队的优秀习惯,让人们在人群中发现你。这种人一入团队就能凸显。

- 自信、坚韧、沉稳、度量……所有向内修炼的良好特质,让自己散发个性魅力。这种人不需要多表现即可见。

- 面相和气场的差异,带来的不同直觉体验,这种第一感对人的认知影响很大。
——最后总结的是:人格魅力

论坛徽章:
3
天秤座
日期:2013-12-27 13:44:58射手座
日期:2014-05-22 16:52:43天蝎座
日期:2014-08-13 16:03:21
67 [报告]
发表于 2014-10-23 16:09 |只看该作者
从一个个人员的面试(微观)的表现,整理出来一套逻辑和整体结构(宏观), 以人为镜,在做面试官观察别人的同时,也总结与人交往过程中哪些有益,哪些有弊。文采出众精彩。
深进去抓细节和重点(微观),跳出来理结构和逻辑(宏观),如此,才会融会贯通而理解,将知识结构化于脑中。深入浅出,则是理解的最高境界。
大学毕业后大大小小面了几十场各类面试,也较为深入的研究过多个行业多累岗位的宣讲会和招聘模式,楼主所说的这些,稍稍研究下就可以被化解。面到最后就是返璞归真。对于面试官,最主要的就是关注在群面表现环节,再考虑经历、证书等,排除第一印象的影响;良好的题目设计,而不是千篇一律看题目就知道讨论结果与讨论套路是极其必要的,我司的题库差太多对于面试者,就是排除掉杂念,破解题目自身的漏洞,这样就可以减少和其他竞争者(合作者)的PK而增大自己的胜率,至于什么时候该用什么样的方法说什么样的话,普遍来说,在面试失败15-20次后可以完成第一阶段的面试经验积累,可以攻克绝大部分普通的面试套路,在面试总数超过25次后达到大成,不是碰到非能力不及的,基本没问题。
0     核心标准永远只有一个,你符不符合我们的职责要求

1     多问一些开放性的问题。面上的,很考验思维能力

2     再问几个细节。看他细致不细致。点上的,能否把问题搞清楚

3     思维能力,表达能力,是最重要的两方面。

3.1 分类。回答问题不要上来就特别具体化,先分类。这是逻辑思维的最基本方法。不然一下子就乱了,深一脚浅一脚的

          能高阶到结构化思维、系统性思维,甚至战略思维当然更好。

3.2 表达清晰。慢一点不要仅

4     说话自信,声音稳重,绝对加分

5     多让面试者自己说。看他的局面掌控能力。有的人经常就不知道绕到哪里了

6     问题不是要打翻他,重点要通过问题发现他的能力与潜力。

7     经验当然重要,但世界变化这么快,我更看重你后续的学习能力

8     "提一些新问题,看他的问题处理能力,复杂场景能力。压力下的从容能力。

如果遇到XXX问题,你怎么处理?"
演员的自我修养 对自己永远要有要求。

论坛徽章:
3
天秤座
日期:2013-12-27 13:44:58射手座
日期:2014-05-22 16:52:43天蝎座
日期:2014-08-13 16:03:21
68 [报告]
发表于 2014-10-23 16:18 |只看该作者
阿里分布式数据库服务原理与实践-shenxun.pdf ( 676.73 KB ,672 downs )   
实时计算服务化实践-qiangqi.pdf ( 8.01 MB ,447 downs )   
构建一个跨机房的Hadoop集群-wuwei.pptx ( 698.49 KB ,405 downs )   
无线互联网-产品质量保证-xuzheng.ppt ( 2.68 MB ,411 downs )   
探求计算性能极限-探求计算密集应用优化的天花板-wangzheng.pdf ( 881.78 KB ,346 downs )   
基于Hadoop_HBase的一淘搜索离线系统-wangfeng.pptx ( 1.05 MB ,401 downs )   
深度学习:机器学习的新浪潮-yukai.pdf ( 5.69 MB ,508 downs )   
百度媒体云技术及架构-chenbing.pdf ( 1.75 MB ,479 downs )   
后端-大型网站SEO优化实践-zhouwenjun.pdf ( 1.77 MB ,379 downs )   
去哪儿酒店实时搜索技术分享-liuyue.pdf ( 1.48 MB ,469 downs )   
淘宝消息中间件技术演变-zhanglewei.pdf ( 1.31 MB ,378 downs )   
AB测试和灰度发布平台架构设计和实践-oucheng.pdf ( 1.08 MB ,339 downs )   
淘宝网CRM平台架构for ADC-yunguang.pdf ( 4.32 MB ,340 downs )   
HouseMD介绍-jushi.pdf ( 360.25 KB ,274 downs )   
Inside TAE-liuhaoyu.pdf ( 3.3 MB ,308 downs )   
Nashorn与JDK8——动态语言在JVM上的高性能实现-mosu.pdf ( 1.09 MB ,307 downs )   
Scala中的函数式特征与并发-wanghongjiang.pdf ( 1.57 MB ,318 downs )   
TMS模块化页面搭建平台-fangjun.pdf ( 1.07 MB ,279 downs )   
Web页面分层交叉实验-chendong.pdf ( 792.51 KB ,279 downs )   
北冥神功- 新一代数据查询中间层-zhijiale.pdf ( 11.24 MB ,341 downs )   
互联网系统的稳定性保证:微博的实践-hongxiaojun.pdf ( 1.02 MB ,311 downs )   
基于OpenStack构建网易云主机服务-zhangxiaolong.pdf ( 1010.79 KB ,300 downs )   
架构模式与实践漫谈-wangfuqiang.pdf ( 12.51 MB ,406 downs )   
容量规划与授权限流降级-zhangjun.pdf ( 414.97 KB ,257 downs )   
淘宝文本中的语义分析以及技术展望-wangtianzhou.pdf ( 3.21 MB ,298 downs )   
天猫个性化推荐架构-zhangqi.pdf ( 2.34 MB ,339 downs )   
新一代前端代码开发与部属方案——独角兽系统功能简介-dengnanqiao.pptx ( 1.2 MB ,279 downs )   
让店铺飞起来-feichang.ppt ( 1.32 MB ,297 downs )   
商品详情页静态异步化-jicheng.pptx ( 876.04 KB ,256 downs )   
架起前端和开发的桥梁-chenzhongyin.ppt ( 4.14 MB ,306 downs )

论坛徽章:
3
天秤座
日期:2013-12-27 13:44:58射手座
日期:2014-05-22 16:52:43天蝎座
日期:2014-08-13 16:03:21
69 [报告]
发表于 2014-10-23 16:19 |只看该作者
淘宝网商品详情页静态异步化-liujunyuan.ppt ( 1.31 MB ,255 downs )   
不一样的装修-wangyufeng.pptx ( 116.91 KB ,248 downs )   
跨终端的文件加载及缓存-liushuang.pdf ( 9.82 MB ,271 downs )   
开放JS在淘宝的应用-shiba.pdf ( 324.43 KB ,237 downs )   
你所不知道的TAE SDK-taogu.pdf ( 629.35 KB ,238 downs )   
DBFree-阿里数据库自动化运维平台-yangxu.pptx ( 1009.57 KB ,249 downs )   
CAP 理论与实践-tongjiawang.pptx ( 2.42 MB ,297 downs )   
iDB-阿里集团数据库服务平台-yezhengsheng.pptx ( 1.08 MB ,243 downs )   
MySQL at NetEase-jianchengyao.pdf ( 937.27 KB ,243 downs )   
OceanBase0.4:从API到SQL-yangchuanhui.pptx ( 1.05 MB ,249 downs )   
阿里巴巴离线大数据处理平台概述-tangzinan.pptx ( 2.51 MB ,311 downs )   
阿里“去IOE”实践-chenzhaoshan.pptx ( 1.47 MB ,290 downs )   
阿里数据同步前世今生-chenshouyuan.pptx ( 1.57 MB ,274 downs )   
大数据时代的月光宝盒-zhangmaosen.pptx ( 1.59 MB ,300 downs )   
分布式数据分析算法-yangxu2.pptx ( 1.01 MB ,291 downs )   
大众点评网高可用数据架构-lujunyi.pdf ( 302.2 KB ,271 downs )   
如何打造360 MySQL服务-yangting.pdf ( 1.57 MB ,270 downs )   
实时计算平台及相关业务实践-chaihua.pptx ( 236.78 KB ,244 downs )   
探索阿里数据藏宝图——数据地图管理实践-liuyingyao.pdf ( 1.64 MB ,297 downs )   
腾讯广点通的数据挖掘-xiaolei.pptx ( 2.08 MB ,273 downs )   
小公司的服务管理和监控成长之路-laiwei.pptx ( 1.78 MB ,289 downs )   
页面资源位监测和价值分析-zhaowenbo.pptx ( 6.13 MB ,245 downs )   
Cascadb TokuDB性能与适用场景分享-yigong.pptx ( 770.29 KB ,212 downs )   
Mysql高并发热点更新性能优化-liuhui.ppt ( 268.5 KB ,244 downs )   
开源软件的商业价值-michael.pdf ( 193.24 KB ,272 downs )   
CM–集群管理与负载均衡系统-sunquan.pptx ( 1020.42 KB ,226 downs )   
垂直抓取系统——EtaoSpider介绍-xiezhenliang.pptx ( 1.1 MB ,231 downs )   
个性化搜索技术和应用-chenxi.pptx ( 4.45 MB ,265 downs )   
关系搜索和推荐-ouwenwu.pptx ( 783.2 KB ,233 downs )   
海量商品的聚合技术及其在搜索中的应用-minghu.pptx ( 1009.46 KB ,240 downs )   
机器学习在搜索排序中的应用-zenganxiang.pptx ( 3.18 MB ,289 downs )   
搜索引擎和淘宝搜索不得不说的故事-zhengnan.pptx ( 1.05 MB ,265 downs )   
实时个性化系统和应用-linjianguo.pptx ( 1.09 MB ,233 downs )   
文本挖掘在电子商务场景中的应用-sunjian.pptx ( 3.17 MB ,262 downs )   
一站式搜索服务平台-Tsearcher-liuming.pptx ( 3.53 MB ,239 downs )   
Android设备体验优化-fengsenlin.pptx ( 1.06 MB ,274 downs )   
百度云推送介绍和架构分享-guozheng.pptx ( 3.73 MB ,283 downs )   
无线客户端数据实战-ninghaiyuan.pdf ( 8.49 MB ,272 downs )   
一个移动互联网技术创业的故事-haopeiqiang.ppt ( 8.58 MB ,302 downs )   
移动设备客户端安全-luojingjian.ppt ( 2.83 MB ,272 downs )

论坛徽章:
3
天秤座
日期:2013-12-27 13:44:58射手座
日期:2014-05-22 16:52:43天蝎座
日期:2014-08-13 16:03:21
70 [报告]
发表于 2014-10-23 16:19 |只看该作者
移动系统中的Java虚拟机-xuweigang.pptx ( 339.14 KB ,213 downs )   
如何有效控制Andoid应用的耗电量-qianjiajing.pptx ( 936.48 KB ,220 downs )   
Lua wax在ios上的应用-huwenjiang.pptx ( 469.03 KB ,186 downs )   
Hybrid组建实践-WindVane项目简述-yujia.pptx ( 4.53 MB ,218 downs )   
Android自动化测试-jiale.pptx ( 885.66 KB ,255 downs )   
ios客户端稳定性-yudong.pptx ( 1.61 MB ,231 downs )   
android app性能优化之list篇-huangkun.ppt ( 1.42 MB ,247 downs )   
OS客户端应用测试实践-chenxu.pptx ( 2.38 MB ,227 downs )   
Fault injection实现原理与应用-liguodong.pptx ( 1.48 MB ,212 downs )  
iOS WEB自动化测试方案的探索与实践-banjun.pdf ( 24.27 MB ,347 downs )   
更好更快的Android自动化测试-luxiaoyu.pptx ( 1.02 MB ,304 downs )   
建设持续交付组织-jinming.pdf ( 2.78 MB ,321 downs )   
数据质量中心的设计与实现-xiemin.pptx ( 1.89 MB ,296 downs )   
无线质量全过程保障实践-xiapeifang.pptx ( 4.24 MB ,293 downs )   
不写代码实现UI自动化测试-xiadawei.pptx ( 7.48 MB ,330 downs )   
多浏览器兼容性测试平台xbrowser剖析-lihaijing.ppt ( 1.32 MB ,267 downs )   
前端无痛质量方案探索-pangeng.pdf ( 6.18 MB ,280 downs )   
淘宝电子商务云应用安全-liyonghui.pptx ( 2.43 MB ,294 downs )   
淘宝网应用性能管理的原理和实践-fangfei.pptx ( 863.6 KB ,282 downs )   
iOS WEB自动化测试方案的探索与实践-banjun.pdf ( 24.27 MB ,347 downs )   
更好更快的Android自动化测试-luxiaoyu.pptx ( 1.02 MB ,304 downs )   
建设持续交付组织-jinming.pdf ( 2.78 MB ,321 downs )   
数据质量中心的设计与实现-xiemin.pptx ( 1.89 MB ,296 downs )   
无线质量全过程保障实践-xiapeifang.pptx ( 4.24 MB ,293 downs )   
不写代码实现UI自动化测试-xiadawei.pptx ( 7.48 MB ,330 downs )   
多浏览器兼容性测试平台xbrowser剖析-lihaijing.ppt ( 1.32 MB ,267 downs )   
前端无痛质量方案探索-pangeng.pdf ( 6.18 MB ,280 downs )   
淘宝电子商务云应用安全-liyonghui.pptx ( 2.43 MB ,294 downs )   
淘宝网应用性能管理的原理和实践-fangfei.pptx ( 863.6 KB ,282 downs )   下
性能持续集成的探索和实践-xuxiao.pptx ( 765.44 KB ,171 downs )   
TCPFLOW业务网络服务质量分析-zhuyouzhi.pdf ( 1.98 MB ,185 downs )   
高性能网关产品的设计与实践-wangxinpu.pdf ( 844.18 KB ,176 downs )   
海量未知木马机器分析-huangzheng.pptx ( 119.37 KB ,162 downs )   
深入理解CPU的读写及优化-maling.pdf ( 944.57 KB ,200 downs )   
自动化运维和数据化运维-从硬盘开始-liuyi.pdf ( 1.41 MB ,202 downs )   
跨平台体验融合-shengbo.ppt ( 11.55 MB ,185 downs )   
设计之外 我们还追求什么样的设计-chenyizhang.pdf ( 2.8 MB ,198 downs )   
数据可视化设计-cuizhiwei.pdf ( 5.92 MB ,212 downs )   
Golden Age Of RTB-shengxuehua.pdf ( 1.58 MB ,169 downs )   下
Tanx业务发展及系统架构-suning.pdf ( 4.75 MB ,180 downs )
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP