zoukankan      html  css  js  c++  java
  • linux学习(二)--setup.s

    执行过bootsect.s,加载了所有系统代码之后,开始向32位模式转变,为main函数的调用做准备,同样,附上图往下看

      1 INITSEG  = 0x9000    ! we move boot here - out of the way
      2 SYSSEG   = 0x1000    ! system loaded at 0x10000 (65536).
      3 SETUPSEG = 0x9020    ! this is the current segment
      4 
      5 .globl begtext, begdata, begbss, endtext, enddata, endbss
      6 .text
      7 begtext:
      8 .data
      9 begdata:
     10 .bss
     11 begbss:
     12 .text
     13 
     14 entry start
     15 start:
     16 
     17 //保存当前光标位置
     18     mov    ax,#INITSEG    
     19     mov    ds,ax            ;ds设置成INITSEG
     20     mov    ah,#0x03        ;int 10读光标功能号3
     21     xor    bh,bh
     22     int    0x10            ;调用中断,读取光标位置
     23     mov    [0],dx            ;光标信息存在dx中,并存入0x90000处
     24     mov    ah,#0x88        ;int 15取扩展内存大小功能号0x88
     25     int    0x15            ;调用中断
     26     mov    [2],ax            ;返回从100000开始的扩展内存大小
     27 
     28 //保存显卡当前显示模式
     29     mov    ah,#0x0f
     30     int    0x10
     31     mov    [4],bx        ; bh = display page
     32     mov    [6],ax        ; al = video mode, ah = window width
     33 
     34 //检查显示方式(EGA/VGA),并选取参数
     35     mov    ah,#0x12    
     36     mov    bl,#0x10
     37     int    0x10
     38     mov    [8],ax        
     39     mov    [10],bx    ;显示内存,显示状态
     40     mov    [12],cx    ;显卡特性参数
     41 
     42 //取第0个硬盘信息
     43     mov    ax,#0x0000
     44     mov    ds,ax
     45     lds    si,[4*0x41];取中断向量,41的值,即硬盘0参数表的地址
     46     mov    ax,#INITSEG
     47     mov    es,ax
     48     mov    di,#0x0080    ;传输向量表到达的目的地址:9000:0080
     49     mov    cx,#0x10    ;取10字节
     50     rep
     51     movsb            ;循环复制
     52 
     53 //取第一个磁盘信息
     54     mov    ax,#0x0000
     55     mov    ds,ax
     56     lds    si,[4*0x46];取中断向量,46的值,即硬盘1参数表的地址
     57     mov    ax,#INITSEG
     58     mov    es,ax
     59     mov    di,#0x0090    ;传输向量表到达的目的地址:9000:0090
     60     mov    cx,#0x10    ;取10字节
     61     rep
     62     movsb
     63 
     64 //检查是否存在第二个硬盘
     65     mov    ax,#0x01500
     66     mov    dl,#0x81
     67     int    0x13
     68     jc    no_disk1    ;如果cf==1,跳转,没有第二个磁盘
     69     cmp    ah,#3        ;判断是否有硬盘
     70     je    is_disk1
     71 //没有则删除第二个硬盘表
     72 no_disk1:
     73     mov    ax,#INITSEGjj
     74     mov    es,ax
     75     mov    di,#0x0090
     76     mov    cx,#0x10
     77     mov    ax,#0x00
     78     rep
     79     stosb
     80 
     81 is_disk1:
     82 
     83 //开始保护模式方面的工作
     84 
     85     cli            ;不允许中断
     86 
     87 //首先我们将系统模块移动到新的目标位置
     88 
     89     mov    ax,#0x0000
     90     cld                ! 'direction'=0, movs moves forward
     91 do_move:
     92     mov    es,ax        ;被复制到的目的地址es:di=>0000:0
     93     add    ax,#0x1000
     94     cmp    ax,#0x9000
     95     jz    end_move
     96     mov    ds,ax        ;原地址ds:si=>1000:0
     97     sub    di,di
     98     sub    si,si
     99     mov     cx,#0x8000    ;移动0x8000字节(64k)
    100     rep
    101     movsw
    102     jmp    do_move
    103 
    104 //加载段描述符
    105 
    106 end_move:
    107     mov    ax,#SETUPSEG    ! right, forgot this at first. didn't work :-)
    108     mov    ds,ax            ;ds指向setup段
    109     lidt    idt_48        ;加载中断描述符表寄存器
    110     lgdt    gdt_48        ;加载全局描述符表寄存器
    111 
    112 //开启A20地址线,准备进入32位寻址模式
    113 
    114     call    empty_8042
    115     mov    al,#0xD1        ! command write
    116     out    #0x64,al
    117     call    empty_8042
    118     mov    al,#0xDF        ! A20 on
    119     out    #0x60,al
    120     call    empty_8042
    121 
    122 ! well, that went ok, I hope. Now we have to reprogram the interrupts :-(
    123 ! we put them right after the intel-reserved hardware interrupts, at
    124 ! int 0x20-0x2F. There they won't mess up anything. Sadly IBM really
    125 ! messed this up with the original PC, and they haven't been able to
    126 ! rectify it afterwards. Thus the bios puts interrupts at 0x08-0x0f,
    127 ! which is used for the internal hardware interrupts as well. We just
    128 ! have to reprogram the 8259's, and it isn't fun.
    129 
    130     mov    al,#0x11        ! initialization sequence
    131     out    #0x20,al        ! send it to 8259A-1
    132     .word    0x00eb,0x00eb        ! jmp $+2, jmp $+2,$表示当前指令地址
    133     out    #0xA0,al        ! and to 8259A-2
    134     .word    0x00eb,0x00eb
    135     mov    al,#0x20        ! start of hardware int's (0x20)
    136     out    #0x21,al
    137     .word    0x00eb,0x00eb
    138     mov    al,#0x28        ! start of hardware int's 2 (0x28)
    139     out    #0xA1,al
    140     .word    0x00eb,0x00eb
    141     mov    al,#0x04        ! 8259-1 is master
    142     out    #0x21,al
    143     .word    0x00eb,0x00eb
    144     mov    al,#0x02        ! 8259-2 is slave
    145     out    #0xA1,al
    146     .word    0x00eb,0x00eb
    147     mov    al,#0x01        ! 8086 mode for both
    148     out    #0x21,al
    149     .word    0x00eb,0x00eb
    150     out    #0xA1,al
    151     .word    0x00eb,0x00eb
    152     mov    al,#0xFF        ! mask off all interrupts for now
    153     out    #0x21,al
    154     .word    0x00eb,0x00eb
    155     out    #0xA1,al
    156 
    157 ! well, that certainly wasn't fun :-(. Hopefully it works, and we don't
    158 ! need no steenking BIOS anyway (except for the initial loading :-).
    159 ! The BIOS-routine wants lots of unnecessary data, and it's less
    160 ! "interesting" anyway. This is how REAL programmers do it.
    161 !
    162 ! Well, now's the time to actually move into protected mode. To make
    163 ! things as simple as possible, we do no register set-up or anything,
    164 ! we let the gnu-compiled 32-bit programs do that. We just jump to
    165 ! absolute address 0x00000, in 32-bit protected mode.
    166 
    167     mov    ax,#0x0001    ! protected mode (PE) bit
    168     lmsw    ax        ! This is it!
    169     jmpi    0,8        ! jmp offset 0 of segment 8 (cs)
    170                     ; 跳转到8:0位置,这里的8为实模式下的段选择符,目的地址是0x00000000
    171 //关于8的解析,这里的8对应二进制的"1000",这里的后两位0表示内核特权级,倒数第三位的0表示gdt
    172 //1表示用全局描述符表的第1项,该项指出代码的基地址是0,也就是接下来执行的head.s
    173 
    174 ! This routine checks that the keyboard command queue is empty
    175 ! No timeout is used - if this hangs there is something wrong with
    176 ! the machine, and we probably couldn't proceed anyway.
    177 
    178 //检查键盘命令队列是否为空,当输入缓冲器为空则可以对其进行写命令
    179 empty_8042:
    180     .word    0x00eb,0x00eb
    181     in    al,#0x64        ! 8042 status port
    182     test    al,#2        ! is input buffer full?
    183     jnz    empty_8042    ! yes - loop
    184     ret
    185 //全局描述符表开始处
    186 gdt:
    187     .word    0,0,0,0    ! dummy//第一描述符,不用
    188 
    189 //这里在gdt表中的偏移量为08,联系我们上面的jmpi 0,8,也就是调用此处的表内容
    190 //加载代码段寄存器时,使用这个偏移
    191     .word    0x07FF        ! 8Mb - limit=2047 (2048*4096=8Mb)
    192     .word    0x0000        ! base address=0
    193     .word    0x9A00        ! code read/exec
    194     .word    0x00C0        ! granularity=4096, 386
    195 
    196 //这里在gdt表中的偏移量是10,当加载数据段寄存器时,使用这个偏移
    197     .word    0x07FF        ! 8Mb - limit=2047 (2048*4096=8Mb)
    198     .word    0x0000        ! base address=0
    199     .word    0x9200        ! data read/write
    200     .word    0x00C0        ! granularity=4096, 386
    201 
    202 idt_48:
    203     .word    0            ! idt limit=0
    204     .word    0,0            ! idt base=0L
    205 
    206 gdt_48:
    207     .word    0x800            ! gdt limit=2048, 256 GDT entries
    208     .word    512+gdt,0x9    ! gdt base = 0X9xxxx
    209     
    210 .text
    211 endtext:
    212 .data
    213 enddata:
    214 .bss
    215 endbss:
  • 相关阅读:
    android中BuildConfig.DEBUG的使用
    Http 状态码完整说明
    Java 线程池
    Gson简要使用笔记
    Android Loader详解四:回调及完整例子
    Android Loader详解三:重启与回调
    Android Loader详解二:使用加载器
    Android Loader详解一:概述
    Metrics介绍和Spring的集成(转)
    Web.xml配置详解之context-param(转)
  • 原文地址:https://www.cnblogs.com/Taolaw/p/10040902.html
Copyright © 2011-2022 走看看