zoukankan      html  css  js  c++  java
  • bootsect.S (读核笔记系列)

       
    这个程序是引导程序。
         按照早期Intel和微机和DOS的约定,机器开启后,由它的ROM BIOS将启动盘的第一扇区(Boot sector)512个字节装入物理内存的0X7C00处,然后跳转到0X7C00开始引导程序的执行。
        所以,第一扇区的内容就是Bootsect,是在创建系统盘时由Linux操作系统写入的。
        当你看下面的代码时,你要明白一点,Bootsect 的任务就是将操作系统内核从引导盘上读到内存中,并将它摆放在内存的适当位置。bootsect读入的内容包括Setup(在下一节中要讲到的)程序和一 个经过压缩的内核映像zImage或bzImage.(如果你有电脑,建议去装装Linux,并且去学习编译内核,这样你会有很多感性的认识。)
        好了,下面把bootsect.S代码贴出来:
    有两个,可以对照看:第一个是linux0.11的,第二个是我现在用的系统linux-2.6.11-6,其中代码已有不少改动。好了!
    第一个:
      1 !
      2 ! SYS_SIZE is the number of clicks (16 bytes) to be loaded.
      3 ! 0x3000 is 0x30000 bytes = 196kB, more than enough for current
      4 ! versions of linux
      5 !
      6 SYSSIZE = 0x3000
      7 !
      8 !    bootsect.s        (C) 1991 Linus Torvalds
      9 !
     10 ! bootsect.s is loaded at 0x7c00 by the bios-startup routines, and moves
     11 ! iself out of the way to address 0x90000, and jumps there.
     12 !
     13 ! It then loads 'setup' directly after itself (0x90200), and the system
     14 ! at 0x10000using BIOS interrupts. 
     15 !
     16 ! NOTE! currently system is at most 8*65536 bytes long. This should be no
     17 ! problem, even in the future. I want to keep it simple. This 512 kB
     18 ! kernel size should be enough, especially as this doesn't contain the
     19 ! buffer cache as in minix
     20 !
     21 ! The loader has been made as simple as possible, and continuos
     22 ! read errors will result in a unbreakable loop. Reboot by hand. It
     23 ! loads pretty fast by getting whole sectors at a time whenever possible.
     24 
     25 .globl begtext, begdata, begbss, endtext, enddata, endbss
     26 .text
     27 begtext:
     28 .data
     29 begdata:
     30 .bss
     31 begbss:
     32 .text
     33 
     34 SETUPLEN = 4                ! nr of setup-sectors
     35 BOOTSEG  = 0x07c0            ! original address of boot-sector
     36 INITSEG  = 0x9000            ! we move boot here - out of the way
     37 SETUPSEG = 0x9020            ! setup starts here
     38 SYSSEG   = 0x1000            ! system loaded at 0x10000 (65536).
     39 ENDSEG   = SYSSEG + SYSSIZE        ! where to stop loading
     40 
     41 ! ROOT_DEV:    0x000 - same type of floppy as boot.
     42 !        0x301 - first partition on first drive etc
     43 ROOT_DEV = 0x306
     44 
     45 entry start
     46 start:
     47     mov    ax,#BOOTSEG
     48     mov    ds,ax
     49     mov    ax,#INITSEG
     50     mov    es,ax
     51     mov    cx,#256
     52     sub    si,si
     53     sub    di,di
     54     rep
     55     movw
     56     jmpi    go,INITSEG
     57 go:    mov    ax,cs
     58     mov    ds,ax
     59     mov    es,ax
     60 ! put stack at 0x9ff00.
     61     mov    ss,ax
     62     mov    sp,#0xFF00        ! arbitrary value >>512
     63 
     64 ! load the setup-sectors directly after the bootblock.
     65 ! Note that 'es' is already set up.
     66 
     67 load_setup:
     68     mov    dx,#0x0000        ! drive 0, head 0
     69     mov    cx,#0x0002        ! sector 2, track 0
     70     mov    bx,#0x0200        ! address = 512in INITSEG
     71     mov    ax,#0x0200+SETUPLEN    ! service 2, nr of sectors
     72     int    0x13            ! read it
     73     jnc    ok_load_setup        ! ok - continue
     74     mov    dx,#0x0000
     75     mov    ax,#0x0000        ! reset the diskette
     76     int    0x13
     77     j    load_setup
     78 
     79 ok_load_setup:
     80 
     81 ! Get disk drive parameters, specifically nr of sectors/track
     82 
     83     mov    dl,#0x00
     84     mov    ax,#0x0800        ! AH=8 is get drive parameters
     85     int    0x13
     86     mov    ch,#0x00
     87     seg cs
     88     mov    sectors,cx
     89     mov    ax,#INITSEG
     90     mov    es,ax
     91 
     92 ! Print some inane message
     93 
     94     mov    ah,#0x03        ! read cursor pos
     95     xor    bh,bh
     96     int    0x10
     97     
     98     mov    cx,#24
     99     mov    bx,#0x0007        ! page 0, attribute 7 (normal)
    100     mov    bp,#msg1
    101     mov    ax,#0x1301        ! write string, move cursor
    102     int    0x10
    103 
    104 ! ok, we've written the message, now
    105 ! we want to load the system (at 0x10000)
    106 
    107     mov    ax,#SYSSEG
    108     mov    es,ax        ! segment of 0x010000
    109     call    read_it
    110     call    kill_motor
    111 
    112 ! After that we check which root-device to use. If the device is
    113 ! defined (!= 0), nothing is done and the given device is used.
    114 ! Otherwise, either /dev/PS0 (2,28) or /dev/at0 (2,8), depending
    115 ! on the number of sectors that the BIOS reports currently.
    116 
    117     seg cs
    118     mov    ax,root_dev
    119     cmp    ax,#0
    120     jne    root_defined
    121     seg cs
    122     mov    bx,sectors
    123     mov    ax,#0x0208        ! /dev/ps0 - 1.2Mb
    124     cmp    bx,#15
    125     je    root_defined
    126     mov    ax,#0x021c        ! /dev/PS0 - 1.44Mb
    127     cmp    bx,#18
    128     je    root_defined
    129 undef_root:
    130     jmp undef_root
    131 root_defined:
    132     seg cs
    133     mov    root_dev,ax
    134 
    135 ! after that (everyting loaded), we jump to
    136 ! the setup-routine loaded directly after
    137 ! the bootblock:
    138 
    139     jmpi    0,SETUPSEG
    140 
    141 ! This routine loads the system at address 0x10000, making sure
    142 ! no 64kB boundaries are crossed. We try to load it as fast as
    143 ! possible, loading whole tracks whenever we can.
    144 !
    145 ! in:    es - starting address segment (normally 0x1000)
    146 !
    147 sread:    .word 1+SETUPLEN    ! sectors read of current track
    148 head:    .word 0            ! current head
    149 track:    .word 0            ! current track
    150 
    151 read_it:
    152     mov ax,es
    153     test ax,#0x0fff
    154 die:    jne die            ! es must be at 64kB boundary
    155     xor bx,bx        ! bx is starting address within segment
    156 rp_read:
    157     mov ax,es
    158     cmp ax,#ENDSEG        ! have we loaded all yet?
    159     jb ok1_read
    160     ret
    161 ok1_read:
    162     seg cs
    163     mov ax,sectors
    164     sub ax,sread
    165     mov cx,ax
    166     shl cx,#9
    167     add cx,bx
    168     jnc ok2_read
    169     je ok2_read
    170     xor ax,ax
    171     sub ax,bx
    172     shr ax,#9
    173 ok2_read:
    174     call read_track
    175     mov cx,ax
    176     add ax,sread
    177     seg cs
    178     cmp ax,sectors
    179     jne ok3_read
    180     mov ax,#1
    181     sub ax,head
    182     jne ok4_read
    183     inc track
    184 ok4_read:
    185     mov head,ax
    186     xor ax,ax
    187 ok3_read:
    188     mov sread,ax
    189     shl cx,#9
    190     add bx,cx
    191     jnc rp_read
    192     mov ax,es
    193     add ax,#0x1000
    194     mov es,ax
    195     xor bx,bx
    196     jmp rp_read
    197 
    198 read_track:
    199     push ax
    200     push bx
    201     push cx
    202     push dx
    203     mov dx,track
    204     mov cx,sread
    205     inc cx
    206     mov ch,dl
    207     mov dx,head
    208     mov dh,dl
    209     mov dl,#0
    210     and dx,#0x0100
    211     mov ah,#2
    212     int 0x13
    213     jc bad_rt
    214     pop dx
    215     pop cx
    216     pop bx
    217     pop ax
    218     ret
    219 bad_rt:    mov ax,#0
    220     mov dx,#0
    221     int 0x13
    222     pop dx
    223     pop cx
    224     pop bx
    225     pop ax
    226     jmp read_track
    227 
    228 /*
    229  * This procedure turns off the floppy drive motor, so
    230  * that we enter the kernel in a known state, and
    231  * don't have to worry about it later.
    232  */
    233 kill_motor:
    234     push dx
    235     mov dx,#0x3f2
    236     mov al,#0
    237     outb
    238     pop dx
    239     ret
    240 
    241 sectors:
    242     .word 0
    243 
    244 msg1:
    245     .byte 13,10
    246     .ascii "Loading system "
    247     .byte 13,10,13,10
    248 
    249 .org 508
    250 root_dev:
    251     .word ROOT_DEV
    252 boot_flag:
    253     .word 0xAA55
    254 
    255 .text
    256 endtext:
    257 .data
    258 enddata:
    259 .bss
    260 endbss:
    261 

    第二个:(头文件贴在最下面!)
     1 /*
     2  *    bootsect.S        Copyright (C) 1991, 1992 Linus Torvalds
     3  *
     4  *    modified by Drew Eckhardt
     5  *    modified by Bruce Evans (bde)
     6  *    modified by Chris Noe (May 1999) (as86 -> gas)
     7  *    gutted by H. Peter Anvin (Jan 2003)
     8  *
     9  * BIG FAT NOTE: We're in real mode using 64k segments.  Therefore segment
    10  * addresses must be multiplied by 16 to obtain their respective linear
    11  * addresses. To avoid confusion, linear addresses are written using leading
    12  * hex while segment addresses are written as segment:offset.
    13  *
    14  */
    15 
    16 #include <asm/boot.h>
    17 
    18 SETUPSECTS    = 4            /* default nr of setup-sectors */
    19 BOOTSEG        = 0x07C0        /* original address of boot-sector */
    20 INITSEG        = DEF_INITSEG        /* we move boot here - out of the way */
    21 SETUPSEG    = DEF_SETUPSEG        /* setup starts here */
    22 SYSSEG        = DEF_SYSSEG        /* system loaded at 0x10000 (65536) */
    23 SYSSIZE        = DEF_SYSSIZE        /* system size: # of 16-byte clicks */
    24                     /* to be loaded */
    25 ROOT_DEV    = 0             /* ROOT_DEV is now written by "build" */
    26 SWAP_DEV    = 0            /* SWAP_DEV is now written by "build" */
    27 
    28 #ifndef SVGA_MODE
    29 #define SVGA_MODE ASK_VGA
    30 #endif
    31 
    32 #ifndef RAMDISK
    33 #define RAMDISK 0
    34 #endif
    35 
    36 #ifndef ROOT_RDONLY
    37 #define ROOT_RDONLY 1
    38 #endif
    39 
    40 .code16
    41 .text
    42 
    43 .global _start
    44 _start:
    45 
    46     # Normalize the start address
    47     jmpl    $BOOTSEG, $start2
    48 
    49 start2:
    50     movw    %cs, %ax
    51     movw    %ax, %ds
    52     movw    %ax, %es
    53     movw    %ax, %ss
    54     movw    $0x7c00, %sp
    55     sti
    56     cld
    57 
    58     movw    $bugger_off_msg, %si
    59 
    60 msg_loop:
    61     lodsb
    62     andb    %al, %al
    63     jz    die
    64     movb    $0xe, %ah
    65     movw    $7, %bx
    66     int    $0x10
    67     jmp    msg_loop
    68 
    69 die:
    70     # Allow the user to press a key, then reboot
    71     xorw    %ax, %ax
    72     int    $0x16
    73     int    $0x19
    74 
    75     # int 0x19 should never return.  In case it does anyway,
    76     # invoke the BIOS reset code
    77     ljmp    $0xf000,$0xfff0
    78 
    79 
    80 bugger_off_msg:
    81     .ascii    "Direct booting from floppy is no longer supported.\r\n"
    82     .ascii    "Please use a boot loader program instead.\r\n"
    83     .ascii    "\n"
    84     .ascii    "Remove disk and press any key to reboot . . .\r\n"
    85     .byte    0
    86     
    87 
    88     # Kernel attributes; used by setup
    89 
    90     .org 497
    91 setup_sects:    .byte SETUPSECTS
    92 root_flags:    .word ROOT_RDONLY
    93 syssize:    .word SYSSIZE
    94 swap_dev:    .word SWAP_DEV
    95 ram_size:    .word RAMDISK
    96 vid_mode:    .word SVGA_MODE
    97 root_dev:    .word ROOT_DEV
    98 boot_flag:    .word 0xAA55
    99 

    下面这个头文件boot.h

     1 #ifndef _LINUX_BOOT_H
     2 #define _LINUX_BOOT_H
     3 
     4 /* Don't touch these, unless you really know what you're doing. */
     5 #define DEF_INITSEG    0x9000
     6 #define DEF_SYSSEG    0x1000
     7 #define DEF_SETUPSEG    0x9020
     8 #define DEF_SYSSIZE    0x7F00
     9 
    10 /* Internal svga startup constants */
    11 #define NORMAL_VGA    0xffff        /* 80x25 mode */
    12 #define EXTENDED_VGA    0xfffe        /* 80x50 mode */
    13 #define ASK_VGA        0xfffd        /* ask for it at bootup */
    14 
    15 #endif
    16 

  • 相关阅读:
    SQL Server 2005 之事务日志体系 (一)
    SQL Server 2005 事务日志之逻辑结构(二)
    SQL Server 2005 清除备份 还原历史记录
    SQL Server 验证器
    SQL Server 2005 事务日志之物理体系(三)
    程序设计语言原理重要概念
    Java作业四 图形用户界面程序设计和多线程
    Java作业二 面向对象程序设计
    Java作业三 语言基础与面向对象
    Java课程学习总结
  • 原文地址:https://www.cnblogs.com/BoyeeStudio/p/250510.html
Copyright © 2011-2022 走看看