Page 1 of 1
Creating an .img from .bin in Linux?
Posted: Sat Dec 30, 2006 8:47 am
by Scalpel
Hi, I started writing an OS in 2003, but have not worked on my code the last two years. Now I'm trying to continue where I left of. I'm using Linux.
I am able to compile my sourcecode into a kernel.bin file (1.1MB), but am having trouble converting it into an .img file I can run on VMWare.
I have an old .img file created from the same sourcecode in 2004, and am able to boot from that file using VMWare, so I know that my kernel/sourcecode is bootable. But, now I don't remember how I made that .img file. I've tried the following:
.
This creates an .img file size 1.1MB, but nothing happens when I boot it in VMWare. I see that my old .img file is exactly 1.44MB.
I see from my notes that I used to use partcopy like this:
, but have not been able to find partcopy for Linux again.
Any pointers? What am I forgetting?
Posted: Sat Dec 30, 2006 10:17 am
by Brynet-Inc
Looks like your trying to boot your kernel without a boot loader...
Kinda strange that your kernel is so large for a hobby kernel..
What file system does your boot disk use?
Does your boot loader load kernel.bin from a file system? or directly?
Not sure what else to say
...
Mounting that old image via a loopback device and copying the new kernel onto it might work.. bit shocked you actually attempted to
boot the kernel directly..
Posted: Sat Dec 30, 2006 3:40 pm
by gaf
That line just copies your disk image to a floppy (-f0) starting at sector 0 and going on until sector 0x168000 (1.40 MiB) is reached. As far as I know there's no port of partcopy for linux. Luckily dd can be used to do pretty much the same thing:
Code: Select all
dd if=disk.img of=/dev/fd0 bs=512 seek=0 count=2880 or simply
dd if=disk.img of=/dev/fd0
Brynet is right when he says that your kernel is way bigger than expected. Maybe your make-file already built an image. Could you post the commands you use to create your kernel ?
scalpel wrote:Any pointers? What am I forgetting?
Probably you're missing the bootsector. You don't happen to remember which one you originally used for your system (Grub, John Fine, Alexei Frounze, etc) ?
regards,
gaf
Posted: Sun Dec 31, 2006 8:48 am
by Scalpel
gaf wrote:Brynet is right when he says that your kernel is way bigger than expected. Maybe your make-file already built an image. Could you post the commands you use to create your kernel ?
Probably you're missing the bootsector. You don't happen to remember which one you originally used for your system (Grub, John Fine, Alexei Frounze, etc) ?
Here is my entire Makefile:
Code: Select all
KERNEL = kernel.bin
CC = gcc
CCFLAGS = -c -ffreestanding -fasm -O2 -I./includes
NASM = nasm
NASMFLAGS = -f aout
LINKER = ld
LINKERFLAGS = -T ./linking/kernel.lnk -o $(KERNEL)
LIBC-DIR = ./sources/libc
X86_H-DIR = $(LIBC-DIR)/x86.h
CTYPE_H-DIR = $(LIBC-DIR)/ctype.h
IO_H-DIR = $(LIBC-DIR)/io.h
STRINGS_H-DIR = $(LIBC-DIR)/strings.h
SYSTEM-DIR = ./sources/system
FILESYSTEM-DIR = $(SYSTEM-DIR)/filesystem
VIDEO-DIR = $(SYSTEM-DIR)/video
TEST-DIR = ./sources/test
MEM-DIR = ./sources/mem
#LIBASM-DIR = ./sources/libasm
KERNEL-DIR = ./sources/kernel
OBJECTS-DIR = ./objects
SOURCES-DIR = ./sources
OBJECTS=$(KERNEL-DIR)/asmkernel.o $(KERNEL-DIR)/kernel.o $(IO_H-DIR)/clrscr.o \
$(IO_H-DIR)/set_cursor.o ${STRINGS_H-DIR}/strlen.o $(STRINGS_H-DIR)/strcmp.o $(X86_H-DIR)/freeze.o \
$(IO_H-DIR)/iprint.o $(IO_H-DIR)/sprintf.o $(STRINGS_H-DIR)/convert_int_to_string.o $(X86_H-DIR)/getcpufamily.o $(X86_H-DIR)/sleep.o \
$(CTYPE_H-DIR)/atof.o $(IO_H-DIR)/printf.o $(IO_H-DIR)/putch.o $(MEM-DIR)/get_ram.o $(STRINGS_H-DIR)/reverse.o $(IO_H-DIR)/outb.o \
$(FILESYSTEM-DIR)/floppy.o $(FILESYSTEM-DIR)/init.o $(VIDEO-DIR)/init.o $(SYSTEM-DIR)/init.o $(SYSTEM-DIR)/time.o $(CTYPE_H-DIR)/ctype.o $(TEST-DIR)/init.o
all: $(KERNEL)
clean:
rm $(OBJECTS) -f
rm $(KERNEL) -f
#compile assembler files
%.o : %.asm
$(NASM) $(NASMFLAGS) -o $@ $<
#compile all C files
%.o : %.c
$(CC) $(CCFLAGS) -o $@ $<
#link objectfiles
$(KERNEL): $(OBJECTS)
$(LINKER) $(LINKERFLAGS) $(OBJECTS)
I have John Fines bootf02 in a directory here, so I guess I've used it somehow?
Posted: Sun Dec 31, 2006 8:56 am
by Scalpel
The first thing my Makefile does is to run
Code: Select all
nasm -f aout -o sources/kernel/asmkernel.o sources/kernel/asmkernel.asm
And here is my asmkernel.asm file. Could this be the boot sector part?
Code: Select all
[bits 32] ;activates 32 bit/protected mode
[global start]
; Registers Value Getting Functions For The C++ Kernel:
[global geteax]
[extern main]
start:
call main
jmp $ ; halt
; For dumping the registers
geteax: ; unsigned long geteax();
ret
Wow, I realize now that I need to add a lot more comments to my files! I'm having a hard time reading my own code...
Posted: Sun Dec 31, 2006 9:47 am
by gaf
And here is my asmkernel.asm file. Could this be the boot sector part?
Nope, that's the entrypoint of your kernel. Once John Fine's bootsector has finished doing the dirty work (a20 gate, pmode and paging) for you it passes control to this piece of code. It's probably the best to just stick with John Fine's loader for the moment. If you still have an old image you could just try to mount it:
sudo losetup /dev/loop0 /home/user/old_kernel.img
sudo mount -t msdos /dev/loop0 /mnt/image
The content of the image should now be available in /mnt/image. To update your kernel just overwrite the old executable:
sudo cp kernel.bin /mnt/image/
sync
The reason why your executable is that big is probably that the C library gets linked to it. This is actually quite pointless as your kernel can't use a standard library that was made for linux. You might thus want to disable it by adding -nostdlib to your makefile:
CCFLAGS = -c -ffreestanding -nostdlib -nostdinc -fno-rtti -fno-exceptions -nostartfiles -fasm -O2 -I./includes
regrads,.
gaf
Posted: Mon Jan 01, 2007 5:59 pm
by Scalpel
gaf, thanks for you reply, but I changed my CCFLAGS line as you suggested, but the kernel.bin file is still being created as 1.1MB. I had to remove the -fno-rtti as gcc complained that the parameter is only valid for C++, while my kernel is C.
I also mounted the old image as you suggested, but replacing the old kernel.bin (4,6Kb) with my newer one (1,1MB) using the losetup/mount trick made the .img unbootable.
Let me take a step back. I'm developing on a virtual (VMWare) Linux machine, and would like my 'make all' command to end up in a .img file I can use on a second virtual VMWare machine. I've been reading a lot of the tutorials and documentation on Bona Fide and OSCR, but have trouble finding some hints as to do this. My machine is a laptop, so I do not have access to a physical floppy drive. When I worked on my code in 2003 I had access to floppy, and that made things a lot easier actually.
I think I need some pointers here. What is the best way to be able to test my OS on a VMWare machine?
Posted: Mon Jan 01, 2007 7:11 pm
by Scalpel
Scalpel wrote:gaf, thanks for you reply, but I changed my CCFLAGS line as you suggested, but the kernel.bin file is still being created as 1.1MB.
I managed to get my kernel down to the correct size by changing my linker script. I noticed that I had a file called linker/kernel.lnk.old, and when I used that the size of my kernel.bin came down to a few K, and I am able to boot it now using the losetup/mount trick.
Here is the kernel.lnk which made my kernel 1.1MB:
Code: Select all
OUTPUT_FORMAT("binary")
ENTRY(start)
SECTIONS
{
. = 0x00100000;
.text :
{
_stext = .;
*(.text);
*(.rodata)
_etext = .;
}
.data ALIGN (0x1000) :
{
_sdata = .;
*(.data)
_edata = .;
}
.bss ALIGN (0x1000) :
{
_sbss = .;
*(COMMON)
*(.bss)
_ebss = .;
}
}
and here is my old kernel.lnk file, which makes my kernel about 4Kb:
Code: Select all
OUTPUT_FORMAT("binary")
ENTRY(start)
SECTIONS
{
.text 0x00100000 :
{
*(.text)
}
.rodata ADDR(.text)+SIZEOF(.text) :
{
*(.rodata)
}
.data :
{
*(.data)
}
.bss :
{
*(.bss)
}
}
Are there any obvious reason in the first file that would make the kernel so big??
Posted: Mon Jan 01, 2007 8:17 pm
by TheQuux
my guess is that the . = 0x00100000 set the output position, while
.text 0x00100000 :
set the code address but not the output address...