Page 1 of 1

Creating a loopback device to emulate a floppy

Posted: Sun Sep 02, 2012 12:07 pm
by richi18007
I was using dd command till now to emulate the floppy disk which was used to load sectors and run the OS .But today ,I wrote the code for paging and the total size of the binary (flat binary) has gone beyond 18 sectors. And I think dd command , which I was using till now to create the floppy disk image is not emulating the floppy properly . I saw it on James Ms kernel development tutorial that he used losetup and mount commands to set up the floppy image (and /dev/loop can emulate a real floppy image , so everything works fine in there I suppose. He might have created a file system on the floppy already I suppose , so everything works ).

I was using dd till now . And I don't have any file system for the binary. I wasn't using any till now either. Here is the dump of my build script

Code: Select all

rm *.o
rm *.bin
rm floppy.img
nasm -f bin -o boot.bin boot.asm 
nasm -f bin -o gdt.bin gdt.asm
nasm -f elf -o desc_flush.o desc_flush.asm 
nasm -f elf -o intr.o intr.asm
nasm -f elf -o paging_helper.o paging.asm  
gcc -c -g -Os -march=i686 -ffreestanding -Wall -Werror -fno-toplevel-reorder -I. -o pic.o pic.c 
gcc -c -g -Os -march=i686 -ffreestanding -Wall -Werror -fno-toplevel-reorder -I. -o vbr.o vbr.c
gcc -c -g -Os -march=i686 -ffreestanding -Wall -Werror -fno-toplevel-reorder -I. -o descriptors.o descriptors.c 
gcc -c -g -Os -march=i686 -ffreestanding -Wall -Werror -fno-toplevel-reorder -I. -o kernel_main.o kernel_main.c
gcc -c -g -Os -march=i686 -ffreestanding -Wall -Werror -fno-toplevel-reorder -I. -o monitor.o monitor.c
gcc -c -g -Os -march=i686 -ffreestanding -Wall -Werror -fno-toplevel-reorder -I. -o pmm.o pmm.c
gcc -c -g -Os -march=i686 -ffreestanding -Wall -Werror -fno-toplevel-reorder -I. -o paging.o paging.c
ld -static -Tlink.ld -nostdlib --nmagic -o vbr.elf vbr.o
ld -static -Tlink_kernel.ld -nostdlib --nmagic -o kernel_main.elf kernel_main.o monitor.o  desc_flush.o descriptors.o intr.o pic.o pmm.o paging.o paging_helper.o
objcopy -O binary vbr.elf vbr.bin
objcopy -O binary kernel_main.elf kernel_main.bin
dd if=/dev/zero of=floppy.img bs=512 count=2880 
dd if=boot.bin of=floppy.img bs=512 count=1 conv=notrunc 
dd if=vbr.bin of=floppy.img bs=512 count=1 conv=notrunc seek=1 
dd if=gdt.bin of=floppy.img bs=512 count=2 conv=notrunc seek=2
dd if=kernel_main.bin of=floppy.img conv=notrunc bs=512 seek=4
Also , all the files have been linked by the linked script in accordance to the dd utility (The stage 2 bootloader is at 0x600 .And it is 2 blocks in size as shown by dd command, so I loaded the kernel at 0xA00 by the linker script and jumped over to it)

Here is the output of the chain of dd commands

Code: Select all

2880+0 records in
2880+0 records out
1474560 bytes (1.5 MB) copied, 0.170441 s, 8.7 MB/s
1+0 records in
1+0 records out
512 bytes (512 B) copied, 6.0998e-05 s, 8.4 MB/s
0+1 records in
0+1 records out
446 bytes (446 B) copied, 8.2063e-05 s, 5.4 MB/s
1+1 records in
1+1 records out
978 bytes (978 B) copied, 8.3641e-05 s, 11.7 MB/s
28+1 records in
28+1 records out
14548 bytes (15 kB) copied, 0.000285953 s, 50.9 MB/s
The floppy disk so created, is it emulating a physical floppy drive correctly? Because I tried to load the first 17 sectors at 0x600 (from first track) like this :

Code: Select all

