Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2112677
  • 博文数量: 438
  • 博客积分: 3871
  • 博客等级: 中校
  • 技术积分: 6075
  • 用 户 组: 普通用户
  • 注册时间: 2011-09-10 00:11
个人简介

邮箱: wangcong02345@163.com

文章分类

全部博文(438)

文章存档

2017年(15)

2016年(119)

2015年(91)

2014年(62)

2013年(56)

2012年(79)

2011年(16)

分类: LINUX

2016-08-16 17:14:06

《操作系统真象还原》学习笔记

1. mbr.S
  1. org 0x7C00
  2.     mov ax, cs
  3.     mov ds, ax
  4.     mov es, ax
  5.     mov ss, ax
  6.     mov ax, 0xb800
  7.     mov gs, ax

  8.     ;print 1MBR
  9.     mov byte [gs:0x00], '1'
  10.     mov byte [gs:0x01], 0xA4
  11.     
  12.     mov byte [gs:0x02], 'M'
  13.     mov byte [gs:0x03], 0xA4

  14.     mov byte [gs:0x04], 'B'
  15.     mov byte [gs:0x05], 0xA4
  16.     
  17.     mov byte [gs:0x06], 'R'
  18.     mov byte [gs:0x07], 0xA4
  19.     
  20.     ;loader loader.bin to 0x9000
  21.     mov bx, 0x9000 ;dst_add in memory
  22.     mov cl, 1    ;sector cnt of disk
  23.     mov eax, 2   ;LBA addr   从第2个扇区开始读数据
  24.     call load_disk

  25.     ;jmp to 0x9000
  26.     jmp 0x9000

  27. load_disk:
  28.     ;eax --> src_addr of disk, in the format of LBA
  29.     ;bx --> memory dst_addr
  30.     ;cx --> sector_count
  31.     mov edx, eax
  32.     mov di, cx

  33.     mov dx, 0x1f2 ;sector count
  34.     mov al, cl
  35.     out dx, al
  36.     
  37.     mov eax, edx ;LBA-->0-8
  38.     mov dx, 0x1f3
  39.     out dx, al    
  40.     
  41.     mov cl, 8
  42.     shr eax, cl ;LBA--> 8-16
  43.     mov dx, 0x1f4
  44.     out dx, al    

  45.     shr eax, cl ;LBA-->16-24
  46.     mov dx, 0x1f5
  47.     out dx, al

  48.     shr eax, cl ;LBA-->16-24
  49.     and al, 0x0f
  50.     or al, 0xe0
  51.     mov dx, 0x1f6
  52.     out dx, al

  53.     mov dx,0x1f7 ;send read cmd
  54.     mov al, 0x20
  55.     out dx, al

  56. not_ready:
  57.     in ax, dx
  58.     and ax,0x88
  59.     cmp ax,0x88
  60.     jnz not_ready
  61.     
  62.     mov ax, di
  63.     mov dx, 256
  64.     mul dx
  65.     mov cx, ax
  66.     mov dx, 0x1f0
  67. goon_read:
  68.     in ax, dx
  69.     mov [bx], ax
  70.     add bx, 2
  71.     loop goon_read
  72.     ret

  73.     jmp $
  74. times 510-($-$$) db 0
  75. dw 0xaa55
2. loader.S
  1. cong@msi:/work/os/code/2loader$ cat loader.S
  2. org 0x9000
  3.     mov ax, cs
  4.     mov ds, ax
  5.     mov es, ax
  6.     mov ss, ax
  7.     mov ax, 0xb800
  8.     mov gs, ax

  9.     mov byte [gs:0x08], '2'
  10.     mov byte [gs:0x09], 0xA4
  11.     
  12.     mov byte [gs:0x0A], 'L'
  13.     mov byte [gs:0x0B], 0xA4

  14.     mov byte [gs:0x0C], 'O'
  15.     mov byte [gs:0x0D], 0xA4
  16.     
  17.     mov byte [gs:0x0E], 'A'
  18.     mov byte [gs:0x0F], 0xA4

  19.     mov byte [gs:0x10], 'D'
  20.     mov byte [gs:0x11], 0xA4

  21.     jmp $
3. Makefile
  1. cong@msi:/work/os/code/2loader$ cat Makefile
  2. ALL: mbr loader
  3. mbr:
  4.     nasm mbr.S -o mbr.bin
  5. loader:
  6.     nasm loader.S -o loader.bin
  7. clean:
  8.     -rm *.o mbr.bin loader.bin
  9. flash:
  10.     -rm ../disk.img
  11.     dd if=/dev/zero of=../disk.img bs=1M count=30
  12.     dd if=./mbr.bin of=../disk.img bs=512 count=1 conv=notrunc
  13.     dd if=./loader.bin of=../disk.img bs=512 count=10 seek=2 conv=notrunc    //seek=2,跳过了(0与1)2个扇区
   0             1            2
