Linux0.11内核--启动引导代码分析bootsect.s


Linux内核中的系统启动引导代码位于/boot目录下

但是,由于。Linus当时是在MINIX系统上开发Linux的,最初MINIX系统上还没有移植gas程序,因此Linus就使用了MINIX系统上的as86。

bootsect需要是16位的实模式程序。目前gas汇编器也支持16位的编译。所以现在也可以直接用as编译器直接编译。

下面是用at&t格式改写的bootsect.s代码

  1.     .code16  
  2. # rewrite with AT&T syntax by falcon <wuzhangjin@gmail.com> at 081012   
  3. #   
  4. # SYS_SIZE is the number of clicks (16 bytes) to be loaded.   
  5. # 0x3000 is 0x30000 bytes = 196kB, more than enough for current   
  6. # versions of linux   
  7. #   
  8.     .equ SYSSIZE, 0x3000  
  9. #   
  10. #   bootsect.s      (C) 1991 Linus Torvalds   
  11. #   
  12. # bootsect.s is loaded at 0x7c00 by the bios-startup routines, and moves   
  13. # iself out of the way to address 0x90000, and jumps there.   
  14. #   
  15. # It then loads 'setup' directly after itself (0x90200), and the system   
  16. # at 0x10000, using BIOS interrupts.    
  17. #   
  18. # NOTE! currently system is at most 8*65536 bytes long. This should be no   
  19. # problem, even in the future. I want to keep it simple. This 512 kB   
  20. # kernel size should be enough, especially as this doesn't contain the   
  21. # buffer cache as in minix   
  22. #   
  23. # The loader has been made as simple as possible, and continuos   
  24. # read errors will result in a unbreakable loop. Reboot by hand. It   
  25. # loads pretty fast by getting whole sectors at a time whenever possible.   
  26.     .global _start, begtext, begdata, begbss, endtext, enddata, endbss  
  27.     .text  
  28.     begtext:  
  29.     .data  
  30.     begdata:  
  31.     .bss  
  32.     begbss:  
  33.     .text  
  34.     .equ SETUPLEN, 4        # nr of setup-sectors  
  35.     .equ BOOTSEG, 0x07c0        # original address of boot-sector  
  36.     .equ INITSEG, 0x9000        # we move boot here - out of the way  
  37.     .equ SETUPSEG, 0x9020       # setup starts here  
  38.     .equ SYSSEG, 0x1000     # system loaded at 0x10000 (65536).  
  39.     .equ ENDSEG, SYSSEG + SYSSIZE   # where to stop loading  
  40. # ROOT_DEV: 0x000 - same type of floppy as boot.   
  41. #       0x301 - first partition on first drive etc   
  42.     .equ ROOT_DEV, 0x301  
  43.     ljmp    $BOOTSEG, $_start  
  44. _start:  
  45.     mov $BOOTSEG, %ax  
  46.     mov %ax, %ds  
  47.     mov $INITSEG, %ax  
  48.     mov %ax, %es  
  49.     mov $256, %cx  
  50.     sub %si, %si  
  51.     sub %di, %di  
  52.     rep   
  53.     movsw  
  54.     ljmp    $INITSEG, $go  
  55. go: mov %cs, %ax  
  56.     mov %ax, %ds  
  57.     mov %ax, %es  
  58. # put stack at 0x9ff00.   
  59.     mov %ax, %ss  
  60.     mov $0xFF00, %sp        # arbitrary value >>512  
  61. # load the setup-sectors directly after the bootblock.   
  62. # Note that 'es' is already set up.   
  63. load_setup:  
  64.     mov $0x0000, %dx        # drive 0, head 0  
  65.     mov $0x0002, %cx        # sector 2, track 0  
  66.     mov $0x0200, %bx        # address = 512, in INITSEG  
  67.     .equ    AX, 0x0200+SETUPLEN  
  68.     mov     $AX, %ax        # service 2, nr of sectors  
  69.     int $0x13           # read it  
  70.     jnc ok_load_setup       # ok - continue  
  71.     mov $0x0000, %dx  
  72.     mov $0x0000, %ax        # reset the diskette  
  73.     int $0x13  
  74.     jmp load_setup  
  75. ok_load_setup:  
  76. # Get disk drive parameters, specifically nr of sectors/track   
  77.     mov $0x00, %dl  
  78.     mov $0x0800, %ax        # AH=8 is get drive parameters  
  79.     int $0x13  
  80.     mov $0x00, %ch  
  81.     #seg cs   
  82.     mov %cx, %cs:sectors+0  # %cs means sectors is in %cs  
  83.     mov $INITSEG, %ax  
  84.     mov %ax, %es  
  85. # Print some inane message   
  86.     mov $0x03, %ah      # read cursor pos  
  87.     xor %bh, %bh  
  88.     int $0x10  
  89.       
  90.     mov $38, %cx  
  91.     mov $0x0007, %bx        # page 0, attribute 7 (normal)  
  92.     #lea    msg1, %bp   
  93.     mov     $msg1, %bp  
  94.     mov $0x1301, %ax        # write string, move cursor  
  95.     int $0x10  
  96. # ok, we've written the message, now   
  97. # we want to load the system (at 0x10000)   
  98.     mov $SYSSEG, %ax  
  99.     mov %ax, %es        # segment of 0x010000  
  100.     call    read_it  
  101.     call    kill_motor  
  102. # After that we check which root-device to use. If the device is   
  103. # defined (#= 0), nothing is done and the given device is used.   
  104. # Otherwise, either /dev/PS0 (2,28) or /dev/at0 (2,8), depending   
  105. # on the number of sectors that the BIOS reports currently.   
  106.     #seg cs   
  107.     mov %cs:root_dev+0, %ax  
  108.     cmp $0, %ax  
  109.     jne root_defined  
  110.     #seg cs   
  111.     mov %cs:sectors+0, %bx  
  112.     mov $0x0208, %ax        # /dev/ps0 - 1.2Mb  
  113.     cmp $15, %bx  
  114.     je  root_defined  
  115.     mov $0x021c, %ax        # /dev/PS0 - 1.44Mb  
  116.     cmp $18, %bx  
  117.     je  root_defined  
  118. undef_root:  
  119.     jmp undef_root  
  120. root_defined:  
  121.     #seg cs   
  122.     mov %ax, %cs:root_dev+0  
  123. # after that (everyting loaded), we jump to   
  124. # the setup-routine loaded directly after   
  125. # the bootblock:   
  126.     ljmp    $SETUPSEG, $0       #jump to  0x9020:0000(setup.s 程序的开始处)  
  127. # This routine loads the system at address 0x10000, making sure   
  128. # no 64kB boundaries are crossed. We try to load it as fast as   
  129. # possible, loading whole tracks whenever we can.   
  130. #   
  131. # in:   es - starting address segment (normally 0x1000)   
  132. #   
  133. sread:  .word 1+ SETUPLEN   # sectors read of current track  
  134. head:   .word 0         # current head  
  135. track:  .word 0         # current track  
  136. read_it:  
  137.     mov %es, %ax  
  138.     test    $0x0fff, %ax  
  139. die:    jne     die         # es must be at 64kB boundary  
  140.     xor     %bx, %bx        # bx is starting address within segment  
  141. rp_read:  
  142.     mov     %es, %ax  
  143.     cmp     $ENDSEG, %ax        # have we loaded all yet?  
  144.     jb  ok1_read  
  145.     ret  
  146. ok1_read:  
  147.     #seg cs   
  148.     mov %cs:sectors+0, %ax  
  149.     sub sread, %ax  
  150.     mov %ax, %cx  
  151.     shl $9, %cx  
  152.     add %bx, %cx  
  153.     jnc     ok2_read  
  154.     je  ok2_read  
  155.     xor     %ax, %ax  
  156.     sub     %bx, %ax  
  157.     shr     $9, %ax  
  158. ok2_read:  
  159.     call    read_track  
  160.     mov     %ax, %cx  
  161.     add     sread, %ax  
  162.     #seg cs   
  163.     cmp     %cs:sectors+0, %ax  
  164.     jne     ok3_read  
  165.     mov     $1, %ax  
  166.     sub     head, %ax  
  167.     jne     ok4_read  
  168.     incw    track   
  169. ok4_read:  
  170.     mov %ax, head  
  171.     xor %ax, %ax  
  172. ok3_read:  
  173.     mov %ax, sread  
  174.     shl $9, %cx  
  175.     add %cx, %bx  
  176.     jnc rp_read  
  177.     mov %es, %ax  
  178.     add $0x1000, %ax  
  179.     mov %ax, %es  
  180.     xor %bx, %bx  
  181.     jmp rp_read  
  182. read_track:  
  183.     push    %ax  
  184.     push    %bx  
  185.     push    %cx  
  186.     push    %dx  
  187.     mov track, %dx  
  188.     mov sread, %cx  
  189.     inc %cx  
  190.     mov %dl, %ch  
  191.     mov head, %dx  
  192.     mov %dl, %dh  
  193.     mov $0, %dl  
  194.     and $0x0100, %dx  
  195.     mov $2, %ah  
  196.     int $0x13  
  197.     jc  bad_rt  
  198.     pop %dx  
  199.     pop %cx  
  200.     pop %bx  
  201.     pop %ax  
  202.     ret  
  203. bad_rt: mov $0, %ax  
  204.     mov $0, %dx  
  205.     int $0x13  
  206.     pop %dx  
  207.     pop %cx  
  208.     pop %bx  
  209.     pop %ax  
  210.     jmp read_track  
  211. #/*   
  212. # * This procedure turns off the floppy drive motor, so   
  213. # * that we enter the kernel in a known state, and   
  214. # * don't have to worry about it later.   
  215. # */   
  216. kill_motor:  
  217.     push    %dx  
  218.     mov $0x3f2, %dx  
  219.     mov $0, %al  
  220.     outsb  
  221.     pop %dx  
  222.     ret  
  223. sectors:  
  224.     .word 0  
  225. msg1:  
  226.     .byte 13,10  
  227.     .ascii "Loading system ... compiled by yan!"  
  228.     .byte 13,10,13,10  
  229.     .org 508  
  230. root_dev:  
  231.     .word ROOT_DEV  
  232. boot_flag:  
  233.     .word 0xAA55  
  234.       
  235.     .text  
  236.     endtext:  
  237.     .data  
  238.     enddata:  
  239.     .bss  
  240.     endbss: 
  • 1
  • 2
  • 下一页

相关内容