标签 博客 下的文章

Compressed 'head.S'

Why do we do this? Don’t ask me.. Incomprehensible are the ways of bootloaders.
                             — comments in arch/i386/boot/compressed/misc.c

There are two ‘head.S’ in linux source package. One is in $(Linux-2.6.15.3_dir/arch/i386/boot/compressed and the other one is in $(Linux-2.6.15.3_dir/arch/i386/kernel. The first one will be analyzed in this artical. Before we go ahead, let’s show a news of linux, that is ‘Army leans toward Linux for FCS(Future Combat System)’.

The first ‘head.S’ is also called ‘compressed head’, which used to decompress the kernel image. Different from those code before, we are now in 32-bit protected mode with paging disabled. The ‘compressed head’ starts from ‘startup_32′.

.text /* ! here just ‘.text’, without ‘.code16′ assembly directive */
.globl startup_32
 
startup_32:
 /*
  * ! clear direction flag
  * ! and clear interrupt flag
  */
 cld
 cli

 /*
  * ! all other segment registers are
  * ! reloaded after protected mode enabled
  * ! __BOOT_DS = 0×18
  */
 movl $(__BOOT_DS),%eax
 movl %eax, %ds
 movl %eax, %es
 movl %eax, %fs
 movl %eax, %gs

 /*
  * ! lss – load full pointer from memory
  * !       to register
  * ! and here ‘ss:esp = stack_start’
  */
 lss stack_start,%esp

 /*
  * ! EAX = 0;
  * ! do {
  * !     DS:[0] = ++EAX;
  * ! } while (DS:[0x100000] == EAX);
  */
 xorl %eax, %eax
1: incl %eax  # check that A20 really IS enabled
 movl %eax, 0×000000 # loop forever if it isn’t
 cmpl %eax, 0×100000
 je 1b

After reload the segment registers, the ‘compressed head’ clears the ‘eflags’ register and fills the kernel bss(the area of uninitialized data of the kernel identified by the _edata and _end symbols) with zeros. Then the decompressed process begins.

 /*
  * ! %esi has been loaded in ‘setup.S’ with ‘INITSET << 4′
  * ! ‘subl $16,%esp’ used to store the first arg, that is
  * ! struct moveparams {
  * !     uch *low_buffer_start;
  * !     int lcount;
  * !     uch *high_buffer_start;
  * !     int hcount;
  * ! } mv;
  * ! the second arg is the %esi which indicates the position
  * ! of the real-mode data
  */
 subl $16,%esp # place for structure on the stack
 movl %esp,%eax
 pushl %esi # real mode pointer as second arg
 pushl %eax # address of structure as first arg

 /*
  * ! if (!decompress_kernel(&mv, esi)) {         // return value in AX
  * !    restore esi from stack;
  * !    ebx = 0;
  * !    goto __BOOT_CS: $__PHYSICAL_START;
  * !    // see linux/arch/i386/kernel/head.S:startup_32
  * ! }
  * ! ‘decompress_kernel’ is coded in
  * ! $(linux-2.6.15.3_dir)/arch/i386/boot/compressed/misc.c
  *
/
 call decompress_kernel
 orl  %eax,%eax
 jnz  3f
 popl %esi # discard address
 popl %esi # real mode pointer
 xorl %ebx,%ebx
 ljmp $(__BOOT_CS), $__PHYSICAL_START

3:
 /*
  * ! move move_rountine_start..move_routine_end to 0×1000
  * ! both the two functions are defined in the tail of
  * ! this file
  */
 movl $move_routine_start,%esi
 movl $0×1000,%edi
 movl $move_routine_end,%ecx
 subl %esi,%ecx
 addl $3,%ecx
 shrl $2,%ecx
 cld
 rep
 movsl

 /*
  * ! Do preparation for ‘move_routine_start’:
  * ! set the parameters
  * ! ebx = real mode pointer
  * ! esi = mv.low_buffer_start
  * ! ecx = mv.lcount
  * ! edx = mv.high_buffer_start
  * ! eax = mv.hcount
  * ! edi = $__PHYSICAL_START
  */
 popl %esi # discard the address
 popl %ebx # real mode pointer
 popl %esi # low_buffer_start
 popl %ecx # lcount
 popl %edx # high_buffer_start
 popl %eax # hcount
 movl $__PHYSICAL_START,%edi
 cli  # make sure we don’t get interrupted

 /*
  * ! jump to physical address: __BOOT_CS:0×1000
  * ! where the move_routine_start function stays
  */
 ljmp $(__BOOT_CS), $0×1000 # and jump to the move routine

 /*
  * ! the control has been transfered to ‘move_routine_start’
  */
move_routine_start:
 movl %ecx,%ebp
 shrl $2,%ecx
 rep
 movsl
 movl %ebp,%ecx
 andl $3,%ecx
 rep
 movsb
 movl %edx,%esi
 movl %eax,%ecx # NOTE: rep movsb won’t move if %ecx == 0
 addl $3,%ecx
 shrl $2,%ecx
 rep
 movsl
 movl %ebx,%esi # Restore setup pointer
 xorl %ebx,%ebx
 ljmp $(__BOOT_CS), $__PHYSICAL_START
move_routine_end:

In ‘move_routine_start’, we perform the operations as follows:
(1) move mv.low_buffer_start to $__PHYSICAL_START, (mv.lcount >> 2) words;
(2) move/append (mv.lcount & 3) bytes;
(3) move/append mv.high_buffer_start, ((mv.hcount + 3) >> 2) words.

After move the decompressed kernel image to its right place, the control will be transfered to physical address:’$(__BOOT_CS):$__PHYSICAL_START’, where the second ‘head.S’ stays.

'名符其实'的国足

已经记不清有多久没有完整地看完一次中国国家足球队的国际A级赛事了。昨天是2007年亚洲杯小组赛的第一场比赛,国足坐镇主场,对手是’神秘’的巴勒斯坦足球队。90分钟下来,国足2:0拿下比赛,按理说我们该庆祝,可是我想大多数中国球迷和我一样,心情沉重呀,不为别的,就为中国足球的未来担心亚。尽管比赛获得了胜利,但是从比赛的过程来看,难掩饰这支国足的真实地位– ‘名符其实’的亚洲二流。

其实我感觉亚洲一流和二流最大的区别在于是否形成了现代足球的’整体’攻防风格,纵观这届中国国足,哪有什么整体而言,进攻毫无章法,防守也总是莫名其妙的出现失误,还好对手太弱,这种失误带来的风险也就小了些。中国足球职业化也这么多年了,我们到底和日本、韩国差在哪?现在日本、韩国和欧洲的一些二流球队过招,已经是有把握言胜的。暂且不说韩国在世界杯上的光辉成绩,就拿去年与塞黑的热身赛来说,同样的一只塞黑队,中国0:1负之,韩国3:0胜之,这样的例子太多太多,足以说明中国足球在各个方面都落后得太多,亚洲二流一点都不贬低中国国足。好了牢骚发到这,说说这场比赛吧。

杜威和李伟峰,两个中后卫,贡献两个头球,依旧在延续着中国足球队一贯的’头球队’和后卫比前锋好使的作风,特别是第二个进球,本该是前锋应该出现的区域,一名中后卫却鬼使神差的站在那里,更令人叫绝的是’球进了’。看到sina网的一则报道’88次为国出战打进11球 李玮峰已成国足二号射手‘,那简直就叫一个’心酸’亚!国足习惯了和弱队的这种打法,而且养成了习惯,一旦和稍强些的对手过招,就会破绽百出。我就是不明白一个脚法一般(从电视上都可以看出杜威和李伟峰的脚法简直业余)的中后卫居然总冲在最前面(我不知道这是不是教练的安排,我想教练还不至于这么差吧,当然发脚球时可以),如果我是其他球员我会如何想呢?"你李伟峰是队长,我们都管不了你,你不相信我们这些前场球员,那你就冲吧"。最终在弱队面前李伟峰算是占了便宜卖了乖,但是在强队面前他那点小伎俩又怎么能奏效呢。作为一名中后卫,你的职责就是防守,无论对手强还是弱。如果你的脚法(传球水平)可以像罗伯特.卡洛斯那样,你倒可以尽情的冲上前助攻,可是现实你的脚法很滥,还是学习学习季铭义,老老实实在后场待着吧。这场比赛,国足的后卫线要不裹足不前,在后场慢腾腾的戏耍着可怜的足球,要不都去充当前锋,这是何等的壮观,这样的场景和打法也就是在中国队才能展现,机会难得,大家莫失良机亚。

再说说’铁哥’,真不明白朱指导为什么还招李铁,难道只因为有感情,这是国足,你朱指导要做的是如何提高国足水平,而不是怜悯和施舍。看看’铁哥’在场上的表现吧。我细致观察过,每当球传到’铁哥’脚下,整个进攻节奏就慢了下来,’铁哥’也不知道是不是眼神儿不好使,拿到球后看了又看看了又看,’半天’后终于出脚了,至于球不是飞出场,就是到了别人脚下。整场比赛,可以用碌碌无为来形容之,真是有他不多,无他不少。

李毅’大帝’我们也不得不说,从球迷对他的’热衷’程度来看,我们也得说说。’大帝’除了那几招拿手的’靠山背’、’犯规’、’乱跑’之外,真不知道他还凭什么来维持他’大帝’的称号。在CCTV5台的直播时我们听到球迷呐喊得最多的就是’大帝’的名字,只不过前面加了一个’换’字;提到最多的也是他的’脚’字,只不过前面加了个’臭’字,这样的前锋能改变国足锋线的疲软状态么。我想大多数球迷此时心中都在呼喊’邹捷’上场了,可是他仅仅在最后1分半钟在走了走场罢了。

说实话,不能完全否定国足,至少在场上还是有认真踢球的队员,董方卓和蒿俊闵这两个新生代着实没有辜负球迷。董方卓有速度、有体格,但是似乎在理解现代足球的道路上还没’入道’,不过前途光明。蒿俊闵 年纪轻轻,敢拼敢抢,欠缺的是大局观和动脑筋。正是这两个小伙子的不辞辛劳的奔跑抢断传球,才给国足中前场带来一丝生气。

至于其他人,不说了,说了也伤心。

最后引用董路的评论’不管是因为我们强大,还是由于敌人弱小;要求中国队踢出水银泻地动山摇般的足球确实是一件很难得事情’。我也要加一句’如果非要让我说出一个爱上中国足球队的期限的话,我希望是一万年。’

如发现本站页面被黑,比如:挂载广告、挖矿等恶意代码,请朋友们及时联系我。十分感谢! Go语言第一课 Go语言精进之路1 Go语言精进之路2 Go语言编程指南
商务合作请联系bigwhite.cn AT aliyun.com

欢迎使用邮件订阅我的博客

输入邮箱订阅本站,只要有新文章发布,就会第一时间发送邮件通知你哦!

这里是 Tony Bai的个人Blog,欢迎访问、订阅和留言! 订阅Feed请点击上面图片

如果您觉得这里的文章对您有帮助,请扫描上方二维码进行捐赠 ,加油后的Tony Bai将会为您呈现更多精彩的文章,谢谢!

如果您希望通过微信捐赠,请用微信客户端扫描下方赞赏码:

如果您希望通过比特币或以太币捐赠,可以扫描下方二维码:

比特币:

以太币:

如果您喜欢通过微信浏览本站内容,可以扫描下方二维码,订阅本站官方微信订阅号“iamtonybai”;点击二维码,可直达本人官方微博主页^_^:
本站Powered by Digital Ocean VPS。
选择Digital Ocean VPS主机,即可获得10美元现金充值,可 免费使用两个月哟! 著名主机提供商Linode 10$优惠码:linode10,在 这里注册即可免费获 得。阿里云推荐码: 1WFZ0V立享9折!


View Tony Bai's profile on LinkedIn
DigitalOcean Referral Badge

文章

评论

  • 正在加载...

分类

标签

归档



View My Stats