;Code to load the second sector on the disk into memory location 0x2000:0x0000
	mov bx, 0x60	; Segment location to read into (remember can't load direct to segment register)
	mov es, bx
	mov bx, 0	; Offset to read into
	mov ah, 02	; BIOS read sector function
	mov al, 0x11	; read 17 sectors on the beginning of the floppy disk 
	mov ch,	0	; Track to read
	mov cl,	02	; Sector to read
	mov dh,	0	; Head to read
	mov dl,	00	; Drive to read
	int 0x13	; Make the BIOS call (int 13h contains mainly BIOS drive functions)
	;Set up the data segment 
	jnc repeat_read_success_first 
	mov si , error_message 
	call print_string 
	jmp repeat_read 
	ret 
And then , I added 0x600 to 512*17 (0x2800) and loaded the next 18 sectors (head=1 , cylinder=0 , sector=1 ) to that location in a similar fashion . but a diassembly of 0x2800 and beyond shows that no data has been loaded .Is it something that I need to correct in reading sectors or something in the build script ?

Re: Creating a loopback device to emulate a floppy

Posted: Sun Sep 02, 2012 12:23 pm
by pikasoo
based on your post information " (head=1 , cylinder=0 , sector=1 ) " head 1 doesnt exists on a floppy, you can try track(cylinder) 1 instead...

assuming you are always booting or using a 1.44mb floppy you have 80 track and 18 sector per track and only 1 head(#0)

source: http://www.pcguide.com/ref/fdd/mediaGeometry-c.html

Re: Creating a loopback device to emulate a floppy

Posted: Sun Sep 02, 2012 1:37 pm
by Combuster
Troll can't read?

From your own source:
Since all (modern) floppy disks use both sides of the disk and therefore always have two heads

Re: Creating a loopback device to emulate a floppy

Posted: Sun Sep 02, 2012 1:46 pm
by richi18007
Only 1 head , each head with 18 tracks(cylinders) and 18 sectors per track
it's 1.44 MB , the size of the floppy disk . This way we only get 737280 bytes , which doesn't sum up.Or does it ?

I still cannot get the paging function to work. The paging function is supposed to print a lot of debug messages , but none of them gets printed. I did as you said (setting ch , cl and dh to 1 , 1 and zero respectively and still no luck . Here is the snippet that I am using to load the sectors

Code: Select all

repeat_read:	;Loads the first 17 sectors 
	;Code to load the second sector on the disk into memory location 0x2000:0x0000
	mov bx, 0x60	; Segment location to read into (remember can't load direct to segment register)
	mov es, bx        ; setting es to 0x60 , the segment we want to read the floppy block into 
	mov bx, 0	        ; Offset to read into
	mov ah, 02	; BIOS read sector function
	mov al, 0x11	; read 17 sectors on the beginning of the floppy disk 
	mov ch,	0	; Track to read
	mov cl,	02	; Sector to read
	mov dh,	0	; Head to read
	mov dl,	00	; Drive to read
	int 0x13	        ; Make the BIOS call (int 13h contains mainly BIOS drive functions)
	jnc repeat_read_success 
	jmp repeat_read 
	ret 
repeat_read_success:
	;Set the data segment.This will make a jump to the stage 2  
	mov ax , 0x60
	jmp 0x60:0x0  ; Load at address 0x600
The above function will load the first 17 sectors to the floppy disk .And the function below will load the next 16 sectors
The only values changed from the above function are the base address to load. And the cylinder and sector value

Code: Select all

repeat_read_stub:
	mov bx , 0x280 ; The first 17 sectors were loaded at 0x600.So the next sector need to be loaded at 0x600+11*200 = 0x2800 .The segment is set to 0x280 .  
	mov es , bx  
	mov bx , 0
	mov ah , 02 
	mov al , 0xF; Read 15 sectors 
	mov dl , 0
	mov cl , 0x01; Reading first sector
	mov dh , 0 ;Reading first head
	mov ch , 0x01 ;reading second cylinder
	int 0x13 
	jnc repeat_read_stub_success
	ret
	;The stub has been loaded . Return 
	mov si , repeat_failure_string 
	call print_string 
	jmp repeat_read_stub 
repeat_read_stub_success:
	mov si , repeat_read_string 
	call print_string 
	jmp repeat_read_success 
	ret 
Is there still anything I am doing wrong ?

Re: Creating a loopback device to emulate a floppy

Posted: Sun Sep 02, 2012 1:48 pm
by Combuster
but a diassembly of 0x2800 and beyond shows that no data has been loaded .Is it something that I need to correct in reading sectors or something in the build script ?
Well the 15k for such a basic kernel is quite a bit, so I expect that there's a lot of space wasted on empty tables in there. So if you happen to find just zeroes in RAM that might just exactly be what's there in the original file.

EDIT: I hope you saw my other reply before you (keep) doing something stupid.

Re: Creating a loopback device to emulate a floppy

Posted: Sun Sep 02, 2012 2:02 pm
by richi18007
The kernel has a IDTs , PIC and keyboard driver code and a lot of debug messages. Previously it was around 6k. After paging, I allocated the paging directory (4096 bytes)and one page table (4096 bytes again )and the size went up to 15k. As long as the entire kernel (with bootloader) was withing 18 sectors , everything was working fine. But after this , well , it doesn't .

I pasted the snippet .After the initializing paging , more messages should be printed , but it's not . I will try debugging it in the morning. I have a workaround , I have a physical memory manager . I can use it to allocate memory dynamically and reduce the size of the binary and thus , get the whole thing working , but it is just a workaround. Sooner or later , the kernel is going to get beyond 18 sectors .

Re: Creating a loopback device to emulate a floppy

Posted: Sun Sep 02, 2012 4:03 pm
by egos
richi18007 wrote:I was using dd command till now to emulate the floppy disk which was used to load sectors and run the OS .But today ,I wrote the code for paging and the total size of the binary (flat binary) has gone beyond 18 sectors...
What's problem? Use linear addressing. Look at my last post here for the code.

Re: Creating a loopback device to emulate a floppy

Posted: Mon Sep 03, 2012 12:40 am
by richi18007
Thank you egos . I can read the sectors correctly now.