- First of all we locate the file's entry cluster through the root
directory which contains 32 bit entries of all the files.
- After that we take the entry cluster and read the sector(s) from
disk.
- Next step is to take the cluster's number and go to the FAT table
where we find the next cluster by finding the
FAT12 entry which has the same number with our cluster number.
Because we want to read the data from the
FAT12 location in memory and each FAT12 entry is 1.5 bytes long
we multiply the current cluster number by 1.5
and the resulting number we add it to the FAT12 start.
Are those steps correct ? I am afraid that i hadn't understood
correctly the usage of the FAT ! :(
1) because you are reading either bytes or words, but only need 12 bits,
you need to shift and/or mask the data to allow you to ignore the bits
belonging to the next or previous entry.
2) You need to apply the same process to the FIRST cluster of the file
as well, in order to get the data for the second, and so on. ANY lookup
in the FAT follows the same process, not just the second and subsequent
ones.
Matt
Thanks for the prompt reply Matt,
now that i have understood how things are going on i fully
understand why we have to perform shift or and operations to the
register that contains the FAT12
entry ! My mistake from the start is that i hadn't understood
correctly the part about each data cluster on disk is "linked" with an
exact address within the FAT,
also i hadn't understood the part about tying to find "location"
inside the FAT where each next cluster resides and also that the
cluster number is always
the same as the FAT entry ! Now i am very happy and i can start
writing a bootloader that actually does something useful instead of
displaying silly messages
at boot loading ! I wish to thank you all for your prompt replies
and for your time. The next time that i will post something to this
group it will be about
my kernel ! :) I have a long way to go next !
Regards,
Panos.
If you start by writing a bootloader, the next time you post it will be
about you bootloader.
You are perfectly free to write you own, but some say it is a waste of
time as it is an uninteresting and disproportionately difficult task.
There are already perfectly good bootloaders, and they all do pretty
much the same thing anyway.
Bjarni
--
INFORMATION WANTS TO BE FREE
Dear Bjarni hallo,
i know that it is a boring job to create you own bootlader but i am
doing all of these things on my spare time in order to understand the
nuts and bolts behind an
operating system instead of just using it ! This is the only reason
i am doing this. :)
Regards,
Panos.
The problem with writing a bootloader is that it has nothing to do with
understanding the nuts and bolts behind an operating system, especially with
x86/x86-64. It is most certainly a waste of time. Not to diminish your
optimism, but no matter what you do with your bootloader, it will have
precisely zero to do with what an operating system does, its architecture,
or your understanding of operating systems.
The main issue is that we still (for a little while longer, I suppose) use
antiquated, legacy boot methods in order to maintain compatibility with
operating systems that are 30 years old. All you're doing is loading a
file, setting up some preliminary cpu structures and then jumping to your
*real* operating system. That's the problem. It's an exercise in futility.
Why? Because no-one is going to use your bootloader anyway unless it rivals
the robustness of a Grub or the new Vista loader, and your bootloader will
still have nothing to do with your actual OS.
I hate to harp on it, because as an enthusiast, you *do* want to understand
these things and prove you can accomplish them, but there's *SO* much more
to do that it's foolish. You could spend all of your dev time making a
robust loader, and that, in itself, would be a project that could consume
all of your time from here to eternity. And within the next decade,
x86-based machines will most likely move to EFI, which will make all of your
work for naught anyway.
You'll learn much more by making a multiboot compliant kernel and using
Grub. Why? because you're going to be doing much more interesting and
theoretical things with the OS itself than you ever would with a utilitarian
piece of software. For instance, you're wasting time writing a FAT12
driver. That's all well and good, but this is something that's very well
understood and documented. Grub can do it already. And anyone trying out
an alternate OS already has Grub (since they most likely use linux).
I don't mean to discourage you by any means, but take it from AOD, we've all
been there and done that, and if you continue down this path, in six years
you'll still be writing the bootloader. Then come the memory map questions,
then the paging questions, then the multitasking questions, then the
privilege level questions, in infinitum.
Get a basic multiboot kernel and start writing an OS. What you're doing is
like someone building a typewriter in order to write a great novel. Buy the
typewriter and write the novel. You're not learning anything about writing
a novel by building a typewriter. Trust me, if you can construct a kernel,
you *can* write a bootloader. The question is whether you should. And the
answer is no.
-Rob Horvath
> The problem with writing a bootloader is that it has nothing to do with
> understanding the nuts and bolts behind an operating system, especially
> with x86/x86-64.
I suppose that's almost true. But not quite - by writing your own
bootloader you increase your overall knowledge of the system. Not by much,
granted.
> It is most certainly a waste of time.
Oh come on! Doesn't that all depend on your reasons for doing it?
> It's an exercise in futility. Why? Because no-one is going to use your
> bootloader anyway unless it rivals the robustness of a Grub or the new
> Vista loader,
Who cares whether anyone else uses it?
> You could spend all of your dev time making a robust loader, and that,
> in itself, would be a project that could consume all of your time from
> here to eternity.
Who cares about robustness? If you're building an operating system in
order to learn about operating systems, then you only need to boot your
own machines.
> you're wasting time writing a FAT12 driver. That's all well and good,
> but this is something that's very well understood and documented. Grub
> can do it already.
I suppose you could say the same about the entire project, then.
I wrote my own bootloader and I'm glad I did it. True, I haven't got very
much further, but that's not because I spent too much time on the
bootloader - it's because I don't have time for OS dev, full stop.
--
Ciaran Keating
Amadan Technologies Pty Ltd
I nominate this to be added to the AOD FAQ as 4.13 "Shouldn't I write a
bootloader first? (NO!)" section.
:)
Rod Pemberton
Hi to all again,
i respect all of your comments but i have to agree with the posting
of Ciaran Keating ! The reason why i have started creating a
bootloader program is because
first of all i am doing it at my spare time and second because this
is the place from where i would like to start ! I understand Rob
Horvath's opinion about not lose
to much time to work on a part of an OS which might be obsolete or
replaced in the next years but to be honest i don't have a problem
because at the end i would
have learn a lot about what makes a computer boot ! I don't loose
to much of my time creating a perfect bootloader, when i am ready with
my bootloader i will
move on to create the kernel. A point worth mentioning here is that
i will not distribute my OS to the internet because i don't expect it
to be a first class OS like
Linux or Windows it is just a small project for myself !.
Regards to all,
Panos.
Much of what you'll learn in writing a bootloader can be used in your future
OS. The standard x86 approach is to write a very minimal 16-bit OS (the
bootloader). It's main purpose is to load your OS into memory. It also may
need to provide information to the OS that can't be obtained by the OS:
memory map, video modes, etc. Frequently, this is done in assembly, but it
could be done in another language. And, then you'll write a complete 32-bit
or 64-bit OS. This can be done in assembly, or C, or C++, or (your choice
here). If the 32/64-bit OS is written in a language other than assembly, it
will usually require some assembly helper routines: special instructions,
and interrupt wrappers.
Today, many people develop their bootloader (and OS) with debuggers and
emulators such as BOCHS, QEMU, VMWARE, etc. This may help you to develop
code faster. I'm also one of the few that develops on real hardware without
an emulator (or debugger). (I have a number of reasons for this. Some
people agree, and some don't. I won't get into it...)
I didn't take the standard route of writing a 16-bit bootloader first. I am
using a special DOS TSR to transfer control to my 32-bit OS from 16-bit DOS.
I had hoped to eventually have GRUB support. GRUB can be easily installed
and there is also a command line version of GRUB for DOS. (i.e., you could
start your OS from DOS using GRUB - like my TSR...) Unfortunately, I found
that while GRUB interfaces nicely with assembly programs and can be used
with C programs using a linker script, it's not well suited to C programs
that don't use linker scripts or for multiple C compilers. Of course, I can
recycle my TSR code into a bootloader if need be...
You'll need to understand these (list below) either for the bootloader or
your OS. It's up to you to decide which of these (and many other issues)
belongs in each. My preference is for as little code as possible to go into
the bootloader - because I'm writing an OS, not a bootloader...
0) deciding what hardware your bootloader and OS will support
1) enabling the A20 line
2) reading from disk using BIOS routines
3) difference between multiple or single stage bootloader
4) determining a memory map from BIOS
5) detecting the CPU type
6) rebooting
7) setting an initial video mode
8) initializing 32-bit/64-bit protected mode to transfer to your OS
(GDT,IDT,etc)
9) setting the keyboard mode and translation
10) setting the mouse modes
11) x86 cpu modes such as v86 or "unreal mode"
12) programming the various PC IC's: RTC, DMA, PIC, PIT, speaker, FPU, IDE,
floppy, VGA, etc...
1st try the FAQ:
http://www.frontiernet.net/~fys/osd_faq/index.htm
2nd try the sites on the FAQ. Some of them have good html forum's and
documents.
3rd try Yahoo (or Google) or Google's Group to search for answers.
4th try Google's Groups Advanced Search to search alt.os.development,
alt.lang.asm, etc., to search for answers.
5th use above, to search for bootloaders or OS's similar to what you desire
and study the code.
6th post some sample code here and ask some questions.
My earlier reply wasn't directed at you or intended to discourage you.
Unfortunately, the time, effort, knowledge, hard to find knowledge,
incompatible hardware, etc., necessary to write both a bootloader and an OS
has frustrated many people, but not everyone. Horvath accurately expressed
the frustrations of a number of people. And, this is also why many suggest
using GRUB.
Good Luck! Keep in touch.
Rod Pemberton
I have to disagree here.
Firstly, if you cannot write code to set up a the GDT, switch to PM,
enable A20, etc. then you cannot write an OS, period. Given the
complexity of scanning through the PCI bus and writing device driver
loading code etc. this stuff is basic.
Writing a bootloader takes a few months, not years. Remember that you do
not need to write a multiboot loader, just one for your OS.
Secondly, if the argument is 'why waste time doing something that
someone else has done already, and better?' then why write an OS at all?
I have to say that, just in my opinion, starting out with the same basic
aims and methods as an existing OS may achieve the aim of learning about
how existing OSes work, but it achieves nothing as far as developing the
OS from it's current position. - it just makes another unfinished clone
of DOS or Linux.
Matt
> i respect all of your comments but i have to agree with the posting
> of Ciaran Keating ! The reason why i have started creating a
> bootloader program is because
> first of all i am doing it at my spare time and second because this
> is the place from where i would like to start ! I understand Rob
> Horvath's opinion about not lose
> to much time to work on a part of an OS which might be obsolete or
> replaced in the next years but to be honest i don't have a problem
> because at the end i would
> have learn a lot about what makes a computer boot ! I don't loose
> to much of my time creating a perfect bootloader, when i am ready with
> my bootloader i will
> move on to create the kernel. A point worth mentioning here is that
> i will not distribute my OS to the internet because i don't expect it
> to be a first class OS like
> Linux or Windows it is just a small project for myself !.
Well, good luck - and enjoy yourself :-)
My main problem with a bootloader is that you're essentially writing two
OSes. One 16-bit OS with real-mode drivers, using the BIOS, usually with a
different compiler and assembler that is used to then load your 32/64-bit OS
with PM drivers not using the BIOS. And once the jump occurs, pretty much
all the coding you did is tossed into the can. That's my issue. The
skillset you develop while writing the loader portion is of course very
valuable to a newcomer. I also started writing a bootloader. But I passed
on it eventually. I realized that I could learn much more by getting into
my actual operating system than I ever could by writing a utilitarian piece
of code that was shoved aside mere seconds into the boot process. Writing a
bootloader is disproportionately difficult and time consuming compared to
the overall scope of an OS.
Anyway, some people start by writing a compiler. Again, I would argue
unnecessary, but some would say it is an absolute necessity.
-Rob Horvath
> Guys, I know what I wrote was contronversial. Feel free to disagree.
Done ;-)
> Writing a bootloader is disproportionately difficult and time consuming
> compared to the overall scope of an OS.
Agreed. If it would take a year to write a usable bootloader, then I
wouldn't do it. But it only takes a few weeks, so it's not such a big deal.
> Anyway, some people start by writing a compiler. Again, I would argue
> unnecessary, but some would say it is an absolute necessity.
Interesting comment. I agree wholeheartedly that writing a compiler has
nothing to do with building an OS. And I certainly don't want to write a
compiler. (Mostly because compilers are more computer science than
software development, and computer science topics bore me fairly quickly.)
And I'm sure that it takes a lot longer to write a compiler (assuming you
want something close to a full C implementation) than to write a
bootloader. So I suppose it's all a matter of taste.
That was one of the premises behind my OS - emphasis on was - that some C
compilers have very low dependence on the host OS compared to compilers,
i.e., DOS versus Linux or Windows, etc. While it's basically true that DOS
C compilers are less dependent on the OS, using a C compiler - instead of
assembly - has presented a bunch of other problems...
120 DOS, BIOS, DPMI calls for 32-bit DOS OpenWatcom
170 DOS, BIOS, DPMI calls for DJGPP (more needed than OW for POSIX
support)
290 syscalls for Linux 2.6.17 (but only 40 for Linux v0.01)
Since I'm part way into developing my OS - which I had never intended to do
in the first place..., a few thing's are more clear to me now. First, I'm
glad I didn't do a bootloader first. I've been able to do much OS
development without it. It appears that I may have some problems getting
GRUB to work with my OS, but it didn't negatively affect the design of my OS
at the initial stages. Second, I'm irritated that I didn't do a compiler
first. Even with assembly, C compilers just aren't designed for OS
development anymore - if they ever were:
little or no control of a functions prolog and epilog
some don't support interrupt routines - requiring interrupt wrappers
bugs in the compiler libraries
poor interface between C and assembly
address mapping issues
compiler dependent on another OS' features or API's
At this point, I've concluded that not having control over the compiler
prevents me from having control over portions of my OS. Or, it interferes
with the way I'd like to design parts of my OS. I'm seriously considering
backtracking and developing some sort of compiler. I've done some work here
already, but not specifically to support my OS. I really only use a small
"safe" subset of C very heavily anyway.
Rod Pemberton
> Since I'm part way into developing my OS - which I had never intended to
> do in the first place...,
Oh, really? What did you set out to do, and how did you end up developing
an OS? (Hmm... did I ask you that before? It faintly rings a bell...)
> Even with assembly, C compilers just aren't designed for OS
> development anymore - if they ever were:
No, I don't think they ever were.
> little or no control of a functions prolog and epilog
Yeah, having to include macros called something like PROLOG and EPILOG
isn't exactly elegant!
> bugs in the compiler libraries
You're probably going to have a few of these either way ;-)
> poor interface between C and assembly
This is probably the single reason I don't use gcc, which was otherwise my
first choice. I was (grudgingly) prepared to learn that Martian assembler
syntax, but the fact that you have to present it to the compiler in a
literal string is just unbearably cumbersome.
> At this point, I've concluded that not having control over the compiler
> prevents me from having control over portions of my OS. Or, it
> interferes with the way I'd like to design parts of my OS.
Actually, now that you remind me - I had wanted to play around with
segmentation, but I couldn't find a compiler to produce 32-bit segmented
code so I gave up on that idea.
I think I'm beginning to see reasons why writing your own compiler might
be a useful step - thanks.
>
>> poor interface between C and assembly
>
> This is probably the single reason I don't use gcc, which was otherwise
> my first choice. I was (grudgingly) prepared to learn that Martian
> assembler syntax, but the fact that you have to present it to the
> compiler in a literal string is just unbearably cumbersome.
>
>
I agree totally. If I have anything real to do with assembler, I cheat
by creating a function in C that does roughly what I want, as far as
referencing the correct parameters etc. then I compile it and extract
the assembler. Dump the assembler back into the source code in an asm()
wrapper, and then modify it to do exactly what I want. This solves the
whole wrapper/pushing of parameters etc. problem.
>> At this point, I've concluded that not having control over the compiler
>> prevents me from having control over portions of my OS. Or, it
>> interferes with the way I'd like to design parts of my OS.
>
> Actually, now that you remind me - I had wanted to play around with
> segmentation, but I couldn't find a compiler to produce 32-bit segmented
> code so I gave up on that idea.
>
I had the same thought, as I wanted to protect individual objects by
creating segments for them. However, although i found a compiler which
could have been modified, I found that segmentation was being phased out
on 64 bit machines, so it seemed a bit of a waste to produce an OS
that would die along with the current generation of processors. The
compiler is described in ' a re-targetable C compiler: design and
implementation' Good book.
Matt
> I think I'm beginning to see reasons why writing your own compiler might
> be a useful step - thanks.
>
>
> --Ciaran Keating
> Amadan Technologies Pty Ltd
...
Panos, I would say if you want to write a FAT12-following bootloader
don't be discouraged from doing so. You don't sounds easily
discouraged, of course :-) Not all will want to write one but if /you/
want to the experience will give you a chance to think properly about
the bare machine's memory layout and the basic steps to getting the
main code in place, and give you a chance to test your development
environment etc before plunging in to the main task.