⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 setup.asm

📁 哈工大的几个人开发的操作系统pyos的部分源码
💻 ASM
字号:
;setup.asm
;for pyos4 
;xieyubo@126.com

;此setup程序完成boot未完成的启动工作,
;包括从BIOS中读出系统信息存放在指定位置
;初始化GDT,LDT表,完成从保护模式到实模式的转换
;实模式的代码也由此程序读入

[BITS 16]           
[ORG 0x0100]
;-------------------------------------------------------------------------------------
jmp                 Main
;-------------------------------------------------------------------------------------
SETUPSEG            equ                 0x9000
SETUPOFFSET         equ                 0x0100
SETUPSIZE           equ                 1024                ;setup的大小 1KB , 必须是 512 的倍数

SYSTEMSEG           equ                 0x0000              
SYSTEMOFFSET        equ                 0x0000
SYSTEMSIZE          equ                 16896                ;SYSTEM的大小 1KB ,此值必须是 512 的倍数,实际值可以不符
                                                             ;10240 共 20个扇区 ( 10240 = 512 * 20 ),目前setup可接受的
                                                             ;大小为 15 + 18 = 33个扇区,即 33 * 512 = 16896 个字节,
                                                             ;如果 SYSTEMSIZE 值超过此字节数,将更改下面读入程序

;下面定义临时GDT表的描述符
;总共定义三个段,一个空段由intel保留,一个代码段,一个数据段
gdt_addr:
                    dw                  0x7fff              ;GDT表的大小
                    dw                  gdt                 ;GDT表的位置
                    dw                  0x0009
gdt:
  gdt_null:
                    dw                  0x0000
                    dw                  0x0000
                    dw                  0x0000
                    dw                  0x0000
  gdt_system_code:
                    dw                  0x3fff              ;段限( 16K * 64KB = 64MB )
                    dw                  0x0000
                    dw                  0x9a00
                    dw                  0x00c0
  gdt_system_data:
                    dw                  0x3fff
                    dw                  0x0000
                    dw                  0x9200
                    dw                  0x00c0    
;-------------------------------------------------------------------------------------
;等待键盘控制器空闲的子程序
Empty_8042:  
  in                al , 0x64
  test              al , 0x2
  jnz               Empty_8042
  ret
;-------------------------------------------------------------------------------------  
Main:  
  ;初始化寄存器,因为Bios中断及call会用到堆栈或ss寄存器
  ;在CPU启动或复位时是由BIOS初始化的,而现在进行了段转移,需要我们重新设置
  mov               ax , SETUPSEG
  mov               ds , ax
  mov               es , ax 
  mov               ss , ax         
  mov               sp , 0xffff
  
  ;-------------------------------------------------------------------------
  ;从BIOS中到底应读出哪些有用信息,现在还不确定,因此暂时跳过此功能块
  ;-----------------------------------------------
  ;0x90000 (1B): 保存启动驱动器号,由boot程序存入
  ;--------------------------------------------------------------------------
  
  ;下面读入system到setup程序的后面
  ;因为0x00000现在是放BIOS中断的地方,因此还不能直接将system读到0x00000处,否则将无法调用BIOS中断读入磁盘
  .readfloopy:
  mov               ax , SETUPSEG          
  mov               es , ax
  mov               bx , SETUPOFFSET + SETUPSIZE
  mov               ah , 2 ; 功能号 2 表示读磁盘扇区
  mov               dl , [0] ; 驱动器号
  mov               dh , 0 ; 0号磁头
  mov               ch , 0 ; 0磁道
  mov               cl , 1 + 1 + SETUPSIZE / 512            ;system所在的启始扇区( 第一个1是指从1开始记数,第二个1是boot所占扇区数)
  ; 目前内核大小超过1磁道 18扇区的容量,因此需要读入两个磁道,这里先读第一个磁道
  mov               al , 15				                    ;读入扇区数( 第一磁道还留有的扇区数 )
  int               0x13

  ; 下面继续读入第二面的第一个磁道,共18扇区,因为前面中断的返回值修改了寄存器,因此必需重新设置
  mov               ax , SETUPSEG          
  mov               es , ax
  mov               bx , SETUPOFFSET + SETUPSIZE + 15 * 512
  mov               ah , 2 ; 功能号 2 表示读磁盘扇区
  mov               dl , [0] ; 驱动器号
  mov               dh , 1 ; 1号磁头
  mov               ch , 0 ; 0磁道
  mov               cl , 1 ; 启始扇区1扇区
  mov               al , 18 ; 读入扇区数
  int               0x13

  jc                .readfloopy

  cli              ;关中断
  ;下面将读入的system搬移到0x00000位置   
  cld   
  mov               si , SETUPOFFSET + SETUPSIZE
  mov               ax , SYSTEMSEG
  mov               es , ax
  mov               di , SYSTEMOFFSET
  mov               cx , SYSTEMSIZE / 4
  rep movsd  

  ;下面开始为进入保护模式而进行初始化工作                                                       
  lgdt              [gdt_addr]                              ;载入gdt的描述符  
  ;下面打开A20地址线
  call              Empty_8042
  mov               al , 0xd1 
  out               0x64 , al
  call              Empty_8042
  mov               al , 0xdf
  out               0x60 , al
  call              Empty_8042
  
  ;下面设置进入32位保护模式运行
  mov               eax , cr0
  or                eax , 1
  mov               cr0 , eax  
  
  ;下面建立临时堆栈,及临时寄存器值
  mov               ax , 0x10
  mov               ds , ax
  mov               es , ax
  mov               ss , ax
  mov               fs , ax
  mov               gs , ax
  mov               sp , 0xffff
  
  jmp dword         0x8:0x0  
;-------------------------------------------------------------------------------------
times 1024-($-$$) db 0

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -