以下源代码来源于linux2.6.26.5的arch/x86/boot/header.S

  1. /*
  2.  *  header.S
  3.  *
  4.  *  Copyright (C) 1991, 1992 Linus Torvalds
  5.  *
  6.  *  Based on bootsect.S and setup.S
  7.  *  modified by more people than can be counted
  8.  *
  9.  *  Rewritten as a common file by H. Peter Anvin (Apr 2007)
  10.  *
  11.  * BIG FAT NOTE: We're in real mode using 64k segments.  Therefore segment
  12.  * addresses must be multiplied by 16 to obtain their respective linear
  13.  * addresses. To avoid confusion, linear addresses are written using leading
  14.  * hex while segment addresses are written as segment:offset.
  15.  *
  16.  */
  17. #include <asm/segment.h>
  18. #include <linux/utsrelease.h>
  19. #include <asm/boot.h>
  20. #include <asm/e820.h>
  21. #include <asm/page.h>
  22. #include <asm/setup.h>
  23. #include "boot.h"
  24. #include "offsets.h"
  25. SETUPSECTS  = 4         /* default nr of setup-sectors */
  26. BOOTSEG     = 0x07C0        /* original address of boot-sector */
  27. SYSSEG      = DEF_SYSSEG        /* system loaded at 0x10000 (65536) */
  28. SYSSIZE     = DEF_SYSSIZE       /* system size: # of 16-byte clicks */
  29.                     /* to be loaded */
  30. ROOT_DEV    = 0         /* ROOT_DEV is now written by "build" */
  31. SWAP_DEV    = 0         /* SWAP_DEV is now written by "build" */
  32. #ifndef SVGA_MODE
  33. #define SVGA_MODE ASK_VGA
  34. #endif
  35. #ifndef RAMDISK
  36. #define RAMDISK 0
  37. #endif
  38. #ifndef ROOT_RDONLY
  39. #define ROOT_RDONLY 1
  40. #endif
  41. #从2.6内核开始linux不再支持从软盘引导系统,因此如果从这里开始引导系统
  42. #必然会出错,以下注释仅供学习之用,我会尽量努力把内核启动部分代码都加
  43. #上注释,但不保证正确性。
  44.     .code16
  45.     .section ".bstext""ax"
  46.     .global bootsect_start
  47. bootsect_start:             
  48.     # Normalize the start address
  49.     ljmp    $BOOTSEG, $start2 #跳转到start2,这个是一个远跳转,注意其语法为:ljmp $段,$段内偏移
  50. start2:
  51.     movw    %cs, %ax    #%cs内容为0x07c0
  52.     movw    %ax, %ds
  53.     movw    %ax, %es
  54.     movw    %ax, %ss
  55.     xorw    %sp, %sp    #%sp清零
  56.     sti             #开中断
  57.     cld             #清除eflags方向位,为msg_loop后的语句做准备
  58.     movw    $bugger_off_msg, %si #将bugger_of_msg标示所在内存地址放入%si
  59. msg_loop:
  60.     lodsb           #从%ds:%si处加载1字节到%al
  61.     andb    %al, %al    #连同下一条语句判断%al是否为0
  62.     jz  bs_die      #若%al为0则跳转到bs_die处
  63.     movb    $0xe, %ah   #若%al不为0,则调用bios中断程序显示%al中的字节,0xe是功能码
  64.     movw    $7, %bx     #%bh=0x00 则为page 0,%bl=0x07指明字体颜色   
  65.     int $0x10       #中断号0x10为显示字符中断
  66.     jmp msg_loop    #跳转到msg_loop处循环显示,每次显示一个字节
  67. bs_die:
  68.     # Allow the user to press a key, then reboot
  69.     xorw    %ax, %ax    #清零%ax
  70.     int $0x16       #调用0x16号bios中断,该中断在%ax为零的时候等待用户按任意键
  71.     int $0x19       #调用0x19号bios中断重启计算机
  72.     # int 0x19 should never return.  In case it does anyway,
  73.     # invoke the BIOS reset code...
  74.     ljmp    $0xf000,$0xfff0 #这条语句应当不会执行,若执行到这里,则这条语句会模拟用户按下reset建
  75.     .section ".bsdata""a"
  76. bugger_off_msg:
  77.     .ascii  "Direct booting from floppy is no longer supported./r/n"
  78.     .ascii  "Please use a boot loader program instead./r/n"
  79.     .ascii  "/n"
  80.     .ascii  "Remove disk and press any key to reboot . . ./r/n"
  81.     .byte   0
Logo

更多推荐