《操作系统真象还原》学习笔记
1. mbr.S
2. loader.S
3. Makefile
0 1 2
0--200 200-400 400-600
4. 检查一下disk.img是不是从0x400-0x600之间有数据
loader.bin的
disk.img中的loader.bin
这不就对上了嘛,说明刷到disk.img的loader.bin己在disk.img的正确位置上
二.调试
2.1 只打印出了1MBR
这说明在0x9000处没有代码
b.重启bochs调试发现从in ax, dx时,读取出来的数据都为0
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正确的运行结果
1. mbr.S
- org 0x7C00
- mov ax, cs
- mov ds, ax
- mov es, ax
- mov ss, ax
- mov ax, 0xb800
- mov gs, ax
-
- ;print 1MBR
- mov byte [gs:0x00], '1'
- mov byte [gs:0x01], 0xA4
-
- mov byte [gs:0x02], 'M'
- mov byte [gs:0x03], 0xA4
-
- mov byte [gs:0x04], 'B'
- mov byte [gs:0x05], 0xA4
-
- mov byte [gs:0x06], 'R'
- mov byte [gs:0x07], 0xA4
-
- ;loader loader.bin to 0x9000
- mov bx, 0x9000 ;dst_add in memory
- mov cl, 1 ;sector cnt of disk
- mov eax, 2 ;LBA addr 从第2个扇区开始读数据
- call load_disk
-
- ;jmp to 0x9000
- jmp 0x9000
-
- load_disk:
- ;eax --> src_addr of disk, in the format of LBA
- ;bx --> memory dst_addr
- ;cx --> sector_count
- mov edx, eax
- mov di, cx
-
- mov dx, 0x1f2 ;sector count
- mov al, cl
- out dx, al
-
- mov eax, edx ;LBA-->0-8
- mov dx, 0x1f3
- out dx, al
-
- mov cl, 8
- shr eax, cl ;LBA--> 8-16
- mov dx, 0x1f4
- out dx, al
-
- shr eax, cl ;LBA-->16-24
- mov dx, 0x1f5
- out dx, al
-
- shr eax, cl ;LBA-->16-24
- and al, 0x0f
- or al, 0xe0
- mov dx, 0x1f6
- out dx, al
-
- mov dx,0x1f7 ;send read cmd
- mov al, 0x20
- out dx, al
-
- not_ready:
- in ax, dx
- and ax,0x88
- cmp ax,0x88
- jnz not_ready
-
- mov ax, di
- mov dx, 256
- mul dx
- mov cx, ax
- mov dx, 0x1f0
- goon_read:
- in ax, dx
- mov [bx], ax
- add bx, 2
- loop goon_read
- ret
-
- jmp $
- times 510-($-$$) db 0
- dw 0xaa55
- cong@msi:/work/os/code/2loader$ cat loader.S
- org 0x9000
- mov ax, cs
- mov ds, ax
- mov es, ax
- mov ss, ax
- mov ax, 0xb800
- mov gs, ax
-
- mov byte [gs:0x08], '2'
- mov byte [gs:0x09], 0xA4
-
- mov byte [gs:0x0A], 'L'
- mov byte [gs:0x0B], 0xA4
-
- mov byte [gs:0x0C], 'O'
- mov byte [gs:0x0D], 0xA4
-
- mov byte [gs:0x0E], 'A'
- mov byte [gs:0x0F], 0xA4
-
- mov byte [gs:0x10], 'D'
- mov byte [gs:0x11], 0xA4
-
- jmp $
- cong@msi:/work/os/code/2loader$ cat Makefile
- ALL: mbr loader
- mbr:
- nasm mbr.S -o mbr.bin
- loader:
- nasm loader.S -o loader.bin
- clean:
- -rm *.o mbr.bin loader.bin
- flash:
- -rm ../disk.img
- dd if=/dev/zero of=../disk.img bs=1M count=30
- dd if=./mbr.bin of=../disk.img bs=512 count=1 conv=notrunc
- dd if=./loader.bin of=../disk.img bs=512 count=10 seek=2 conv=notrunc //seek=2,跳过了(0与1)2个扇区
0--200 200-400 400-600
4. 检查一下disk.img是不是从0x400-0x600之间有数据
loader.bin的
- cong@msi:/work/os/code/2loader$ xxd ./loader.bin
- 0000000: 8cc8 8ed8 8ec0 8ed0 b800 b88e e865 c606 .............e..
- 0000010: 0800 3265 c606 0900 a465 c606 0a00 4c65 ..2e.....e....Le
- 0000020: c606 0b00 a465 c606 0c00 4f65 c606 0d00 .....e....Oe....
- 0000030: a465 c606 0e00 4165 c606 0f00 a465 c606 .e....Ae.....e..
- 0000040: 1000 4465 c606 1100 a4eb fe ..De.......
- cong@msi:/work/os/code/2loader$ xxd -seek 0x400 -l 0x200 ../disk.img ;-seek是从偏移多少开始打印,-l是打印多少字符
- 0000400: 8cc8 8ed8 8ec0 8ed0 b800 b88e e865 c606 .............e..
- 0000410: 0800 3265 c606 0900 a465 c606 0a00 4c65 ..2e.....e....Le
- 0000420: c606 0b00 a465 c606 0c00 4f65 c606 0d00 .....e....Oe....
- 0000430: a465 c606 0e00 4165 c606 0f00 a465 c606 .e....Ae.....e..
- 0000440: 1000 4465 c606 1100 a4eb fe00 0000 0000 ..De............
- 0000450: 0000 0000 0000 0000 0000 0000 0000 0000 ................
- 0000460: 0000 0000 0000 0000 0000 0000 0000 0000 ................
二.调试
2.1 只打印出了1MBR
- <bochs:2> b 0x9000
- <bochs:3> c
- (0) Breakpoint 2, 0x00009000 in ?? ()
- Next at t=156817011
- (0) [0x000000009000] 0000:9000 (unk. ctxt): add byte ptr ds:[bx+si], al ; 0000
- <bochs:4> u /10
- 00009000: ( ): add byte ptr ds:[bx+si], al ; 0000
- 00009002: ( ): add byte ptr ds:[bx+si], al ; 0000
- 00009004: ( ): add byte ptr ds:[bx+si], al ; 0000
- 00009006: ( ): add byte ptr ds:[bx+si], al ; 0000
- 00009008: ( ): add byte ptr ds:[bx+si], al ; 0000
- 0000900a: ( ): add byte ptr ds:[bx+si], al ; 0000
- 0000900c: ( ): add byte ptr ds:[bx+si], al ; 0000
- 0000900e: ( ): add byte ptr ds:[bx+si], al ; 0000
- 00009010: ( ): add byte ptr ds:[bx+si], al ; 0000
- 00009012: ( ): add byte ptr ds:[bx+si], al ; 0000
b.重启bochs调试发现从in ax, dx时,读取出来的数据都为0
- (0) [0x000000007c96] 0000:7c96 (unk. ctxt): in ax, dx ; ed
- <bochs:7> r -->r 指令打印寄存器的值
- eax: 0x00000100 256 -->执行in ax,dx之前eax=0x100
- ecx: 0x00090100 590080
- edx: 0x000001f0 496
- ebx: 0x00009000 36864
- esp: 0x0000ffd4 65492
- ebp: 0x00000000 0
- esi: 0x000e0000 917504
- edi: 0x00000001 1
- eip: 0x00007c96
- eflags 0x00000006: id vip vif ac vm rf nt IOPL=0 of df if tf sf zf af PF cf
- <bochs:8> s -->s单步与n的区别是call之后的函数s会进,n不进
- Next at t=156815985
- (0) [0x000000007c97] 0000:7c97 (unk. ctxt): mov word ptr ds:[bx], ax ; 8907
- <bochs:9> r -->r 指令打印寄存器的值
- eax: 0x00000000 0 -->执行in ax,dx后eax=0x0000,说明硬盘读操作读到的数据为0
- ecx: 0x00090100 590080
- edx: 0x000001f0 496
- ebx: 0x00009000 36864
- esp: 0x0000ffd4 65492
- ebp: 0x00000000 0
- esi: 0x000e0000 917504
- edi: 0x00000001 1
- eip: 0x00007c97
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 正确的代码打包
![](https://i-blog.csdnimg.cn/blog_migrate/f5eb4426879d9c4b4b2deb15679e0746.png)
2.3正确的运行结果
![](https://i-blog.csdnimg.cn/blog_migrate/1fe17c9d8aed557fa39cc341cc00c44b.png)