《操作系统真相还原》读书笔记八:获取物理内存容量以及本书源代码

编写mbr.S汇编代码

;LOADER_BASE_ADDR equ 0x900
;LOADER_START_SECTOR equ 0x2
%include "boot.inc"

SECTION MBR vstart=0x7c00
  mov ax,cs
  mov ds,ax
  mov es,ax
  mov ss,ax
  mov fs,ax
  mov sp,0x7c00
  mov ax,0xb800
  mov gs,ax
  
  mov ax,0x0600
  mov bx,0x0700
  mov cx,0
  mov dx, 184fh
  int 10h
  
  mov byte [gs:0x00], '1'
  mov byte [gs:0x01], 0xA4
  
  mov byte [gs:0x02], ' '
  mov byte [gs:0x03], 0xA4
  
  mov byte [gs:0x04], 'M'
  mov byte [gs:0x05], 0xA4
  
  mov byte [gs:0x06], 'B'
  mov byte [gs:0x07], 0xA4
  
  mov byte [gs:0x08], 'R'
  mov byte [gs:0x09], 0xA4
  
  mov eax,LOADER_START_SECTOR
  mov bx, LOADER_BASE_ADDR
  mov cx,4  ; 读取的扇区数,读取4个扇区
  call rd_disk_m_16
  jmp LOADER_BASE_ADDR + 0x300
  
rd_disk_m_16:
  mov esi,eax
  mov di,cx
  
  mov dx,0x1f2
  mov al,cl
  out dx,al
  
  mov eax,esi
  
  mov dx,0x1f3
  out dx,al
  
  mov cl,8
  shr eax,cl
  mov dx,0x1f4
  out dx,al
  
  shr eax,cl
  mov dx,0x1f5
  out dx,al
  
  shr eax,cl
  and al,0x0f
  or al,0xe0
  mov dx,0x1f6
  out dx,al

  mov dx,0x1f7
  mov al,0x20
  out dx,al

.not_ready:
  nop
  in al,dx
  and al,0x88

  cmp al,0x08
  jnz .not_ready

  mov ax,di
  mov dx,256
  mul dx
  mov cx,ax
  
  mov dx,0x1f0
.go_on_ready:
  in ax,dx
  mov [bx],ax
  add bx,2
  loop .go_on_ready
  ret
  
  times 510-($-$$) db 0
  db 0x55,0xaa

编写loader.S汇编代码

;LOADER_BASE_ADDR equ 0x900
;LOADER_START_SECTOR equ 0x2
%include "boot.inc"

SECTION LOADER vstart=LOADER_BASE_ADDR
 LOADER_STACK_TOP equ LOADER_BASE_ADDR
 
 GDT_BASE: dd 0x00000000
           dd 0x00000000
		  
 CODE_DESC: dd 0x0000FFFF
            dd DESC_CODE_HIGH4

 DATA_STACK_DESC:  dd 0x0000FFFF
                   dd DESC_DATA_HIGH4
				   
 VIDEO_DESC:  dd 0x80000007
              dd DESC_VIDEO_HIGH4
			  
  GDT_SIZE equ $-GDT_BASE
  GDT_LIMIT equ GDT_SIZE-1
  times 60 dq 0
  
  SELECTOR_CODE equ (0x0001 << 3) + TI_GDT + RPL0
  SELECTOR_DATA equ (0x0002 << 3) + TI_GDT + RPL0
  SELECTOR_VIDEO equ (0x0003 << 3) + TI_GDT + RPL0
  
  ;用于保存内存容量,以字节为单位,此位置好记
  ; 0x900 + 32 + 480 = 0xb00
  total_mem_bytes dd 0
  
  gdt_ptr  dw GDT_LIMIT
           dd GDT_BASE
  
  ; 人工对齐
  ards_buf times 244 db 0
  ards_nr dw 0
   
loader_start:
;-------  int 15h eax = 0000E820h ,edx = 534D4150h ('SMAP') 获取内存布局  -------
   xor ebx,ebx
   mov edx,0x534d4150
   mov di,ards_buf
.e820_mem_get_loop:
  mov eax, 0x0000e820
  mov ecx,20
  int 0x15
   jc .e820_failed_so_try_e801
  add di,cx
  inc word[ards_nr]
  cmp ebx,0
  jnz .e820_mem_get_loop
  
  mov cx,[ards_nr]
  mov ebx,ards_buf
  xor edx,edx
 .find_max_mem_area:
  mov eax,[ebx]
  add eax,[ebx+8]
  add ebx,20
  cmp edx,eax
  jge .next_ards
  mov edx,eax
 .next_ards:
  loop .find_max_mem_area
  jmp .mem_get_ok
 
;------  int 15h ax = E801h 获取内存大小,最大支持4G  ------
 .e820_failed_so_try_e801:
   mov ax,0xe801
   int 0x15
   jc .e801_failed_so_try88
   
 ; 先算出低15M的内存
   mov cx,0x400
   mul cx
   shl edx,16 ; 左移16位
   and eax,0x0000FFFF
   or edx,eax
   add edx,0x100000
   mov esi,edx
   
 ; 再将16M以上的内存
   xor eax,eax
   mov ax,bx
   mov ecx,0x10000
   mul ecx
   
   add esi,eax
  mov edx,esi
  jmp .mem_get_ok  
   
;-----------------  int 15h ah = 0x88 获取内存大小,只能获取64M之内  ----------
.e801_failed_so_try88:
  mov ah,0x88
  int 0x15
  jc .error_hlt
  and eax,0x0000FFFF
  
  mov cx,0x400
  mul cx,
  shl edx,16
  or edx,eax
  add edx,0x100000  
  

  .mem_get_ok:
    mov [total_mem_bytes], edx
   
;-----------------   准备进入保护模式   -------------------
;1 打开A20
;2 加载gdt
;3 将cr0的pe位置1
  
   ;准备进入保护模式
   in al,0x92
   or al,0000_0010b
   out 0x92,al
   
   lgdt [gdt_ptr]
   
   mov eax,cr0
   or eax,0x00000001
   mov cr0,eax
   
   jmp dword SELECTOR_CODE:p_mode_start
   
 .error_hlt:		      ;出错则挂起
   hlt
   
[bits 32]
  p_mode_start:
    mov ax,SELECTOR_DATA
	mov ds,ax
	mov es,ax
	mov ss,ax
	mov esp,LOADER_STACK_TOP
	mov ax,SELECTOR_VIDEO
	mov gs,ax
	
	mov byte[gs:160],'p'
	
	jmp $

宏文件boot.inc和读书笔记七中一致。

编译代码
在这里插入图片描述

nasm -I include/ -o mbr.bin mbr.S
nasm -I include/ -o loader.bin loader.S

dd if=/home/truthos/oscode/c5/a/boot/mbr.bin of=/home/truthos/bochs/hd60M.img bs=512 count=1 conv=notrunc

dd if=/home/truthos/oscode/c5/a/boot/loader.bin of=/home/truthos/bochs/hd60M.img  count=4 seek=2 conv=notrunc

xp 0xb00 查看物理内存0xb00出的内容
在这里插入图片描述

程序正常运行
在这里插入图片描述

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值