OS development beginner
OS development beginner
Hello
I am working with Red Hat Linux 7.2 and i am just beginning to experiment with OS development.
Here are the steps that i have taken.
1) Create a very small assembly file myos.s which contains the following lines:
( I know that this code will not do anything useful, but i just want to see if i can get this code loaded into memory.)
BOOTSEG = 0X07C0
INITSEG = 0X90000
.code16
.text
.global _start
_start:
movw $BOOTSEG, %ax
movw %ax,%ds
movw $INITSEG, %ax
movw %ax, %es
movw $256, %cx
2) assemble myos.s with the following line:
as -o myos.o myos.s
3) link object file myos.o with the following line:
ld -Ttext 0x0 -s --oformat binary -o myos myos.o
4) I move the file myos to the directory /boot
5) In the /boot/grub directory i edit the grub.conf file and add the following lines:
title MyOS
root (hd0,0)
kernel /myos
6) Then I reboot the system, and select MyOS to be loaded.
After selecting MyOS i get the following message:
Booting 'MyOS'
root (hd0,0)
Filesystem type is ext2fs, partition type 0x83
kernel /myos
Error 13: Invalid or unsupported executable format
Press any key to continue...
My question is how do i get a small nugget of code loaded into memory and executed (even if does nothing useful).
Thank You
Michael Morrison
I am working with Red Hat Linux 7.2 and i am just beginning to experiment with OS development.
Here are the steps that i have taken.
1) Create a very small assembly file myos.s which contains the following lines:
( I know that this code will not do anything useful, but i just want to see if i can get this code loaded into memory.)
BOOTSEG = 0X07C0
INITSEG = 0X90000
.code16
.text
.global _start
_start:
movw $BOOTSEG, %ax
movw %ax,%ds
movw $INITSEG, %ax
movw %ax, %es
movw $256, %cx
2) assemble myos.s with the following line:
as -o myos.o myos.s
3) link object file myos.o with the following line:
ld -Ttext 0x0 -s --oformat binary -o myos myos.o
4) I move the file myos to the directory /boot
5) In the /boot/grub directory i edit the grub.conf file and add the following lines:
title MyOS
root (hd0,0)
kernel /myos
6) Then I reboot the system, and select MyOS to be loaded.
After selecting MyOS i get the following message:
Booting 'MyOS'
root (hd0,0)
Filesystem type is ext2fs, partition type 0x83
kernel /myos
Error 13: Invalid or unsupported executable format
Press any key to continue...
My question is how do i get a small nugget of code loaded into memory and executed (even if does nothing useful).
Thank You
Michael Morrison
RE:OS development beginner
Write your resultant binary to a floppy:
dd if=myOS of=/dev/fd0 bs=512 count=1
And reboot with your floppy in the drive.
You can use GRUB, however, I'm not familiar with it. I'm guessing GRUB is complaining because it's looking at your myOS file, and can't tell what type of format it is, so you must, either, force GRUB to detect it as a flat binary (ie, format-less), or add in the proper formatting necessary for GRUB to recognize it as one of its supported formats (eg. elf)
Jeff
dd if=myOS of=/dev/fd0 bs=512 count=1
And reboot with your floppy in the drive.
You can use GRUB, however, I'm not familiar with it. I'm guessing GRUB is complaining because it's looking at your myOS file, and can't tell what type of format it is, so you must, either, force GRUB to detect it as a flat binary (ie, format-less), or add in the proper formatting necessary for GRUB to recognize it as one of its supported formats (eg. elf)
Jeff
RE:OS development beginner
CarbonBased wrote:
>Write your resultant binary to a floppy:
>
>dd if=myOS of=/dev/fd0 bs=512 count=1
>
>And reboot with your floppy in the drive.
Unfortunately, this won't work; gas only produces 32-bit p-mode object code. Part of the advantage of using GRUB is that it handles the switch to p-mode before loading your kernel image.
>Write your resultant binary to a floppy:
>
>dd if=myOS of=/dev/fd0 bs=512 count=1
>
>And reboot with your floppy in the drive.
Unfortunately, this won't work; gas only produces 32-bit p-mode object code. Part of the advantage of using GRUB is that it handles the switch to p-mode before loading your kernel image.
RE:OS development beginner
The problem is in that you are using a binary file, when GRUB expects an ELF file by default AFIACT. Next, you are telling it to look for the image in the root directory, when it is actually in the /boot directory. You are also not indicating where the boot loader should go, but the code assumes it will be in 0x7C00 - one of the few places it *can't* be loaded to AFIAK, since GRUB's stage one code is already there. Finally, you did not include a MultiBoot header at the beginning of your code.
There seems to be some misunderstanding about how GRUB works (not surprising, as the docs are rather confusing). Since GRUB is itself a bootloader, you don't need one of your own. It is meant to load your kernel for you, already in set up into p-mode. You don't need to do any more pre-kernel setup; it starts directly at the beginning of your kernel.
This means that a) you don't have to start you code at 0x7C00, but you *do* have to tell GRUB where you want the kernel loaded; and b) since it is already in p-mode, you can only change the segment settings by altering the GDT, which you also have to provide to GRUB at initialization anyway.
GRUB is highly configurable, but only within those parameters it was designed for - namely, the MultiBoot design. In most configurations, it loads a conventional executable file (either ELF or a.out formats) from a conventional file system (the current list of those it supports are: BSD FFS, DOS FAT16 and FAT32, Minix fs, Linux ext2fs, ReiserFS, JFS, XFS, and VSTa fs). AFAICT, it will not load a flat binary file directly, as it needs the symbol table information for on-the-fly linking. You could use the chainloading option, but that is only meant as a way of supporting non-multiboot OSes like Windows, by calling their existing bootloaders; to do that here defeats the purpose of using GRUB at all.
I strongly recommend you review the GRUB documentation, and the MultiBoot specification. You may want to experiment with GRUB in interactive mode before putting setting your loader data into grub.conf, as it may take a bit of tweaking to get the configuration right.
Corrections of any errors or misunderstandings I've made are welcome. Fnord more information, see some of the pages below (or consult your pineal gland).
The GRUB Manual
http://www.omoikane.co.jp/i/info/html/g ... b_toc.html
The MultiBoot Specification v. 0.07
http://www.mcc.ac.uk/grub/multiboot.html
"MultiBooting with GRUB HOW-TO"
http://www.tldp.org/HOWTO/mini/Multiboot-with-GRUB.html
the GNU GRUB documentation page
http://www.gnu.org/software/grub/
A GRUB Tutorial
http://www.washingdishes.freeuk.com/grubtut.html
"Getting to Know GRUB", a detailed free tutorial from IBM (you have to register on the Devworks site, though)
http://www-105.ibm.com/developerworks/e ... enDocument
There seems to be some misunderstanding about how GRUB works (not surprising, as the docs are rather confusing). Since GRUB is itself a bootloader, you don't need one of your own. It is meant to load your kernel for you, already in set up into p-mode. You don't need to do any more pre-kernel setup; it starts directly at the beginning of your kernel.
This means that a) you don't have to start you code at 0x7C00, but you *do* have to tell GRUB where you want the kernel loaded; and b) since it is already in p-mode, you can only change the segment settings by altering the GDT, which you also have to provide to GRUB at initialization anyway.
GRUB is highly configurable, but only within those parameters it was designed for - namely, the MultiBoot design. In most configurations, it loads a conventional executable file (either ELF or a.out formats) from a conventional file system (the current list of those it supports are: BSD FFS, DOS FAT16 and FAT32, Minix fs, Linux ext2fs, ReiserFS, JFS, XFS, and VSTa fs). AFAICT, it will not load a flat binary file directly, as it needs the symbol table information for on-the-fly linking. You could use the chainloading option, but that is only meant as a way of supporting non-multiboot OSes like Windows, by calling their existing bootloaders; to do that here defeats the purpose of using GRUB at all.
I strongly recommend you review the GRUB documentation, and the MultiBoot specification. You may want to experiment with GRUB in interactive mode before putting setting your loader data into grub.conf, as it may take a bit of tweaking to get the configuration right.
Corrections of any errors or misunderstandings I've made are welcome. Fnord more information, see some of the pages below (or consult your pineal gland).
The GRUB Manual
http://www.omoikane.co.jp/i/info/html/g ... b_toc.html
The MultiBoot Specification v. 0.07
http://www.mcc.ac.uk/grub/multiboot.html
"MultiBooting with GRUB HOW-TO"
http://www.tldp.org/HOWTO/mini/Multiboot-with-GRUB.html
the GNU GRUB documentation page
http://www.gnu.org/software/grub/
A GRUB Tutorial
http://www.washingdishes.freeuk.com/grubtut.html
"Getting to Know GRUB", a detailed free tutorial from IBM (you have to register on the Devworks site, though)
http://www-105.ibm.com/developerworks/e ... enDocument
RE:OS development beginner
Gas for dos/djgpp only produces 32-bit object code, but what about gas for Linux? Part of the Linux boot-loader is written in gas, is it not?
Why have the .code16 directive if it isn't even supported? Strange. Everybody should just use nasm
If you assembled using nasm, though, the code would work if simply written to the boot sector of a floppy using dd. It already assumes 0x7c00 as the physical address.
I just figured this'd be the easiest way to get his code in memory (the original question). The code is real mode code in the first place (.code16), so you wouldn't want to use grub (which would load the code in pmode, as you said).
Jeff
Why have the .code16 directive if it isn't even supported? Strange. Everybody should just use nasm
If you assembled using nasm, though, the code would work if simply written to the boot sector of a floppy using dd. It already assumes 0x7c00 as the physical address.
I just figured this'd be the easiest way to get his code in memory (the original question). The code is real mode code in the first place (.code16), so you wouldn't want to use grub (which would load the code in pmode, as you said).
Jeff
RE:OS development beginner
OK, apparently, my information is quite out of date, then. I know that, at least in the past, Linux boot sectors were (and for all I know, still are) assembled using a special assembler called either as86 or ld86, depending on the version. I hadn't known about the .code16 directive in gas until you mentioned it, and had to look it up to be sure it did exist. I'd been under the impression that gas didn't support 16-bit code at all. Since I use NASM myself (though I may play around with an assembler of my own at some point), I never put much though to the matter.
RE:OS development beginner
thanks for the advice guys. carbonBased's solution was the simple solution that i was searching for and produced the desired results(which was nothing). Also thank you to Schol-R-LEA, i need to read through your responses once more to fully understand your advice (it is a little above me, i really a novice with this stuff). But thanks again.
RE:OS development beginner
If you want a simple step-by-step run through writing your own Bootloader (so that you don't have to rely on GRUB), you can download the Bootloader Development Walkthrough from my site (www.electrichamster.net/Lucie). It's not entirely finished yet but it should see you through to a point where you are quite confident and able to continue on your own.
RE:OS development beginner
Perhaps what is needed is a GRUB walkthrough. I think that will be my next project, once I've gotten LoIS done...