0--200   200-400  400-600
4. 检查一下disk.img是不是从0x400-0x600之间有数据
loader.bin的
  1. cong@msi:/work/os/code/2loader$ xxd ./loader.bin
  2. 0000000: 8cc8 8ed8 8ec0 8ed0 b800 b88e e865 c606 .............e..
  3. 0000010: 0800 3265 c606 0900 a465 c606 0a00 4c65 ..2e.....e....Le
  4. 0000020: c606 0b00 a465 c606 0c00 4f65 c606 0d00 .....e....Oe....
  5. 0000030: a465 c606 0e00 4165 c606 0f00 a465 c606 .e....Ae.....e..
  6. 0000040: 1000 4465 c606 1100 a4eb fe ..De.......
disk.img中的loader.bin
  1. cong@msi:/work/os/code/2loader$ xxd -seek 0x400 -l 0x200 ../disk.img   ;-seek是从偏移多少开始打印,-l是打印多少字符
  2. 0000400: 8cc8 8ed8 8ec0 8ed0 b800 b88e e865 c606 .............e..
  3. 0000410: 0800 3265 c606 0900 a465 c606 0a00 4c65 ..2e.....e....Le
  4. 0000420: c606 0b00 a465 c606 0c00 4f65 c606 0d00 .....e....Oe....
  5. 0000430: a465 c606 0e00 4165 c606 0f00 a465 c606 .e....Ae.....e..
  6. 0000440: 1000 4465 c606 1100 a4eb fe00 0000 0000 ..De............
  7. 0000450: 0000 0000 0000 0000 0000 0000 0000 0000 ................
  8. 0000460: 0000 0000 0000 0000 0000 0000 0000 0000 ................
这不就对上了嘛,说明刷到disk.img的loader.bin己在disk.img的正确位置上

二.调试
2.1 只打印出了1MBR
  1. <bochs:2> b 0x9000
  2. <bochs:3> c
  3. (0) Breakpoint 2, 0x00009000 in ?? ()
  4. Next at t=156817011
  5. (0) [0x000000009000] 0000:9000 (unk. ctxt): add byte ptr ds:[bx+si], al ; 0000
  6. <bochs:4> u /10
  7. 00009000: ( ): add byte ptr ds:[bx+si], al ; 0000
  8. 00009002: ( ): add byte ptr ds:[bx+si], al ; 0000
  9. 00009004: ( ): add byte ptr ds:[bx+si], al ; 0000
  10. 00009006: ( ): add byte ptr ds:[bx+si], al ; 0000
  11. 00009008: ( ): add byte ptr ds:[bx+si], al ; 0000
  12. 0000900a: ( ): add byte ptr ds:[bx+si], al ; 0000
  13. 0000900c: ( ): add byte ptr ds:[bx+si], al ; 0000
  14. 0000900e: ( ): add byte ptr ds:[bx+si], al ; 0000
  15. 00009010: ( ): add byte ptr ds:[bx+si], al ; 0000
  16. 00009012: ( ): add byte ptr ds:[bx+si], al ; 0000
这说明在0x9000处没有代码

b.重启bochs调试发现从in ax, dx时,读取出来的数据都为0
  1. (0) [0x000000007c96] 0000:7c96 (unk. ctxt): in ax, dx ; ed
  2. <bochs:7> r               -->r 指令打印寄存器的值
  3. eax: 0x00000100 256               -->执行in ax,dx之前eax=0x100
  4. ecx: 0x00090100 590080
  5. edx: 0x000001f0 496
  6. ebx: 0x00009000 36864
  7. esp: 0x0000ffd4 65492
  8. ebp: 0x00000000 0
  9. esi: 0x000e0000 917504
  10. edi: 0x00000001 1
  11. eip: 0x00007c96
  12. eflags 0x00000006: id vip vif ac vm rf nt IOPL=0 of df if tf sf zf af PF cf
  13. <bochs:8> s             -->s单步与n的区别是call之后的函数s会进,n不进
  14. Next at t=156815985
  15. (0) [0x000000007c97] 0000:7c97 (unk. ctxt): mov word ptr ds:[bx], ax ; 8907
  16. <bochs:9> r               -->r 指令打印寄存器的值
  17. eax: 0x00000000 0                -->执行in ax,dx后eax=0x0000,说明硬盘读操作读到的数据为0
  18. ecx: 0x00090100 590080
  19. edx: 0x000001f0 496
  20. ebx: 0x00009000 36864
  21. esp: 0x0000ffd4 65492
  22. ebp: 0x00000000 0
  23. esi: 0x000e0000 917504
  24. edi: 0x00000001 1
  25. eip: 0x00007c97
c.
L35行edx来保存eax的值,但是接着L3行就将dx设为0x1f2,把保存的eax值破坏了
d.
not_ready:
    in ax, dx              --> in 指令是8位的,这会使ax=0xFFFF
    and ax,0x88        --> and 之后ax=0x88
    cmp ax,0x88       --> cmp操作一定相等,所以读到到的值为0了。
2.2 正确的代码打包
2loader.rar   (下载后改名为2loader.tar.gz)
2.3正确的运行结果


阅读(1233) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~