diff --git a/Makefile.end b/Makefile.end new file mode 100644 index 000000000..39218ff08 --- /dev/null +++ b/Makefile.end @@ -0,0 +1,14 @@ +# +# GRUB Makefile ending stub, to be automatically added to the end of the +# part created by configure. +# + +PROGS= stage1 ffs_stage1_5 stage2 stage2_debug + +all: + @for X in $(PROGS) ; do (cd $$X ; $(MAKE)) ; done + +clean: + @for X in $(PROGS) ; do (cd $$X ; $(MAKE) clean) ; done + rm -f config.log + diff --git a/README b/README new file mode 100644 index 000000000..3067bdb07 --- /dev/null +++ b/README @@ -0,0 +1,69 @@ + + + GRUB -- GRand Unified Boot-loader + + version 0.5 + + by Erich Boleyn + + +Introduction + + This is the public release of GRUB version 0.5, a bootloader for + PC-compatible machines. + + +Installation + + Precompiled versions are included in the "bin" directory: + + bin/ + stage1 This is the 512-byte stage1 which reads + in the rest of GRUB at boot-time. + ffs_stage1_5 This is an example for how to build a + "stage 1.5" to automatically load a stage2 + from the filesystem. + stage2 This is the main part of GRUB. + stage2_debug Same as "stage2", but compiled with the + debug features enabled. + + Instructions for installing can be found in "docs/install.html". + + +Building From Source + + To build GRUB from source, first run the bourne-shell script "configure" + (options can be found by running "./configure --help"). It will complain + of missing or bad tools determined by it's tests. If it completes + successfully, then just type "make". + + Note that the binary names correspond to subdirectories in the top level + of the distribution. See the makefiles in there for details on where + the source files are drawn from, but in general, the "stage1" only uses + the "stage1.S" file, and the others use source files from the "shared_src" + subdirectory. + + IMPORTANT SIZE LIMITS: + + - For the various stage2's, if they are being loaded from a block-list + in the stage1, then be sure your blocklist is big enough. The + automated install will generally do this for you, it's just when + dropping it on a raw floppy, you get the default compiled in, which + is 512 * 80 disk sectors, or 40960 bytes. + + - For the FFS stage1.5, if you want to fit into the "bootloader" area + of an FFS partition, it cannot be larger than 512 * 14 disk sectors, + or 7168 bytes. + + +Other Documentation + + Pretty much all of the documentation and other helpful information is + in the "docs" directory mostly as HTML files, the root of which is + "index.html". + + The FAQ and Installation instructions really need to be updated and + improved! + + The TODO and NEWS files are always up-to-date. + diff --git a/configure b/configure new file mode 100644 index 000000000..328672ba1 --- /dev/null +++ b/configure @@ -0,0 +1,379 @@ +#!/bin/sh + +# +# My mini-configure, used only for: +# +# (1) Setting compiler tool names +# (2) Determining assembly-level munging of C symbols +# (3) Setting defines for the makefiles in a simple manner +# +# Tried to be somewhat compatible with the autoconf configure. +# I hope this doesn't confuse people. +# +# In a subsequent release, I'll probably integrate these tests into +# autoconf and just use that. +# + +# +# Starting definitions for variables +target= +silent=no +tool_vars="CC LD OBJCOPY" +tool_names="gcc ld objcopy" +tool_targeted="yes yes yes" +link_addrs="8000 2000 7C00" +path_parts=`echo ${PATH} | sed -e s/:/\ /g` + +# +# This part is very much taken from autoconf-2.10 +# +# Checking for options +# + +ac_prev= +for ac_option +do + + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval "$ac_prev=\$ac_option" + ac_prev= + continue + fi + + case "$ac_option" in + -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; + *) ac_optarg= ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case "$ac_option" in + + -help | --help | --hel | --he) + cat << EOF +Usage: configure [options] [target] +General Options: + --help print this message + --quiet, --silent do not print \`checking...' messages + --version print the fact that this isn't autoconf ;-) +Target Options: + --target=TARGET use \`TARGET' as a prefix to all of the tool names +EOF + exit 0 ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target="$ac_optarg" ;; + + -version | --version | --versio | --versi | --vers) + echo "mini-configure written by Erich Boleyn with parts from autoconf-2.10" + exit 0 ;; + + *) + echo "Warning: unrecognized configure option: \"$ac_option\"" ;; + + esac +done + +# +# Utility functions +# + +get_substr() +{ + local get_local + get_local=$(($2+2)) + eval $1=\$$get_local +} + +count_substrs() +{ + local count_local + eval $1=-1 + for count_local in $@ ; do + eval $1=\$\(\(\$$1+1\)\) + done +} + +tool_failed() +{ + cat << EOF >> ../config.log + +Tool \`$@' either failed tests or cannot be found. +EOF + cat << EOF + + +FATAL ERROR in configuration !! + +Tool \`$@' either failed tests or cannot be found. Please make sure +that some standard local compiler, \`grep', \`sed', GNU \`gcc', and +the complete GNU binutils version 2.8.1 or beyond are installed. The first +2 are used for automatic configuration, and the rest are required for +building GRUB. The file \`config.log' contains the debugging output of +this run, and the subdirectory \`.conf_test_dir' contains the files and +programs produced. +EOF + exit 0 +} + +check_exit_status() +{ + exit_status=$? + if [ $exit_status -ne 0 ]; then + echo "Command failed with exit status $exit_status" >> ../config.log + tool_failed $@ + fi +} + +findtool() +{ + local tool pathstr fail + echo -n "Looking for tool \`$1' ... " >> ../config.log + tool= + case "$1" in + /*) + if [ ! -e "$1" ]; then + tool_failed $1 + fi + tool=$1 + ;; + *) + for pathstr in $path_parts ; do + if [ -e "$pathstr/$1" ]; then + tool="$pathstr/$1" + fi + done + if [ "$tool" = "" ]; then + tool_failed $1 + fi + ;; + esac + echo "found as \`$tool'" >> ../config.log +} + +find_symbol_munge() +{ + local munge_local i tmpvar + + munge_local=`grep \.globl $2 | grep $1` + count_substrs i $munge_local + + if [ $i -ne 2 ]; then + tool_failed ${CC} + fi + + munge_local=`echo $munge_local | sed -e s/\\.globl// | sed -e s/$1/\ x\ /` + count_substrs i $munge_local + + get_substr tmpvar 1 $munge_local + eval munge_$1=$tmpvar + + if [ $i -eq 2 ]; then + get_substr tmpvar 2 $munge_local + eval munge_$1="\"\$munge_$1 \\#\\# $tmpvar\"" + fi + + if [ $i -eq 3 ]; then + get_substr tmpvar 3 $munge_local + eval munge_$1="\"\$munge_$1 \\#\\# $tmpvar\"" + fi +} + + +# Cleanup from previous incomplete tests +if [ -d .conf_test_dir ]; then + rm -rf .conf_test_dir +fi + +# Clear configuration log +if [ -e config.log ]; then + rm -rf config.log +fi + +mkdir .conf_test_dir +cd .conf_test_dir + +# +# Find tools +# + +if [ "$silent" != "yes" ]; then + echo -n "checking for build tools... " +fi + +# Initialize numbering +i=0 + +for tool_var in $tool_vars ; do + i=$(($i+1)) + get_substr tool_name $i ${tool_names} + eval tmpvar=\$\{$tool_var\} + if [ "$tmpvar" = "" ]; then + get_substr tmpvar $i ${tool_targeted} + if [ "$target" != "" -a "$tmpvar" = "yes" ]; then + tool_name=$target$tool_name + fi + eval export $tool_var=$tool_name + fi + + eval findtool \$\{$tool_var\} + + if [ "$silent" != "yes" ]; then + echo -n "$tool_var " + fi +done + +if [ "$silent" != "yes" ]; then + echo +fi + +# +# Create test C source file to determine how symbols are munged +# + +if [ "$silent" != "yes" ]; then + echo -n "checking C symbol munging in output of ${CC} ... " +fi + +cat << EOF > test_sym.c + +int +func1(int *list) +{ + list[1] = 0; + + return list[0]; +} + +double +func2(double a, int *list) +{ + list[0] = ((int) a) + list[1]; + + return a; +} + +EOF + +echo "Compiling test_sym.c to assembly with ${CC}" >> ../config.log +${CC} -S test_sym.c >> ../config.log 2>&1 +check_exit_status ${CC} + +# Perform actual test(s) here + +find_symbol_munge func1 test_sym.s +find_symbol_munge func2 test_sym.s + +# if they are not equal, this simple compiling scheme will fail! + +echo "C symbol amalgam macros (using \"x\" as base, and must match):" >> ../config.log +echo " \"$munge_func1\" and \"$munge_func2\"" >> ../config.log + +if [ "$munge_func1" != "$munge_func2" ]; then + tool_failed ${CC} +fi + +if [ "$silent" != "yes" ]; then + echo done +fi + +# +# Create test C source file to determine if our version of objcopy +# is buggy +# + +if [ "$silent" != "yes" ]; then + echo -n "checking to see if ${OBJCOPY} is buggy... " +fi + +cat << EOF > test_objcopy.c + +void +blah(void) +{ + *((int *) 1000) = 2; +} + +EOF + +echo "Compiling test_objcopy.c with ${CC}" >> ../config.log +${CC} -nostdinc -c test_objcopy.c >> ../config.log 2>&1 +check_exit_status ${CC} + +# Perform actual test(s) here + +for link_addr in $link_addrs ; do + echo "Linking test_objcopy.o with ${LD} at $link_addr" >> ../config.log + ${LD} -N -Ttext $link_addr test_objcopy.o -o test_objcopy >> ../config.log 2>&1 + check_exit_status ${LD} + ${OBJCOPY} -O binary test_objcopy testout >> ../config.log 2>&1 + check_exit_status ${OBJCOPY} + + if [ -r testout.old ]; then + cmp testout testout.old >> ../config.log 2>&1 + check_exit_status ${OBJCOPY} + fi + mv testout testout.old +done + +if [ "$silent" != "yes" ]; then + echo done +fi + +# +# Write out results +# + +cd .. + +if [ ! -d bin ]; then + mkdir bin +fi + +# +# Write config file +# + +if [ "$silent" != "yes" ]; then + echo -n "creating \`Makefile'... " +fi + +cat << EOF > Makefile +# +# This stub \`Makefile' was created automatically by configure. +# (BEGINNING OF AUTOMATICALLY GENERATED PORTION) + +EOF + +for tool_var in $tool_vars ; do + eval echo \"export $tool_var = \$\{$tool_var\}\" >> Makefile +done + +cat << EOF >> Makefile +export SHARED_FLAGS = -pipe -fno-builtin -nostdinc -O2 -DEXT_C\(x\)="$munge_func1" + +# (END OF AUTOMATICALLY GENERATED PORTION) +# + +EOF + +cat Makefile.end >> Makefile + +if [ "$silent" != "yes" ]; then + echo done +fi + +# +# Delete test directory +# + +rm -rf .conf_test_dir + + diff --git a/docs/BUGS b/docs/BUGS new file mode 100644 index 000000000..e384f209c --- /dev/null +++ b/docs/BUGS @@ -0,0 +1,31 @@ + +Known problems/bugs: + + - FreeBSD boot command-line options are slightly problematic, and + OpenBSD options are probably quite wrong. This is because they + use options that are bits in a data word passed at boot time, and + the developers change the encoding sometimes. Will re-sync in a later + release. + + - Password feature in the config file is a bit primitive, and needs + fleshing out/design work to make more intuitive. + + - If an "uppermem=" command was used to tell GRUB it had a different + amount of upper memory available, then the user escapes to the menu + interface, the upper memory displayed there still says the amount + set by the user instead of being reset to the default by the escape. + It actually resets when the next command-line is entered or config + file entry is executed. + + - There is at least one problem when using an "install_partition" that is + a BSD sub-partition where the PC partition isn't explicit (i.e. + the default 0xFF00FF is a problem)... this is when using "makeactive" + without explicitly setting the root partition. If this is done, a + "no such partition" error will be generated. + + - Cannot boot FreeBSD "kzip"ed image. Use a normal kernel (using GRUB's + automatic "gzip" decompression works fine). + + - Hitting Ctrl-Alt-Delete when in GRUB locks some machines. Use Reset + for now. (This apparently hasn't been observed for a while) + diff --git a/docs/COPYING b/docs/COPYING new file mode 100644 index 000000000..a43ea2126 --- /dev/null +++ b/docs/COPYING @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 675 Mass Ave, Cambridge, MA 02139, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/docs/NEWS b/docs/NEWS new file mode 100644 index 000000000..672367df8 --- /dev/null +++ b/docs/NEWS @@ -0,0 +1,213 @@ + +Version 0.5: + + - Improved error messages in the stage1 to be strings (easier + to read than the previous case of single characters), and + removed any display in the case of no error (less confusing). + + - New document describing error conditions and messages. + + - Improved configure/build process. + + - Made the early bootup interrupt-safe. Wasn't doing cli/sti when + necessary sometimes. + + - It now shuts off the floppy before transferring control to any other + programs/modules/loaders. (chain-loading doesn't matter here, + just loading 32-bit modules/kernels) + + - Fixed a few stupid bugs, including a several in the ext2fs code. + + - Linux boot format support extended from just "zImage" to include + "bzImage" and initial ramdisk (also called "initrd") support for + both. "initrd" support is untested, but the critical parts were + taken from a supplied patch and seem OK. + + - Several new command features. See the command-listing for details. + +Version 0.4: + + - GRUB now correctly points ES:SI at a partition descriptor when + chain-loading. + + - Many minor bugs fixed (some in the build scripts). + + - Intel MPS 1.4 config/check code is totally new, and the "syscmd=" + command is completely removed. Check command-listing for details. + +Version 0.4-pre -- (pre-release for public testing): + + - Reorganized docs, moved most "NOTE" items to a FAQ (with new + entries as well). + + - Now supports automatic decompression of any files loaded via the + GRUB stage2 filesystem code. Simply compress the file using GNU + gzip normally, then when loading, the GRUB internals will see the + contents in the decompressed state... i.e. all GRUB functions operate + normally as if it is the uncompressed file. An extra version of the + "module" loading function has been added which disables this + functionality if desired (in all the other cases, not decompressing + doesn't make sense). + + - Changed device strings used in filesystem code to more logical + format. Added "relative" disk and partition capability, see + command-listing and filesystem syntax description for details. + + - "install=" command vastly improved. Also moved to non-debug area. + Check command-listing and install documentation for details. + + - Added several new commands: "rootnoverify=", "uppermem=", and a + new debug command "displaymem". Check command-listing for details. + + - Added versioning numbers (and subsequently broke compatibility with + some of the previous code, so GRUB should be re-installed!). + + - Added unattended booting support via new "fallback=" command. + + - During debug probe of SMP configuration table compatible with Intel + MPS 1.4 standard, GRUB now checks for a pointer in the EBDA. + + - Using a "default=" entry greater than 11 caused the UI to do funny + things (it didn't pre-scroll the list to the appropriate place). + + - Reading files on FAT floppies had yet more problems related by many + users of version 0.3 6/17/96. Again, all known problems fixed. + + - "Extended" partitions now work (still cannot make an extended partition + active with "makeactive" command). + + - The build environment is greatly simplified, now using an autoconf-like + "configure" script. + +Version 0.3 dated 6/17/96 -- public "beta" release: + + - Yet more documentation improvements. + + - Known bugs in floppy operation fixed (12-bit FAT didn't work for most + cases, and inserting other floppies didn't flush the filesystem cache). + + - NASTY uninitialized pointer bug causing "raw" floppy operation to crash + on several PCs is now fixed. This seems to have been the root cause of + all of the compatibility problems that have currently been observed. + + - debug-mode command added to automate most difficult step of installation + for common cases (new install method #4). + + - Testing "mini-debugger" now merged with command-line when "DEBUG" + defined in compile (no SYSDEBUG option anymore). See description of + commands in the command-line for details. + +Version 0.3 dated 6/2/96 -- first public "alpha" release: + + - Completed initial licenses. + + - Initial filesystem documentation written. + + - Block-list and FAT filesystems now work as documented (in particular, + for the blocklist filesystem, shortcuts like "+1" for "0+1,512" now + work correctly). + + - Fixed several problems (old and new) in the various filesystems + (for example, the ext2fs filesystem code is now much faster, as it + caches some mapping blocks where it didn't at all before). Filesystem + semantics are much more uniform as well (symbolic links and reading + a directory as a file now return errors where it would silently fail + before). + + - "makeactive" now works for standard PC partitions on hard disks (not + extended partitions... so any PC partition number above 3 will give + a "no such partition" error). If a BSD sub-partition is is used, it + will ignore it, and only use the primary PC partition number. + +Version 0.3 dated 5/20/96: + + - Updated instructions (though still very sparse). + + - New floppy probe (works much like the Linux floppy boot probe) attempts + to find the size of a floppy in a drive. Might still need work! Please + try on various floppy drives with various media! + + - New floppy handler will claim a non-existent drive if the floppy disk + isn't present in the drive. (for example, it won't be on the list of + installed drives unless a floppy is present) + + - Stage1 now compatible with both a hard disk MBR and the DOS BIOS + parameter block (see "install/README" for more details on how this can + be used). + + - Block-list filesystem partially works, as described in the file "NOTES". + Loading an a.out or elf kernel won't work with it, but all other filetypes + pretty much should. (certainly chain-loading works OK) NOTE: + you must use the full format "0+1,512" for just he first block... no + parameters can be implicit in this version.. THis is being fixed too. + + - Linux ext2 filesystem works. (it's very slow for big files, but this + is being fixed) + + - Linux boot type now supported. Use a standard piggybacked image as + with LILO. Put in hack to support >64MB via GRUB placing the RAM size + as the first item on the command-line automatically. Must pass root + partition on command-line using normal Linux syntax... if not, it uses + it's builtin root partition. + + - Supports chain-loading. For details, see "COMMANDS" and the examples + directory. (was able to boot DOS and Windows NT on my test box). NOTE + that the "root partition" must be set to work right. "makeactive" + is currently a no-op. + + - Several weird bugs fixed. One important note: If you recompile, + it will warn about a clash with builtin "strcmp". This is normal... + do NOT remove the strcmp definition, as then GCC will possibly put + inline code from it's own builtin function in some places. (my strcmp + has slightly different functionality, hence the problem) + + - Mini-debugger is currently broken. + +Version 0.2 dated 4/12/96: + + - Completely new menu-based UI. See "COMMANDS" and the examples + directory for details. NOTE that the argument to a command must + be preceded by a space between it and the '=', in both the config + file and the command-line. This will be fixed. + +Version 0.1 dated 3/31/96 (lots of changes): + + - Newer version of Multiboot Standard (version 0.6) supported. + + - Autodetects kernel types. Supports Multiboot, FreeBSD, NetBSD (Linux + isn't finished). + + - Stage 1.5 works now. Default setup is now for working with a BSD FFS + floppy loading "/grub/stage2" as the main bootloader. + + - Filesystem support improved. It didn't work on many floppies + before (problem with the partition-detection code). + + - Memory probe now supports arbitrary amounts of RAM (some technical + limitations exist, see Multiboot standard version 0.6 for details). + + - A mini-debugger is included by default, activated by hitting '~' + on the command-line (it might interfere with things, but it + seems OK for my alpha-testing). The commands are in the function + "enter_sysdebug" defined in "common.c". If you have an Intel MPS- + compatible machine, there are extra commands enabled for SMP cpu + testing. 'q' exits and goes back to what you were doing before. + +Version 0.0 dated 2/6/96: + + - Newer version of Multiboot Standard (version 0.4) supported. + +Version 0.0 dated 12/10/95: + + - You can now perform TAB-based completion listing of any valid + partially completed disk/partition/file-name combination. Try it + out to see what you like, examples are in the NOTES file under + "Device completion". + + - Fixed a bug causing the memory size routine to sometimes report + rediculous values. + + - Fixed some documentation (what little there is :-/ and a few assembly + bugs in the BIOS access routines that nobody reported yet, so I won't + detail it here. + diff --git a/docs/PC_partitioning.txt b/docs/PC_partitioning.txt new file mode 100644 index 000000000..521a80794 --- /dev/null +++ b/docs/PC_partitioning.txt @@ -0,0 +1,2417 @@ + + + How It Works -- CHS Translation + + Plus BIOS Types, LBA and Other Good Stuff + + Version 4a + + by Hale Landis (landis@sugs.tware.com) + +THE "HOW IT WORKS" SERIES + +This is one of several How It Works documents. The series +currently includes the following: + +* How It Works -- CHS Translation +* How It Works -- Master Boot Record +* How It Works -- DOS Floppy Boot Sector +* How It Works -- OS2 Boot Sector +* How It Works -- Partition Tables + + +Introduction (READ THIS!) +------------------------- + +This is very technical. Please read carefully. There is lots of +information here that can sound confusing the first time you read +it. + +Why is an understanding of how a BIOS works so important? The +basic reason is that the information returned by INT 13H AH=08H +is used by FDISK, it is used in the partition table entries +within a partition record (like the Master Boot Record) that are +created by FDISK, and it is used by the small boot program that +FDISK places into the Master Boot Record. The information +returned by INT 13H AH=08H is in cylinder/head/sector (CHS) +format -- it is not in LBA format. The boot processing done by +your computer's BIOS (INT 19H and INT 13H) is all CHS based. + +Read this so that you are not confused by all the false +information going around that says "LBA solves the >528MB +problem". + +Read this so that you understand the possible data integrity +problem that a WD EIDE type BIOS creates. Any BIOS that has a +"LBA mode" in the BIOS setup could be a WD EIDE BIOS. Be very +careful and NEVER chage the "LBA mode" setting after you have +partitioned and installed your software. + +History +------- + +Changes between this version and the preceeding version are +marked by "!" at left margin of the first line of a changed +or new paragraph. + +Version 4 -- BIOS Types 8 and 10 updated. + +Version 3 -- New BIOS types found and added to this list. More + detailed information is listed for each BIOS type. A section + describing CHS translation was added. + +Version 2 -- A rewrite of version 1 adding BIOS types not + included in version 1. + +Version 1 -- First attempt to classify the BIOS types and + describe what each does or does not do. + +Definitions +----------- + +* 528MB - The maximun drive capacity that is supported by 1024 + cylinders, 16 heads and 63 sectors (1024x16x63x512). This + is the limit for CHS addressing in the original IBM PC/XT + and IBM PC/AT INT 13H BIOS. + +* 8GB - The maximum drive capacity that can be supported by 1024 + cylinders, 256 heads and 63 sectors (1024x256x63x512). This + is the limit for the BIOS INT 13H AH=0xH calls. + +* ATA - AT Attachment -- The real name of what is widely known + as IDE. + +* CE Cylinder - Customer Engineering cylinder. This is the + last cylinder in P-CHS mode. IBM has always reserved this + cylinder for use of disk diagnostic programs. Many BIOS do + not account for it correctly. It is of questionable value + these days and probably should be considered obsolete. + However, since there is no industry wide agreement, beware. + There is no CE Cylinder reserved in the L-CHS address. Also + beware of diagnostic programs that don't realize they are + operating in L-CHS mode and think that the last L-CHS cylinder + is the CE Cylinder. + +* CHS - Cylinder/Head/Sector. This is the traditional way to + address sectors on a disk. There are at least two types + of CHS addressing: the CHS that is used at the INT 13H + interface and the CHS that is used at the ATA device + interface. In the MFM/RLL/ESDI and early ATA days the CHS + used at the INT 13H interface was the same as the CHS used at + the device interface. + + Today we have CHS translating BIOS types that can use one CHS + at the INT 13H interface and a different CHS at the device + interface. These two types of CHS will be called the logical + CHS or L-CHS and the physical CHS or P-CHS in this document. + L-CHS is the CHS used at the INT 13H interface and P-CHS is + the CHS used at the device interface. + + The L-CHS used at the INT 13 interface allows up to 256 heads, + up to 1024 cylinders and up to 63 sectors. This allows + support of up to 8GB drives. This scheme started with either + ESDI or SCSI adapters many years ago. + + The P-CHS used at the device interface allows up to 16 heads + up to 65535 cylinders, and up to 63 sectors. This allows + access to 2^28 sectors (136GB) on an ATA device. When a P-CHS + is used at the INT 13H interface it is limited to 1024 + cylinders, 16 heads and 63 sectors. This is where the old + 528MB limit originated. + + ATA devices may also support LBA at the device interface. LBA + allows access to approximately 2^28 sectors (137GB) on an ATA + device. + + A SCSI host adapter can convert a L-CHS directly to an LBA + used in the SCSI read/write commands. On a PC today, SCSI is + also limited to 8GB when CHS addressing is used at the INT 13H + interface. + +* EDPT - Enhanced fixed Disk Parameter Table -- This table + returns additional information for BIOS drive numbers 80H and + 81H. The EDPT for BIOS drive 80H is pointed to by INT 41H. + The EDPT for BIOS drive 81H is pointed to by INT 46H. The + EDPT is a fixed disk parameter table with an AxH signature + byte. This table format returns two sets of CHS information. + One set is the L-CHS and is probably the same as returned by + INT 13H AH=08H. The other set is the P-CHS used at the drive + interface. This type of table allows drives with >1024 + cylinders or drives >528MB to be supported. The translated + CHS will have <=1024 cylinders and (probably) >16 heads. The + CHS used at the drive interface will have >1024 cylinders and + <=16 heads. It is unclear how the IBM defined CE cylinder is + accounted for in such a table. Compaq probably gets the + credit for the original definition of this type of table. + +* FDPT - Fixed Disk Parameter Table - This table returns + additional information for BIOS drive numbers 80H and 81H. + The FDPT for BIOS drive 80H is pointed to by INT 41H. The + FDPT for BIOS drive 81H is pointed to by INT 46H. A FDPT does + not have a AxH signature byte. This table format returns a + single set of CHS information. The L-CHS information returned + by this table is probably the same as the P-CHS and is also + probably the same as the L-CHS returned by INT 13H AH=08H. + However, not all BIOS properly account for the IBM defined CE + cylinder and this can cause a one or two cylinder difference + between the number of cylinders returned in the AH=08H data + and the FDPT data. IBM gets the credit for the original + definition of this type of table. + +* LBA - Logical Block Address. Another way of addressing + sectors that uses a simple numbering scheme starting with zero + as the address of the first sector on a device. The ATA + standard requires that cylinder 0, head 0, sector 1 address + the same sector as addressed by LBA 0. LBA addressing can be + used at the ATA interface if the ATA device supports it. LBA + addressing is also used at the INT 13H interface by the AH=4xH + read/write calls. + +* L-CHS -- Logical CHS. The CHS used at the INT 13H interface by + the AH=0xH calls. See CHS above. + +* MBR - Master Boot Record (also known as a partition table) - + The sector located at cylinder 0 head 0 sector 1 (or LBA 0). + This sector is created by an "FDISK" utility program. The MBR + may be the only partition table sector or the MBR can be the + first of multiple partition table sectors that form a linked + list. A partition table entry can describe the starting and + ending sector addresses of a partition (also known as a + logical volume or a logical drive) in both L-CHS and LBA form. + Partition table entries use the L-CHS returned by INT 13H + AH=08H. Older FDISK programs may not compute valid LBA + values. + +* OS - Operating System. + +* P-CHS -- Physical CHS. The CHS used at the ATA device + interface. This CHS is also used at the INT 13H interface by + older BIOS's that do not support >1024 cylinders or >528MB. + See CHS above. + +Background and Assumptions +-------------------------- + +First, please note that this is written with the OS implementor +in mind and that I am talking about the possible BIOS types as +seen by an OS during its hardware configuration search. + +It is very important that you not be confused by all the +misinformation going around these days. All OS's that want to be +co-resident with another OS (and that is all of the PC based OS's +that I know of) MUST use INT 13H to determine the capacity of a +hard disk. And that capacity information MUST be determined in +L-CHS mode. Why is this? Because: 1) FDISK and the partition +tables are really L-CHS based, and 2) MS/PC DOS uses INT 13H +AH=02H and AH=03H to read and write the disk and these BIOS calls +are L-CHS based. The boot processing done by the BIOS is all +L-CHS based. During the boot processing, all of the disk read +accesses are done in L-CHS mode via INT 13H and this includes +loading the first of the OS's kernel code or boot manager's code. + +Second, because there can be multiple BIOS types in any one +system, each drive may be under the control of a different type +of BIOS. For example, drive 80H (the first hard drive) could be +controlled by the original system BIOS, drive 81H (the second +drive) could be controlled by a option ROM BIOS and drive 82H +(the third drive) could be controlled by a software driver. +Also, be aware that each drive could be a different type, for +example, drive 80H could be an MFM drive, drive 81H could be an +ATA drive, drive 82H could be a SCSI drive. + +Third, not all OS's understand or use BIOS drive numbers greater +than 81H. Even if there is INT 13H support for drives 82H or +greater, the OS may not use that support. + +Fourth, the BIOS INT 13H configuration calls are: + +* AH=08H, Get Drive Parameters -- This call is restricted to + drives up to 528MB without CHS translation and to drives up to + 8GB with CHS translation. For older BIOS with no support for + >1024 cylinders or >528MB, this call returns the same CHS as + is used at the ATA interface (the P-CHS). For newer BIOS's + that do support >1024 cylinders or >528MB, this call returns a + translated CHS (the L-CHS). The CHS returned by this call is + used by FDISK to build partition records. + +* AH=41H, Get BIOS Extensions Support -- This call is used to + determine if the IBM/Microsoft Extensions or if the Phoenix + Enhanced INT 13H calls are supported for the BIOS drive + number. + +* AH=48H, Extended Get Drive Parameters -- This call is used to + determine the CHS geometries, LBA information and other data + about the BIOS drive number. + +* the FDPT or EDPT -- While not actually a call, but instead a + data area, the FDPT or EDPT can return additional information + about a drive. + +* other tables -- The IBM/Microsoft extensions provide a pointer + to a drive parameter table via INT 13H AH=48H. The Phoenix + enhancement provides a pointer to a drive parameter table + extension via INT 13H AH=48H. These tables are NOT the same + as the FDPT or EDPT. + +Note: The INT 13H AH=4xH calls duplicate the older AH=0xH calls +but use a different parameter passing structure. This new +structure allows support of drives with up to 2^64 sectors +(really BIG drives). While at the INT 13H interface the AH=4xH +calls are LBA based, these calls do NOT require that the drive +support LBA addressing. + +CHS Translation Algorithms +-------------------------- + +NOTE: Before you send me email about this, read this entire + section. Thanks! + +As you read this, don't forget that all of the boot processing +done by the system BIOS via INT 19H and INT 13H use only the INT +13H AH=0xH calls and that all of this processing is done in CHS +mode. + +First, lets review all the different ways a BIOS can be called +to perform read/write operations and the conversions that a BIOS +must support. + +! * An old BIOS (like BIOS type 1 below) does no CHS translation + and does not use LBA. It only supports the AH=0xH calls: + + INT 13H (L-CHS == P-CHS) ATA + AH=0xH --------------------------------> device + (L-CHS) (P-CHS) + +* A newer BIOS may support CHS translation and it may support + LBA at the ATA interface: + + INT 13H L-CHS ATA + AH=0xH --+--> to --+----------------> device + (L-CHS) | P-CHS | (P-CHS) + | | + | | P-CHS + | +--> to --+ + | LBA | + | | + | L-CHS | ATA + +--> to -----------------+---> device + LBA (LBA) + +* A really new BIOS may also support the AH=4xH in addtion to + the older AH\0xH calls. This BIOS must support all possible + combinations of CHS and LBA at both the INT 13H and ATA + interfaces: + + INT 13H ATA + AH=4xH --+-----------------------------> device + (LBA) | (LBA) + | + | LBA + +--> to ---------------+ + P-CHS | + | + INT 13H L-CHS | ATA + AH=0xH --+--> to --+------------+---> device + (L-CHS) | P-CHS | (P-CHS) + | | + | | P-CHS + | +--> to --+ + | LBA | + | | + | L-CHS | ATA + +--> to -----------------+---> device + LBA (LBA) + +You would think there is only one L-CHS to P-CHS translation +algorithm, only one L-CHS to LBA translation algorithm and only +one P-CHS to LBA translation algorithm. But this is not so. +Why? Because there is no document that standardizes such an +algorithm. You can not rely on all BIOS's and OS's to do these +translations the same way. + +The following explains what is widely accepted as the +"correct" algorithms. + +An ATA disk must implement both CHS and LBA addressing and +must at any given time support only one P-CHS at the device +interface. And, the drive must maintain a strick relationship +between the sector addressing in CHS mode and LBA mode. Quoting +the ATA-2 document: + + LBA = ( (cylinder * heads_per_cylinder + heads ) + * sectors_per_track ) + sector - 1 + + where heads_per_cylinder and sectors_per_track are the current + translation mode values. + +This algorithm can also be used by a BIOS or an OS to convert +a L-CHS to an LBA as we'll see below. + +This algorithm can be reversed such that an LBA can be +converted to a CHS: + + cylinder = LBA / (heads_per_cylinder * sectors_per_track) + temp = LBA % (heads_per_cylinder * sectors_per_track) + head = temp / sectors_per_track + sector = temp % sectors_per_track + 1 + +While most OS's compute disk addresses in an LBA scheme, an OS +like DOS must convert that LBA to a CHS in order to call INT 13H. + +Technically an INT 13H should follow this process when +converting an L-CHS to a P-CHS: + + 1) convert the L-CHS to an LBA, + 2) convert the LBA to a P-CHS, + +If an LBA is required at the ATA interface, then this third +step is needed: + + 3) convert the P-CHS to an LBA. + +All of these conversions are done by normal arithmetic. + +However, while this is the technically correct way to do +things, certain short cuts can be taken. It is possible to +convert an L-CHS directly to a P-CHS using bit a bit shifting +algorithm. This combines steps 1 and 2. And, if the ATA device +being used supports LBA, steps 2 and 3 are not needed. The LBA +value produced in step 1 is the same as the LBA value produced in +step 3. + +AN EXAMPLE + +Lets look at an example. Lets say that the L-CHS is 1000 +cylinders 10 heads and 50 sectors, the P-CHS is 2000 cylinders, 5 +heads and 50 sectors. Lets say we want to access the sector at +L-CHS 2,4,3. + +* step 1 converts the L-CHS to an LBA, + + lba = 1202 = ( ( 2 * 10 + 4 ) * 50 ) + 3 - 1 + +* step 2 converts the LBA to the P-CHS, + + cylinder = 4 = ( 1202 / ( 5 * 50 ) + temp = 202 = ( 1202 % ( 5 * 50 ) ) + head = 4 = ( 202 / 50 ) + sector = 3 = ( 202 % 50 ) + 1 + +* step 3 converts the P-CHS to an LBA, + + lba = 1202 = ( ( 4 * 5 + 4 ) * 50 ) + 3 - 1 + +Most BIOS (or OS) software is not going to do all of this to +convert an address. Most will use some other algorithm. There +are many such algorithms. + +BIT SHIFTING INSTEAD + +If the L-CHS is produced from the P-CHS by 1) dividing the +P-CHS cylinders by N, and 2) multiplying the P-CHS heads by N, +where N is 2, 4, 8, ..., then this bit shifting algorithm can be +used and N becomes a bit shift value. This is the most common +way to make the P-CHS geometry of a >528MB drive fit the INT 13H +L-CHS rules. Plus this algorithm maintains the same sector +ordering as the more complex algorithm above. Note the +following: + + Lcylinder = L-CHS cylinder being accessed + Lhead = L-CHS head being accessed + Lsector = L-CHS sector being accessed + + Pcylinder = the P-CHS cylinder being accessed + Phead = the P-CHS head being accessed + Psector = P-CHS sector being accessed + + NPH = is the number of heads in the P-CHS + N = 2, 4, 8, ..., the bit shift value + +The algorithm, which can be implemented using bit shifting +instead of multiply and divide operations is: + + Pcylinder = ( Lcylinder * N ) + ( Lhead / NPH ); + Phead = ( Lhead % NPH ); + Psector = Lsector; + +A BIT SHIFTING EXAMPLE + +Lets apply this to our example above (L-CHS = 1000,10,50 and +P-CHS = 2000, 5, 50) and access the same sector at at L-CHS +2,4,3. + + Pcylinder = 4 = ( 2 * 2 ) + ( 4 / 5 ) + Phead = 4 = ( 4 % 5 ) + Psector = 3 = 3 + +As you can see, this produces the same P-CHS as the more +complex method above. + +SO WHAT IS THE PROBLEM? + +The basic problem is that there is no requirement that a CHS +translating BIOS followed these rules. There are many other +algorithms that can be implemented to perform a similar function. +Today, there are at least two popular implementions: the Phoenix +implementation (described above) and the non-Phoenix +implementations. + +SO WHY IS THIS A PROBLEM IF IT IS HIDDEN INSIDE THE BIOS? + +Because a protected mode OS that does not want to use INT 13H +must implement the same CHS translation algorithm. If it +doesn't, your data gets scrambled. + +WHY USE CHS AT ALL? + +In the perfect world of tomorrow, maybe only LBA will be used. +But today we are faced with the following problems: + +* Some drives >528MB don't implement LBA. + +* Some drives are optimized for CHS and may have lower + performance when given commands in LBA mode. Don't forget + that LBA is something new for the ATA disk designers who have + worked very hard for many years to optimize CHS address + handling. And not all drive designs require the use of LBA + internally. + +* The L-CHS to LBA conversion is more complex and slower than + the bit shifting L-CHS to P-CHS conversion. + +* DOS, FDISK and the MBR are still CHS based -- they use the + CHS returned by INT 13H AH=08H. Any OS that can be installed + on the same disk with DOS must understand CHS addressing. + +* The BIOS boot processing and loading of the first OS kernel + code is done in CHS mode -- the CHS returned by INT 13H AH=08H + is used. + +* Microsoft has said that their OS's will not use any disk + capacity that can not also be accessed by INT 13H AH=0xH. + +These are difficult problems to overcome in today's industry +environment. The result: chaos. + +DANGER TO YOUR DATA! + +See the description of BIOS Type 7 below to understand why a +WD EIDE BIOS is so dangerous to your data. + +The BIOS Types +-------------- + +I assume the following: + +a) All BIOS INT 13H support has been installed by the time the OS + starts its boot processing. I'm don't plan to cover what + could happen to INT 13H once the OS starts loading its own + device drivers. + +b) Drives supported by INT 13H are numbered sequentially starting + with drive number 80H (80H-FFH are hard drives, 00-7FH are + floppy drives). + +And remember, any time a P-CHS exists it may or may not account + for the CE Cylinder properly. + +I have identified the following types of BIOS INT 13H support as +seen by an OS during its boot time hardware configuration +determination: + +BIOS Type 1 + + Origin: Original IBM PC/XT. + + BIOS call support: INT 13H AH=0xH and FDPT for BIOS drives + 80H and 81H. There is no CHS translation. INT 13H AH=08H + returns the P-CHS. The FDPT should contain the same P-CHS. + + Description: Supports up to 528MB from a table of drive + descriptions in BIOS ROM. No support for >1024 cylinders or + drives >528MB or LBA. + + Support issues: For >1024 cylinders or >528MB support, either + an option ROM with an INT 13H replacement (see BIOS types 4-7) + -or- a software driver (see BIOS type 8) must be added to the + system. + +BIOS Type 2 + + Origin: Unknown, but first appeared on systems having BIOS + drive type table entries defining >1024 cylinders. Rumored to + have originated at the request of Novell or SCO. + + BIOS call support: INT 13H AH=0xH and FDPT for BIOS drives + 80H and 81H. INT 13H AH=08H should return a L-CHS with the + cylinder value limited to 1024. Beware, many BIOS perform + a logical AND on the cylinder value. A correct BIOS will + limit the cylinder value as follows: + + cylinder = cylinder > 1024 ? 1024 : cylinder; + + An incorrect BIOS will limit the cylinder value as follows + (this implementation turns a 540MB drive into a 12MB drive!): + + cylinder = cylinder & 0x03ff; + + The FDPT will return a P-CHS that has the full cylinder + value. + + Description: For BIOS drive numbers 80H and 81H, this BIOS + type supports >1024 cylinders or >528MB without using a + translated CHS in the FDPT. INT 13H AH=08H truncates + cylinders to 1024 (beware of buggy implementations). The FDPT + can show >1024 cylinders thereby allowing an OS to support + drives >528MB. May convert the L-CHS or P-CHS directly to an + LBA if the ATA device supports LBA. + + Support issues: Actual support of >1024 cylinders is OS + specific -- some OS's may be able to place OS specific + partitions spanning or beyond cylinder 1024. Usually all OS + boot code must be within first 1024 cylinders. The FDISK + program of an OS that supports such partitions uses an OS + specific partition table entry format to identify these + paritions. There does not appear to be a standard (de facto + or otherwise) for this unusual partition table entry. + Apparently one method is to place -1 into the CHS fields and + use the LBA fields to describe the location of the partition. + This DOES NOT require the drive to support LBA addressing. + Using an LBA in the partition table entry is just a trick to + get around the CHS limits in the partition table entry. It is + unclear if such a partition table entry will be ignored by an + OS that does not understand what it is. For an OS that does + not support such partitions, either an option ROM with an INT + 13H replacement (see BIOS types 4-7) -or- a software driver + (see BIOS type 8) must be added to the system. + + Note: OS/2 can place HPFS partitions and Linux can place + Linux partitions beyond or spanning cylinder 1024. (Anyone + know of other systems that can do the same?) + +BIOS Type 3 + + Origin: Unknown, but first appeared on systems having BIOS + drive type table entires defining >1024 cylinders. Rumored to + have originated at the request of Novell or SCO. + + BIOS call support: INT 13H AH=0xH and FDPT for BIOS drives + 80H and 81H. INT 13H AH=08H can return an L-CHS with more + than 1024 cylinders. + + Description: This BIOS is like type 2 above but it allows up + to 4096 cylinders (12 cylinder bits). It does this in the INT + 13H AH=0xH calls by placing two most significant cylinder bits + (bits 11 and 10) into the upper two bits of the head number + (bits 7 and 6). + + Support issues: Identification of such a BIOS is difficult. + As long as the drive(s) supported by this type of BIOS have + <1024 cylinders this BIOS looks like a type 2 BIOS because INT + 13H AH=08H should return zero data in bits 7 and 6 of the head + information. If INT 13H AH=08H returns non zero data in bits + 7 and 6 of the head information, perhaps it can be assumed + that this is a type 3 BIOS. For more normal support of >1024 + cylinders or >528MB, either an option ROM with an INT 13H + replacement (see BIOS types 4-7) -or- a software driver (see + BIOS type 8) must be added to the system. + + Note: Apparently this BIOS type is no longer produced by any + BIOS vendor. + +BIOS Type 4 + + Origin: Compaq. Probably first appeared in systems with ESDI + drives having >1024 cylinders. + + BIOS call support: INT 13H AH=0xH and EDPT for BIOS drives + 80H and 81H. If the drive has <1024 cylinders, INT 13H AH=08H + returns the P-CHS and a FDPT is built. If the drive has >1024 + cylinders, INT 13H AH=08H returns an L-CHS and an EDPT is + built. + + Description: Looks like a type 2 BIOS when an FDPT is built. + Uses CHS translation when an EDPT is used. May convert the + L-CHS directly to an LBA if the ATA device supports LBA. + + Support issues: This BIOS type may support up to four drives + with a EDPT (or FDPT) for BIOS drive numbers 82H and 83H + located in memory following the EDPT (or FDPT) for drive 80H. + Different CHS translation algorithms may be used by the BIOS + and an OS. + +BIOS Type 5 + + Origin: The IBM/Microsoft BIOS Extensions document. For many + years this document was marked "confidential" so it did not + get wide spread distribution. + + BIOS call support: INT 13H AH=0xH, AH=4xH and EDPT for BIOS + drives 80H and 81H. INT 13H AH=08H returns an L-CHS. INT 13H + AH=41H and AH=48H should be used to get P-CHS configuration. + The FDPT/EDPT should not be used. In some implementations the + FDPT/EDPT may not exist. + + Description: A BIOS that supports very large drives (>1024 + cylinders, >528MB, actually >8GB), and supports the INT 13H + AH=4xH read/write functions. The AH=4xH calls use LBA + addressing and support drives with up to 2^64 sectors. These + calls do NOT require that a drive support LBA at the drive + interface. INT 13H AH=48H describes the L-CHS used at the INT + 13 interface and the P-CHS or LBA used at the drive interface. + This BIOS supports the INT 13 AH=0xH calls the same as a BIOS + type 4. + + Support issues: While the INT 13H AH=4xH calls are well + defined, they are not implemented in many systems shipping + today. Currently undefined is how such a BIOS should respond + to INT 13H AH=08H calls for a drive that is >8GB. Different + CHS translation algorithms may be used by the BIOS and an OS. + + Note: Support of LBA at the drive interface may be automatic + or may be under user control via a BIOS setup option. Use of + LBA at the drive interface does not change the operation of + the INT 13 interface. + +BIOS Type 6 + + Origin: The Phoenix Enhanced Disk Drive Specification. + + BIOS call support: INT 13H AH=0xH, AH=4xH and EDPT for BIOS + drives 80H and 81H. INT 13H AH=08H returns an L-CHS. INT 13H + AH=41H and AH=48H should be used to get P-CHS configuration. + INT 13H AH=48H returns the address of the Phoenix defined + "FDPT Extension" table. + + Description: A BIOS that supports very large drives (>1024 + cylinders, >528MB, actually >8GB), and supports the INT 13H + AH=4xH read/write functions. The AH=4xH calls use LBA + addressing and support drives with up to 2^64 sectors. These + calls do NOT require that a drive support LBA at the drive + interface. INT 13H AH=48H describes the L-CHS used at the INT + 13 interface and the P-CHS or LBA used at the drive interface. + This BIOS supports the INT 13 AH=0xH calls the same as a BIOS + type 4. The INT 13H AH=48H call returns additional information + such as host adapter addresses, DMA support, LBA support, etc, + in the Phoenix defined "FDPT Extension" table. + + Phoenix says this this BIOS need not support the INT 13H + AH=4xH read/write calls but this BIOS is really an + extension/enhancement of the original IBM/MS BIOS so most + implementations will probably support the full set of INT 13H + AH=4xH calls. + + Support issues: Currently undefined is how such a BIOS should + respond to INT 13H AH=08H calls for a drive that is >8GB. + Different CHS translation algorithms may be used by the BIOS + and an OS. + + Note: Support of LBA at the drive interface may be automatic + or may be under user control via a BIOS setup option. Use of + LBA at the drive interface does not change the operation of + the INT 13 interface. + +BIOS Type 7 + + Origin: Described in the Western Digital Enhanced IDE + Implementation Guide. + + BIOS call support: INT 13H AH=0xH and FDPT or EDPT for BIOS + drives 80H and 81H. An EDPT with a L-CHS of 16 heads and 63 + sectors is built when "LBA mode" is enabled. An FDPT is built + when "LBA mode" is disabled. + + Description: Supports >1024 cylinders or >528MB using a EDPT + with a translated CHS *** BUT ONLY IF *** the user requests + "LBA mode" in the BIOS setup *** AND *** the drive supports + LBA. As long as "LBA mode" is enabled, CHS translation is + enabled using a L-CHS with <=1024 cylinders, 16, 32, 64, ..., + heads and 63 sectors. Disk read/write commands are issued in + LBA mode at the ATA interface but other commands are issued in + P-CHS mode. Because the L-CHS is determined by table lookup + based on total drive capacity and not by a multiply/divide of + the P-CHS cylinder and head values, it may not be possible to + use the simple (and faster) bit shifting L-CHS to P-CHS + algorithms. + + When "LBA mode" is disabled, this BIOS looks like a BIOS type + 2 with an FDPT. The L-CHS used is taken either from the BIOS + drive type table or from the device's Identify Device data. + This L-CHS can be very different from the L-CHS returned when + "LBA mode" is enabled. + + This BIOS may support FDPT/EDPT for up to four drives in the + same manner as described in BIOS type 4. + + The basic problem with this BIOS is that the CHS returned by + INT 13H AH=08H changes because of a change in the "LBA mode" + setting in the BIOS setup. This should not happen. This use + or non-use of LBA at the ATA interface should have no effect + on the CHS returned by INT 13H AH=08H. This is the only BIOS + type know to have this problem. + + Support issues: If the user changes the "LBA mode" setting in + BIOS setup, INT 13H AH=08H and the FDPT/EDPT change + which may cause *** DATA CORRUPTION ***. The user should be + warned to not change the "LBA mode" setting in BIOS setup once + the drive has been partitioned and software installed. + Different CHS translation algorithms may be used by the BIOS + and an OS. + +BIOS Type 8 + + Origin: Unknown. Perhaps Ontrack's Disk Manager was the + first of these software drivers. Another example of such a + driver is Micro House's EZ Drive. + + BIOS call support: Unknown (anyone care to help out here?). + Mostly likely only INT 13H AH=0xH are support. Probably a + FDPT or EDPT exists for drives 80H and 81H. + +! Description: A software driver that "hides" in the MBR such + that it is loaded into system memory before any OS boot + processing starts. These drivers can have up to three parts: + a part that hides in the MBR, a part that hides in the + remaining sectors of cylinder 0, head 0, and an OS device + driver. The part in the MBR loads the second part of the + driver from cylinder 0 head 0. The second part provides a + replacement for INT 13H that enables CHS translation for at + least the boot drive. Usually the boot drive is defined in + CMOS setup as a type 1 or 2 (5MB or 10MB drive). Once the + second part of the driver is loaded, this definition is + changed to describe the true capacity of the drive and INT 13H + is replaced by the driver's version of INT 13H that does CHS + translation. In some cases the third part, an OS specific + device driver, must be loaded to enable CHS translation for + devices other than the boot device. + +! I don't know the details of how these drivers respond to INT + 13H AH=08H or how they set up drive parameter tables (anyone + care to help out here?). Some of these drivers convert the + L-CHS to an LBA, then they add a small number to the LBA and + finally they convert the LBA to a P-CHS. This in effect skips + over some sectors at the front of the disk. + + Support issues: Several identified -- Some OS installation + programs will remove or overlay these drivers; some of these + drivers do not perform CHS translation using the same + algorithms used by the other BIOS types; special OS device + drivers may be required in order to use these software drivers + For example, under MS Windows the standard FastDisk driver + (the 32-bit disk access driver) must be replaced by a driver + that understands the Ontrack, Micro House, etc, version of INT + 13H. Different CHS translation algorithms may be used by the + driver and an OS. + +! The hard disk vendors have been shipping these drivers with + their drives over 528MB during the last year and they have + been ignoring the statements of Microsoft and IBM that these + drivers would not be supported in future OS's. Now it appears + that both Microsoft and IBM are in a panic trying to figure + out how to support some of these drivers in WinNT, Win95 and + OS/2. It is unclear what the outcome of this will be at this + time. + +! NOTE: THIS IS NOT A PRODUCT ENDORSEMENT! An alternate + solution for an older ISA system is one of the BIOS + replacement cards. This cards have a BIOS option ROM. AMI + makes such a card called the "Disk Extender". This card + replaces the motherboard's INT 13H BIOS with a INT 13H BIOS + that does some form of CHS translation. Another solution for + older VL-Bus systems is an ATA-2 (EIDE) type host adapter card + that provides a option ROM with an INT 13H replacement. + +BIOS Type 9 + + Origin: SCSI host adapters. + + BIOS call support: Probably INT 13H AH=0xH and FDPT for BIOS + drives 80H and 81H, perhaps INT 13H AH=4xH. + + Description: Most SCSI host adapters contain an option ROM + that enables INT 13 support for the attached SCSI hard drives. + It is possible to have more than one SCSI host adapter, each + with its own option ROM. The CHS used at the INT 13H + interface is converted to the LBA that is used in the SCSI + commands. INT 13H AH=08H returns a CHS. This CHS will have + <=1024 cylinders, <=256 heads and <=63 sectors. The FDPT + probably will exist for SCSI drives with BIOS drive numbers of + 80H and 81H and probably indicates the same CHS as that + returned by INT 13H AH=08H. Even though the CHS used at the + INT 13H interface looks like a translated CHS, there is no + need to use a EDPT since there is no CHS-to-CHS translation + used. Other BIOS calls (most likely host adapter specific) + must be used to determine other information about the host + adapter or the drives. + + The INT 13H AH=4xH calls can be used to get beyond 8GB but + since there is little support for these calls in today's OS's, + there are probably few SCSI host adapters that support these + newer INT 13H calls. + + Support issues: Some SCSI host adapters will not install + their option ROM if there are two INT 13H devices previously + installed by another INT 13H BIOS (for example, two + MFM/RLL/ESDI/ATA drives). Other SCSI adapters will install + their option ROM and use BIOS drive numbers greater than 81H. + Some older OS's don't understand or use BIOS drive numbers + greater than 81H. SCSI adapters are currently faced with the + >8GB drive problem. + +BIOS Type 10 + + Origin: A european system vendor. + + BIOS call support: INT 13H AH=0xH and FDPT for BIOS drives + 80H and 81H. + + Description: This BIOS supports drives >528MB but it does not + support CHS translation. It supports only ATA drives with LBA + capability. INT 13H AH=08H returns an L-CHS. The L-CHS is + converted directly to an LBA. The BIOS sets the ATA drive to + a P-CHS of 16 heads and 63 sectors using the Initialize Drive + Parameters command but it does not use this P-CHS at the ATA + interface. + +! Support issues: OS/2 will probably work with this BIOS as + long as the drive's power on default P-CHS mode uses 16 heads + and 63 sectors. Because there is no EDPT, OS/2 uses the ATA + Identify Device power on default P-CHS, described in + Identify Device words 1, 3 and 6 as the current P-CHS for the + drive. However, this may not represent the correct P-CHS. A + newer drive will have the its current P-CHS information in + Identify Device words 53-58 but for some reason OS/2 does not + use this information. + +---------------------------------------------------------------------- + + How it Works -- Partition Tables + + Version 1b + + by Hale Landis (landis@sugs.tware.com) + + +THE "HOW IT WORKS" SERIES + +This is one of several How It Works documents. The series +currently includes the following: + +* How It Works -- CHS Translation +* How It Works -- Master Boot Record +* How It Works -- DOS Floppy Boot Sector +* How It Works -- OS2 Boot Sector +* How It Works -- Partition Tables + + +PARTITION SECTOR/RECORD/TABLE BASICS + +FDISK creates all partition records (sectors). The primary +purpose of a partition record is to hold a partition table. The +rules for how FDISK works are unwritten but so far most FDISK +programs (DOS, OS/2, WinNT, etc) seem to follow the same basic +idea. + +First, all partition table records (sectors) have the same +format. This includes the partition table record at cylinder 0, +head 0, sector 1 -- what is known as the Master Boot Record +(MBR). The last 66 bytes of a partition table record contain a +partition table and a 2 byte signature. The first 446 bytes of +these sectors usually contain a program but only the program in +the MBR is ever executed (so extended partition table records +could contain something other than a program in the first 466 +bytes). See "How It Works -- The Master Boot Record". + +Second, extended partitions are "nested" inside one another and +extended partition table records form a "linked list". I will +attempt to show this in a diagram below. + +PARTITION TABLE ENTRY FORMAT + +Each partition table entry is 16 bytes and contains things like +the start and end location of a partition in CHS, the start in +LBA, the size in sectors, the partition "type" and the "active" +flag. Warning: older versions of FDISK may compute incorrect +LBA or size values. And note: When your computer boots itself, +only the CHS fields of the partition table entries are used +(another reason LBA doesn't solve the >528MB problem). The CHS +fields in the partition tables are in L-CHS format -- see "How It +Works -- CHS Translation". + +There is no central clearing house to assign the codes used in +the one byte "type" field. But codes are assigned (or used) to +define most every type of file system that anyone has ever +implemented on the x86 PC: 12-bit FAT, 16-bit FAT, HPFS, NTFS, +etc. Plus, an extended partition also has a unique type code. + +Note: I know of no complete list of all the type codes that have +been used to date. However, I try to include such a list in a +future version of this document. + +The 16 bytes of a partition table entry are used as follows: + + +--- Bit 7 is the active partition flag, bits 6-0 are zero. + | + | +--- Starting CHS in INT 13 call format. + | | + | | +--- Partition type byte. + | | | + | | | +--- Ending CHS in INT 13 call format. + | | | | + | | | | +-- Starting LBA. + | | | | | + | | | | | +-- Size in sectors. + | | | | | | + v <--+---> v <--+--> v v + + 0 1 2 3 4 5 6 7 8 9 A B C D E F + DH DL CH CL TB DL CH CL LBA..... SIZE.... + + 80 01 01 00 06 0e be 94 3e000000 0c610900 1st entry + + 00 00 81 95 05 0e fe 7d 4a610900 724e0300 2nd entry + + 00 00 00 00 00 00 00 00 00000000 00000000 3rd entry + + 00 00 00 00 00 00 00 00 00000000 00000000 4th entry + +Bytes 0-3 are used by the small program in the Master Boot Record +to read the first sector of an active partition into memory. The +DH, DL, CH and CL above show which x86 register is loaded when +the MBR program calls INT 13H AH=02H to read the active +partition's boot sector. See "How It Works -- Master Boot +Record". + +These entries define the following partitions: + +1) The first partition, a primary partition DOS FAT, starts at + CHS 0H,1H,1H (LBA 3EH) and ends at CHS 294H,EH,3EH with a size + of 9610CH sectors. + +2) The second partition, an extended partition, starts at CHS + 295H,0H,1H (LBA 9614AH) and ends at CHS 37DH,EH,3EH with a + size of 34E72H sectors. + +3) The third and fourth table entries are unused. + +PARTITION TABLE RULES + +Keep in mind that there are NO written rules and NO industry +standards on how FDISK should work but here are some basic rules +that seem to be followed by most versions of FDISK: + +1) In the MBR there can be 0-4 "primary" partitions, OR, 0-3 + primary partitions and 0-1 extended partition entry. + +2) In an extended partition there can be 0-1 "secondary" + partition entries and 0-1 extended partition entries. + +3) Only 1 primary partition in the MBR can be marked "active" at + any given time. + +4) In most versions of FDISK, the first sector of a partition + will be aligned such that it is at head 0, sector 1 of a + cylinder. This means that there may be unused sectors on the + track(s) prior to the first sector of a partition and that + there may be unused sectors following a partition table + sector. + + For example, most new versions of FDISK start the first + partition (primary or extended) at cylinder 0, head 1, sector + 0. This leaves the sectors at cylinder 0, head 0, sectors + 2...n as unused sectors. This same layout may be seen on the + first track of an extended partition. See example 2 below. + + Also note that software drivers like Ontrack's Disk Manager + depend on these unused sectors because these drivers will + "hide" their code there (in cylinder 0, head 0, sectors + 2...n). This is also a good place for boot sector virus + programs to hang out. + +5) The partition table entries (slots) can be used in any order. + Some versions of FDISK fill the table from the bottom up and + some versions of FDISK fill the table from the top down. + Deleting a partition can leave an unused entry (slot) in the + middle of a table. + +6) And then there is the "hack" that some newer OS's (OS/2 and + Linux) use in order to place a partition spanning or passed + cylinder 1024 on a system that does not have a CHS translating + BIOS. These systems create a partition table entry with the + partition's starting and ending CHS information set to all + FFH. The starting and ending LBA information is used to + describe the location of the partition. The LBA can be + converted back to a CHS -- most likely a CHS with more than + 1024 cylinders. Since such a CHS can't be used by the system + BIOS, these partitions can not be booted or accessed until the + OS's kernel and hard disk device drivers are loaded. It is + not known if the systems using this "hack" follow the same + rules for the creation of these type of partitions. + +There are NO written rules as to how an OS scans the partition +table entries so each OS can have a different method. For DOS, +this means that different versions could assign different drive +letters to the same FAT file system partitions. + +PARTITION NESTING + +What do I mean when I say the partitions are "nested" within each +other? Lets look at this example: + + M = Master Boot Record (and any unused sectors + on the same track) + E = Extended partition record (and any unused sectors + on the same track) + pri = a primary partition (first sector is a "boot" sector) + sec = a secondary partition (first sector is a "boot" sector) + + + |<----------------the entire disk-------------->| + | | + |M | + | | + | E<---rest of 1st ext part---------->| + | | + | E<---rest of 2nd ext part---->| + + +The first extended partition is described in the MBR and it +occupies the entire disk following the primary partition. The +second extended partition is described in the first extended +partition record and it occupies the entire disk following the +first secondary partition. + +PARTITION TABLE LINKING + +What do I mean when I say the partition records (tables) form a +"linked" list? This means that the MBR has an entry that +describes (points to) the first extended partition, the first +extended partition table has an entry that describes (points to) +the second extended partition table, and so on. There is, in +theory, no limited to out long this linked list is. When you ask +FDISK to show the DOS "logical drives" it scans the linked list +looking for all of the DOS FAT type partitions that may exist. +Remember that in an extended partition table, only two entries of +the four can be used (rule 2 above). + +And one more thing... Within a partition, the layout of the file +system data varies greatly. However, the first sector of a +partition is expected to be a "boot" sector. A DOS FAT file +system has: a boot sector, first FAT sectors, second FAT +sectors, root directory sectors and finally the file data area. +See "How It Works -- OS2 Boot Sector". + + +EXAMPLE 1 + +A disk containing four DOS FAT partitions (C, D, E and F): + + + |<---------------------the entire disk------------------->| + | | + |M<---C:---> | + | | + | E<---D:---><-rest of 1st ext part------------>| + | | + | E<---E:---><-rest of 2nd ext part->| + | | + | E<---------F:---------->| + + +EXAMPLE 2 + +So here is an example of a disk with two primary partitions, one +DOS FAT and one OS/2 HPFS, plus an extended partition with +another DOS FAT: + + + |<------------------the entire disk------------------>| + | | + |M | + | | + | | + | | + | E| + + +Or in more detail ('n' is the highest cylinder, head or sector +number number allowed in the indicated field of the CHS)... + + + +-------------------------------------+ + CHS=0,0,1 | Master Boot Record containing | + | partition table search program and | + | a partition table | + | +---------------------------------+ | + | | DOS FAT partition description | | points to CHS=0,1,1 + | +---------------------------------+ | points to CHS=a + | | OS/2 HPFS partition description | | + | +---------------------------------+ | + | | unused table entry | | + | +---------------------------------+ | + | | extended partition entry | | points to CHS=b + | +---------------------------------+ | + +-------------------------------------+ +CHS=0,0,2 | the rest of "track 0" -- this is | : +to | where the software drivers such as | : normally +CHS=0,0,n | Ontrack's Disk Manager or Micro | : unused + | House's EZ Drive are located. | : + +-------------------------------------+ +CHS=0,1,1 | Boot sector for the DOS FAT | : + | partition | : a DOS FAT + +-------------------------------------+ : file +CHS=0,1,2 | rest of the DOS FAT partition | : system +to | (FAT table, root directory and | : +CHS=x-1,n,n | user data area) | : + +-------------------------------------+ +CHS=x,0,1 | Boot sector for the OS/2 HPFS | : + | file system partition | : an OS/2 + +-------------------------------------+ : HPFS file +CHS=x,0,2 | rest of the OS/2 HPFS file system | : system +to | partition | : +CHS=y-1,n,n | | : + +-------------------------------------+ +CHS=y,0,1 | Partition record for the extended | + | partition containing a partition | + | record program (never executed) and | + | a partition table | + | +---------------------------------+ | + | | DOS FAT partition description | | points to CHS=b+1 + | +---------------------------------+ | + | | unused table entry | | + | +---------------------------------+ | + | | unused table entry | | + | +---------------------------------+ | + | | unused table entry | | + | +---------------------------------+ | + +-------------------------------------+ +CHS=y,0,2 | the rest of the first track of the | : normally +to | extended partition | : unused +CHS=y,0,n | | : + +-------------------------------------+ +CHS=y,1,1 | Boot sector for the DOS FAT | : + | partition | : a DOS FAT + +-------------------------------------+ : file +CHS=y,1,2 | rest of the DOS FAT partition | : system +to | (FAT table, root directory and | : +CHS=n,n,n | user data area) | : + +-------------------------------------+ + +EXAMPLE 3 + +Here is a partition record from an extended partition (the first +sector of an extended partition). Note that it contains no +program code. It contains only the partition table and the +signature data. + +OFFSET 0 1 2 3 4 5 6 7 8 9 A B C D E F *0123456789ABCDEF* +000000 00000000 00000000 00000000 00000000 *................* +000010 TO 0001af SAME AS ABOVE +0001b0 00000000 00000000 00000000 00000001 *................* +0001c0 8195060e fe7d3e00 0000344e 03000000 *.....}>...4N....* +0001d0 00000000 00000000 00000000 00000000 *................* +0001e0 00000000 00000000 00000000 00000000 *................* +0001f0 00000000 00000000 00000000 000055aa *..............U.* + +NOTES + +Thanks to yue@heron.Stanford.EDU (Kenneth C. Yue) for pointing +out that in V0 of this document I did not properly describe the +unused sectors normally found around the partition table sectors. + +----------------------------------------------------------------------- + + How It Works -- Master Boot Record + + Version 1a + + by Hale Landis (landis@sugs.tware.com) + + +THE "HOW IT WORKS" SERIES + +This is one of several How It Works documents. The series +currently includes the following: + +* How It Works -- CHS Translation +* How It Works -- Master Boot Record +* How It Works -- DOS Floppy Boot Sector +* How It Works -- OS2 Boot Sector +* How It Works -- Partition Tables + + +MASTER BOOT RECORD + +This article is a disassembly of a Master Boot Record (MBR). The +MBR is the sector at cylinder 0, head 0, sector 1 of a hard disk. +An MBR is created by the FDISK program. The FDISK program of all +operating systems must create a functionally similar MBR. The MBR +is first of what could be many partition sectors, each one +containing a four entry partition table. + +At the completion of your system's Power On Self Test (POST), INT +19 is called. Usually INT 19 tries to read a boot sector from +the first floppy drive. If a boot sector is found on the floppy +disk, the that boot sector is read into memory at location +0000:7C00 and INT 19 jumps to memory location 0000:7C00. +However, if no boot sector is found on the first floppy drive, +INT 19 tries to read the MBR from the first hard drive. If an +MBR is found it is read into memory at location 0000:7c00 and INT +19 jumps to memory location 0000:7c00. The small program in the +MBR will attempt to locate an active (bootable) partition in its +partition table. If such a partition is found, the boot sector +of that partition is read into memory at location 0000:7C00 and +the MBR program jumps to memory location 0000:7C00. Each +operating system has its own boot sector format. The small +program in the boot sector must locate the first part of the +operating system's kernel loader program (or perhaps the kernel +itself or perhaps a "boot manager program") and read that into +memory. + +INT 19 is also called when the CTRL-ALT-DEL keys are used. On +most systems, CTRL-ALT-DEL causes an short version of the POST to +be executed before INT 19 is called. + +===== + +Where stuff is: + + The MBR program code starts at offset 0000. + The MBR messages start at offset 008b. + The partition table starts at offset 00be. + The signature is at offset 00fe. + +Here is a summary of what this thing does: + + If an active partition is found, that partition's boot record + is read into 0000:7c00 and the MBR code jumps to 0000:7c00 + with SI pointing to the partition table entry that describes + the partition being booted. The boot record program uses this + data to determine the drive being booted from and the location + of the partition on the disk. + + If no active partition table enty is found, ROM BASIC is + entered via INT 18. All other errors cause a system hang, see + label HANG. + +NOTES (VERY IMPORTANT): + + 1) The first byte of an active partition table entry is 80. + This byte is loaded into the DL register before INT 13 is + called to read the boot sector. When INT 13 is called, DL is + the BIOS device number. Because of this, the boot sector read + by this MBR program can only be read from BIOS device number + 80 (the first hard disk). This is one of the reasons why it + is usually not possible to boot from any other hard disk. + + 2) The MBR program uses the CHS based INT 13H AH=02H call to + read the boot sector of the active partition. The location of + the active partition's boot sector is in the partition table + entry in CHS format. If the drive is >528MB, this CHS must be + a translated CHS (or L-CHS, see my BIOS TYPES document). + No addresses in LBA form are used (another reason why LBA + doesn't solve the >528MB problem). + +===== + +Here is the entire MBR record (hex dump and ascii). + +OFFSET 0 1 2 3 4 5 6 7 8 9 A B C D E F *0123456789ABCDEF* +000000 fa33c08e d0bc007c 8bf45007 501ffbfc *.3.....|..P.P...* +000010 bf0006b9 0001f2a5 ea1d0600 00bebe07 *................* +000020 b304803c 80740e80 3c00751c 83c610fe *...<.t..<.u.....* +000030 cb75efcd 188b148b 4c028bee 83c610fe *.u......L.......* +000040 cb741a80 3c0074f4 be8b06ac 3c00740b *.t..<.t.....<.t.* +000050 56bb0700 b40ecd10 5eebf0eb febf0500 *V.......^.......* +000060 bb007cb8 010257cd 135f730c 33c0cd13 *..|...W.._s.3...* +000070 4f75edbe a306ebd3 bec206bf fe7d813d *Ou...........}.=* +000080 55aa75c7 8bf5ea00 7c000049 6e76616c *U.u.....|..Inval* +000090 69642070 61727469 74696f6e 20746162 *id partition tab* +0000a0 6c650045 72726f72 206c6f61 64696e67 *le.Error loading* +0000b0 206f7065 72617469 6e672073 79737465 * operating syste* +0000c0 6d004d69 7373696e 67206f70 65726174 *m.Missing operat* +0000d0 696e6720 73797374 656d0000 00000000 *ing system......* +0000e0 00000000 00000000 00000000 00000000 *................* +0000f0 TO 0001af SAME AS ABOVE +0001b0 00000000 00000000 00000000 00008001 *................* +0001c0 0100060d fef83e00 00000678 0d000000 *......>....x....* +0001d0 00000000 00000000 00000000 00000000 *................* +0001e0 00000000 00000000 00000000 00000000 *................* +0001f0 00000000 00000000 00000000 000055aa *..............U.* + +===== + +Here is the disassembly of the MBR... + +This sector is initially loaded into memory at 0000:7c00 but +it immediately relocates itself to 0000:0600. + + BEGIN: NOW AT 0000:7C00, RELOCATE + +0000:7C00 FA CLI disable int's +0000:7C01 33C0 XOR AX,AX set stack seg to 0000 +0000:7C03 8ED0 MOV SS,AX +0000:7C05 BC007C MOV SP,7C00 set stack ptr to 7c00 +0000:7C08 8BF4 MOV SI,SP SI now 7c00 +0000:7C0A 50 PUSH AX +0000:7C0B 07 POP ES ES now 0000:7c00 +0000:7C0C 50 PUSH AX +0000:7C0D 1F POP DS DS now 0000:7c00 +0000:7C0E FB STI allow int's +0000:7C0F FC CLD clear direction +0000:7C10 BF0006 MOV DI,0600 DI now 0600 +0000:7C13 B90001 MOV CX,0100 move 256 words (512 bytes) +0000:7C16 F2 REPNZ move MBR from 0000:7c00 +0000:7C17 A5 MOVSW to 0000:0600 +0000:7C18 EA1D060000 JMP 0000:061D jmp to NEW_LOCATION + + NEW_LOCATION: NOW AT 0000:0600 + +0000:061D BEBE07 MOV SI,07BE point to first table entry +0000:0620 B304 MOV BL,04 there are 4 table entries + + SEARCH_LOOP1: SEARCH FOR AN ACTIVE ENTRY + +0000:0622 803C80 CMP BYTE PTR [SI],80 is this the active entry? +0000:0625 740E JZ FOUND_ACTIVE yes +0000:0627 803C00 CMP BYTE PTR [SI],00 is this an inactive entry? +0000:062A 751C JNZ NOT_ACTIVE no +0000:062C 83C610 ADD SI,+10 incr table ptr by 16 +0000:062F FECB DEC BL decr count +0000:0631 75EF JNZ SEARCH_LOOP1 jmp if not end of table +0000:0633 CD18 INT 18 GO TO ROM BASIC + + FOUND_ACTIVE: FOUND THE ACTIVE ENTRY + +0000:0635 8B14 MOV DX,[SI] set DH/DL for INT 13 call +0000:0637 8B4C02 MOV CX,[SI+02] set CH/CL for INT 13 call +0000:063A 8BEE MOV BP,SI save table ptr + + SEARCH_LOOP2: MAKE SURE ONLY ONE ACTIVE ENTRY + +0000:063C 83C610 ADD SI,+10 incr table ptr by 16 +0000:063F FECB DEC BL decr count +0000:0641 741A JZ READ_BOOT jmp if end of table +0000:0643 803C00 CMP BYTE PTR [SI],00 is this an inactive entry? +0000:0646 74F4 JZ SEARCH_LOOP2 yes + + NOT_ACTIVE: MORE THAN ONE ACTIVE ENTRY FOUND + +0000:0648 BE8B06 MOV SI,068B display "Invld prttn tbl" + + DISPLAY_MSG: DISPLAY MESSAGE LOOP + +0000:064B AC LODSB get char of message +0000:064C 3C00 CMP AL,00 end of message +0000:064E 740B JZ HANG yes +0000:0650 56 PUSH SI save SI +0000:0651 BB0700 MOV BX,0007 screen attributes +0000:0654 B40E MOV AH,0E output 1 char of message +0000:0656 CD10 INT 10 to the display +0000:0658 5E POP SI restore SI +0000:0659 EBF0 JMP DISPLAY_MSG do it again + + HANG: HANG THE SYSTEM LOOP + +0000:065B EBFE JMP HANG sit and stay! + + READ_BOOT: READ ACTIVE PARITION BOOT RECORD + +0000:065D BF0500 MOV DI,0005 INT 13 retry count + + INT13RTRY: INT 13 RETRY LOOP + +0000:0660 BB007C MOV BX,7C00 +0000:0663 B80102 MOV AX,0201 read 1 sector +0000:0666 57 PUSH DI save DI +0000:0667 CD13 INT 13 read sector into 0000:7c00 +0000:0669 5F POP DI restore DI +0000:066A 730C JNB INT13OK jmp if no INT 13 +0000:066C 33C0 XOR AX,AX call INT 13 and +0000:066E CD13 INT 13 do disk reset +0000:0670 4F DEC DI decr DI +0000:0671 75ED JNZ INT13RTRY if not zero, try again +0000:0673 BEA306 MOV SI,06A3 display "Errr ldng systm" +0000:0676 EBD3 JMP DISPLAY_MSG jmp to display loop + + INT13OK: INT 13 ERROR + +0000:0678 BEC206 MOV SI,06C2 "missing op sys" +0000:067B BFFE7D MOV DI,7DFE point to signature +0000:067E 813D55AA CMP WORD PTR [DI],AA55 is signature correct? +0000:0682 75C7 JNZ DISPLAY_MSG no +0000:0684 8BF5 MOV SI,BP set SI +0000:0686 EA007C0000 JMP 0000:7C00 JUMP TO THE BOOT SECTOR + WITH SI POINTING TO + PART TABLE ENTRY + +Messages here. + +0000:0680 ........ ........ ......49 6e76616c * Inval* +0000:0690 69642070 61727469 74696f6e 20746162 *id partition tab* +0000:06a0 6c650045 72726f72 206c6f61 64696e67 *le.Error loading* +0000:06b0 206f7065 72617469 6e672073 79737465 * operating syste* +0000:06c0 6d004d69 7373696e 67206f70 65726174 *m.Missing operat* +0000:06d0 696e6720 73797374 656d00.. ........ *ing system. * + +Data not used. + +0000:06d0 ........ ........ ......00 00000000 * .....* +0000:06e0 00000000 00000000 00000000 00000000 *................* +0000:06f0 00000000 00000000 00000000 00000000 *................* +0000:0700 00000000 00000000 00000000 00000000 *................* +0000:0710 00000000 00000000 00000000 00000000 *................* +0000:0720 00000000 00000000 00000000 00000000 *................* +0000:0730 00000000 00000000 00000000 00000000 *................* +0000:0740 00000000 00000000 00000000 00000000 *................* +0000:0750 00000000 00000000 00000000 00000000 *................* +0000:0760 00000000 00000000 00000000 00000000 *................* +0000:0770 00000000 00000000 00000000 00000000 *................* +0000:0780 00000000 00000000 00000000 00000000 *................* +0000:0790 00000000 00000000 00000000 00000000 *................* +0000:07a0 00000000 00000000 00000000 00000000 *................* +0000:07b0 00000000 00000000 00000000 0000.... *............ * + +The partition table starts at 0000:07be. Each partition table +entry is 16 bytes. This table defines a single primary partition +which is also an active (bootable) partition. + +0000:07b0 ........ ........ ........ ....8001 * ....* +0000:07c0 0100060d fef83e00 00000678 0d000000 *......>....x....* +0000:07d0 00000000 00000000 00000000 00000000 *................* +0000:07e0 00000000 00000000 00000000 00000000 *................* +0000:07f0 00000000 00000000 00000000 0000.... *............ * + +The last two bytes contain a 55AAH signature. + +0000:07f0 ........ ........ ........ ....55aa *..............U.* + +--------------------------------------------------------------------- + + How It Works -- DOS Floppy Disk Boot Sector + + Version 1a + + by Hale Landis (landis@sugs.tware.com) + + +THE "HOW IT WORKS" SERIES + +This is one of several How It Works documents. The series +currently includes the following: + +* How It Works -- CHS Translation +* How It Works -- Master Boot Record +* How It Works -- DOS Floppy Boot Sector +* How It Works -- OS2 Boot Sector +* How It Works -- Partition Tables + + +DOS FLOPPY DISK BOOT SECTOR + +This article is a disassembly of a floppy disk boot sector for a +DOS floppy. The boot sector of a floppy disk is located at +cylinder 0, head 0, sector 1. This sector is created by a floppy +disk formating program, such as the DOS FORMAT program. The boot +sector of a FAT hard disk partition has a similar layout and +function. Basically a bootable FAT hard disk partition looks +like a big floppy during the early stages of the system's boot +processing. + +At the completion of your system's Power On Self Test (POST), INT +19 is called. Usually INT 19 tries to read a boot sector from +the first floppy drive. If a boot sector is found on the floppy +disk, the that boot sector is read into memory at location +0000:7C00 and INT 19 jumps to memory location 0000:7C00. +However, if no boot sector is found on the first floppy drive, +INT 19 tries to read the MBR from the first hard drive. If an +MBR is found it is read into memory at location 0000:7c00 and INT +19 jumps to memory location 0000:7c00. The small program in the +MBR will attempt to locate an active (bootable) partition in its +partition table. If such a partition is found, the boot sector +of that partition is read into memory at location 0000:7C00 and +the MBR program jumps to memory location 0000:7C00. Each +operating system has its own boot sector format. The small +program in the boot sector must locate the first part of the +operating system's kernel loader program (or perhaps the kernel +itself or perhaps a "boot manager program") and read that into +memory. + +INT 19 is also called when the CTRL-ALT-DEL keys are used. On +most systems, CTRL-ALT-DEL causes an short version of the POST to +be executed before INT 19 is called. + +===== + +Where stuff is: + + The BIOS Parameter Block (BPB) starts at offset 0. + The boot sector program starts at offset 3e. + The messages issued by this program start at offset 19e. + The DOS hidden file names start at offset 1e6. + The boot sector signature is at offset 1fe. + +Here is a summary of what this thing does: + +1) Copy Diskette Parameter Table which is pointed to by INT 1E. +2) Alter the copy of the Diskette Parameter Table. +3) Alter INT 1E to point to altered Diskette Parameter Table. +4) Do INT 13 AH=00, disk reset call. +5) Compute sector address of root directory. +6) Read first sector of root directory into 0000:0500. +7) Confirm that first two directory entries are for IO.SYS + and MSDOS.SYS. +8) Read first 3 sectors of IO.SYS into 0000:0700 (or 0070:0000). +9) Leave some information in the registers and jump to + IO.SYS at 0070:0000. + +NOTE: + + This program uses the CHS based INT 13H AH=02 to read the FAT + root directory and to read the IO.SYS file. If the drive is + >528MB, this CHS must be a translated CHS (or L-CHS, see my + BIOS TYPES document). Except for internal computations no + addresses in LBA form are used, another reason why LBA doesn't + solve the >528MB problem. + +===== + +Here is the entire sector in hex and ascii. + +OFFSET 0 1 2 3 4 5 6 7 8 9 A B C D E F *0123456789ABCDEF* +000000 eb3c904d 53444f53 352e3000 02010100 *.<.MSDOS5.0.....* +000010 02e00040 0bf00900 12000200 00000000 *...@............* +000020 00000000 0000295a 5418264e 4f204e41 *......)ZT.&NO NA* +000030 4d452020 20204641 54313220 2020fa33 *ME FAT12 .3* +000040 c08ed0bc 007c1607 bb780036 c5371e56 *.....|...x.6.7.V* +000050 1653bf3e 7cb90b00 fcf3a406 1fc645fe *.S.>|.........E.* +000060 0f8b0e18 7c884df9 894702c7 073e7cfb *....|.M..G...>|.* +000070 cd137279 33c03906 137c7408 8b0e137c *..ry3.9..|t....|* +000080 890e207c a0107cf7 26167c03 061c7c13 *.. |..|.&.|...|.* +000090 161e7c03 060e7c83 d200a350 7c891652 *..|...|....P|..R* +0000a0 7ca3497c 89164b7c b82000f7 26117c8b *|.I|..K|. ..&.|.* +0000b0 1e0b7c03 c348f7f3 0106497c 83164b7c *..|..H....I|..K|* +0000c0 00bb0005 8b16527c a1507ce8 9200721d *......R|.P|...r.* +0000d0 b001e8ac 0072168b fbb90b00 bee67df3 *.....r........}.* +0000e0 a6750a8d 7f20b90b 00f3a674 18be9e7d *.u... .....t...}* +0000f0 e85f0033 c0cd165e 1f8f048f 4402cd19 *._.3...^....D...* +000100 585858eb e88b471a 48488a1e 0d7c32ff *XXX...G.HH...|2.* +000110 f7e30306 497c1316 4b7cbb00 07b90300 *....I|..K|......* +000120 505251e8 3a0072d8 b001e854 00595a58 *PRQ.:.r....T.YZX* +000130 72bb0501 0083d200 031e0b7c e2e28a2e *r..........|....* +000140 157c8a16 247c8b1e 497ca14b 7cea0000 *.|..$|..I|.K|...* +000150 7000ac0a c07429b4 0ebb0700 cd10ebf2 *p....t).........* +000160 3b16187c 7319f736 187cfec2 88164f7c *;..|s..6.|....O|* +000170 33d2f736 1a7c8816 257ca34d 7cf8c3f9 *3..6.|..%|.M|...* +000180 c3b4028b 164d7cb1 06d2e60a 364f7c8b *.....M|.....6O|.* +000190 ca86e98a 16247c8a 36257ccd 13c30d0a *.....$|.6%|.....* +0001a0 4e6f6e2d 53797374 656d2064 69736b20 *Non-System disk * +0001b0 6f722064 69736b20 6572726f 720d0a52 *or disk error..R* +0001c0 65706c61 63652061 6e642070 72657373 *eplace and press* +0001d0 20616e79 206b6579 20776865 6e207265 * any key when re* +0001e0 6164790d 0a00494f 20202020 20205359 *ady...IO SY* +0001f0 534d5344 4f532020 20535953 000055aa *SMSDOS SYS..U.* + +===== + +The first 62 bytes of a boot sector are known as the BIOS +Parameter Block (BPB). Here is the layout of the BPB fields +and the values they are assigned in this boot sector: + + db JMP instruction at 7c00 size 2 = eb3c + db NOP instruction 7c02 1 90 + db OEMname 7c03 8 'MSDOS5.0' + dw bytesPerSector 7c0b 2 0200 + db sectPerCluster 7c0d 1 01 + dw reservedSectors 7c0e 2 0001 + db numFAT 7c10 1 02 + dw numRootDirEntries 7c11 2 00e0 + dw numSectors 7c13 2 0b40 (ignore numSectorsHuge) + db mediaType 7c15 1 f0 + dw numFATsectors 7c16 2 0009 + dw sectorsPerTrack 7c18 2 0012 + dw numHeads 7c1a 2 0002 + dd numHiddenSectors 7c1c 4 00000000 + dd numSectorsHuge 7c20 4 00000000 + db driveNum 7c24 1 00 + db reserved 7c25 1 00 + db signature 7c26 1 29 + dd volumeID 7c27 4 5a541826 + db volumeLabel 7c2b 11 'NO NAME ' + db fileSysType 7c36 8 'FAT12 ' + +===== + +Here is the boot sector... + +The first 3 bytes of the BPB are JMP and NOP instructions. + +0000:7C00 EB3C JMP START +0000:7C02 90 NOP + +Here is the rest of the BPB. + +0000:7C00 ......4d 53444f53 352e3000 02010100 * MSDOS5.0.....* +0000:7C10 02e00040 0bf00900 12000200 00000000 *...@............* +0000:7C20 00000000 0000295a 5418264e 4f204e41 *......)ZT.&NO NA* +0000:7C30 4d452020 20204641 54313220 2020.... *ME FAT12 * + +Now pay attention here... + + The 11 bytes starting at 0000:7c3e are immediately overlaid by + information copied from another part of memory. That + information is the Diskette Parameter Table. This data is + pointed to by INT 1E. This data is: + + 7c3e = Step rate and head unload time. + 7c3f = Head load time and DMA mode flag. + 7c40 = Delay for motor turn off. + 7c41 = Bytes per sector. + 7c42 = Sectors per track. + 7c43 = Intersector gap length. + 7c44 = Data length. + 7c45 = Intersector gap length during format. + 7c46 = Format byte value. + 7c47 = Head settling time. + 7c48 = Delay until motor at normal speed. + + The 11 bytes starting at 0000:7c49 are also overlaid by the + following data: + + 7c49 - 7c4c = diskette sector address (as LBA) + of the data area. + 7c4d - 7c4e = cylinder number to read from. + 7c4f - 7c4f = sector number to read from. + 7c50 - 7c53 = diskette sector address (as LBA) + of the root directory. + + START: START OF BOOT SECTOR PROGRAM + +0000:7C3E FA CLI interrupts off +0000:7C3F 33C0 XOR AX,AX set AX to zero +0000:7C41 8ED0 MOV SS,AX SS is now zero +0000:7C43 BC007C MOV SP,7C00 SP is now 7c00 +0000:7C46 16 PUSH SS also set ES +0000:7C47 07 POP ES to zero + + The INT 1E vector is at 0000:0078. + Get the address that the vector points to + into the DS:SI registers. + +0000:7C48 BB7800 MOV BX,0078 BX is now 78 +0000:7C4B 36 SS: +0000:7C4C C537 LDS SI,[BX] DS:SI is now [0:78] +0000:7C4E 1E PUSH DS save DS:SI -- +0000:7C4F 56 PUSH SI saves param tbl addr +0000:7C50 16 PUSH SS save SS:BX -- +0000:7C51 53 PUSH BX saves INT 1E address + + Move the diskette param table to 0000:7c3e. + +0000:7C52 BF3E7C MOV DI,7C3E DI is address of START +0000:7C55 B90B00 MOV CX,000B count is 11 +0000:7C58 FC CLD clear direction +0000:7C59 F3 REPZ move the diskette param +0000:7C5A A4 MOVSB table to 0000:7c3e +0000:7C5B 06 PUSH ES also set DS +0000:7C5C 1F POP DS to zero + + Alter some of the diskette param table data. + +0000:7C5D C645FE0F MOV BYTE PTR [DI-02],0F change head settle time + at 0000:7c47 +0000:7C61 8B0E187C MOV CX,[7C18] sectors per track +0000:7C65 884DF9 MOV [DI-07],CL save at 0000:7c42 + + Change INT 1E so that it points to the + altered Diskette param table at 0000:7c3e. + +0000:7C68 894702 MOV [BX+02],AX change INT 1E segment +0000:7C6B C7073E7C MOV WORD PTR [BX],7C3E change INT 1E offset + + Call INT 13 with AX=0000, disk reset, so + that the new diskette param table is used. + +0000:7C6F FB STI interrupts on +0000:7C70 CD13 INT 13 do diskette reset call +0000:7C72 7279 JB TALK jmp if any error + + Detemine the starting sector address of + the root directory as an LBA. + +0000:7C74 33C0 XOR AX,AX AX is now zero +0000:7C76 3906137C CMP [7C13],AX number sectros zero? +0000:7C7A 7408 JZ SMALL_DISK yes +0000:7C7C 8B0E137C MOV CX,[7C13] number of sectors +0000:7C80 890E207C MOV [7C20],CX save in huge num sects + + SMALL_DISK: + +0000:7C84 A0107C MOV AL,[7C10] number of FAT tables +0000:7C87 F726167C MUL WORD PTR [7C16] number of fat sectors +0000:7C8B 03061C7C ADD AX,[7C1C] number of hidden sectors +0000:7C8F 13161E7C ADC DX,[7C1E] number of hidden sectors +0000:7C93 03060E7C ADD AX,[7C0E] number of reserved sectors +0000:7C97 83D200 ADC DX,+00 number of reserved sectors +0000:7C9A A3507C MOV [7C50],AX save start addr +0000:7C9D 8916527C MOV [7C52],DX of root dir (as LBA) +0000:7CA1 A3497C MOV [7C49],AX save start addr +0000:7CA4 89164B7C MOV [7C4B],DX of root dir (as LBA) + + Determine sector address of first sector + in the data area as an LBA. + +0000:7CA8 B82000 MOV AX,0020 size of a dir entry (32) +0000:7CAB F726117C MUL WORD PTR [7C11] number of root dir entries +0000:7CAF 8B1E0B7C MOV BX,[7C0B] bytes per sector +0000:7CB3 03C3 ADD AX,BX +0000:7CB5 48 DEC AX +0000:7CB6 F7F3 DIV BX +0000:7CB8 0106497C ADD [7C49],AX add to start addr +0000:7CBC 83164B7C00 ADC WORD PTR [7C4B],+00 of root dir (as LBA) + + Read the first root dir sector into 0000:0500. + +0000:7CC1 BB0005 MOV BX,0500 addr to read into +0000:7CC4 8B16527C MOV DX,[7C52] get start of address +0000:7CC8 A1507C MOV AX,[7C50] of root dir (as LBA) +0000:7CCB E89200 CALL CONVERT call conversion routine +0000:7CCE 721D JB TALK jmp is any error +0000:7CD0 B001 MOV AL,01 read 1 sector +0000:7CD2 E8AC00 CALL READ_SECTORS read 1st root dir sector +0000:7CD5 7216 JB TALK jmp if any error +0000:7CD7 8BFB MOV DI,BX addr of 1st dir entry +0000:7CD9 B90B00 MOV CX,000B count is 11 +0000:7CDC BEE67D MOV SI,7DE6 addr of file names +0000:7CDF F3 REPZ is this "IO.SYS"? +0000:7CE0 A6 CMPSB +0000:7CE1 750A JNZ TALK no +0000:7CE3 8D7F20 LEA DI,[BX+20] addr of next dir entry +0000:7CE6 B90B00 MOV CX,000B count is 11 +0000:7CE9 F3 REPZ is this "MSDOS.SYS"? +0000:7CEA A6 CMPSB +0000:7CEB 7418 JZ FOUND_FILES they are equal + + TALK: + + Display "Non-System disk..." message, + wait for user to hit a key, restore + the INT 1E vector and then + call INT 19 to start boot processing + all over again. + +0000:7CED BE9E7D MOV SI,7D9E "Non-System disk..." +0000:7CF0 E85F00 CALL MSG_LOOP display message +0000:7CF3 33C0 XOR AX,AX INT 16 function +0000:7CF5 CD16 INT 16 read keyboard +0000:7CF7 5E POP SI get INT 1E vector's +0000:7CF8 1F POP DS address +0000:7CF9 8F04 POP [SI] restore the INT 1E +0000:7CFB 8F4402 POP [SI+02] vector's data +0000:7CFE CD19 INT 19 CALL INT 19 to try again + + SETUP_TALK: + +0000:7D00 58 POP AX pop junk off stack +0000:7D01 58 POP AX pop junk off stack +0000:7D02 58 POP AX pop junk off stack +0000:7D03 EBE8 JMP TALK now talk to the user + + FOUND_FILES: + + Compute the sector address of the first + sector of IO.SYS. + +0000:7D05 8B471A MOV AX,[BX+1A] get starting cluster num +0000:7D08 48 DEC AX subtract 1 +0000:7D09 48 DEC AX subtract 1 +0000:7D0A 8A1E0D7C MOV BL,[7C0D] sectors per cluster +0000:7D0E 32FF XOR BH,BH +0000:7D10 F7E3 MUL BX multiply +0000:7D12 0306497C ADD AX,[7C49] add start addr of +0000:7D16 13164B7C ADC DX,[7C4B] root dir (as LBA) + + Read IO.SYS into memory at 0000:0700. IO.SYS + is 3 sectors long. + +0000:7D1A BB0007 MOV BX,0700 address to read into +0000:7D1D B90300 MOV CX,0003 read 3 sectors + + READ_LOOP: + + Read the first 3 sectors of IO.SYS + (IO.SYS is much longer than 3 sectors). + +0000:7D20 50 PUSH AX save AX +0000:7D21 52 PUSH DX save DX +0000:7D22 51 PUSH CX save CX +0000:7D23 E83A00 CALL CONVERT call conversion routine +0000:7D26 72D8 JB SETUP_TALK jmp if error +0000:7D28 B001 MOV AL,01 read one sector +0000:7D2A E85400 CALL READ_SECTORS read one sector +0000:7D2D 59 POP CX restore CX +0000:7D2E 5A POP DX restore DX +0000:7D2F 58 POP AX restore AX +0000:7D30 72BB JB TALK jmp if any INT 13 error +0000:7D32 050100 ADD AX,0001 add one to the sector addr +0000:7D35 83D200 ADC DX,+00 add one to the sector addr +0000:7D38 031E0B7C ADD BX,[7C0B] incr mem addr by sect size +0000:7D3C E2E2 LOOP READ_LOOP read next sector + + Leave information in the AX, BX, CX and DX + registers for IO.SYS to use. Finally, + jump to IO.SYS at 0070:0000. + +0000:7D3E 8A2E157C MOV CH,[7C15] media type +0000:7D42 8A16247C MOV DL,[7C24] drive number +0000:7D46 8B1E497C MOV BX,[7C49] get start addr of +0000:7D4A A14B7C MOV AX,[7C4B] root dir (as LBA) +0000:7D4D EA00007000 JMP 0070:0000 JUMP TO 0070:0000 + + MSG_LOOP: + + This routine displays a message using + INT 10 one character at a time. + The message address is in DS:SI. + +0000:7D52 AC LODSB get message character +0000:7D53 0AC0 OR AL,AL end of message? +0000:7D55 7429 JZ RETURN jmp if yes +0000:7D57 B40E MOV AH,0E display one character +0000:7D59 BB0700 MOV BX,0007 video attrbiutes +0000:7D5C CD10 INT 10 display one character +0000:7D5E EBF2 JMP MSG_LOOP do again + + CONVERT: + This routine + converts a sector address (an LBA) to + a CHS address. The LBA is in DX:AX. + +0000:7D60 3B16187C CMP DX,[7C18] hi part of LBA > sectPerTrk? +0000:7D64 7319 JNB SET_CARRY jmp if yes +0000:7D66 F736187C DIV WORD PTR [7C18] div by sectors per track +0000:7D6A FEC2 INC DL add 1 to sector number +0000:7D6C 88164F7C MOV [7C4F],DL save sector number +0000:7D70 33D2 XOR DX,DX zero DX +0000:7D72 F7361A7C DIV WORD PTR [7C1A] div number of heads +0000:7D76 8816257C MOV [7C25],DL save head number +0000:7D7A A34D7C MOV [7C4D],AX save cylinder number +0000:7D7D F8 CLC clear carry +0000:7D7E C3 RET return + + SET_CARRY: + +0000:7D7F F9 STC set carry + + RETURN: + +0000:7D80 C3 RET return + + READ_SECTORS: + + The caller of this routine supplies: + AL = number of sectors to read + ES:BX = memory location to read into + and CHS address to read from in + memory locations 7c25 and 7C4d-7c4f. + +0000:7D81 B402 MOV AH,02 INT 13 read sectors +0000:7D83 8B164D7C MOV DX,[7C4D] get cylinder number +0000:7D87 B106 MOV CL,06 shift count +0000:7D89 D2E6 SHL DH,CL shift upper cyl left 6 bits +0000:7D8B 0A364F7C OR DH,[7C4F] or in sector number +0000:7D8F 8BCA MOV CX,DX move to CX +0000:7D91 86E9 XCHG CH,CL CH=cyl lo, CL=cyl hi + sect +0000:7D93 8A16247C MOV DL,[7C24] drive number +0000:7D97 8A36257C MOV DH,[7C25] head number +0000:7D9B CD13 INT 13 read sectors +0000:7D9D C3 RET return + +Data not used. + +0000:7D90 ca86e98a 16247c8a 36257ccd 13c3.... *.....$|.6%|... * + +Messages here. + +0000:7D90 ........ ........ ........ ....0d0a * ..* +0000:7Da0 4e6f6e2d 53797374 656d2064 69736b20 *Non-System disk * +0000:7Db0 6f722064 69736b20 6572726f 720d0a52 *or disk error..R* +0000:7Dc0 65706c61 63652061 6e642070 72657373 *eplace and press* +0000:7Dd0 20616e79 206b6579 20776865 6e207265 * any key when re* +0000:7De0 6164790d 0a00.... ........ ........ *ady... * + +MS DOS hidden file names (first two root directory entries). + +0000:7De0 ........ ....494f 20202020 20205359 * IO SY* +0000:7Df0 534d5344 4f532020 20535953 000055aa *SMSDOS SYS..U.* + +The last two bytes contain a 55AAH signature. + +0000:7Df0 ........ ........ ........ ....55aa * U.* + +--------------------------------------------------------------------- + + How It Works -- OS2 Boot Sector + + Version 1a + + by Hale Landis (landis@sugs.tware.com) + + +THE "HOW IT WORKS" SERIES + +This is one of several How It Works documents. The series +currently includes the following: + +* How It Works -- CHS Translation +* How It Works -- Master Boot Record +* How It Works -- DOS Floppy Boot Sector +* How It Works -- OS2 Boot Sector +* How It Works -- Partition Tables + + +OS2 BOOT SECTOR + +Note: I'll leave it to someone else to provide you with a +disassembly of an OS/2 HPFS boot sector, or a Linux boot sector, +or a WinNT boot sector, etc. + +This article is a disassembly of a floppy or hard disk boot +sector for OS/2. Apparently OS/2 uses the same boot sector for +both environments. Basically a bootable FAT hard disk partition +looks like a big floppy during the early stages of the system's +boot processing. This sector is at cylinder 0, head 0, sector 1 +of a floppy or it is the first sector within a FAT hard disk +partition. OS/2 floppy disk and hard disk boot sectors are +created by the OS/2 FORMAT program. + +At the completion of your system's Power On Self Test (POST), INT +19 is called. Usually INT 19 tries to read a boot sector from +the first floppy drive. If a boot sector is found on the floppy +disk, the that boot sector is read into memory at location +0000:7C00 and INT 19 jumps to memory location 0000:7C00. +However, if no boot sector is found on the first floppy drive, +INT 19 tries to read the MBR from the first hard drive. If an +MBR is found it is read into memory at location 0000:7c00 and INT +19 jumps to memory location 0000:7c00. The small program in the +MBR will attempt to locate an active (bootable) partition in its +partition table. If such a partition is found, the boot sector +of that partition is read into memory at location 0000:7C00 and +the MBR program jumps to memory location 0000:7C00. Each +operating system has its own boot sector format. The small +program in the boot sector must locate the first part of the +operating system's kernel loader program (or perhaps the kernel +itself or perhaps a "boot manager program") and read that into +memory. + +INT 19 is also called when the CTRL-ALT-DEL keys are used. On +most systems, CTRL-ALT-DEL causes an short version of the POST to +be executed before INT 19 is called. + +===== + +Where stuff is: + + The BIOS Parameter Block (BPB) starts at offset 0. + The boot sector program starts at offset 46. + The messages issued by this program start at offset 198. + The OS/2 boot loader file name starts at offset 1d5. + The boot sector signature is at offset 1fe. + +Here is a summary of what this thing does: + + 1) If booting from a hard disk partition, skip to step 6. + 2) Copy Diskette Parameter Table which is pointed to by INT 1E + to the top of memory. + 3) Alter the copy of the Diskette Parameter Table. + 4) Alter INT 1E to point to altered Diskette Parameter Table at + the top of memory. + 5) Do INT 13 AH=00, disk reset call so that the altered + Diskette Parameter Table is used. + 6) Compute sector address of the root directory. + 7) Read the entire root directory into memory starting at + location 1000:0000. + 8) Search the root directory entires for the file OS2BOOT. + 9) Read the OS2BOOT file into memory at 0800:0000. +10) Do a far return to enter the OS2BOOT program at 0800:0000. + +NOTES: + + This program uses the CHS based INT 13H AH=02 to read the FAT + root directory and to read the OS2BOOT file. If the drive is + >528MB, this CHS must be a translated CHS (or L-CHS, see my + BIOS TYPES document). Except for internal computations no + addresses in LBA form are used, another reason why LBA doesn't + solve the >528MB problem. + +===== + +Here is the entire sector in hex and ascii. + +OFFSET 0 1 2 3 4 5 6 7 8 9 A B C D E F *0123456789ABCDEF* +000000 eb449049 424d2032 302e3000 02100100 *.D.IBM 20.0.....* +000010 02000200 00f8d800 3e000e00 3e000000 *........>...>...* +000020 06780d00 80002900 1c0c234e 4f204e41 *.x....)...#NO NA* +000030 4d452020 20204641 54202020 20200000 *ME FAT ..* +000040 00100000 0000fa33 db8ed3bc ff7bfbba *.......3.....{..* +000050 c0078eda 803e2400 00753d1e b840008e *.....>$..u=..@..* +000060 c026ff0e 1300cd12 c1e0068e c033ff33 *.&...........3.3* +000070 c08ed8c5 367800fc b90b00f3 a41fa118 *....6x..........* +000080 0026a204 001e33c0 8ed8a378 008c067a *.&....3....x...z* +000090 001f8a16 2400cd13 a0100098 f7261600 *....$........&..* +0000a0 03060e00 5091b820 00f72611 008b1e0b *....P.. ..&.....* +0000b0 0003c348 f7f35003 c1a33e00 b800108e *...H..P...>.....* +0000c0 c033ff59 890e4400 58a34200 33d2e873 *.3.Y..D.X.B.3..s* +0000d0 0033db8b 0e11008b fb51b90b 00bed501 *.3.......Q......* +0000e0 f3a65974 0583c320 e2ede335 268b471c *..Yt... ...5&.G.* +0000f0 268b571e f7360b00 fec08ac8 268b571a *&.W..6......&.W.* +000100 4a4aa00d 0032e4f7 e203063e 0083d200 *JJ...2.....>....* +000110 bb00088e c333ff06 57e82800 8d360b00 *.....3..W.(..6..* +000120 cbbe9801 eb03bead 01e80900 bec201e8 *................* +000130 0300fbeb feac0ac0 7409b40e bb0700cd *........t.......* +000140 10ebf2c3 50525103 061c0013 161e00f7 *....PRQ.........* +000150 361800fe c28ada33 d2f7361a 008afa8b *6......3..6.....* +000160 d0a11800 2ac34050 b402b106 d2e60af3 *....*.@P........* +000170 8bca86e9 8a162400 8af78bdf cd1372a6 *......$.......r.* +000180 5b598bc3 f7260b00 03f85a58 03c383d2 *[Y...&....ZX....* +000190 002acb7f afc31200 4f532f32 20212120 *.*......OS/2 !! * +0001a0 53595330 31343735 0d0a0012 004f532f *SYS01475.....OS/* +0001b0 32202121 20535953 30323032 350d0a00 *2 !! SYS02025...* +0001c0 12004f53 2f322021 21205359 53303230 *..OS/2 !! SYS020* +0001d0 32370d0a 004f5332 424f4f54 20202020 *27...OS2BOOT * +0001e0 00000000 00000000 00000000 00000000 *................* +0001f0 00000000 00000000 00000000 000055aa *..............U.* + +===== + +The first 62 bytes of a boot sector are known as the BIOS +Parameter Block (BPB). Here is the layout of the BPB fields +and the values they are assigned in this boot sector: + + db JMP instruction at 7c00 size 2 = eb44 + db NOP instruction 7c02 1 90 + db OEMname 7c03 8 'IBM 20.0' + dw bytesPerSector 7c0b 2 0200 + db sectPerCluster 7c0d 1 01 + dw reservedSectors 7c0e 2 0001 + db numFAT 7c10 1 02 + dw numRootDirEntries 7c11 2 0200 + dw numSectors 7c13 2 0000 (use numSectorsHuge) + db mediaType 7c15 1 f8 + dw numFATsectors 7c16 2 00d8 + dw sectorsPerTrack 7c18 2 003e + dw numHeads 7c1a 2 000e + dd numHiddenSectors 7c1c 4 00000000 + dd numSectorsHuge 7c20 4 000d7806 + db driveNum 7c24 1 80 + db reserved 7c25 1 00 + db signature 7c26 1 29 + dd volumeID 7c27 4 001c0c23 + db volumeLabel 7c2b 11 'NO NAME ' + db fileSysType 7c36 8 'FAT ' + +===== + +Here is the boot sector... + +The first 3 bytes of the BPB are JMP and NOP instructions. + +0000:7C00 EB44 JMP START +0000:7C02 90 NOP + +Here is the rest of the BPB. + +0000:7C00 eb449049 424d2032 302e3000 02100100 *.D.IBM 20.0.....* +0000:7C10 02000200 00f8d800 3e000e00 3e000000 *........>...>...* +0000:7C20 06780d00 80002900 1c0c234e 4f204e41 *.x....)...#NO NA* +0000:7C30 4d452020 20204641 54202020 20200000 *ME FAT ..* + +Additional data areas. + +0000:7C30 ........ ........ ........ ....0000 * ..* +0000:7C40 00100000 0000.... ........ ........ *...... * + + Note: + + 0000:7c3e (DS:003e) = number of sectors in the FATs and root dir. + 0000:7c42 (DS:0042) = number of sectors in the FAT. + 0000:7c44 (DS:0044) = number of sectors in the root dir. + + START: START OF BOOT SECTOR PROGRAM + +0000:7C46 FA CLI interrupts off +0000:7C47 33DB XOR BX,BX zero BX +0000:7C49 8ED3 MOV SS,BX SS now zero +0000:7C4B BCFF7B MOV SP,7BFF SP now 7bff +0000:7C4E FB STI interrupts on +0000:7C4F BAC007 MOV DX,07C0 set DX to +0000:7C52 8EDA MOV DS,DX 07c0 + + Are we booting from a floppy or a + hard disk partition? + +0000:7C54 803E240000 CMP BYTE PTR [0024],00 is driveNum in BPB 00? +0000:7C59 753D JNZ NOT_FLOPPY jmp if not zero + + We are booting from a floppy. The + Diskette Parameter Table must be + copied and altered... + + Diskette Parameter Table is pointed to by INT 1E. This + program moves this table to high memory, alters the table, and + changes INT 1E to point to the altered table. + + This table contains the following data: + + ????:0000 = Step rate and head unload time. + ????:0001 = Head load time and DMA mode flag. + ????:0002 = Delay for motor turn off. + ????:0003 = Bytes per sector. + ????:0004 = Sectors per track. + ????:0005 = Intersector gap length. + ????:0006 = Data length. + ????:0007 = Intersector gap length during format. + ????:0008 = Format byte value. + ????:0009 = Head settling time. + ????:000a = Delay until motor at normal speed. + + Compute a valid high memory address. + +0000:7C5B 1E PUSH DS save DS +0000:7C5C B84000 MOV AX,0040 set ES +0000:7C5F 8EC0 MOV ES,AX to 0040 (BIOS data area) +0000:7C61 26 ES: reduce system memory +0000:7C62 FF0E1300 DEC WORD PTR [0013] size by 1024 +0000:7C66 CD12 INT 12 get system memory size +0000:7C68 C1E06 SHL AX,06 shift AX (mult by 64) +0000:7C6B 8EC0 MOV ES,AX move to ES +0000:7C6D 33FF XOR DI,DI zero DI + + Move the diskette param table to high memory. + +0000:7C6F 33C0 XOR AX,AX zero AX +0000:7C71 8ED8 MOV DS,AX DS now zero +0000:7C73 C5367800 LDS SI,[0078] DS:SI = INT 1E vector +0000:7C77 FC CLD clear direction +0000:7C78 B90B00 MOV CX,000B count is 11 +0000:7C7B F3 REPZ copy diskette param table +0000:7C7C A4 MOVSB to top of memory + + Alter the number of sectors per track + in the diskette param table in high memory. + +0000:7C7D 1F POP DS restore DS +0000:7C7E A11800 MOV AX,[0018] get sectorsPerTrack from BPB +0000:7C81 26 ES: alter sectors per track +0000:7C82 A20400 MOV [0004],AL in diskette param table + + Change INT 1E to point to altered diskette + param table and do a INT 13 disk reset call. + +0000:7C85 1E PUSH DS save DS +0000:7C86 33C0 XOR AX,AX AX now zero +0000:7C88 8ED8 MOV DS,AX DS no zero +0000:7C8A A37800 MOV [0078],AX alter INT 1E vector +0000:7C8D 8C067A00 MOV [007A],ES to point to altered + diskette param table +0000:7C91 1F POP DS restore DS +0000:7C92 8A162400 MOV DL,[0024] driveNum from BPB +0000:7C96 CD13 INT 13 diskette reset + + NOT_FLOPPY: + + Compute the location and the size of + the root directory. Read the entire + root directory into memory. + +0000:7C98 A01000 MOV AL,[0010] get numFAT +0000:7C9B 98 CBW make into a word +0000:7C9C F7261600 MUL WORD PTR [0016] mult by numFatSectors +0000:7CA0 03060E00 ADD AX,[000E] add reservedSectors +0000:7CA4 50 PUSH AX save +0000:7CA5 91 XCHG CX,AX move to CX +0000:7CA6 B82000 MOV AX,0020 dir entry size +0000:7CA9 F7261100 MUL WORD PTR [0011] mult by numRootDirEntries +0000:7CAD 8B1E0B00 MOV BX,[000B] get bytesPerSector +0000:7CB1 03C3 ADD AX,BX add +0000:7CB3 48 DEC AX subtract 1 +0000:7CB4 F7F3 DIV BX div by bytesPerSector +0000:7CB6 50 PUSH AX save number of dir sectors +0000:7CB7 03C1 ADD AX,CX add number of fat sectors +0000:7CB9 A33E00 MOV [003E],AX save +0000:7CBC B80010 MOV AX,1000 AX is now 1000 +0000:7CBF 8EC0 MOV ES,AX ES is now 1000 +0000:7CC1 33FF XOR DI,DI DI is now zero +0000:7CC3 59 POP CX get number dir sectors +0000:7CC4 890E4400 MOV [0044],CX save +0000:7CC8 58 POP AX get number fat sectors +0000:7CC9 A34200 MOV [0042],AX save +0000:7CCC 33D2 XOR DX,DX DX now zero +0000:7CCE E87300 CALL READ_SECTOR read 1st sect of root dir +0000:7CD1 33DB XOR BX,BX BX is now zero +0000:7CD3 8B0E1100 MOV CX,[0011] number of root dir entries + + DIR_SEARCH: SEARCH FOR OS2BOOT. + + Search the root directory for the file + name OS2BOOT. + +0000:7CD7 8BFB MOV DI,BX DI is dir entry addr +0000:7CD9 51 PUSH CX save CX +0000:7CDA B90B00 MOV CX,000B count is 11 +0000:7CDD BED501 MOV SI,01D5 addr of "OS2BOOT" +0000:7CE0 F3 REPZ is 1st dir entry +0000:7CE1 A6 CMPSB for "OS2BOOT"? +0000:7CE2 59 POP CX restore CX +0000:7CE3 7405 JZ FOUND_OS2BOOT jmp if OS2BOOT +0000:7CE5 83C320 ADD BX,+20 incr to next dir entry +0000:7CE8 E2ED LOOP DIR_SEARCH try again + + FOUND_OS2BOOT: FOUND OS2BOOT. + + OS2BOOT was found. Get the starting + cluster number and convert to a sector + address. Read OS2BOOT into memory and + finally do a far return to enter + the OS2BOOT program. + +0000:7CEA E335 JCXZ FAILED1 JMP if CX zero. +0000:7CEC 26 ES: get the szie of +0000:7CED 8B471C MOV AX,[BX+1C] the OS2BOOT file +0000:7CF0 26 ES: from the OS2BOOT +0000:7CF1 8B571E MOV DX,[BX+1E] directory entry +0000:7CF4 F7360B00 DIV WORD PTR [000B] div by bytesPerSect +0000:7CF8 FEC0 INC AL add 1 +0000:7CFA 8AC8 MOV CL,AL num sectors OS2BOOT +0000:7CFC 26 ES: get the starting +0000:7CFD 8B571A MOV DX,[BX+1A] cluster number +0000:7D00 4A DEC DX subtract 1 +0000:7D01 4A DEC DX subtract 1 +0000:7D02 A00D00 MOV AL,[000D] sectorsPerCluster +0000:7D05 32E4 XOR AH,AH mutiply +0000:7D07 F7E2 MUL DX to get LBA +0000:7D09 03063E00 ADD AX,[003E] add number of FAT sectors +0000:7D0D 83D200 ADC DX,+00 to LBA +0000:7D10 BB0008 MOV BX,0800 set ES +0000:7D13 8EC3 MOV ES,BX to 0800 +0000:7D15 33FF XOR DI,DI set ES:DI to entry point +0000:7D17 06 PUSH ES address of +0000:7D18 57 PUSH DI OS2BOOT +0000:7D19 E82800 CALL READ_SECTOR read OS2BOOT into memory +0000:7D1C 8D360B00 LEA SI,[000B] set DS:SI +0000:7D20 CB RETF "far return" to OS2BOOT + + FAILED1: OS2BOOT WAS NOT FOUND. + +0000:7D21 BE9801 MOV SI,0198 "SYS01475" message +0000:7D24 EB03 JMP FAILED3 + + FAILED2: ERROR FROM INT 13. + +0000:7D26 BEAD01 MOV SI,01AD "SYS02025" message + + FAILED3: OUTPUT ERROR MESSAGES. + +0000:7D29 E80900 CALL MSG_LOOP display message +0000:7D2C BEC201 MOV SI,01C2 "SYS02027" message +0000:7D2F E80300 CALL MSG_LOOP display message +0000:7D32 FB STI interrupts on + + HANG: HANG THE SYSTEM! + +0000:7D33 EBFE JMP HANG sit and stay! + + MSG_LOOP: DISPLAY AN ERROR MESSAGE. + + Routine to display the message + text pointed to by SI. + +0000:7D35 AC LODSB get next char of message +0000:7D36 0AC0 OR AL,AL end of message? +0000:7D38 7409 JZ RETURN jmp if yes +0000:7D3A B40E MOV AH,0E write 1 char +0000:7D3C BB0700 MOV BX,0007 video attributes +0000:7D3F CD10 INT 10 INT 10 to write 1 char +0000:7D41 EBF2 JMP MSG_LOOP do again + + RETURN: + +0000:7D43 C3 RET return + + READ_SECTOR: ROUTINE TO READ SECTORS. + + Read sectors into memory. Read multiple + sectors but don't read across a track + boundary. + + The caller supplies the following: + DX:AX = sector address to read (as LBA) + CX = number of sectors to read + ES:DI = memory address to read into + +0000:7D44 50 PUSH AX save lower part of LBA +0000:7D45 52 PUSH DX save upper part of LBA +0000:7D46 51 PUSH CX save number of sect to read +0000:7D47 03061C00 ADD AX,[001C] add numHiddenSectors +0000:7D4B 13161E00 ADC DX,[001E] to LBA +0000:7D4F F7361800 DIV WORD PTR [0018] div by sectorsPerTrack +0000:7D53 FEC2 INC DL add 1 to sector number +0000:7D55 8ADA MOV BL,DL save sector number +0000:7D57 33D2 XOR DX,DX zero upper part of LBA +0000:7D59 F7361A00 DIV WORD PTR [001A] div by numHeads +0000:7D5D 8AFA MOV BH,DL save head number +0000:7D5F 8BD0 MOV DX,AX save cylinder number +0000:7D61 A11800 MOV AX,[0018] sectorsPerTrack +0000:7D64 2AC3 SUB AL,BL sub sector number +0000:7D66 40 INC AX add 1 +0000:7D67 50 PUSH AX save number of sector to rea +d +0000:7D68 B402 MOV AH,02 INT 13 read sectors +0000:7D6A B106 MOV CL,06 shift count +0000:7D6C D2E6 SHL DH,CL shift high cyl left +0000:7D6E 0AF3 OR DH,BL or in sector number +0000:7D70 8BCA MOV CX,DX move cyl/sect to CX +0000:7D72 86E9 XCHG CH,CL swap cyl/sect +0000:7D74 8A162400 MOV DL,[0024] driveNum +0000:7D78 8AF7 MOV DH,BH head number +0000:7D7A 8BDF MOV BX,DI memory addr to read into +0000:7D7C CD13 INT 13 INT 13 read sectors call +0000:7D7E 72A6 JB FAILED2 jmp if any error +0000:7D80 5B POP BX get number of sectors read +0000:7D81 59 POP CX restore CX +0000:7D82 8BC3 MOV AX,BX number of sector to AX +0000:7D84 F7260B00 MUL WORD PTR [000B] multiply by sector size +0000:7D88 03F8 ADD DI,AX add to memory address +0000:7D8A 5A POP DX restore upper part of LBA +0000:7D8B 58 POP AX resotre lower part of LBA +0000:7D8C 03C3 ADD AX,BX add number of sector just +0000:7D8E 83D200 ADC DX,+00 read to LBA +0000:7D91 2ACB SUB CL,BL decr requested num of sect +0000:7D93 7FAF JG READ_SECTOR jmp if not zero +0000:7D95 C3 RET return + +Data not used. + +0000:7D90 ........ ....1200 ........ ........ * .. * + +Messages here. + +0000:7D90 ........ ........ 4f532f32 20212120 * OS/2 !! * +0000:7Da0 53595330 31343735 0d0a0012 004f532f *SYS01475.....OS/* +0000:7Db0 32202121 20535953 30323032 350d0a00 *2 !! SYS02025...* +0000:7Dc0 12004f53 2f322021 21205359 53303230 *..OS/2 !! SYS020* +0000:7Dd0 32370d0a 00...... ........ ........ *27... * + +OS/2 loader file name. + +0000:7Dd0 ........ ..4f5332 424f4f54 20202020 * OS2BOOT * + +Data not used. + +0000:7De0 00000000 00000000 00000000 00000000 *................* +0000:7Df0 00000000 00000000 00000000 0000.... *.............. * + +The last two bytes contain a 55AAH signature. + +0000:7Df0 ........ ........ ........ ....55aa * U.* + diff --git a/docs/TODO b/docs/TODO new file mode 100644 index 000000000..7e8888fe4 --- /dev/null +++ b/docs/TODO @@ -0,0 +1,21 @@ + + Check for other patches sent in e-mail!!! There are several... + + Add support/delays so that a floppy can be installed from + another floppy. + + Add bootable CDROM support (this probably means I have to support + ISO-9660 plus maybe even the Rock Ridge extensions... ugh). + Add/Finish LBA and/or Int13 extensions support. + + Fix keyboard/gateA20 bug (???? at least look at the code). + The keyboard status bits may be checked wrong. + + Add indirect block support to the BSD FFS filesystem code, so files + larger than 16MB can be read. + ??? Make symbolic links work for BSD FFS and Linux ext2fs filesystems. + + ??? Add command for modifying partition types. + + Fix-up FreeBSD, NetBSD (and OpenBSD ?) command-line boot parameters + diff --git a/docs/bios_mapping.txt b/docs/bios_mapping.txt new file mode 100644 index 000000000..b32d96351 --- /dev/null +++ b/docs/bios_mapping.txt @@ -0,0 +1,68 @@ + + +BIOS Device Mapping Techniques + + +NOTE: This is only necessary to do for hard disks. Floppies are + already easy to determine. (IDE are in the order of "Master from + controller on INT 14, Slave from controller on INT 14, Master from + controller on INT 15, and Slave from controller on INT 15, and + always come before SCSI) + + +Both of these techniques should be usable from any PC OS, and neither +require any special support in the drivers themselves. This document +will be flushed out into detailed explanations, particularly for #2 +below. + +The general rule is that technique #1 is the quick and dirty solution. +It works most of the time, but doesn't cover all the bases, and is +relatively simple. + +Technique #2 is much more complex, but it has potential to solve the +problem under all conditions, plus allow access of the remaining +BIOS devices when not all of them have OS drivers. + + +-- BIOS device mapping technique #1 -- + +Before activating ANY of the device drivers, gather enough data +from similar sectors on each of the disks such that each one can be +uniquely identified. + +After activating the device drivers, compare data from the drives +using the OS drivers. This should hopefully be sufficient to provide +such a mapping. + +Problems: (1) The data on some BIOS devices might be identical (so +the part reading the drives from the BIOS should have some mechanism +to give up), and (2) There might be extra drives not accessible from +the BIOS which are identical to some drive used by the BIOS (so it +should be capable of giving up there as well). + + +-- BIOS device mapping technique #2 -- + +This first step may be unnecessary, but first create copy-on-write +mappings for the device drivers writing into PC RAM. Keep the original +copies for the "clean BIOS virtual machine" to be created later. + +For each device driver brought online, determine which BIOS devices +become inaccessible by: + + -- Creating a "clean BIOS virtual machine". + -- Set the I/O permission map for the I/O area claimed by the device driver + to no permissions (neither read nor write). + -- Access each device. + -- Record which devices succed, and those which try to access the + "restricted" I/O areas (hopefully, this will be an "xor" situation). + +For each device driver, given how many of the BIOS devices were subsumed +by it (there should be no gaps in this list), it should be easy to +determine which devices on the controller these are. + +In general, you have at most 2 disks from each controller given BIOS numbers, +but they pretty much always count from the lowest logically numbered devices +on the controller. + + diff --git a/docs/boot-proposal.html b/docs/boot-proposal.html new file mode 100644 index 000000000..bd414447c --- /dev/null +++ b/docs/boot-proposal.html @@ -0,0 +1,664 @@ + + + +Multiboot Standard + + + + +

Multiboot Standard

+

Version 0.6

+ +
+ +

Contents

+ + + +
+ +

Motivation

+ +Every OS ever created tends to have its own boot loader. Installing a new +OS on a machine generally involves installing a whole new set of boot +mechanisms, each with completely different install-time and boot-time user +interfaces. Getting multiple operating systems to coexist reliably on one +machine through typical "chaining" mechanisms can be a nightmare. There is +little or no choice of boot loaders for a particular operating system - if +the one that comes with the OS doesn't do exactly what you want, or doesn't +work on your machine, you're screwed.

+ +While we may not be able to fix this problem in existing commercial +operating systems, it shouldn't be too difficult for a few people in the +free OS communities to put their heads together and solve this problem for +the popular free operating systems. That's what this standard aims for. +Basically, it specifies an interface between a boot loader and a operating +system, such that any complying boot loader should be able to load any +complying operating system. This standard does NOT specify how boot +loaders should work - only how they must interface with the OS being +loaded.

+ +


+ +

Terminology

+ +Throughout this document, the term "boot loader" means whatever program or +set of programs loads the image of the final operating system to be run on +the machine. The boot loader may itself consist of several stages, but +that is an implementation detail not relevant to this standard. Only the +"final" stage of the boot loader - the stage that eventually transfers +control to the OS - needs to follow the rules specified in this document +in order to be "MultiBoot compliant"; earlier boot loader stages can be +designed in whatever way is most convenient.

+ +The term "OS image" is used to refer to the initial binary image that the +boot loader loads into memory and transfers control to to start the OS. +The OS image is typically an executable containing the OS kernel.

+ +The term "boot module" refers to other auxiliary files that the boot loader +loads into memory along with the OS image, but does not interpret in any +way other than passing their locations to the OS when it is invoked.

+ +


+ +

Scope and Requirements

+ +

Architectures

+ +This standard is primarily targetted at PC's, since they are the most +common and have the largest variety of OS's and boot loaders. However, to +the extent that certain other architectures may need a boot standard and do +not have one already, a variation of this standard, stripped of the +x86-specific details, could be adopted for them as well.

+ +

Operating systems

+ +This standard is targetted toward free 32-bit operating systems that can be +fairly easily modified to support the standard without going through lots of +bureaucratic rigmarole. The particular free OS's that this standard is +being primarily designed for are Linux, FreeBSD, NetBSD, Mach, and VSTa. +It is hoped that other emerging free OS's will adopt it from the start, and +thus immediately be able to take advantage of existing boot loaders. It +would be nice if commercial operating system vendors eventually adopted +this standard as well, but that's probably a pipe dream.

+ +

Boot sources

+ +It should be possible to write compliant boot loaders that +load the OS image from a variety of sources, including floppy disk, hard +disk, and across a network.

+ +Disk-based boot loaders may use a variety of techniques to find the +relevant OS image and boot module data on disk, such as by interpretation +of specific file systems (e.g. the BSD/Mach boot loader), using +precalculated "block lists" (e.g. LILO), loading from a special "boot +partition" (e.g. OS/2), or even loading from within another operating +system (e.g. the VSTa boot code, which loads from DOS). Similarly, +network-based boot loaders could use a variety of network hardware and +protocols.

+ +It is hoped that boot loaders will be created that support multiple loading +mechanisms, increasing their portability, robustness, and +user-friendliness.

+ +

Boot-time configuration

+ +It is often necessary for one reason or another for the user to be able to +provide some configuration information to the OS dynamically at boot time. +While this standard should not dictate how this configuration information +is obtained by the boot loader, it should provide a standard means for the +boot loader to pass such information to the OS.

+ +

Convenience to the OS

+ +OS images should be easy to generate. Ideally, an OS image should simply +be an ordinary 32-bit executable file in whatever file format the OS +normally uses. It should be possible to 'nm' or disassemble OS images just +like normal executables. Specialized tools should not be needed to create +OS images in a "special" file format. If this means shifting some work +from the OS to the boot loader, that is probably appropriate, because all +the memory consumed by the boot loader will typically be made available +again after the boot process is created, whereas every bit of code in the +OS image typically has to remain in memory forever. The OS should not have +to worry about getting into 32-bit mode initially, because mode switching +code generally needs to be in the boot loader anyway in order to load OS +data above the 1MB boundary, and forcing the OS to do this makes creation +of OS images much more difficult.

+ +Unfortunately, there is a horrendous variety of executable file formats +even among free Unix-like PC-based OS's - generally a different format for +each OS. Most of the relevant free OS's use some variant of a.out format, +but some are moving to ELF. It is highly desirable for boot loaders not to +have to be able to interpret all the different types of executable file +formats in existence in order to load the OS image - otherwise the boot +loader effectively becomes OS-specific again.

+ +This standard adopts a compromise solution to this problem. +MultiBoot compliant boot images always either (a) are in ELF format, or (b) +contain a "magic MultiBoot header", described below, which allows the boot +loader to load the image without having to understand numerous a.out +variants or other executable formats. This magic header does not need +to be at the very beginning of the executable file, so kernel images can +still conform to the local a.out format variant in addition to being +MultiBoot compliant.

+ +

Boot modules

+ +Many modern operating system kernels, such as those of VSTa and Mach, do +not by themselves contain enough mechanism to get the system fully +operational: they require the presence of additional software modules at +boot time in order to access devices, mount file systems, etc. While these +additional modules could be embedded in the main OS image along with the +kernel itself, and the resulting image be split apart manually by the OS +when it receives control, it is often more flexible, more space-efficient, +and more convenient to the OS and user if the boot loader can load these +additional modules independently in the first place.

+ +Thus, this standard should provide a standard method for a boot loader to +indicate to the OS what auxiliary boot modules were loaded, and where they +can be found. Boot loaders don't have to support multiple boot modules, +but they are strongly encouraged to, because some OS's will be unable to +boot without them.

+ +


+ +

Details

+ +There are three main aspects of the boot-loader/OS image interface this +standard must specify:

+ +

    +
  • The format of the OS image as seen by the boot loader. +
  • The state of the machine when the boot loader starts the OS. +
  • The format of the information passed by the boot loader to the OS. +
+ +

OS Image Format

+ +An OS image is generally just an ordinary 32-bit executable file in the +standard format for that particular OS, except that it may be linked at a +non-default load address to avoid loading on top of the PC's I/O region +or other reserved areas, and of course it can't use shared libraries or +other fancy features. Initially, only images in a.out format are +supported; ELF support will probably later be specified in the standard.

+ +Unfortunately, the exact meaning of the text, data, bss, and entry fields +of a.out headers tends to vary widely between different executable flavors, +and it is sometimes very difficult to distinguish one flavor from another +(e.g. Linux ZMAGIC executables and Mach ZMAGIC executables). Furthermore, +there is no simple, reliable way of determining at what address in memory +the text segment is supposed to start. Therefore, this standard requires +that an additional header, known as a 'multiboot_header', appear somewhere +near the beginning of the executable file. In general it should come "as +early as possible", and is typically embedded in the beginning of the text +segment after the "real" executable header. It _must_ be contained +completely within the first 8192 bytes of the executable file, and must be +longword (32-bit) aligned. These rules allow the boot loader to find and +synchronize with the text segment in the a.out file without knowing +beforehand the details of the a.out variant. The layout of the header is +as follows:

+ +

+	+-------------------+
+0	| magic: 0x1BADB002 |	(required)
+4	| flags		    |	(required)
+8	| checksum	    |	(required)
+	+-------------------+
+8	| header_addr	    |	(present if flags[16] is set)
+12	| load_addr	    |	(present if flags[16] is set)
+16	| load_end_addr	    |	(present if flags[16] is set)
+20	| bss_end_addr	    |	(present if flags[16] is set)
+24	| entry_addr	    |	(present if flags[16] is set)
+	+-------------------+
+
+ +All fields are in little-endian byte order, of course. The first field is +the magic number identifying the header, which must be the hex value +0x1BADB002.

+ +The flags field specifies features that the OS image requests or requires +of the boot loader. Bits 0-15 indicate requirements; if the boot loader +sees any of these bits set but doesn't understand the flag or can't fulfill +the requirements it indicates for some reason, it must notify the user and +fail to load the OS image. Bits 16-31 indicate optional features; if any +bits in this range are set but the boot loader doesn't understand them, it +can simply ignore them and proceed as usual. Naturally, all +as-yet-undefined bits in the flags word must be set to zero in OS +images. This way, the flags fields serves for version control as well as +simple feature selection.

+ +If bit 0 in the flags word is set, then all boot modules loaded along with +the OS must be aligned on page (4KB) boundaries. Some OS's expect to be +able to map the pages containing boot modules directly into a paged address +space during startup, and thus need the boot modules to be page-aligned.

+ +If bit 1 in the flags word is set, then information on available memory +via at least the 'mem_*' fields of the multiboot_info structure defined +below must be included. If the bootloader is capable of passing a memory +map (the 'mmap_*' fields) and one exists, then it must be included as +well.

+ +If bit 16 in the flags word is set, then the fields at offsets 8-24 in the +multiboot_header are valid, and the boot loader should use them instead of +the fields in the actual executable header to calculate where to load the +OS image. This information does not need to be provided if the kernel +image is in ELF format, but it should be provided if the images is in a.out +format or in some other format. Compliant boot loaders must be able to +load images that either are in ELF format or contain the load address +information embedded in the multiboot_header; they may also directly +support other executable formats, such as particular a.out variants, but +are not required to.

+ +All of the address fields enabled by flag bit 16 are physical addresses. +The meaning of each is as follows:

+ +

    +
  • header_addr -- Contains the address corresponding to the +beginning of the multiboot_header - the physical memory location at which +the magic value is supposed to be loaded. This field serves to "synchronize" +the mapping between OS image offsets and physical memory addresses. +
  • load_addr -- Contains the physical address of the beginning +of the text segment. The offset in the OS image file at which to start +loading is defined by the offset at which the header was found, minus +(header_addr - load_addr). load_addr must be less than or equal to +header_addr. +
  • load_end_addr -- Contains the physical address of the end of the +data segment. (load_end_addr - load_addr) specifies how much data to load. +This implies that the text and data segments must be consecutive in the +OS image; this is true for existing a.out executable formats. +
  • bss_end_addr -- Contains the physical address of the end of +the bss segment. The boot loader initializes this area to zero, and +reserves the memory it occupies to avoid placing boot modules and other +data relevant to the OS in that area. +
  • entry -- The physical address to which the boot loader should +jump in order to start running the OS. +
+ +The checksum is a 32-bit unsigned value which, when added to +the other required fields, must have a 32-bit unsigned sum of zero.

+ +

Machine State

+ +When the boot loader invokes the 32-bit operating system, +the machine must have the following state:

+ +

    +
  • CS must be a 32-bit read/execute code segment with an offset of 0 +and a limit of 0xffffffff. +
  • DS, ES, FS, GS, and SS must be a 32-bit read/write data segment with +an offset of 0 and a limit of 0xffffffff. +
  • The address 20 line must be usable for standard linear 32-bit +addressing of memory (in standard PC hardware, it is wired to +0 at bootup, forcing addresses in the 1-2 MB range to be mapped to the +0-1 MB range, 3-4 is mapped to 2-3, etc.). +
  • Paging must be turned off. +
  • The processor interrupt flag must be turned off. +
  • EAX must contain the magic value 0x2BADB002; the presence of this value +indicates to the OS that it was loaded by a MultiBoot-compliant boot +loader (e.g. as opposed to another type of boot loader that the OS can +also be loaded from). +
  • EBX must contain the 32-bit physical address of the multiboot_info +structure provided by the boot loader (see below). +
+ +All other processor registers and flag bits are undefined. This includes, +in particular:

+ +

    +
  • ESP: the 32-bit OS must create its own stack as soon as it needs one. +
  • GDTR: Even though the segment registers are set up as described above, +the GDTR may be invalid, so the OS must not load any segment registers +(even just reloading the same values!) until it sets up its own GDT. +
  • IDTR: The OS must leave interrupts disabled until it sets up its own IDT. +
+ +However, other machine state should be left by the boot loader in "normal +working order", i.e. as initialized by the BIOS (or DOS, if that's what +the boot loader runs from). In other words, the OS should be able to make +BIOS calls and such after being loaded, as long as it does not overwrite +the BIOS data structures before doing so. Also, the boot loader must leave +the PIC programmed with the normal BIOS/DOS values, even if it changed them +during the switch to 32-bit mode.

+ +

Boot Information Format

+ +Upon entry to the OS, the EBX register contains the physical address of +a 'multiboot_info' data structure, through which the boot loader +communicates vital information to the OS. The OS can use or ignore any +parts of the structure as it chooses; all information passed by the boot +loader is advisory only.

+ +The multiboot_info structure and its related substructures may be placed +anywhere in memory by the boot loader (with the exception of the memory +reserved for the kernel and boot modules, of course). It is the OS's +responsibility to avoid overwriting this memory until it is done using it.

+ +The format of the multiboot_info structure (as defined so far) follows:

+ +

+	+-------------------+
+0	| flags		    |	(required)
+	+-------------------+
+4	| mem_lower	    |	(present if flags[0] is set)
+8	| mem_upper	    |	(present if flags[0] is set)
+	+-------------------+
+12	| boot_device	    |	(present if flags[1] is set)
+	+-------------------+
+16	| cmdline	    |	(present if flags[2] is set)
+	+-------------------+
+20	| mods_count	    |	(present if flags[3] is set)
+24	| mods_addr	    |	(present if flags[3] is set)
+	+-------------------+
+28 - 40 | syms		    |   (present if flags[4] or flags[5] is set)
+	+-------------------+
+44	| mmap_length	    |	(present if flags[6] is set)
+48	| mmap_addr	    |	(present if flags[6] is set)
+	+-------------------+
+
+ +The first longword indicates the presence and validity of other fields in +the multiboot_info structure. All as-yet-undefined bits must be set to +zero by the boot loader. Any set bits that the OS does not understand +should be ignored. Thus, the flags field also functions as a version +indicator, allowing the multiboot_info structure to be expanded in the +future without breaking anything.

+ +If bit 0 in the multiboot_info.flags word is set, then the 'mem_*' fields +are valid. 'mem_lower' and 'mem_upper' indicate the amount of lower and upper +memory, respectively, in kilobytes. Lower memory starts at address 0, and +upper memory starts at address 1 megabyte. The maximum possible +value for lower memory is 640 kilobytes. The value returned for upper +memory is maximally the address of the first upper memory hole minus +1 megabyte. It is not guaranteed to be this value.

+ +If bit 1 in the multiboot_info.flags word is set, then the 'boot_device' +field is valid, and indicates which BIOS disk device the boot loader loaded +the OS from. If the OS was not loaded from a BIOS disk, then this field +must not be present (bit 3 must be clear). The OS may use this field as a +hint for determining its own "root" device, but is not required to. The +boot_device field is layed out in four one-byte subfields as follows:

+ +

+	+-------+-------+-------+-------+
+	| drive | part1 | part2 | part3 |
+	+-------+-------+-------+-------+
+
+ +The first byte contains the BIOS drive number as understood by the BIOS +INT 0x13 low-level disk interface: e.g. 0x00 for the first floppy disk or +0x80 for the first hard disk.

+ +The three remaining bytes specify the boot partition. 'part1' specifies +the "top-level" partition number, 'part2' specifies a "sub-partition" in +the top-level partition, etc. Partition numbers always start from zero. +Unused partition bytes must be set to 0xFF. For example, if the disk is +partitioned using a simple one-level DOS partitioning scheme, then 'part1' +contains the DOS partition number, and 'part2' and 'part3' are both zero. +As another example, if a disk is partitioned first into DOS partitions, and +then one of those DOS partitions is subdivided into several BSD partitions +using BSD's "disklabel" strategy, then 'part1' contains the DOS partition +number, 'part2' contains the BSD sub-partition within that DOS partition, +and 'part3' is 0xFF.

+ +DOS extended partitions are indicated as partition numbers starting from 4 +and increasing, rather than as nested sub-partitions, even though the +underlying disk layout of extended partitions is hierarchical in nature. +For example, if the boot loader boots from the second extended partition +on a disk partitioned in conventional DOS style, then 'part1' will be 5, +and 'part2' and 'part3' will both be 0xFF.

+ +If bit 2 of the flags longword is set, the 'cmdline' field is valid, and +contains the physical address of the the command line to be passed to the +kernel. The command line is a normal C-style null-terminated string.

+ +If bit 3 of the flags is set, then the 'mods' fields indicate to the kernel +what boot modules were loaded along with the kernel image, and where they +can be found. 'mods_count' contains the number of modules loaded; +'mods_addr' contains the physical address of the first module structure. +'mods_count' may be zero, indicating no boot modules were loaded, even if +bit 1 of 'flags' is set. Each module structure is formatted as follows:

+ +

+	+-------------------+
+0	| mod_start	    |
+4	| mod_end	    |
+	+-------------------+
+8	| string	    |
+	+-------------------+
+12	| reserved (0)	    |
+	+-------------------+
+
+ +The first two fields contain the start and end addresses of the boot module +itself. The 'string' field provides an arbitrary string to be associated +with that particular boot module; it is a null-terminated ASCII string, +just like the kernel command line. The 'string' field may be 0 if there is +no string associated with the module. Typically the string might be a +command line (e.g. if the OS treats boot modules as executable programs), +or a pathname (e.g. if the OS treats boot modules as files in a file +system), but its exact use is specific to the OS. The 'reserved' field +must be set to 0 by the boot loader and ignored by the OS.

+ +NOTE: Bits 4 & 5 are mutually exclusive.

+ +If bit 4 in the multiboot_info.flags word is set, then the following +fields in the multiboot_info structure starting at byte 28 are valid:

+ +

+	+-------------------+
+28	| tabsize	    |
+32	| strsize	    |
+36	| addr		    |
+40	| reserved (0)	    |
+	+-------------------+
+
+ +These indicate where the symbol table from an a.out kernel image can be +found. 'addr' is the physical address of the size (4-byte unsigned +long) of an array of a.out-format 'nlist' structures, followed immediately +by the array itself, then the size (4-byte unsigned long) of a set of +null-terminated ASCII strings (plus sizeof(unsigned long) in this case), +and finally the set of strings itself. 'tabsize' is equal to it's size +parameter (found at the beginning of the symbol section), and 'strsize' +is equal to it's size parameter (found at the beginning of the string section) +of the following string table to which the symbol table refers. Note that +'tabsize' may be 0, indicating no symbols, even if bit 4 in the flags +word is set.

+ +If bit 5 in the multiboot_info.flags word is set, then the following +fields in the multiboot_info structure starting at byte 28 are valid:

+ +

+	+-------------------+
+28	| num		    |
+32	| size		    |
+36	| addr		    |
+40	| shndx		    |
+	+-------------------+
+
+ +These indicate where the section header table from an ELF kernel is, the +size of each entry, number of entries, and the string table used as the +index of names. They correspond to the 'shdr_*' entries ('shdr_num', etc.) +in the Executable and Linkable Format (ELF) specification in the program +header. All sections are loaded, and the physical address fields +of the elf section header then refer to where the sections are in memory +(refer to the i386 ELF documentation for details as to how to read the +section header(s)). Note that 'shdr_num' may be 0, indicating no symbols, +even if bit 5 in the flags word is set.

+ +If bit 6 in the multiboot_info.flags word is set, then the 'mmap_*' fields +are valid, and indicate the address and length of a buffer containing a +memory map of the machine provided by the BIOS. 'mmap_addr' is the address, +and 'mmap_length' is the total size of the buffer. The buffer consists of +one or more of the following size/structure pairs ('size' is really used +for skipping to the next pair):

+ +

+	+-------------------+
+-4	| size		    |
+	+-------------------+
+0	| BaseAddrLow	    |
+4	| BaseAddrHigh	    |
+8	| LengthLow	    |
+12	| LengthHigh	    |
+16	| Type		    |
+	+-------------------+
+
+ +where 'size' is the size of the associated structure in bytes, which can +be greater than the minimum of 20 bytes. 'BaseAddrLow' is the lower 32 +bits of the starting address, and 'BaseAddrHigh' is the upper 32 bits, +for a total of a 64-bit starting address. 'LengthLow' is the lower 32 bits +of the size of the memory region in bytes, and 'LengthHigh' is the upper 32 +bits, for a total of a 64-bit length. 'Type' is the variety of address +range represented, where a value of 1 indicates available RAM, and all +other values currently indicated a reserved area.

+ +The map provided is guaranteed to list all standard RAM that should +be available for normal use.

+ +


+ +

Authors

+ +
+Bryan Ford
+Computer Systems Laboratory
+University of Utah
+Salt Lake City, UT 84112
+(801) 581-4280
+baford@cs.utah.edu
+
+Erich Stefan Boleyn
+924 S.W. 16th Ave, #202
+Portland, OR, USA  97205
+(503) 226-0741
+erich@uruk.org
+
+ +We would also like to thank the many other people have provided comments, +ideas, information, and other forms of support for our work.

+ +

Revision History

+ +
+Version 0.6   3/29/96  (a few wording changes, header checksum, and
+                        clarification of machine state passed to the OS)
+Version 0.5   2/23/96  (name change)
+Version 0.4   2/1/96   (major changes plus HTMLification)
+Version 0.3   12/23/95
+Version 0.2   10/22/95
+Version 0.1   6/26/95
+
+ +
+ +

Notes on PCs

+ +In reference to bit 0 of the multiboot_info.flags parameter, +if the bootloader +in question uses older BIOS interfaces, or the newest ones are not +available (see description about bit 6), then a maximum of either +15 or 63 megabytes of memory may be reported. It is HIGHLY recommended +that bootloaders perform a thorough memory probe.

+ +In reference to bit 1 of the multiboot_info.flags parameter, it is +recognized that determination of which BIOS drive maps to which +OS-level device-driver is non-trivial, at best. Many kludges have +been made to various OSes instead of solving this problem, most of +them breaking under many conditions. To encourage the use of +general-purpose solutions to this problem, here are 2 +BIOS Device Mapping Techniques.

+ +In reference to bit 6 of the multiboot_info.flags parameter, it is +important to note that the data structure used there +(starting with 'BaseAddrLow') is the data returned by the +INT 15h, AX=E820h +- Query System Address Map call. More information +on reserved memory regions is defined on that web page. +The interface here is meant to allow a bootloader to +work unmodified with any reasonable extensions of the BIOS interface, +passing along any extra data to be interpreted by the OS as desired.

+ +


+ +

Example OS Code (from Bryan Ford)

+ +EDITOR'S NOTE: These examples are relevant to the Proposal version 0.5, +which is basically identical except for the multiboot OS header, which was +missing the checksum. A patch to bring Mach4 UK22 up to version 0.6 is +available in the GRUB FTP area mentioned in the +Example Bootloader Code section below.

+ +The Mach 4 distribution, available by anonymous FTP from +flux.cs.utah.edu:/flux, contains a C header file that defines the +MultiBoot data structures described above; anyone is welcome to rip it +out and use it for other boot loaders and OS's:

+ +

+        mach4-i386/include/mach/machine/multiboot.h
+
+ +This distribution also contains code implementing a "Linux boot adaptor", +which collects a MultiBoot-compliant OS image and an optional set of boot +modules, compresses them, and packages them into a single traditional Linux +boot image that can be loaded from LILO or other Linux boot loaders. There +is also a corresponding "BSD boot adaptor" which can be used to wrap a +MultiBoot kernel and set of modules and produce an image that can be loaded +from the FreeBSD and NetBSD boot loaders. All of this code can be used as-is +or as a basis for other boot loaders. These are the directories of primary +relevance:

+ +

+        mach4-i386/boot
+        mach4-i386/boot/bsd
+        mach4-i386/boot/linux
+
+ +The Mach kernel itself in this distribution contains code that demonstrates +how to create a compliant OS. The following files are of primary +relevance:

+ +

+        mach4-i386/kernel/i386at/boothdr.S
+        mach4-i386/kernel/i386at/model_dep.c
+
+ +Finally, I have created patches against the Linux 1.2.2 and FreeBSD 2.0 +kernels, in order to make them compliant with this proposed standard. +These patches are available in kahlua.cs.utah.edu:/private/boot.

+ +


+ +

Example Bootloader Code (from Erich Boleyn)

+ +The GRUB bootloader project +will be fully +Multiboot-compliant, supporting all required and optional +features present in this standard.

+ +A final release has not been made, but both the GRUB beta release +(which is quite stable) and a patch for Multiboot version 0.6 for +Mach4 UK22 are available in the GRUB +public release +area.

+ +


+ +erich@uruk.org

+ + + + diff --git a/docs/commands.txt b/docs/commands.txt new file mode 100644 index 000000000..9586df2ef --- /dev/null +++ b/docs/commands.txt @@ -0,0 +1,228 @@ + + +Listing of commands available in the configuration files, a subset of +which is usable on the command-line. + +The interpretation of the config file represents a simple state-machine, +where: + + (1) Config-file specific commands have to be used before any others. + (2) A multiboot kernel must be loaded before modules can be. + (3) A kernel must be loaded before either the config-file entry ends, + or any "boot" command is issued in any case. + +Semantics are as follows: + + -- The files *must* be in plain-text format!! + + -- "#" at the beginning of a line means it is a comment line in a config + file only. + + -- Options are separated by spaces. + + -- All numbers can be either decimal or hexidecimal. A hexidecimal number + must be preceeded by "0x", and is case insensitive. + + -- Extra options/text at the end of the line is ignored unless otherwise + specified. + + -- Bad commands generally get included in the current entry being added + to, except before entries start, where they are ignored. + + +Notes for interpreting commands described in double-quotes below: + + -- "literal_string" : means use the string "literal_string". + -- "" : means the whole name "" represents some variable + quantity that is interpreted at runtime (like a number + or device/file name). + -- "[option]" : means "option" is may be omitted. + -- "..." : means extra text included at the end of the line is used for + some purpose. + + +Commands usable in config files only. + + -- "timeout= " + Sets a timeout, in seconds, before automatically booting the + default entry (normally the first entry defined). + + -- "default= " + Sets the default entry to entry number (otherwise it is 0, + the first entry). + + -- "fallback= " + Goes into unattended boot mode: if the default boot entry has any + errors, instead of waiting for the user to do anything, it + immediately starts over using the entry (same numbering + as the "default=" command). This obviously doesn't help if the + machine was in the middle of the boot process (after leaving GRUBs + code) and rebooted. + + -- "password= " + Disables all interactive editing control (menu entry editor + and command-line). If the password is entered, it + loads the as a new config file and restarts + the GRUB Stage 2. + + -- "title= ..." + Starts a new menu entry, and sets it's name to the contents of the + rest of the line, starting with the first non-space character. + + +Commands usable in config files and interactively. + + -- "pause= ..." + Prints the entirety of "pause= ..." to the end of it's line, then + waits until a key is pressed. + + NOTE that placing a ^G in it will cause the speaker to emit the + standard beep sound, which is useful when asking the user to change + floppies, etc. + + -- "uppermem= " + Forces GRUB to ignore what it found during the autoprobe of the + memory available to the system, and to use as the number + of kilobytes of upper memory installed. Any address range maps + of the system are discarded. + + NOTE: This should be used with great caution, and should only + be necessary on some old machines. GRUB's BIOS probe can pick up + all RAM on all new machines the author has ever heard of. It can + also be used for debugging purposes to lie to an OS. + + -- "root= []" + Sets the current "root partition" to the device , then + attempts to mount it to get the partition size (for passing the + partition descriptor in ES:ESI, used by some chainloaded + bootloaders), the BSD drive-type (for booting BSD kernels using + their native boot format), and fixup automatic determination of + the PC partition where a BSD sub-partition is located. The optional + parameter is a number to tell a kernel which is using + one of the BSD boot methodologies how many BIOS drive numbers + are on controllers before the current one. An example is if there + is an IDE disk and a SCSI disk, then set the root partition + normally, except for a kernel using a BSD boot methodology + (FreeBSD or NetBSD), then use a "1" for . + + -- "rootnoverify= []" + Similar to "root=", but doesn't attempt to mount the partition. + This is useful for when an OS is outside of the area of the disk + that GRUB can read, but setting the correct root partition is still + desired. + + NOTE: the items mentioned in "root=" above which are derived from + attempting the mount will NOT work correctly. + + -- "chainloader= " + Loads as a chainloader. + + NOTE: like any other file loaded by the filesystem code, it can + use the blocklist notation to grab the first sector of the current + partition with "+1". + + -- "kernel= ..." + Attempts to load the primary boot image (Multiboot a.out or ELF, + Linux zImage or bzImage, FreeBSD-a.out, or NetBSD-a.out) from + . This command ignores the rest of the contents of the line, + except that the entire line starting with the kernel filename is + passed verbatim as the "kernel command-line". The module state is + reset by this (i.e. reload any modules). + + -- "module= ..." + Loads a boot module for a Multiboot format boot image (no + interpretation of the file contents are made, so the user of this + command/writer of the config file must know what the kernel in + question works with). The rest of the line is passed as the "module + command-line" much like with the "kernel=" command. + + -- "modulenounzip= ..." + Exactly like "module", except that automatic decompression is + disabled. + + -- "initrd= ..." + Loads an initial ramdisk for a Linux format boot image and sets + the appropriate parameters in the Linux setup area in memory. + + -- "install= [d] [p] []" + This command is fairly complex, and for detailed examples one + should look at the install documentation. In short, it will + perform a full install presuming the stage1.5 or stage2 (they're + loaded the same way, I'll just refer to it as a stage2 from now on) + is in it's final install location (pretty much all other edits are + performed by the "install=" command). + + In slightly more detail, it will load , validate + that it is a GRUB stage1 of the right version number, install + blocklists for loading (if the option "d" is present, + the stage1 will always look for the actual disk was + installed on, rather than using the booting drive) as a stage2 + into memory at address (for a stage1.5, an address of + 0x2000 should be used, and for a stage2, an address of 0x8000 + should be used), then write the completed stage1 to the first + block of the device . If the options "p" or + are present, then it reads the first block of stage2, modifies it + with the values of the partition was found on (for "p") or + places the string into the area telling the stage2 + where to look for a configuration file at boot time. Finally, it + preserves the DOS BPB (and for hard disks, the partition table) of + the sector the stage1 is to be installed into. + + -- "makeactive" + Sets the active partition on the root disk to GRUB's root partition + (on a floppy this is a NO-OP). This is limited to working with + "primary" PC partitions. + + -- "boot" + This boots the OS/chainloader which has been loaded. Only necessary + if running the fully interactive command-line (it is implicit at the + end of a config-file entry). + + +Commands usable in config files and interactively which are only available +in the debug version of the GRUB Stage 2. + + -- "testload= " + Reads the entire contents of in several different ways and + compares them, to test the filesystem code. The output is somewhat + cryptic (see the "T" subcommand of "syscmd=" below), but if no + errors are reported and the part right at the end which reads + "i=, filepos=" has and equal, then it is definitely + consistent, and very likely works correctly subject to a consistent + offset error. A good idea if this works is then to try loading a + kernel with your code. + + -- "read= " + Reads a 32-bit unsigned value at address and displays it + in hex format. + + -- "displaymem" + Displays what GRUB thinks the system address space map of the + machine is, including all regions of physical RAM installed. + The "upper/lower memory" thing GRUB has uses the standard BIOS + interface for the available memory in the first megabyte, or + "lower memory", and a synthesized number from various BIOS + interfaces of the memory starting at 1MB and going up to the first + chipset hole for "upper memory" (the standard PC "upper memory" + interface is limited to reporting a maximum of 64MB). + + -- "impsprobe" + Probes Intel MPS spec 1.1 or 1.4 configuration table and boots + the various other CPUs which are found into a tight loop. + + -- "fstest" + Toggles filesystem test mode. + + Filesytem test mode, when turned on, prints out data corresponding + to all the device reads and what values are being sent to the + low-level routines. The format is: + + "" for high-level reads + inside a partition (so "sector" is an offset from + the start of the partition). + "[sector]" for low-level sector requests from the disk + (so "sector" is offset from the start of the disk). + + Filesystem test mode is turned off by any uses of the "install=" or + "testload=" commands. + diff --git a/docs/embedded_data.txt b/docs/embedded_data.txt new file mode 100644 index 000000000..ed40c3b7a --- /dev/null +++ b/docs/embedded_data.txt @@ -0,0 +1,118 @@ + + +NOTE that GRUB's own install functions can alter all of the significant +variables here... look in the install.html file for details. + +This file describes embedded variables in GRUB's stage1 and stage2 and +how they are meant to be used and manipulated. + +The primary reason for them being in well-defined locations is to allow +changes/installation/etc. without needing to recompile the modules, just +patch the binary directly. + + +"stage1" : + +NOTE: these are all defined in "stage1/stage1.S". + + -- at offset 0x1BC : "major version" + + This is the major version byte (should be a 1). + + -- at offset 0x1BD : "minor version" + + This is the minor version byte (should be a 0). + + -- at offset 0x1B8 : "stage2 start address" + + This is the data for the "ljmp" command to the starting address + of the component loaded by the stage1. The format is two 2-byte + words: the first is the IP, and the second is the CS segment + register (remember, we're in x86 real-mode... 16-bit instruction + pointer and segment registers shifted left by 4 bits). + + A "stage1.5" should be loaded at address 0x2000, and a "stage2" + should be loaded at address 0x8000. Both use a CS of 0. + + -- at offset 0x1B0 : "firstlist" + + This is the ending address of the blocklist data area. + + The trick here is that it is actually read backward, and the first + 8-byte blocklist is not read here, but after the pointer is + decremented 8 bytes, then after reading it, it decrements again, + reads, decrements, reads, etc. until it is finished. The + terminating condition is when the number of sectors to be read + in the next blocklist is 0. + + The format of a blocklist can be seen from the example in the + code just before the "firstlist" label. (note that it is + always from the beginning of the disk, and *NOT* relative to + the partition boundaries) + + -- at offset 0x1B0 : "loading drive" + + This is the BIOS drive number to load the blocklists from. + If the number is 0xFF, then load from the booting drive. + + +"stage1.5" and "stage2" (same structure) : + +NOTE: these are all defined at the beginning of "shared_src/asm.S". + + -- at offset 0x6 : "major version" + + This is the major version byte (should be a 1). + + -- at offset 0x7 : "minor version" + + This is the minor version byte (should be a 0). + + -- at offset 0x8 : "install_partition" + + This is an unsigned long representing the partition on the currently + booted disk which GRUB should expect to find it's data files and + treat as the default root partition. + + The format of is exactly the same as the "partition" part (the "disk" + part is ignored) of the data passed to an OS by a Multiboot-compliant + bootloader in the "boot_device" data element, with one exception. + + The exception is that if the first level of disk partitioning is + left as 0xFF (decimal 255, which is marked as no partitioning being + used), but the second level does have a partition number, it looks + for the first BSD-style PC partition, and finds the numbered BSD + sub-partition in it. The default "install_partition" 0xFF00FF, + would then find the first BSD-style PC partition, and use the "a" + partition in it, and 0xFF01FF would use the "b" partition, etc. + + If an explicit first-level partition is given, then no search is + performed, and it will expect that the BSD-style PC partition is + in the appropriate location, else a "no such partition" error will + be returned. + + IMPORTANT NOTE: If a "stage1.5" is being used, it will pass it's own + "install_partition" to any "stage2" it loads, therefore overwriting + the one present in the "stage2". + + -- at offset 0xC : "version_string" + + This is the "stage1.5" or "stage2" version string. It isn't + meant to be changed, simply easy to find. + + -- after the terminating zero of "version_string" : "config_file" + + This is the location, using the GRUB filesystem syntax, of the + config file. It will, by default, look in the "install_partition" + of the disk GRUB was loaded from, though one can use any valid + GRUB filesystem string, up to and including making it look on + other disks. + + IMPORTANT NOTE: The bootloader itself doesn't search for the end of + "version_string", it simply knows where "config_file" is, so the + beginning of the string cannot be moved after compile-time. This + should be OK, since the "version_string" is meant to be static. + + IMPORTANT NOTE #2: The code of stage2 starts again at offset 0x70, + so "config_file" string obviously can't go past there. Also, + remember to terminate the string with a 0. diff --git a/docs/errors.html b/docs/errors.html new file mode 100644 index 000000000..86f14c204 --- /dev/null +++ b/docs/errors.html @@ -0,0 +1,198 @@ + + + +GRUB Error Messages + + + + +

GRUB Error Messages

+

by +Erich Boleyn

+ +
+ +

Contents

+ + + +
+ +

Errors Reported by the Stage 1

+ +The general way that the Stage 1 handles errors is to print an +error string and then halt. Pressing Ctrl-Alt-Del will reboot.

+ +The following is a comprehensive list of error messages for the +Stage 1:

+ +

    +
  • "Hard Disk Error"

    +This error message will occur if the Stage 2 or Stage 1.5 is being read +from a hard disk, and the attempt to determine the size and +geometry of the hard disk fails.

    +

  • "Floppy Error"

    +This error message will occur if the Stage 2 or Stage 1.5 is being read +from a floppy disk, and the attempt to determine the size and +geometry of the floppy disk fails. It's listed as a different error +since the probe sequence is different than for hard disks.

    +

  • "Read Error"

    +This error message will occur if a disk read error happens while trying +to read the Stage 2 or Stage 1.5.

    +

  • "Geom Error"

    +This error message will occur if the location of the Stage 2 or Stage 1.5 +is not in the area supported by reading the disk with the BIOS directly. +This could occur because the BIOS translated geometry has been changed +by the user or the disk is moved to another machine or controller after +installation, or GRUB was not installed using itself (if it was, the +Stage 2 version of this error would have been seen during that process +and it would not have completed the install).

    +

+ +
+ +

Errors Reported by the Stage 1.5

+ +The general way that the Stage 1.5 handles errors is to print an +error number in the form "Error: " and then halt. Pressing +Ctrl-Alt-Del will reboot.

+ +The error numbers correspond to the +Errors Reported by the Stage 2 in the +listed sequence.

+ +


+ +

Errors Reported by the Stage 2

+ +The general way that the Stage 2 handles errors is to abort the +operation in question, print an error string, then (if possible) +either continue based on the fact that an error occurred or wait +for the user to deal with the error.

+ +The following is a comprehensive list of error messages for the +Stage 2 (error numbers for the Stage 1.5 are listed before the +colon in each description):

+ +

    +
  • 1 : "Selected item won't fit into memory"

    +This error is returned if a kernel, module, or raw file load +command is either trying to load it's data such that it won't fit into +memory or it is simply too big.

    +

  • 2 : "Selected disk doesn't exist"

    +This error is returned if the device part of a device- or full filename +refers to a disk or BIOS device that is not present or not recognized +by the BIOS in the system.

    +

  • 3 : "Disk read error"

    +This error is returned if there is a disk read error when trying to probe or +read data from a particular disk.

    +

  • 4 : "Disk write error"

    +This error is returned if there is a disk write error when trying to write +to a particular disk. This would generally only occur during an +install of set active partition command.

    +

  • 5 : "Disk geometry error"

    +This error is returned when a read is attempted at a linear block address +beyond the end of the BIOS translated area. This generally happens +if your disk is larger than the BIOS can handle (512MB for (E)IDE disks on +older machines or larger than 8GB in general).

    +

  • 6 : "Attempt to access block outside partition"

    +This error is returned if a linear block address +is outside of the disk partition. This generally happens +because of a corrupt filesystem on the disk or a bug in the code handling +it in GRUB (it's a great debugging tool).

    +

  • 7 : "Partition table invalid or corrupt"

    +This error is returned if the sanity checks on the integrity of the partition +table fail. This is a bad sign.

    +

  • 8 : "No such partition"

    +This error is returned if a partition is requested in the device part of a +device- or full filename which isn't on the selected disk.

    +

  • 9 : "Bad filename (must be absolute pathname or blocklist)"

    +This error is returned if a filename is requested which doesn't fit the +syntax/rules listed in the Filesystem +Description.

    +

  • 10 : "Bad file or directory type"

    +This error is returned if a file requested is not a regular file, but +something like a symbolic link, directory, or FIFO.

    +

  • 11 : "File not found"

    +This error is returned if the specified filename cannot be found, but +everything else (like the disk/partition info) is OK.

    +

  • 12 : "Cannot mount selected partition"

    +This error is returned if the partition requested exists, but the filesystem +type cannot be recognized by GRUB.

    +

  • 13 : "Inconsistent filesystem structure"

    +This error is returned by the filesystem code to denote an internal +error caused by the sanity checks of the filesystem structure on disk +not matching what it expects. This is usually caused by a corrupt +filesystem or bugs in the code handling it in GRUB.

    +

  • 14 : "Filesystem compatibility error, can\'t read whole file"

    +Some of the filesystem reading code in GRUB has limits on the length of +the files it can read. This error is returned when the user runs into +such a limit.

    +

  • 15 : "Error while parsing number"

    +This error is returned if GRUB was expecting to read a numbur and encountered +bad data.

    +

  • 16 : "Device string unrecognizable"

    +This error is returned if a device string was expected, and the string +encountered didn't fit the +syntax/rules listed in the Filesystem +Description.

    +

  • 17 : "Invalid device requested"

    +This error is returned if a device string is recognizable but does not +fall under the other device errors.

    +

  • 18 : "Invalid or unsupported executable format"

    +This error is returned if the kernel image boing loaded is not recognized +as Multiboot or one of the supported native formats (Linux zImage or +bzImage, FreeBSD, or NetBSD).

    +

  • 19 : "Loading below 1MB is not supported"

    +This error is returned if the lowest address in a kernel is below the +1MB boundary. The Linux zImage format is a special case and can be +handled since it has a fixed loading address and maximum size.

    +

  • 20 : "Unsupported Multiboot features requested"

    +This error is returned when the Multiboot features word in the Multiboot +header requires a feature that is not recognized. The point of this is +that the kernel requires special handling which GRUB is likely unable +to provide.

    +

  • 21 : "Unknown boot failure"

    +This error is returned if the boot attempt did not succeed for reasons +which are unknown.

    +

  • 22 : "Must load Multiboot kernel before modules"

    +This error is returned if the module load command is used before loading +a Multiboot kernel. It only makes sense in this case anyway, as GRUB +has no idea how to communicate the presence of location of such modules +to a non-Multiboot-aware kernel.

    +

  • 23 : "Must load Linux kernel before initrd"

    +This error is returned if the initrd command is used before loading +a Linux kernel. Similar to the above error, it only makes sense in that +case anyway.

    +

  • 24 : "Cannot boot without kernel loaded"

    +This error is returned if GRUB is told to execute the boot sequence without +having a kernel to start.

    +

  • 25 : "Unrecognized command"

    +This error is returned if an unrecognized command is entered into the +command-line or in a boot sequence section of a config file and that +entry is selected.

    +

  • 26 : "Bad or incompatible header on compressed file"

    +This error is returned if the file header for a supposedly compressed file +is bad.

    +

  • 27 : "Bad or corrupt data while decompressing file"

    +This error is returned the run-length decompression code gets an +internal error. This is usually from a corrupt file.

    +

  • 28 : "Bad or corrupt version of stage1/stage2"

    +This error is returned if the install command is pointed to incompatible +or corrupt versions of the stage1 or stage2. It can't detect corruption +in general, but this is a sanity check on the version numbers, which +should be correct.

    +

+ +
+ +erich@uruk.org

+ + + + + diff --git a/docs/faq.html b/docs/faq.html new file mode 100644 index 000000000..374772ff7 --- /dev/null +++ b/docs/faq.html @@ -0,0 +1,213 @@ + + + +GRUB FAQ -- Frequently Asked Questions + + + + +

GRUB FAQ -- Frequently Asked Questions

+

for version 0.4

+ +
+ +

Contents

+ + + +
+ +

General

+ +
    +
  • I thought there was no way to autodetect all of the RAM +on a PC, can GRUB really do it reliably?

    +For any fairly modern machine, yes. GRUB can also generally detect +more than 64MB, as described in the +GRUB Technical Info. It has been tried in +many machines with memory sizes ranging from 72MB up to 2 GB in one case. +There are some machines still in use which don't report most of their RAM +using any of the well-known BIOS memory interfaces. For those, there +really is no recourse but to use the "uppermem=" command to set it +manually, which is described in the +list of commands.

    +Note that passing this value correctly to Linux involved patching +a "mem=" statement onto the beginning of the command-line, and for FreeBSD +required a fix to some earlier versions (as it figured any value over +64MB was a bug and it would panic on this). A Multiboot compliant kernel +has no problem.

    +

  • Is there any way to abort operations?

    +Whenever GRUB is waiting for input, if the user presses the ESC key, +then as much of the internal state changes as possible is cancelled +and GRUB goes up one +interface level (if at the top level, it just redraws the screen).

    +

  • What does GRUB do if there is an error during booting a config +file entry (such as a disk read error) ?

    +Unless otherwise told to (via the "fallback=" command), GRUB will drop +into the interactive command-line after displaying the error message +to the user. If the user presses enter (perhaps after some editing), then +it will attempt to execute this line and if successful continue from where +it left off in the config file entry.

    +

+ +
+ +

Commands

+ +Here is the generic +list of commands.

+ +

    +
  • When editing the config file for GRUB in DOS/Windows/NT, do I +have to worry about CR/LF translation?

    +No. GRUB will work with CR/LF or LF only line endings in it's +configuration file perfectly fine. I have created and managed a config +file from Windows 95 using the NOTEPAD program with no problems after +installing GRUB on the hard disk using a floppy created from Windows 95 +as well.

    +

  • I noticed that there are some command examples in hexidecimal and +some in decimal, what formats are supported and where?

    +Whenever there is a number entered by the user from either a command-line +or the config file, it can be entered in decimal or hexidecimal as desired +(the letters used for hex numbers are case-insensitive). +The way GRUB uses to distinguish them is that hex numbers +start with "0x", so one could type "128" or "0x80" alternately.

    +

  • Some commands corrupt some memory state

    +Performing an "install=" or "testload=" command will corrupt any +chainloaders/kernels currently loaded into memory. I.e. simply redo +the loads or always make sure that installs or testloads are done first.

    +

  • When running interactively, can an a different chainloader/kernel +be loaded after one has already been, or do I have to reset all the +internal state with the ESC key?

    +Any "chainloader=" or "kernel=" command used overrides any previous ones, +and in the case of Multiboot-compatible kernels, requires that modules +be reloaded.

    +

+ +
+ +

Filesystems

+ +Here is the listing of +GRUB Filesystems and Interfaces.

+ +

    +
  • What is the "root partition" ?

    +This is both the default partition for searching for/loading files and +the source of the "root partition" information used for chainloaders +and data passed to kernels in various formats. This defaults to the +"install_partition" variable in the +embedded data of the +stage1.5/stage2, and can be changed via the "root=" or "rootnoverify=" +commands.

    +

  • What filesystems are supported, and how do I tell it which one +to use?

    +GRUB comes with support for DOS FAT, BSD FFS, and Linux +ext2fs filesystems, plus a blocklisting notation for accessing blocks +directly. When using the normal file syntax, GRUB will autodetect the +filesystem type.

    +

  • When booting an OS, how do I tell the OS what the root +partition is?

    +The root partition setting in GRUB is mostly for it's own use (where +it looks for data by default if no device is specified), and is passed +to a fully Multiboot-compliant OS. When possible, the information is +passed along to the OS being booted. Here is a listing of where each +of the major OSes GRUB is being used for gets it's root partition from:

    +

      +
    • FreeBSD: GRUB passes it in the same manner as it's original +bootloader, as of the version 2.1.0 release.

      +

    • NetBSD: GRUB passes it in the same manner as it's original +bootloader, as of the version 1.1 release.

      +

    • Linux: GRUB doesn't pass any special root partition info, +so unless the root partition is set on the command-line, the default +one complied into the image will be used.

      +

    • Mach4: Mach4 currently ignores the root partition info +passed in the Multiboot info structure. You have to explicitly +put it on the command-line via a "root=hd0a" or "root=hd0s1" type +of command; see the release notes on Mach4 for details.

      +NOTE: The default version of the UK22 release is compliant with an +earlier and incompatible multiboot version. A patch to bring it up +to Multiboot 0.6 is available in the GRUB FTP area. +The version distributed with +the GNU HURD already has this patch.

      +

    • Chainloaded OS's such as DOS or NT: The only way they +have of knowing anything about a root or boot partition is via +preset offsets in their boot sectors (such as the "hidden sectors" +parameter of the DOS BIOS parameter block) or +the "active partition" marker (see "makeactive" in the list of +commands).

      +

    +
+ +
+ +

Installation

+ +Here is the +GRUB Installation Guide.

+ +

    +
  • What partition does GRUB look for the config file on?

    +GRUB looks for the config file in the default root partition, unless +a partition name was included at the beginning of the config file name +when it was installed (in that case it ignores the default).

    +To keep matters simple, it is recommended that when installing, ALWAYS +use the "p" option in the "install=" command when the stage2 file is +in a partition type readable by GRUB, +which will force default root partition to be the +same as where the stage2 is (i.e. that's where it looks for the config +file).

    +

  • How do I install taking a stage1 from a floppy and +placing it on another floppy in the same drive

    +You don't. There is currently no provision to pause an install +operation so you can switch floppies in the middle. Placing the stage1 +as a file on the destination floppy, or on a hard disk somewhere, is +what has to be done here.

    +

  • When trying to install using the stage1 from my hard disk, +it complained about a "bad or corrupt version"

    +When installing to a floppy, you must use a stage1 which has NOT been used +to boot off of a hard disk, as an essential piece of code for floppy +booting is deleted when installing the stage1 to a hard disk. A +"bad or corrupt version" error will be returned if the code is +not present.

    +

  • When using a stage1.5 AND stage2, does the "install_partition" +need to be set in the stage2?

    +After the Stage 2 is loaded, the Stage 1.5 will patch the +"install_partition" in the +embedded data with it's own value. This +behavior is to make it easier to install new versions of the Stage 2 +without having to patch special values into it each time, since the +whole point of the Stage 1.5 is to allow the convenience of reading +the largest component as a normal file.

    +

  • Is there anywhere on a hard disk I can put GRUB's stage2 which is +separate from the rest of the filesystems?

    +Sometimes. This is something of an advanced operation to set up, and is +not recommended for general use.

    +On all PC-partitioned hard disks, there is an area after the +partition table (starting at the second sector) but before the first +partition. This can be used for more-or-less any purpose that is +desired, as it is usually dead space. On most modern hard disks, +it is 31.5K in size (63 disk sectors), which is large enough for the +non-debug version of GRUB. If a some other special "multi-OS" bootloader +is installed, then this might already be in use by that program.

    +On Linux or FreeBSD, one would use a "dd" command to place the stage2 on +the disk (here's a Linux example using the first SCSI disk): +

    +dd if=stage2 of=/dev/sda bs=512 seek=1
    +
    +...then run the install command mostly normally, but for the stage2 file +use the blocklist string "1+63", which will point to this area.

    +

+ +
+ +erich@uruk.org

+ + + + diff --git a/docs/filesystem.txt b/docs/filesystem.txt new file mode 100644 index 000000000..d9ede6937 --- /dev/null +++ b/docs/filesystem.txt @@ -0,0 +1,299 @@ + +The top of this file is the filesystem syntax and semantics. +The rest of the file describes the interface used by the filesystem +code. + + +General FS semantics rules: + + -- When listing completions, directories are not labeled any differently + from files (symbolic links, FIFOs, etc. are listed as well). + + -- Only regular directories and files are interpreted (i.e. a symbolic + link or FIFO would generate a "Bad file type" error if an attempt + is made to read one... an attempt to read a directory as a file + or vice-versa will also generate a "Bad file type" error). + + -- All numbers can be either decimal or hexidecimal. A hexidecimal number + must be preceeded by "0x", and is case insensitive. + + +VERY IMPORTANT NOTE about devices: The only disk devices accessible from a + bootloader are BIOS-controlled devices. All any PC bootloader knows is + the "device number" (floppies are numbered consecutively starting with 0, + and hard drives are numbered consecutively starting with 0x80). There + is no way to tell if a hard drive is IDE, ESDI, SCSI, etc. GRUB punts + and simply uses the BIOS device number in all circumstances. It is + presumed the OS has some mechanism to translate to the physical + controllers (examples are provided in the Multiboot document). Some + OSes kludge it by requiring disklabels like the *BSDs use (which, might + it be noted, breaks under some circumstances, and may not always be + possible to use). + + +Device syntax like this ("[]" means optional), but note, no spaces +are allowed!!! + +disk/partition -> "([,[,]])" + + A shortcut for bios devices are: + fd0 -> 0 (first floppy disk) + fd1 -> 1 (second floppy disk) + + ... + + hd0 -> 0x80 (first hard disk) + hd1 -> 0x81 (second hard disk) + + whole disks: "(fd0)" -- first floppy, "(hd0)" -- first hard disk. + PC partitions: "(hd0,0)" -- first hard disk PC partition 0, + "(hd1,3)" or "(0x81,3)" -- second hard disk PC partition 3. + BSD sub-partitions: "(hd0,1,a)" -- first hard disk, first PC + partition contains BSD sub-partitions, BSD sub-partition "a". + "(0)" -- BIOS device 0 (first floppy disk) whole disk. + "(0x80,0)" -- first PC partition on BIOS device 0x80 (first hard disk). + +A shortcut for specifying BSD sub-partitions is: + "(,)" + + "(hd0,a)" -- first hard disk, searches for first PC partition + containing BSD sub-partitions, then finds the "a" subpartition. + "(fd0,a)" -- first floppy disk, searches for BSD partition "a". + +Inheriting from the defaults can be done by the following variations: + + -- omitting the drive number completely will use the current + device taken from the current root partition. + + "(,0)" looks for the first PC partition on the current disk. + + -- omitting the partition information (but using at least one comma + after the bios device number) changes the bios device but + leaves the partition the same. + + "(hd1,)" looks for the same partition as the current root but + on hard disk 1. + + +Interactive device completion (usable on the command-line after the "=" +in a command, like "kernel="): + +(nothing) -> lists all possible disks (hard and floppy) +"(" -> same +"(h" -> error (doesn't know what "h" means). +"(hd" -> error (doesn't know what "hd" means). +"(hd0" -> lists the first hard disk +"(hd0," -> lists all partitions on the first hard disk +"(hd0,a" -> finds and mounts BSD partition 'a', then reports FS type. +"(hd0,a)" -> same +"(hd0,a)/" -> lists all files in root directory... (becomes file-completion + listing at this point). + +NOTE: for any of the completion stuff, it searches back to the beginning + of the line or the most recent space, then uses that string for the + completion listing operation (file, device, partition). It uses the + *cursor* position as the determiner, so, in the above example, one could + have "(hd0,a)/kernel" on the command-line, then move the cursor to the + beginning (with C-a or lots of C-b's), then hit TAB, move it one character + forward (with C-f), hit TAB again, etc. with the same results as the + above example!!! + + +Block-list syntax like this: + +Primitive-block-list -> "" = "{,}+" +example: "1+20" or "+5" + +The interpretation of a primitive-block-list is that the first number +is the first block, then a "+", and a block-length (must be greater than +zero). These are all relative to the partition, and must be contained +within the partition boundaries (a whole disk would be "(hd0)"). If +the starting number is omitted, it is presumed to be zero (the first +block). + +construction -> "" = + ",,...,{\,}" +example: "1+100,200+1,300+300," + +This represents a conglomerate of blocks, all to be loaded as part of +one block-list. If the exact length is omitted, then it is calculated as +the size of all of the blocks. + + +Absolute-pathname syntax like this: + +Directory notation is via a forward slash, always in absolute form (like +a UNIX absolute pathname), like: "/kernel" or "/test/kernel". + + +Overall filename syntax is: + +[][][] + + is optional (will use the root partition then), but never ignored. + +Either or must be used when providing +the name for a generic file. If is used, all past it in the +filename is ignored (i.e. if you use both, the blocklist takes precedence). + +Legal characters as parts of a directory/filename are any normally +printable ascii character (not control-characters of any kind) except +a space (since it is the delimiter of the end of the whole file/device +name string) and "/" (since it is used as a directory delimiter). + +So, legal examples are: + + "(hd0,a)/kernel" + "/kernel" + "1+20,25+10,15000" + "(hd0,a)1+20" + "(hd0,a)1+20,400+50,500+100" + "1+20,25+10,15000/kernel" + "(hd0,a)1+20,400+500/kernel" + + + +INTERFACE DESCRIPTION +--------------------- + + +This file also describes the generic interface used by the filesystem code. + + The "BLK_NOTES" heading below is for the blocklist filesystem. + + The "FAT_NOTES" heading below is for the FAT filesystem. + + The "FFS_NOTES" heading below is for the FFS filesystem. + + +General function description: + +For any particular partition, it is presumed that only one of the "normal" +filesystems such as FAT, FFS, or ext2fs can be used, so there is +a switch table managed by the functions in "disk_io.c". The notation is +that you can only "mount" one at a time. + +The blocklist filesystem has a special place in the system. In addition +to the "normal" filesystem (or even without one mounted), you can access +disk blocks directly (in the indicated partition) via the blocklist +notation. Using the blocklist filesystem doesn't effect any other +filesystem mounts. + + +Interface description (this was done somewhat hastily, so important +parts might be missing): + +Errors generated: + + -- look at "fsys_ffs.c" for examples... (yeah, this is a cop-out for + now, I know). + +The variables which can be read by the filesystem backend are: + + -- "current_drive", a global which contains the current BIOS drive + number (numbered from 0, if a floppy, and numbered from 0x80, + if a hard disk). + + -- "current_slice", a global which contains the current partition + type, if a hard disk. + + -- "part_length", a global which contains the current partition + length, in sectors. + + -- "print_possibilities", a global which is true when the "dir" + function should print the possible completions of a file, and + false when it should try to actually open a file of that name. + + -- the "#define FSYS_BUF", which points to a filesystem buffer which + is 32K in size, to use in any way which the filesystem backend + desires. + +The variables which need to be written by a filesystem backend are: + + -- "filepos", a global which should be the current position in + the file. + + NOTE: the value of "filepos" can be changed out from under the + filesystem code in the current implementation. Don't depend on + it being the same for later calls into the back-end code!!! + + -- "filemax", a global which should be the length of the file. + + -- "debug_fs_func", a global which should be set to the value of + "debug_fs" ONLY during reading of data for the file, not any + other FS data, inodes, FAT tables, whatever, then set to NULL + at all other times (it will be NULL by default). If this isn't + done correctly, then the "testload=" and "install=" commands + won't work correctly!!! (look at "fsys_ffs.c" for details). + +The functions expected to be used by the filesystem backend are: + + -- "devread", which only reads sectors from within a partition. Sector + 0 is the first sector in the partition. + + -- If the backend uses the blocklist code (like the FAT filesystem + backend does), then "read" can be used, after setting "blocklist" + to 1. + +The functions expected to be defined by the filesystem backend are described +at least moderately in the file "filesys.h". Their usage is fairly evident +from their use in the functions in "disk_io.c", look for the use of the +"fsys_table" array. + +NOTE: The semantics are such that then "mount"ing the filesystem, presume +the filesystem buffer "FSYS_BUF" is corrupted, and (re-)load all important +contents. When opening and reading a file, presume that the data from +the "mount" is available, and doesn't get corrupted by the open/read (i.e. +multiple opens and/or reads will be done with only one mount if in the +same filesystem). + + +BLK_NOTES: + +block filesystem info goes like this: + +NOTE: a "block-list" is two 4-byte values, representing the start and length + of a set of 512 byte sectors. + + + [ cur_filepos, cur_block_list, cur_block_num, + block-list, block-list, block-list, etc.... ] + + +The buffer is 32Kbytes long, so the maximum length of such a list is +32Kbytes - 12 bytes. + + +FAT_NOTES: + +The filenames are all mapped to lower-case. + +The FAT filesystem actually uses the "blocklist" filesystem as it's read +routine, reading the appropriate FAT entries and placing them into the +blocklist area. (in this case, a portion of the end of the blocklist +buffer area is used for FAT filesystem information) + +It concatenates adjacent blocks in the FAT table together when possible +to consolodate the number of blocklists. + +NOTE: The above is important, since there is a maximum number of + approx 1800 blocklists. This is generally more than adequate, but + if it runs off the end and a read is attempted in this area, an + "ERR_FILELENGTH" error will be generated. + + +FFS_NOTES: + +Notes on the FFS filesystem implementation and limitations. + +Limitations: + + -- Only 1 level of indirect blocks is supported. This implies a + limitation in file-length to approx 16MB. If a read past this point + is attempted, an "ERR_FILELENGTH" error is generated. + + -- If the "blocksize" is greater than 8Kbytes, various buffers will + overwrite themselves and the whole thing will come apart at the + seams. + + diff --git a/docs/grub.html b/docs/grub.html new file mode 100644 index 000000000..790e3696b --- /dev/null +++ b/docs/grub.html @@ -0,0 +1,120 @@ + + + +GRUB -- GRand Unified Bootloader + + + + +

GRUB -- GRand Unified Bootloader

+

version 0.5

+

by +Erich Boleyn

+ +
+ +

Master Contents

+ +Some of these contents are included in other pages.

+ +

+ +NOTE: Up-to-date versions of this documentation directory can +be found at +http://www.uruk.org/grub/. The +specifics might be for a newer version of the program, so check the +online NEWS file for details +about the differences.

+ +


+ +

Introduction

+ +GRUB is an attempt to produce a bootloader for IBM PC-compatible machines +that has both the capability to be friendly to beginning or +otherwise non-technically +interested users and the flexibility to help experts in diverse +environments. It is currently most useful for users of at least +one of the various free UNIX-like operating systems, though it can +be used with most any PC operating system.

+ +This project actually started because we wanted to boot the +GNU HURD +operating system on top of + +Mach4 on an IBM PC-compatible system in a manner compliant +with the Multiboot Standard, which +was put together as a general solution to the problem of the different +boot formats and the functionality they need. +I then tried to add support for the extra functionality to the +standard bootloader used for FreeBSD. The number of things I had to do +to get it all to work multiplied until it was obviously necessary to +start from scratch with something different.

+ +GRUB has evolved a long way from it's beginnings as a multi-module +bootloader. Several +of the techniques used have no analogue in the rest of the free +software world, and a few are apparently superior to most proprietary OSes +as well. +The documentation here and in the multiboot proposal should be very +useful to prospective OS and bootloader writers for PCs.

+ +The name comes from the acronym, but also from the realization that although +a grub is one of the smaller (and less interesting) critters - barely worthy +of notice - it is nearly ubiquitous and vital to the order of things.

+ +


+ +

Thanks To

+ +
    +
  • Members of the Multiboot e-mail list and Bryan Ford +(baford@cs.utah.edu) -- for all the multiboot discussion +and OS code to test with.

    +

  • VaX#n8 (vax@linkdead.paranoia.com) -- for testing feedback plus the +initial implementation for the ext2fs filesystem.

    +

  • Miles Bader (miles@gnu.ai.mit.edu) -- for testing feedback.

    +

  • Eric Hanchrow (erich@microsoft.com) -- for interstate remote +debugging by hand.

    +

  • Gord Matzigkeit (gord@enci.ucalgary.ca) -- for lots of +testing feedback.

    +

  • Heiko Schroeder (heiko@pool.informatik.rwth-aachen.de) -- for +a re-writing stage1 to be much more readable, plus several patches.

    +

+ +
+ +

Distribution and Status

+ +GRUB is currently available under the +GNU General Public License. +This should not be an issue for OS developers or users who dislike +the terms of the GPL, as it is a separate package, and will not +have any licensing impact upon their own work or installation. +If it is still an issue, +send me e-mail and maybe we can +work something out.

+ +The publically available releases are available on my +FTP site, and I +believe they will get included in the GNU FTP sites as well.

+ +Here are links to the NEWS file, +TODO list, and list of known BUGS.

+ +


+ +erich@uruk.org

+ + + + diff --git a/docs/install.html b/docs/install.html new file mode 100644 index 000000000..07d428ee0 --- /dev/null +++ b/docs/install.html @@ -0,0 +1,160 @@ + + + +GRUB Installation Guide + + + + +

GRUB Installation Guide

+

by +Erich Boleyn

+ +
+ +

Contents

+ + + +

Getting Started Quickly

+ +If you just want to use GRUB, or simply try it out quickly, try the +Install using "rawrite" or "dd" to floppy disk in the +following section to create a "raw" GRUB floppy.

+ +


+ +

Install using "rawrite" or "dd" to floppy disk

+ +This installation method can generally only access the command-line +part of the interface (since there is no filesystem in which to +find a config-file). It is also by far the simplest installation +method to get going.

+ +NOTE: This will destroy any data currently on the floppy.

+ +Execute your OS's equivalent of (this should work for recent FreeBSD +versions and Linux just fine):

+ +

+	dd if=bin/stage1 of=/dev/fd0 bs=512 count=1
+	dd if=bin/stage2 of=/dev/fd0 bs=512 seek=1
+
+ +Under DOS/Windows/NT, courtesy of Eric +Hanchrow (erich@microsoft.com): + +
    +
  • Use the copy /b command to binary concatenate the stage1 +and stage2 files together via: +
    +	copy /b stage1 + stage2 grub.raw
    +
    +
  • Use rawrite.exe (which is available in many places on the net and in +some Linux distributions) to write grub.raw to a floppy. +
+ +
+ +

Automated Install using GRUB

+ +IMPORTANT NOTE: If the stage1 is installed on a specific +partition, this can erase the normal boot-sector used by an OS. +GRUB can boot Linux, FreeBSD, NetBSD, Mach, and the GNU HURD directly, +so this may be desired. Generally, it is a good idea to back up the +first sector of a partition if installing GRUB's stage1 there. +For the first sector of a hard disk, this is OK, since it's easy +to reinitialize it via "FDISK /MBR" in DOS, or other methods in other +OSes.

+ +GRUB has a command called "install=" which is described in +the list of commands. The purpose +of this section is to give examples and describe how to use the command +in different situations.

+ +NOTE: Given that "install=" can be used in config-file entries, +this could very easily be used as part of a completely automated set of +install scripts for an OS.

+ +First, you make a "raw" GRUB floppy created via Install +using "rawrite" or "dd" to floppy disk above. Actually, any booting +copy of GRUB of the right version number will work fine, this is simply +a way to get the process started easily.

+ +On the partition that is the desired area for GRUB to be installed in +(call it the "install partition"), make a "/boot/grub" directory and +place the stage2 and menu.lst (config file) there. (If desired, place +a stage1.5 there as well)

+ +Now use the "install=" command appropriately, and you're done!

+ +Examples of how to use the "install=" command:

+ +

    +
  • Making a Hard Disk bootable with GRUB's stage2 on PC partition +number 2: Make a directory in the partition called "/boot/grub", +place the stage2 (and if desired, your config file called "menu.lst"), +then run the following command after getting GRUB's command-line from +booting the floppy: +
    +	install= (fd0)+1 (hd0) (hd0,2)/boot/grub/stage2 0x8000 p
    +
    +This tells GRUB to grab the first sector of the floppy and use it as +the stage1, create a blocklist using the file "/boot/grub/stage2" on +the first hard disk, partition number 2, merge them together, set the +load address to 0x8000 (correct for a stage2), write the "install +partition" number into the first sector of the stage2 (the "p" at the +end), then write the result to the first sector of the hard disk.

    +

  • Same as above, but placing the stage1 on the floppy, then having +it start the stage2 on the hard disk: The difference here is you're +telling GRUB's stage1 to read from the first hard disk no matter where +stage1 is being run from: +
    +	install= (fd0)+1 d (fd0) (hd0,2)/boot/grub/stage2 0x8000 p
    +
    +The "d" option near the beginning is what sets the "forced" loading +from the disk where the stage2 was installed from. The rest of the +options are the same except for the "destination device" to place the +finished stage1 on is changed to the floppy disk.

    +

  • Installing from an "install directory" to the second hard disk: +Here we're loading the stage1 from a file on the first hard disk, +installing stage2 from the first BSD "a" partition on the second hard disk, +and setting the "config file" of the stage2 to a different value than +usual: +
    +	install= (hd0,2)/boot/grub/stage1 (hd1) (hd1,a)/boot/grub/stage2 0x8000 p /grubdir/configfile
    +
    +
+ + +An easily imaginable way of using this as part of an automated +installation process would be to note that the commands listed above +can be part of any sequence of commands in an entry in a GRUB config +file, so this could be automated even more by using a GRUB floppy with +a filesystem and config file, with an entry such as:

+ +

+	# Start of entries
+	title=	   Linux HD install
+
+	# install command
+	install=   (fd0)+1 (hd0) (hd0,1)/boot/grub/stage2 0x8000 p
+
+	# actually boot here
+	root=      (hd0,1)
+	kernel=    /zImage root=/dev/hda2
+
+ +...then have the install script continue from there after boot of the OS.

+ +


+ +erich@uruk.org

+ + + + + diff --git a/docs/mem64mb.html b/docs/mem64mb.html new file mode 100644 index 000000000..15fdb798f --- /dev/null +++ b/docs/mem64mb.html @@ -0,0 +1,329 @@ + + + +INT 15h, AX=E820h - Query System Address Map + + + + +

INT 15h, AX=E820h - Query System Address Map

+
+ +Real mode only.

+ +This call returns a memory map of all the installed RAM, and of physical +memory ranges reserved by the BIOS. The address map is returned by making +successive calls to this API, each returning one "run" of physical address +information. Each run has a type which dictates how this run of physical +address range should be treated by the operating system.

+ +If the information returned from INT 15h, AX=E820h in some way differs from +INT 15h, AX=E801h or +INT 15h AH=88h, +then the information returned from E820h +supersedes what is returned from these older interfaces. +This allows the BIOS +to return whatever information it wishes to for compatibility reasons.

+ +


+ +Input:

+ +

+	EAX	Function Code	E820h
+	EBX	Continuation	Contains the "continuation value" to get the
+				next run of physical memory.  This is the
+				value returned by a previous call to this
+				routine.  If this is the first call, EBX
+				must contain zero.
+	ES:DI	Buffer Pointer	Pointer to an  Address Range Descriptor
+				structure which the BIOS is to fill in.
+	ECX	Buffer Size	The length in bytes of the structure passed
+				to the BIOS.  The BIOS will fill in at most
+				ECX bytes of the structure or however much
+				of the structure the BIOS implements.  The
+				minimum size which must be supported by both
+				the BIOS and the caller is 20 bytes.  Future
+				implementations may extend this structure.
+	EDX	Signature	'SMAP' -  Used by the BIOS to verify the
+				caller is requesting the system map
+				information to be returned in ES:DI.
+
+ +Output:

+ +

+	CF	Carry Flag	Non-Carry - indicates no error
+	EAX	Signature	'SMAP' - Signature to verify correct BIOS
+				revision.
+	ES:DI	Buffer Pointer	Returned Address Range Descriptor pointer.
+				Same value as on input.
+	ECX	Buffer Size	Number of bytes returned by the BIOS in the
+				address range descriptor.  The minimum size
+				structure returned by the BIOS is 20 bytes.
+	EBX	Continuation	Contains the continuation value to get the
+				next address descriptor.  The actual
+				significance of the continuation value is up
+				to the discretion of the BIOS.  The caller
+				must pass the continuation value unchanged
+				as input to the next iteration of the E820
+				call in order to get the next Address Range
+				Descriptor.  A return value of zero means that
+				this is the last descriptor.  Note that the
+				BIOS indicate that the last valid descriptor
+				has been returned by either returning a zero
+				as the continuation value, or by returning
+				carry.
+
+ +
+ +

Address Range Descriptor Structure

+ +
+Offset in Bytes		Name		Description
+	0	    BaseAddrLow		Low 32 Bits of Base Address
+	4	    BaseAddrHigh	High 32 Bits of Base Address
+	8	    LengthLow		Low 32 Bits of Length in Bytes
+	12	    LengthHigh		High 32 Bits of Length in Bytes
+	16	    Type		Address type of  this range.
+
+ +The BaseAddrLow and BaseAddrHigh together are the 64 bit +BaseAddress of this range. The BaseAddress +is the physical address of the +start of the range being specified.

+ +The LengthLow and LengthHigh together are the 64 bit +Length of this range. +The Length is the physical contiguous length in bytes of a range being +specified.

+ +The Type field describes the usage of the described address range as +defined in the table below.

+ +

+Value	Pneumonic		Description
+1	AddressRangeMemory	This run is available RAM usable by the
+				operating system.
+2	AddressRangeReserved	This run of addresses is in use or reserved
+				by the system, and must not be used by the
+				operating system.
+Other	Undefined		Undefined - Reserved for future use.  Any
+				range of this type must be treated by the
+				OS as if the type returned was
+				AddressRangeReserved.
+
+ +The BIOS can use the AddressRangeReserved address range type to block out +various addresses as "not suitable" for use by a programmable device.

+ +Some of the reasons a BIOS would do this are:

+ +

    +
  • The address range contains system ROM. +
  • The address range contains RAM in use by the ROM. +
  • The address range is in use by a memory mapped system device. +
  • The address range is for whatever reason are unsuitable for a +standard device to use as a device memory space. +
+ +
+ +

Assumptions and Limitations

+ +
    +
  • 1. The BIOS will return address ranges describing base board +memory and ISA or PCI memory that is contiguous with that baseboard memory. +
  • 2. The BIOS WILL NOT return a range description for the memory +mapping of PCI devices, ISA Option ROM's, and ISA plug & play cards. This +is because the OS has mechanisms available to detect them. +
  • 3. The BIOS will return chipset defined address holes that are not +being used by devices as reserved. +
  • 4. Address ranges defined for base board memory mapped I/O devices +(for example APICs) will be returned as reserved. +
  • 5. All occurrences of the system BIOS will be mapped as reserved. +This includes the area below 1 MB, at 16 MB (if present) and at +end of the address space (4 gig). +
  • 6. Standard PC address ranges will not be reported. Example video +memory at A0000 to BFFFF physical will not be described by this +function. The range from E0000 to EFFFF is base board specific +and will be reported as suits the bas board. +
  • 7. All of lower memory is reported as normal memory. It is OS's +responsibility to handle standard RAM locations reserved for +specific uses, for example: the interrupt vector table(0:0) and +the BIOS data area(40:0). +
+ +
+ +

Example address map

+ +This sample address map describes a machine which has 128 MB RAM, 640K +of base memory and 127 MB extended. The base memory has 639K +available for the user and 1K for an extended BIOS data area. There +is a 4 MB Linear Frame Buffer (LFB) based at 12 MB. The memory hole +created by the chipset is from 8 M to 16 M. There are memory mapped +APIC devices in the system. The IO Unit is at FEC00000 and the Local +Unit is at FEE00000. The system BIOS is remapped to 4G - 64K.

+ +Note that the 639K endpoint of the first memory range is also the base +memory size reported in the BIOS data segment at 40:13.

+ +Key to types: "ARM" is AddressRangeMemory, "ARR" is AddressRangeReserved.

+ +

+Base (Hex)	Length	Type	Description
+0000 0000	639K	ARM	Available Base memory - typically the same
+				value as is returned via the INT 12 function.
+0009 FC00	1K	ARR	Memory reserved for use by the BIOS(s).
+				This area typically includes the Extended
+				BIOS data area.
+000F 0000	64K	ARR	System BIOS
+0010 0000	7M	ARM	Extended memory, this is not limited to
+				the 64 MB address range.
+0080 0000	8M	ARR	Chipset memory hole required to support the
+				LFB mapping at 12 MB.
+0100 0000	120M	ARM	Base board RAM relocated above a chipset
+				memory hole.
+FEC0 0000	4K	ARR	IO APIC memory mapped I/O at FEC00000.  Note
+				the range of addresses required for an APIC
+				device may vary from base OEM to OEM.
+FEE0 0000	4K	ARR	Local APIC memory mapped I/O at FEE00000.
+FFFF 0000	64K	ARR	Remapped System BIOS at end of address space.
+
+ +
+ +

Sample operating system usage

+ +The following code segment is intended to describe the algorithm needed when +calling the Query System Address Map function. It is an implementation +example and uses non standard mechanisms.

+ +

+    E820Present = FALSE;
+    Regs.ebx = 0;
+    do {
+        Regs.eax = 0xE820;
+        Regs.es  = SEGMENT (&Descriptor);
+        Regs.di  = OFFSET  (&Descriptor);
+        Regs.ecx = sizeof  (Descriptor);
+	Regs.edx = 'SMAP';
+
+        _int( 0x15, Regs );
+
+        if ((Regs.eflags & EFLAG_CARRY)  ||  Regs.eax != 'SMAP') {
+            break;
+        }
+
+        if (Regs.ecx < 20  ||  Regs.ecx > sizeof (Descriptor) ) {
+            // bug in bios - all returned descriptors must be
+            // at least 20 bytes long, and can not be larger then
+            // the input buffer.
+
+            break;
+        }
+
+	E820Present = TRUE;
+	.
+        .
+        .
+        Add address range Descriptor.BaseAddress through
+        Descriptor.BaseAddress + Descriptor.Length
+        as type Descriptor.Type
+	.
+        .
+        .
+
+    } while (Regs.ebx != 0);
+
+    if (!E820Present) {
+	.
+        .
+        .
+	call INT 15h, AX=E801h and/or INT 15h, AH=88h to obtain old style
+	memory information
+	.
+        .
+        .
+    }
+
+ +
+ +

INT 15h, AX=E801h - Get Memory Size for +Large Configurations

+ +
+ +Real mode only (as far as I know).

+ +Originally defined for EISA servers, this interface is capable of +reporting up to 4 GB of RAM. While not nearly as flexible as E820h, it +is present in many more systems.

+ +Input:

+ +

+	AX	Function Code	E801h
+
+ +Output:

+ +

+	CF	Carry Flag	Non-Carry - indicates no error
+	AX	Extended 1	Number of contiguous KB between 1 and 16 MB,
+				maximum 0x3C00 = 15 MB.
+	BX	Extended 2	Number of contiguous 64 KB blocks between
+				16 MB and 4 GB.
+	CX	Configured 1	Number of contiguous KB between 1 and 16 MB,
+				maximum 0x3C00 = 15 MB.
+	DX	Configured 2	Number of contiguous 64 KB blocks between
+				16 MB and 4 GB.
+
+ +Not sure what this difference between the "Extended" and "Configured" +numbers are, but they appear to be identical, as reported from the BIOS.

+ +NOTE: It is possible for a machine using this interface to report a memory +hole just under 16 MB (Count 1 is less than 15 MB, but Count 2 is +non-zero).

+ +


+ +

INT 15h, AH=88h - Get Extended Memory Size

+ +
+ +Real mode only.

+ +This interface is quite primitive. It returns a single value for +contiguous memory above 1 MB. The biggest +limitation is that the value returned is a 16-bit value, in KB, +so it has a maximum saturation of just under 64 MB even presuming +it returns as much as it can. On some systems, it won't return +anything above the 16 MB boundary.

+ +The one useful point is that it works on every PC available.

+ +Input:

+ +

+	AH	Function Code	88h
+
+ +Output:

+ +

+	CF	Carry Flag	Non-Carry - indicates no error
+	AX	Memory Count	Number of contiguous KB above 1 MB.
+
+ +
+ +erich@uruk.org

+ + + + diff --git a/docs/menu.lst b/docs/menu.lst new file mode 100644 index 000000000..c78821a31 --- /dev/null +++ b/docs/menu.lst @@ -0,0 +1,44 @@ +# +# Sample boot menu configuration file +# + +# Timeout here... +timeout = 30 + +# For booting Mach (getting kernel from floppy) +title= Utah Mach4 multiboot +root= (hd0,2) +pause=My test!! +kernel= (fd0)/boot/kernel root=hd0s3 +module= (fd0)/boot/bootstrap + +# For booting FreeBSD (getting kernel from floppy) +title= FreeBSD 2.2-SNAP +root= (hd0,2) +kernel= (fd0)/kernel + +# For booting the GNU HURD (getting kernel from floppy) +title= GNU HURD +root= (hd0,a) +kernel= /boot/kernel root=hd0a +module= /boot/serverboot + +# For booting OS/2 (test, I have no OS/2 to test for!) +title= OS/2 +root= (hd0,1) +makeactive +chainloader= /boot/chain.os2 +# This is similar to "chainload", but loads a specific file + +# For booting Windows NT 3.5 or DOS +title= Windows NT 3.5/DOS boot menu +root= (0x80,0) +makeactive +chainloader= +1 + +# For booting DOS from a Windows NT/DOS installation +title= DOS +root= (0x80,0) +makeactive +chainloader= /bootsect.dos + diff --git a/docs/technical.html b/docs/technical.html new file mode 100644 index 000000000..c2adff4db --- /dev/null +++ b/docs/technical.html @@ -0,0 +1,390 @@ + + + +GRUB Technical Info + + + + +

GRUB Technical Info

+

by +Erich Boleyn

+ +
+ +

Contents

+ + + +
+ +

Challenges/Issues

+ +Several major issues have plagued bootloaders for IBM PC compatibles for +a long time, mostly related to compatibility.

+ +For more detail about the operation of standard floppy and hard disk +bootloaders, I have a 100K text document version of +Hale Landis' How It Works Series, +which is about the BIOS, booting, etc., and is very informative, though +mildly outdated, and with what seem to be a few errors. I'm looking into +getting updated information for flushing it out myself into a real +HTML document.

+ +The worst problems and the general way they are solved in GRUB are +listed here (some of these have to be cooperatively solved with the OS):

+ +

Bootloader Size Limits

+ +Bootloaders have to be very small, typically limited to one or more very +small areas on the media in question.

+ +At the start of the process, the BIOS loads the first block off of the +boot disk (floppy or hard drive), 512 bytes in size. This one block +must be capable of performing all the functions necessary to start up +the system, or handing off to another program. On a hard disk, at +least 64 bytes are reserved for a partition table, therefore unusable.

+ +Traditionally, if the first block is not enough, at the start of the +partition with the OS being booted (or, for a floppy, just at the +beginning) is a fixed area, the size (generally from 512 bytes to +8 Kbytes) of which is dependent on the filesystem variety in question.

+ +Most bootloaders are written to fit within this limitation, giving them +only room for a very sparse functionality.

+ +GRUB is very large compared to other bootloaders (typically +20 to 30 K). A mechanism is +in place which can load all of it's components for different +installal methods. +The feeling from +the author is that this will not be a problem since most of the features pay +for themselves both in terms of space (certainly the generic decompression +code, for example) and flexibilty +to both end-users and experts.

+ +

Partitioning Issues

+ +The traditional layout of a floppy on a PC is with the first block +being the boot-controller, and the rest of the disk being formatted +to some filesystem type.

+ +The traditional layout of a hard disk on a PC is with the first block +being the boot-controller, referred to as the MBR (Master Boot Record), +with the rest of the disk subdivided into 4 sections (called +"partitions"), each of which look either like a logical floppy +(boot block + filsystem), or a full hard disk (sort of a recursive +definition here, though only one of the partitions can be one of +these). Inside one of the recursive hard disk definitions, only one +of the 4 partitions can have a filesystem. The pratical result is that +an arbitrary number of partitions can be represented. The biggest +problem here is that generally only one of the 4 partitions listed +directly in the main MBR can be the "active" one, which is the one +where any subsidary boot blocks are pulled from.

+ +Most bootloaders don't deal with the "active partition" marker in +a very intelligent manner.

+ +GRUB can both PC style partitions (normal and extended DOS-style) and +386BSD/Mach style BSD sub-partitions in a consistent manner, plus it +can set the "active partition" marker as desired (he "active partition" +marker is currently irrelevant to GRUBs actual behavior, this still +needs some work related to default device notations).

+ +

Geometry Translation

+ +There are several methods of using the BIOS to access a disk before +any kind of driver is active. The only consistent one is the INT 13h +interface, which uses an addressing scheme based on the Cylinder, Head, +and Sector positions of a block, packed into a value consisting of 10 bits, +8 bits, and 6 bits, respectively.

+ +To attempt to get around this issue, and in the case of SCSI disks, to allow +a differential number of sectors in different physical cylinders without +confusing the heck out of the software, the concept of Geometry Translation +was introduced. Geometry Translation produces a transparent virtual +mapping from some phantom number of Cylinders, Sectors and Heads onto +the real hardware of the disk, generally trying to increase the space of +the disk accessible via the INT 13h interface.

+ +Another problem created from the above is that different controller/BIOS +combinations (and possibly even different particular installations of +software) can use different geometry translations, and since the bootloaders +on the disk depend on the particular numbers, they either have to be +carefully updated, or, in some cases, the whole OS must be re-installed when +moving the disk to another controller/BIOS combination.

+ +The essential issue is that pretty much all bootloaders prior to GRUB use +Cylinder/Head/Sector numbers for the first stage of booting, so if +that mapping should change, your OS can't boot, even though the linear +mapping is the same, and if you could get it booted somehow, everything +work would fine.

+ +GRUB solves this by translating from/to a linear block-number +AT ALL TIMES. This turns out to be OK, as the major OS used +to test a BIOS translation mechanism, DOS, uses exactly the same +mappings.

+ +

512MB - 8GB BIOS Translation Size Limits

+ +Related to the Gemetry Translation problem is the problem that in standard +INT 13h BIOS interface has a maximum of 24 bits to access the disk with.

+ +The problem is that even +presuming a perfectly spanned space, 24 bits is only 16 M blocks, +and at 512 bytes each, +this is a maximum disk size of 8 GB. Most real systems have limitations +of either 512 MB (this is where the IDE limit of 508 MB comes from, I'm +pretty sure, as the top 4 bits of the "head" number can't be used +in most BIOS IDE interfaces), or 1 GB, though this is changing, moving +toward the 8 GB maximum size.

+ +GRUB can't universally solve this problem, as there is no new interface +which is used in all machines. At least one newer interface which +is present on some machines ("LBA", which is in more and more new +ones, supposedly) may +be able to be used transparently in place of INT 13h when available. +This is still being investigated.

+ +

Memory size determination

+ +Various OS's do this differently. Some rely on their bootloader, and +some perform the probe themselves. Most are limited to detecting a +maximum of 64MB on a PC, in any case. Kludges where a hard-coded +portion telling the machine how much RAM is installed, or even compiling +it in, have been made for many OSes.

+ +Since this is both once-only +code and only involves the BIOS, the solution which Multiboot and +GRUB uses is to perform the probe in the bootloader. +Look at the bulleted item "Detects all Installed RAM" in the section +Features below.

+ +


+ +

Specifications and other Goals

+ +The primary requirement for GRUB is that it be compliant with the +Multiboot Standard.

+ +The other goals, listed in approximate order of importance, are:

+ +

    +
  • Basic functions must be easy for an end-user to use.

    +

  • Rich functionality for OS experts/designers.

    +

  • Compatibility for booting FreeBSD, NetBSD, and Linux. +Proprietary OS's such as DOS, Windows NT, and OS/2 are +supported via a chain-loading function.

    +

+ +Except for specific compatibility modes (chain-loading and the +Linux 'piggyback' format), +all kernels will be started in much the same state as in the Multiboot +Standard listed above. Only kernels being loaded at 1 megabyte or above +are presently supported. Any attempt to load below that boundary will +simply result in immediate failure and an error message reporting the +problem.

+ +


+ +

Features

+ +In addition to the requirements in the previous section, GRUB has the +following features (note that the Multiboot Standard doesn't explicitly +require everything listed in it, but GRUB will support all options):

+ +

    +
  • Multiple Executable Formats: Supports many of the a.out +variants plus ELF. Any symbol table present is also loaded.

    +

  • Supports Non-Multiboot OS's: Supports many of the various +free 32-bit OS's prior to any Multiboot compliance. Chiefly FreeBSD, +NetBSD, and Linux. Chain-loading is also supported.

    +

  • Loads Multiple Modules: Multiboot feature of loading multiple +modules is fully supported.

    +

  • Configuration File: +Supports a human-readable text configuration file with preset boot commands. +The list of commands are a superset +of those supported on the command-line. +An example command-file is provided.

    +

  • Menu Interface: A menu-interface listing +the preset boot commands, with a programmable timeout, is available. +There is no fixed limit on the number of boot command-set entries, and +should have space for several hundred.

    +

  • Flexible Command-Line Interface: A fairly flexible +command-line interface, accessible from the +menu, is available to edit any preset commands, or simply start a new +command-set from scratch. +The list of commands are a subset of those +supported for command-files. Editing commands closely resemble the +BASH shell command-line, with TAB-completion-listing (it doesn't +perform the completion, just lists the possibilities) of commands, +devices, partitions, and files in a directory depending on context. +If no config file is present, it goes into the command-line.

    +

  • Multiple Filesystem Types: Supports multiple filesystem +types transparently, plus an explicitly usable block-list notation. +The currently supported filesystem types are BSD FFS, DOS FAT, +and Linux ext2fs. There is also a page describing the +GRUB filesystems and interfaces.

    +

  • Decompression Support: Can decompress files which were +compressed with using "gzip". This function is both automatic and +transparent to the user (i.e. all functions operate normally upon +the uncompressed contents of the files in question). This is a win +on 2 fronts, as it both greatly reduces file size and loading time (there +are a few pathological cases where loading a very badly organized ELF +kernel might make it take longer, but IMO you'll never see this in +practice), a particularly major win for floppies. It is conceivable +that some kernel modules should be loaded in a compressed state, so a +variant of the module loading command which doesn't uncompress them +can be used.

    +

  • Access Data on Any Installed Device: Supports reading data +from any or all floppy or hard disk(s) recognized by the BIOS, independent +of the setting for the root partition.

    +

  • Geometry Translation-Idependent: Subject to the constraint +that it cannot go past the end of the geometry-translated area of a drive, +the particular translation used is generally irrelevant. This implies a +drive installed and running on a controller with one translation in use +may in general be moved to another controller with a different translation +(or the translation settings on the first controller, if configurable, +may be changed) with no adverse effects and no other changes necessary.

    +

  • Detects All Installed RAM: GRUB can generally find all the +installed RAM on a PC-compatible machine. It uses the +BIOS query technique described on the + +INT 15h, AX=E820h - Query System Address Map web page. As described on +the Multiboot Standard web page listed above, OS's which only use the +lower and upper memory values (whose presence is determined by bit 0 of +the flags word passed to the OS) may not be capable of receiving information +on all of installed memory. On most machines, upper memory is contiguous, +so the problem does not arise.

    +

+ +Future directions might include an internal programming language for +supporting richer sets of boot options with control statements +(it becomes a boot-script at that point), +and possibly support for non-IBM PC-compatible machines.

+ +One definite path for future work is how to fairly transparently get +around the 8 GB geometry translation limitation.

+ +


+ +

Other Implementation Details

+ +GRUB can completely replace the primary bootloader on a hard disk or +floppy disk. On a hard disk, it can also be run after some other +bootloader capable of chain-loading.

+ +GRUB is broken into 2 distinct components, or stages, which are loaded at +different times in the boot process. The Stage 1 has to know where to +find Stage 2, and the Stage 2 has to know where to find it's configuration +file (if Stage 2 doesn't have a config file, it drops into the command-line +interface and waits for a user command).

+ +Here is a memory map of the various components:

+ +

+
+      0       to    4K-1 :   Interrupt & BIOS area.
+
+      down  from    8K-1 :   16-bit stack area.
+
+      8K   to  (ebss1.5) :   Stage-1.5 (optionally) loaded here by Stage-1.
+
+      0x7c00  to  0x7dff :   Stage-1 loaded here by the BIOS.
+      0x7e00  to  0x7e08 :   scratch space used by Stage-1.
+
+      32K    to  (ebss2) :   Stage-2 loaded here by Stage-1.5 or Stage-1.
+
+        (middle area)    :   heap used for random memory allocation.
+
+      down  from  416K-1 :   32-bit stack area.
+
+      416K    to  448K-1 :   Filesystem info buffer (when reading a filesys).
+      448K  to  479.5K-1 :   BIOS track read buffer.
+      479.5K  to  480K-1 :   512 byte fixed SCRATCH area.
+
+      480K    to  511K-1 :   general storage heap.
+
+
+ +Description of GRUB's major components (and some of the boot sequence):

+ +

Stage 1

+ +Stage 1 is only used to load Stage 2. If Stage 2 can be loaded in +some other manner in a compatible fashion, then Stage 1 is unnecessary, +and doesn't need to be used.

+ +

    +
  • On a floppy, there is generally only one possible boot area, the first +boot sector. The Stage 1 portion would go there.

    +

  • On a hard disk, Stage 1 can be part of the MBR block or part of the +first block of some partition.

    +

+ +Stage 1 "knows" where Stage 2 is by entries in a block-list loading table +embedded in it. It loads the lists of blocks off of the booting drive, +then jumps to a specified CS:IP in 16-bit real mode. These are described +in the page on embedded data. It queries the +BIOS for the disk geometry, and maps the linear block numbers there to +C:H:S addresses used by the INT 13h BIOS interface.

+ +See the Installation +Guide for details on how to set up loading Stage 2 from Stage 1.

+ +

OPTIONAL Stage 1.5

+ +Since the Stage 2 is so large (typically 30K or larger in size), +a special stripped down version of the +Stage 2 code, sort of a Stage 1.5, can be used because it might fit into +one of the fixed areas of the disk. The idea is to have the Stage 1.5 +look for a certain file and attempt to execute it as a Stage 2 (this +allows changing Stage 2 easily, while leaving it a normal file in +the filesystem).

+ +This is actually the case for the BSD FFS filesystem. There is a fixed +area 7K in size at the beginning of the partition which is reserved for +the bootloader. The Stage 1.5 with BSD FFS filesystem support is +about 6.5 K in size when compiled in a.out format, and fits nicely, +allowing the Stage 2 to be a normal file in the "/boot/grub" directory +of the install partition.

+ +This same technique can in principle be applied to other filesystems, +but the problem here is that the fixed area available to bootloaders is +generally quite small (0.5 to 3 K), and a Stage 1.5 wouldn't fit.

+ +It contains +embedded data +on where to look for the install partition +and the Stage 2 (it uses what would be the "configuration file" +entry in the Stage 2 for this purpose).

+ +

Stage 2

+ +This component is the GRUB proper.

+ +It gets most of the information about the machine and the boot state +from the BIOS and information passed into it at starting time, except +that it contains +embedded data +on where to look for the install partition and the configuration file.

+ +The first action of the Stage 2 is to look for it's configuration file. +If one is not found, then +it drops into the command-line interface. +If one is found, the full menu interface is activated containing +whatever entries were found in the file (the command-line is still +available via a command from the menu interface).

+ +


+ +erich@uruk.org

+ + + + diff --git a/docs/using.html b/docs/using.html new file mode 100644 index 000000000..8920c938e --- /dev/null +++ b/docs/using.html @@ -0,0 +1,99 @@ + + + +Using GRUB + + + + +

Using GRUB

+

by +Erich Boleyn

+ +
+ +

Contents

+ + + +GRUB has both a simple menu interface for preset options from a +configuration file, and a highly flexible command-line for performing +any desired combination of boot commands.

+ +The first action GRUB takes after it is loaded is +to look for it's configuration file. +If one is not found, then +it drops into the command-line interface (and stays there). +If one is found, the full menu interface is activated containing +whatever entries were found in the file (the command-line is still +available via a command from the menu interface).

+ +


+ +

Command-Line Interface

+ +The command-line interface provides a prompt and after it an editable +text area much like a command-line in DOS or UNIX. Each command is +immediately executed after it is entered. The +list of commands are a subset of those available +in the configuration file, used with exactly the same syntax.

+ +Cursor movement and editing of the text on the line can be done +via a subset of the functions +available in the BASH shell (C-f forward, C-b backward, C-a beginning +of line, C-e end of line, C-k delete to end, C-u delete to beginning; +the PC left and right arrow keys, HOME, DELETE, and END work as well).

+ +When typing commands interactively, if the cursor is before the "=" +character in a command being typed, pressing the TAB key will display +a listing of the available commands, and if the cursor is after the +"=" character, the TAB will provide +a completion listing of disks, partitions, and filenames depending on +the context.

+ +


+ +

Menu Interface

+ +The menu interface is quite easy to use. It's commands are both +reasonably intuitive and described onscreen.

+ +Basically, the menu interface provides a list of "boot configurations" +to the user to choose from. Use the arrow keys to select the entry +of choice, then press ENTER to run it. An optional timeout is available +to boot the default entry (the first one if not set), +which is aborted by pressing any key.

+ +Commands are available to enter a bare command-line (operating +exactly like the non-config-file version of GRUB, but allowing one to +return to the menu if desired) or to edit any of the "boot +configurations". + +


+ +

Menu Entry Editor

+ +This looks much like the main menu interface, but with the lines in the +menu being individual commands of the selected configuration instead of +configuration names.

+ +If an ESC is pressed in the editor, it aborts all the changes made to +the configuration entry and goes back to the main menu interface.

+ +When a particular line is selected, then it +places the user in a special version of the command-line for editing +that line. When the user is finished, GRUB replaces the line in question +in the "boot configuration" with the changes (unless it was aborted via +ESC, and in that case the changes are thrown away).

+ +


+ +erich@uruk.org

+ + + + diff --git a/ffs_stage1_5/Makefile b/ffs_stage1_5/Makefile new file mode 100644 index 000000000..067e2d313 --- /dev/null +++ b/ffs_stage1_5/Makefile @@ -0,0 +1,50 @@ +# +# GRUB ffs_stage1_5 makefile +# + +CFLAGS= $(SHARED_FLAGS) -DFSYS_FFS -DNO_DECOMPRESSION -DNO_FANCY_STUFF \ + -DNO_BLOCK_FILES -DCONFIG_FILE_ASM=".string \"/boot/grub/stage2\"" \ + -I../shared_src + +# "asm.o" absolutely has to come first in the link line! +SHARED_OBJS= asm.o char_io.o common.o disk_io.o stage1_5.o fsys_ffs.o + +all: ../bin/ffs_stage1_5 + +asm.o: ../shared_src/asm.S ../shared_src/shared.h Makefile ../Makefile + $(CC) $(CFLAGS) -c ../shared_src/asm.S + +char_io.o: ../shared_src/char_io.c ../shared_src/shared.h Makefile \ + ../Makefile + $(CC) $(CFLAGS) -c ../shared_src/char_io.c + +common.o: ../shared_src/common.c ../shared_src/shared.h Makefile \ + ../Makefile + $(CC) $(CFLAGS) -c ../shared_src/common.c + +disk_io.o: ../shared_src/disk_io.c ../shared_src/filesys.h \ + ../shared_src/pc_slice.h ../shared_src/shared.h Makefile \ + ../Makefile + $(CC) $(CFLAGS) -c ../shared_src/disk_io.c + +stage1_5.o: ../shared_src/stage1_5.c ../shared_src/shared.h Makefile \ + ../Makefile + $(CC) $(CFLAGS) -c ../shared_src/stage1_5.c + +fsys_ffs.o: ../shared_src/fsys_ffs.c ../shared_src/filesys.h \ + ../shared_src/pc_slice.h ../shared_src/shared.h \ + ../shared_src/defs.h ../shared_src/disk_inode.h \ + ../shared_src/disk_inode_ffs.h ../shared_src/dir.h \ + ../shared_src/fs.h Makefile ../Makefile + $(CC) $(CFLAGS) -c ../shared_src/fsys_ffs.c + +# "asm.o" absolutely has to come first in the link line! +ffs_stage1_5.exec: $(SHARED_OBJS) Makefile ../Makefile + $(LD) -N -Ttext 2000 -o ffs_stage1_5.exec $(SHARED_OBJS) + +../bin/ffs_stage1_5: ffs_stage1_5.exec Makefile ../Makefile + $(OBJCOPY) -O binary ffs_stage1_5.exec ../bin/ffs_stage1_5 + +clean: + rm -f $(SHARED_OBJS) ffs_stage1_5.exec + diff --git a/shared_src/apic.h b/shared_src/apic.h new file mode 100644 index 000000000..b81bda365 --- /dev/null +++ b/shared_src/apic.h @@ -0,0 +1,73 @@ +/* + * + * + * Author: Erich Boleyn http://www.uruk.org/~erich/ + * + * Header file for Intel Architecture local and I/O APIC definitions. + * + * This file was created from information in the Intel Pentium Pro + * Family Developer's Manual, Volume 3: Operating System Writer's + * Manual, order number 242692-001, which can be ordered from the + * Intel literature center. + */ + +#ifndef _APIC_H +#define _APIC_H + +/* + * APIC Defines. + */ + +#define APIC_BROADCAST_ID 0xFF + +/* + * APIC register definitions + */ + +/* + * Shared defines for I/O and local APIC definitions + */ +/* APIC version register */ +#define APIC_VERSION(x) ((x) & 0xFF) +/* if the APIC version is equal or greater than APIC_VER_NEW, it + is a "new" APIC */ +#define APIC_VER_NEW 0x10 +/* this next one is used in all cases but an old local APIC, which has + 2 entries in it's LVT */ +#define APIC_MAXREDIR(x) (((x) >> 16) & 0xFF) +/* APIC id register */ +#define APIC_OLD_ID(x) ((x) >> 24) +#define APIC_NEW_ID(x) (((x) >> 24) & 0xF) + +#define IOAPIC_REGSEL 0 +#define IOAPIC_RW 0x10 +#define IOAPIC_ID 0 +#define IOAPIC_VER 1 +#define IOAPIC_REDIR 0x10 +#define LAPIC_ID 0x20 +#define LAPIC_VER 0x30 +#define LAPIC_TPR 0x80 +#define LAPIC_APR 0x90 +#define LAPIC_PPR 0xA0 +#define LAPIC_EOI 0xB0 +#define LAPIC_LDR 0xD0 +#define LAPIC_DFR 0xE0 +#define LAPIC_SPIV 0xF0 +#define LAPIC_SPIV_ENABLE_APIC 0x100 +#define LAPIC_ISR 0x100 +#define LAPIC_TMR 0x180 +#define LAPIC_IRR 0x200 +#define LAPIC_ESR 0x280 +#define LAPIC_ICR 0x300 +#define LAPIC_DEST_MASK 0xFFFFFF +#define LAPIC_LVTT 0x320 +#define LAPIC_LVTPC 0x340 +#define LAPIC_LVT0 0x350 +#define LAPIC_LVT1 0x360 +#define LAPIC_LVTE 0x370 +#define LAPIC_TICR 0x380 +#define LAPIC_TCCR 0x390 +#define LAPIC_TDCR 0x3E0 + +#endif /* _APIC_H */ + diff --git a/shared_src/smp-imps.c b/shared_src/smp-imps.c new file mode 100644 index 000000000..86aeb8e6d --- /dev/null +++ b/shared_src/smp-imps.c @@ -0,0 +1,549 @@ +/* + * + * + * Author: Erich Boleyn http://www.uruk.org/~erich/ + * + * Source file implementing Intel MultiProcessor Specification (MPS) + * version 1.1 and 1.4 SMP hardware control for Intel Architecture CPUs, + * with hooks for running correctly on a standard PC without the hardware. + * + * This file was created from information in the Intel MPS version 1.4 + * document, order number 242016-004, which can be ordered from the + * Intel literature center. + * + * General limitations of this code: + * + * (1) : This code has never been tested on an MPS-compatible system with + * 486 CPUs, but is expected to work. + * (2) : Presumes "int", "long", and "unsigned" are 32 bits in size, and + * that 32-bit pointers and memory addressing is used uniformly. + */ + +#define _SMP_IMPS_C + + +/* + * XXXXX The following absolutely must be defined!!! + * + * The "KERNEL_PRINT" could be made a null macro with no danger, of + * course, but pretty much nothing would work without the other + * ones defined. + */ + +#if 0 +#define KERNEL_PRINT(x) /* some kind of print function */ +#define CMOS_WRITE_BYTE(x,y) /* write unsigned char "y" at CMOS loc "x" */ +#define CMOS_READ_BYTE(x) /* read unsigned char at CMOS loc "x" */ +#define PHYS_TO_VIRTUAL(x) /* convert physical address "x" to virtual */ +#define VIRTUAL_TO_PHYS(x) /* convert virtual address "x" to physical */ +#endif + + +/* + * Includes here + */ + +#include "apic.h" +#include "smp-imps.h" + + +/* + * Defines that are here so as not to be in the global header file. + */ +#define EBDA_SEG_ADDR 0x40E +#define BIOS_RESET_VECTOR 0x467 +#define LAPIC_ADDR_DEFAULT 0xFEE00000uL +#define IOAPIC_ADDR_DEFAULT 0xFEC00000uL +#define CMOS_RESET_CODE 0xF +#define CMOS_RESET_JUMP 0xa +#define CMOS_BASE_MEMORY 0x15 + + +/* + * Static defines here for SMP use. + */ + +#define DEF_ENTRIES 23 + +static int lapic_dummy = 0; +static struct { + imps_processor proc[2]; + imps_bus bus[2]; + imps_ioapic ioapic; + imps_interrupt intin[16]; + imps_interrupt lintin[2]; +} defconfig = { + { { IMPS_BCT_PROCESSOR, 0, 0, 0, 0, 0}, + { IMPS_BCT_PROCESSOR, 1, 0, 0, 0, 0} }, + { { IMPS_BCT_BUS, 0, {'E', 'I', 'S', 'A', ' ', ' '}}, + { 255, 1, {'P', 'C', 'I', ' ', ' ', ' '}} }, + { IMPS_BCT_IOAPIC, 0, 0, IMPS_FLAG_ENABLED, IOAPIC_ADDR_DEFAULT }, + { { IMPS_BCT_IO_INTERRUPT, IMPS_INT_EXTINT, 0, 0, 0, 0xFF, 0}, + { IMPS_BCT_IO_INTERRUPT, IMPS_INT_INT, 0, 0, 1, 0xFF, 1}, + { IMPS_BCT_IO_INTERRUPT, IMPS_INT_INT, 0, 0, 0, 0xFF, 2}, + { IMPS_BCT_IO_INTERRUPT, IMPS_INT_INT, 0, 0, 3, 0xFF, 3}, + { IMPS_BCT_IO_INTERRUPT, IMPS_INT_INT, 0, 0, 4, 0xFF, 4}, + { IMPS_BCT_IO_INTERRUPT, IMPS_INT_INT, 0, 0, 5, 0xFF, 5}, + { IMPS_BCT_IO_INTERRUPT, IMPS_INT_INT, 0, 0, 6, 0xFF, 6}, + { IMPS_BCT_IO_INTERRUPT, IMPS_INT_INT, 0, 0, 7, 0xFF, 7}, + { IMPS_BCT_IO_INTERRUPT, IMPS_INT_INT, 0, 0, 8, 0xFF, 8}, + { IMPS_BCT_IO_INTERRUPT, IMPS_INT_INT, 0, 0, 9, 0xFF, 9}, + { IMPS_BCT_IO_INTERRUPT, IMPS_INT_INT, 0, 0, 10, 0xFF, 10}, + { IMPS_BCT_IO_INTERRUPT, IMPS_INT_INT, 0, 0, 11, 0xFF, 11}, + { IMPS_BCT_IO_INTERRUPT, IMPS_INT_INT, 0, 0, 12, 0xFF, 12}, + { IMPS_BCT_IO_INTERRUPT, IMPS_INT_INT, 0, 0, 13, 0xFF, 13}, + { IMPS_BCT_IO_INTERRUPT, IMPS_INT_INT, 0, 0, 14, 0xFF, 14}, + { IMPS_BCT_IO_INTERRUPT, IMPS_INT_INT, 0, 0, 15, 0xFF, 15} }, + { { IMPS_BCT_LOCAL_INTERRUPT, IMPS_INT_EXTINT, 0, 0, 15, 0xFF, 0}, + { IMPS_BCT_LOCAL_INTERRUPT, IMPS_INT_NMI, 0, 0, 15, 0xFF, 1} } +}; + +/* + * Exported globals here. + */ + +int imps_any_new_apics = 0; +volatile int imps_release_cpus = 0; +int imps_enabled = 0; +int imps_num_cpus = 1; +unsigned imps_lapic_addr = ((unsigned)(&lapic_dummy)) - LAPIC_ID; +unsigned char imps_cpu_apic_map[IMPS_MAX_CPUS]; +unsigned char imps_apic_cpu_map[IMPS_MAX_CPUS]; + + +/* + * MPS checksum function + * + * Function finished. + */ + +static int +get_checksum(unsigned start, int length) +{ + unsigned sum = 0; + + while (length-- > 0) { + sum += *((unsigned char *) (start++)); + } + + return (sum&0xFF); +} + + +/* + * Primary function for booting individual CPUs. + * + * This must be modified to perform whatever OS-specific initialization + * that is required. + */ + +static int +boot_cpu(imps_processor *proc) +{ + int apicid = proc->apic_id; + unsigned bootaddr, send_status, accept_status, cfg; + unsigned bios_reset_vector = PHYS_TO_VIRTUAL(BIOS_RESET_VECTOR); + + /* %%%%% ESB */ + extern char patch_code[]; + bootaddr = 256*1024; + bcopy(patch_code, (char *)bootaddr, 32); + + /* + * Generic CPU startup sequence starts here. + */ + + /* set BIOS reset vector */ + CMOS_WRITE_BYTE(CMOS_RESET_CODE, CMOS_RESET_JUMP); + *((volatile unsigned *) bios_reset_vector) = bootaddr << 12; + + /* clear the error register */ + if (proc->apic_ver & 0x10) { + IMPS_LAPIC_WRITE(LAPIC_ESR, 0); + accept_status = IMPS_LAPIC_READ(LAPIC_ESR); + } + +#if 0 + /* assert INIT IPI */ + cfg = IMPS_LAPIC_READ(LAPIC_ICR+1); + cfg &= LAPIC_DEST_MASK; + IMPS_LAPIC_WRITE(LAPIC_ICR+1, cfg); + cfg = IMPS_LAPIC_READ(LAPIC_ACR); + cfg &= ; + + /* %%%%% ESB finish adding startup sequence */ +#endif + + /* clean up BIOS reset vector */ + CMOS_WRITE_BYTE(CMOS_RESET_CODE, 0); + *((volatile unsigned *) bios_reset_vector) = 0; + + /* + * Generic CPU startup sequence ends here. + */ + + KERNEL_PRINT(("\n")); + + return 1; + + /* XXXXX add OS-specific initialization here! */ +} + + +/* + * read bios stuff and fill tables + */ + +static void +add_processor(imps_processor *proc) +{ + int apicid = proc->apic_id; + + KERNEL_PRINT((" Processor [APIC id %d ver %d]: ", + apicid, proc->apic_ver)); + if (!(proc->flags & IMPS_FLAG_ENABLED)) { + KERNEL_PRINT(("DISABLED\n")); + return; + } + if (proc->apic_ver > 0xF) { + imps_any_new_apics = 1; + } + if (proc->flags & (IMPS_CPUFLAG_BOOT)) { + KERNEL_PRINT(("#0 Bootstrap Processor (BSP)\n")); + return; + } + imps_cpu_apic_map[imps_num_cpus] = apicid; + imps_apic_cpu_map[apicid] = imps_num_cpus; + if (boot_cpu(proc)) { + + /* XXXXX add OS-specific setup for secondary CPUs here */ + + imps_num_cpus++; + } +} + + +static void +add_bus(imps_bus *bus) +{ + char str[8]; + + bcopy(bus->bus_type, str, 6); + str[6] = 0; + KERNEL_PRINT((" Bus id %d is %s\n", bus->id, str)); + + /* XXXXX add OS-specific code here */ +} + + +static void +add_ioapic(imps_ioapic *ioapic) +{ + KERNEL_PRINT((" I/O APIC id %d ver %d, address: 0x%x ", + ioapic->id, ioapic->ver, ioapic->addr)); + if (!(ioapic->flags & IMPS_FLAG_ENABLED)) { + KERNEL_PRINT(("DISABLED\n")); + return; + } + KERNEL_PRINT(("\n")); + + /* XXXXX add OS-specific code here */ +} + + +static void +imps_read_config_table(unsigned start, int count) +{ + while (count-- > 0) { + switch (*((unsigned char *)start)) { + case IMPS_BCT_PROCESSOR: + add_processor((imps_processor *)start); + start += 12; /* 20 total */ + break; + case IMPS_BCT_BUS: + add_bus((imps_bus *)start); + break; + case IMPS_BCT_IOAPIC: + add_ioapic((imps_ioapic *)start); + break; +#if 0 /* XXXXX uncomment this if "add_io_interrupt" is implemented */ + case IMPS_BCT_IO_INTERRUPT: + add_io_interrupt((imps_interrupt *)start); + break; +#endif +#if 0 /* XXXXX uncomment this if "add_local_interrupt" is implemented */ + case IMPS_BCT_LOCAL_INTERRUPT: + add_local_interupt((imps_interrupt *)start); + break; +#endif + default: + } + start += 8; + } +} + + +static int +imps_bad_bios(imps_fps *fps_ptr) +{ + int sum; + imps_cth *local_cth_ptr + = (imps_cth *) PHYS_TO_VIRTUAL(fps_ptr->cth_ptr); + + if (fps_ptr->feature_info[0] > IMPS_FPS_DEFAULT_MAX) { + KERNEL_PRINT((" Invalid MP System Configuration type %d\n", + fps_ptr->feature_info[0])); + return 1; + } + + if (fps_ptr->cth_ptr) { + sum = get_checksum((unsigned)local_cth_ptr, + local_cth_ptr->base_length); + if (local_cth_ptr->sig != IMPS_CTH_SIGNATURE || sum) { + KERNEL_PRINT((" Bad MP Config Table sig 0x%x and/or checksum 0x%x\n", (unsigned)(fps_ptr->cth_ptr), sum)); + return 1; + } + if (local_cth_ptr->spec_rev != fps_ptr->spec_rev) { + KERNEL_PRINT((" Bad MP Config Table sub-revision # %d\n", local_cth_ptr->spec_rev)); + return 1; + } + if (local_cth_ptr->extended_length) { + sum = (get_checksum(((unsigned)local_cth_ptr) + + local_cth_ptr->base_length, + local_cth_ptr->extended_length) + + local_cth_ptr->extended_checksum) & 0xFF; + if (sum) { + KERNEL_PRINT((" Bad Extended MP Config Table checksum 0x%x\n", sum)); + return 1; + } + } + } else if (!fps_ptr->feature_info[0]) { + KERNEL_PRINT((" Missing configuration information\n")); + return 1; + } + + return 0; +} + + +static void +imps_read_bios(imps_fps *fps_ptr) +{ + int apicid; + unsigned cth_start, cth_count; + imps_cth *local_cth_ptr + = (imps_cth *)PHYS_TO_VIRTUAL(fps_ptr->cth_ptr); + char *str_ptr; + + KERNEL_PRINT(("Intel MultiProcessor Spec 1.%d BIOS support detected\n", + fps_ptr->spec_rev)); + + /* + * Do all checking of errors which would definitely + * lead to failure of the SMP boot here. + */ + + if (imps_bad_bios(fps_ptr)) { + KERNEL_PRINT((" Disabling MPS support\n")); + return; + } + + if (fps_ptr->feature_info[1] & IMPS_FPS_IMCRP_BIT) { + str_ptr = "IMCR and PIC"; + } else { + str_ptr = "Virtual Wire"; + } + if (fps_ptr->cth_ptr) { + imps_lapic_addr = local_cth_ptr->lapic_addr; + } else { + imps_lapic_addr = LAPIC_ADDR_DEFAULT; + } + KERNEL_PRINT((" APIC config: \"%s mode\" Local APIC address: 0x%x\n", + str_ptr, imps_lapic_addr)); + imps_lapic_addr = PHYS_TO_VIRTUAL(imps_lapic_addr); + + /* + * Setup primary CPU. + */ + apicid = IMPS_LAPIC_READ(LAPIC_SPIV); + IMPS_LAPIC_WRITE(LAPIC_SPIV, apicid|LAPIC_SPIV_ENABLE_APIC); + imps_any_new_apics = IMPS_LAPIC_READ(LAPIC_VER) & 0xF0; + apicid = IMPS_APIC_ID(IMPS_LAPIC_READ(LAPIC_ID)); + imps_cpu_apic_map[0] = apicid; + imps_apic_cpu_map[apicid] = 0; + + if (fps_ptr->cth_ptr) { + char str1[16], str2[16]; + bcopy(local_cth_ptr->oem_id, str1, 8); + str1[8] = 0; + bcopy(local_cth_ptr->prod_id, str2, 12); + str2[12] = 0; + KERNEL_PRINT((" OEM id: %s Product id: %s\n", str1, str2)); + cth_start = ((unsigned) local_cth_ptr) + sizeof(imps_cth); + cth_count = local_cth_ptr->entry_count; + } else { + *((volatile unsigned *) IOAPIC_ADDR_DEFAULT) = IOAPIC_ID; + defconfig.ioapic.id + = IMPS_APIC_ID(*((volatile unsigned *) + (IOAPIC_ADDR_DEFAULT+IOAPIC_RW))); + *((volatile unsigned *) IOAPIC_ADDR_DEFAULT) = IOAPIC_VER; + defconfig.ioapic.ver + = APIC_VERSION(*((volatile unsigned *) + (IOAPIC_ADDR_DEFAULT+IOAPIC_RW))); + defconfig.proc[apicid].flags + = IMPS_FLAG_ENABLED|IMPS_CPUFLAG_BOOT; + defconfig.proc[!apicid].flags = IMPS_FLAG_ENABLED; + imps_num_cpus = 2; + if (fps_ptr->feature_info[0] == 1 + || fps_ptr->feature_info[0] == 5) { + bcopy("ISA ", defconfig.bus[0].bus_type, 6); + } + if (fps_ptr->feature_info[0] == 4 + || fps_ptr->feature_info[0] == 7) { + bcopy("MCA ", defconfig.bus[0].bus_type, 6); + } + if (fps_ptr->feature_info[0] > 4) { + defconfig.proc[0].apic_ver = 0x10; + defconfig.proc[1].apic_ver = 0x10; + defconfig.bus[1].type = IMPS_BCT_BUS; + } + if (fps_ptr->feature_info[0] == 2) { + defconfig.intin[2].type = 255; + defconfig.intin[13].type = 255; + } + if (fps_ptr->feature_info[0] == 7) { + defconfig.intin[0].type = 255; + } + cth_start = (unsigned) &defconfig; + cth_count = DEF_ENTRIES; + } + imps_read_config_table(cth_start, cth_count); + + /* %%%%% ESB read extended entries here */ + + imps_enabled = 1; +} + + +/* + * Given a region to check, this actually looks for the "MP Floating + * Pointer Structure". The return value indicates if the correct + * signature and checksum for a floating pointer structure of the + * appropriate spec revision was found. If so, then do not search + * further. + * + * NOTE: The memory scan will always be in the bottom 1 MB. + * + * This function presumes that "start" will always be aligned to a 16-bit + * boundary. + * + * Function finished. + */ + +static int +imps_scan(unsigned start, unsigned length) +{ + IMPS_DEBUG_PRINT(("Scanning from 0x%x for %d bytes\n", + start, length)); + + while (length > 0) { + imps_fps *fps_ptr = (imps_fps *) PHYS_TO_VIRTUAL(start); + + if (fps_ptr->sig == IMPS_FPS_SIGNATURE + && fps_ptr->length == 1 + && (fps_ptr->spec_rev == 1 || fps_ptr->spec_rev == 4) + && !get_checksum(start, 16)) { + IMPS_DEBUG_PRINT(("Found MP Floating Structure Pointer at %x\n", start)); + imps_read_bios(fps_ptr); + return 1; + } + + length -= 16; + start += 16; + } + + return 0; +} + + +/* + * This is the primary function for probing for MPS compatible hardware + * and BIOS information. Call this during the early stages of OS startup, + * before memory can be messed up. + * + * The probe looks for the "MP Floating Pointer Structure" at locations + * listed at the top of page 4-2 of the spec. + * + * Environment requirements from the OS to run: + * + * (1) : A non-linear virtual to physical memory mapping is probably OK, + * as (I think) the structures all fall within page boundaries, + * but a linear mapping is recommended. Currently assumes that + * the mapping will remain identical over time (which should be + * OK since it only accesses memory which shouldn't be munged + * by the OS anyway). + * (2) : The OS only consumes memory which the BIOS says is OK to use, + * and not any of the BIOS standard areas (the areas 0x400 to + * 0x600, the EBDA, 0xE0000 to 0xFFFFF, and unreported physical + * RAM). Sometimes a small amount of physical RAM is not + * reported by the BIOS, to be used to store MPS and other + * information. + * (3) : It must be possible to read the CMOS. + * (4) : There must be between 512K and 640K of lower memory (this is a + * sanity check). + * + * Function finished. + */ + +int +imps_probe(void) +{ + /* + * Determine possible address of the EBDA + */ + unsigned ebda_addr = *((unsigned short *) + PHYS_TO_VIRTUAL(EBDA_SEG_ADDR)) << 4; + + /* + * Determine amount of installed lower memory (not *available* + * lower memory). + * + * NOTE: This should work reliably as long as we verify the + * machine is at least a system that could possibly have + * MPS compatibility to begin with. + */ + unsigned mem_lower = ((CMOS_READ_BYTE(CMOS_BASE_MEMORY+1) << 8) + | CMOS_READ_BYTE(CMOS_BASE_MEMORY)) << 10; + +#ifdef IMPS_DEBUG + imps_enabled = 0; + imps_num_cpus = 1; +#endif + + /* + * Sanity check : if this isn't reasonable, it is almost impossibly + * unlikely to be an MPS compatible machine, so return failure. + */ + if (mem_lower < 512*1024 || mem_lower > 640*1024) { + return 0; + } + + if (ebda_addr > mem_lower - 1024 + || ebda_addr + *((unsigned char *) PHYS_TO_VIRTUAL(ebda_addr)) + * 1024 > mem_lower) { + ebda_addr = 0; + } + + if (((ebda_addr && imps_scan(ebda_addr, 1024)) + || (!ebda_addr && imps_scan(mem_lower - 1024, 1024)) + || imps_scan(0xF0000, 0x10000)) && imps_enabled) { + return 1; + } + + /* + * If no BIOS info on MPS hardware is found, then return failure. + */ + + return 0; +} + diff --git a/shared_src/smp-imps.h b/shared_src/smp-imps.h new file mode 100644 index 000000000..ca7abfc31 --- /dev/null +++ b/shared_src/smp-imps.h @@ -0,0 +1,239 @@ +/* + * + * + * Author: Erich Boleyn http://www.uruk.org/~erich/ + * + * Header file implementing Intel MultiProcessor Specification (MPS) + * version 1.1 and 1.4 SMP hardware control for Intel Architecture CPUs, + * with hooks for running correctly on a standard PC without the hardware. + * + * This file was created from information in the Intel MPS version 1.4 + * document, order number 242016-004, which can be ordered from the + * Intel literature center. + */ + +#ifndef _SMP_IMPS_H +#define _SMP_IMPS_H + +/* make sure "apic.h" is included */ +#ifndef _APIC_H +#error Must include "apic.h" before "smp-imps.h" +#endif /* !_APIC_H */ + +/* + * Defines used. + */ + +#ifdef IMPS_DEBUG +#define IMPS_DEBUG_PRINT(x) KERNEL_PRINT(x) +#else /* !IMPS_DEBUG */ +#define IMPS_DEBUG_PRINT(x) +#endif /* !IMPS_DEBUG */ + +#define IMPS_MAX_CPUS APIC_BROADCAST_ID + +/* + * Defines representing limitations on values usable in different + * situations. This mostly depends on whether the APICs are old + * (82489DX) or new (SIO or Pentium/Pentium Pro integrated APICs). + * + * NOTE: It appears that the APICs must either be all old or all new, + * or broadcasts won't work right. + * NOTE #2: Given that, the maximum ID which can be sent to predictably + * is 14 for new APICs and 254 for old APICs. So, this all implies that + * a maximum of 15 processors is supported with the new APICs, and a + * maximum of 255 processors with the old APICs. + */ + +#define IMPS_APIC_ID(x) \ + ( imps_any_new_apics ? APIC_NEW_ID(x) : APIC_OLD_ID(x) ) + +/* + * This is the value that must be in the "sig" member of the MP + * Floating Pointer Structure. + */ +#define IMPS_FPS_SIGNATURE ('_' | ('M'<<8) | ('P'<<16) | ('_'<<24)) +#define IMPS_FPS_IMCRP_BIT 0x80 +#define IMPS_FPS_DEFAULT_MAX 7 + +/* + * This is the value that must be in the "sig" member of the MP + * Configuration Table Header. + */ +#define IMPS_CTH_SIGNATURE ('P' | ('C'<<8) | ('M'<<16) | ('P'<<24)) + +/* + * These are the "type" values for Base MP Configuration Table entries. + */ +#define IMPS_FLAG_ENABLED 1 +#define IMPS_BCT_PROCESSOR 0 +#define IMPS_CPUFLAG_BOOT 2 +#define IMPS_BCT_BUS 1 +#define IMPS_BCT_IOAPIC 2 +#define IMPS_BCT_IO_INTERRUPT 3 +#define IMPS_BCT_LOCAL_INTERRUPT 4 +#define IMPS_INT_INT 0 +#define IMPS_INT_NMI 1 +#define IMPS_INT_SMI 2 +#define IMPS_INT_EXTINT 3 + + +/* + * Typedefs and data item definitions done here. + */ + +typedef struct imps_fps imps_fps; /* MP floating pointer structure */ +typedef struct imps_cth imps_cth; /* MP configuration table header */ +typedef struct imps_processor imps_processor; +typedef struct imps_bus imps_bus; +typedef struct imps_ioapic imps_ioapic; +typedef struct imps_interrupt imps_interrupt; + + +/* + * Data structures defined here + */ + +/* + * MP Floating Pointer Structure (fps) + * + * Look at page 4-3 of the MP spec for the starting definitions of + * this structure. + */ +struct imps_fps +{ + unsigned sig; + imps_cth *cth_ptr; + unsigned char length; + unsigned char spec_rev; + unsigned char checksum; + unsigned char feature_info[5]; +}; + +/* + * MP Configuration Table Header (cth) + * + * Look at page 4-5 of the MP spec for the starting definitions of + * this structure. + */ +struct imps_cth +{ + unsigned sig; + unsigned short base_length; + unsigned char spec_rev; + unsigned char checksum; + char oem_id[8]; + char prod_id[12]; + unsigned oem_table_ptr; + unsigned short oem_table_size; + unsigned short entry_count; + unsigned lapic_addr; + unsigned short extended_length; + unsigned char extended_checksum; + char reserved[1]; +}; + +/* + * Base MP Configuration Table Types. They are sorted according to + * type (i.e. all of type 0 come first, etc.). Look on page 4-6 for + * the start of the descriptions. + */ + +struct imps_processor +{ + unsigned char type; /* must be 0 */ + unsigned char apic_id; + unsigned char apic_ver; + unsigned char flags; + unsigned signature; + unsigned features; + char reserved[8]; +}; + +struct imps_bus +{ + unsigned char type; /* must be 1 */ + unsigned char id; + char bus_type[6]; +}; + +struct imps_ioapic +{ + unsigned char type; /* must be 2 */ + unsigned char id; + unsigned char ver; + unsigned char flags; + unsigned addr; +}; + +struct imps_interrupt +{ + unsigned char type; /* must be 3 or 4 */ + unsigned char int_type; + unsigned short flags; + unsigned char source_bus_id; + unsigned char source_bus_irq; + unsigned char dest_apic_id; + unsigned char dest_apic_intin; +}; + + +/* + * Exported globals here. + */ + +/* + * "imps_any_new_apics" is non-zero if any of the APICS (local or I/O) + * are *not* an 82489DX. This is useful to determine if more than 15 + * CPUs can be supported (true if zero). + */ +extern int imps_any_new_apics; + +/* + * "imps_enabled" is non-zero if the probe sequence found IMPS + * information and was successful. + */ +extern int imps_enabled; + +/* + * This contains the local APIC hardware address. + */ +extern unsigned imps_lapic_addr; + +/* + * This represents the number of CPUs found. + */ +extern int imps_num_cpus; + +/* + * These map from virtual cpu numbers to APIC id's and back. + */ +extern unsigned char imps_cpu_apic_map[IMPS_MAX_CPUS]; +extern unsigned char imps_apic_cpu_map[IMPS_MAX_CPUS]; + + +/* + * This is the primary function for probing for Intel MPS 1.1/1.4 + * compatible hardware and BIOS information. While probing the CPUs + * information returned from the BIOS, this also starts up each CPU + * and gets it ready for use. + * + * Call this during the early stages of OS startup, before memory can + * be messed up. + * + * Returns 1 if IMPS information was found and is valid, else 0. + */ + +int imps_probe(void); + + +/* + * Defines that use variables + */ + +#define IMPS_LAPIC_READ(x) (*((volatile unsigned *) (imps_lapic_addr+(x)))) +#define IMPS_LAPIC_WRITE(x, y) \ + (*((volatile unsigned *) (imps_lapic_addr+(x))) = (y)) + +#endif /* !_SMP_IMPS_H */ + diff --git a/stage1/Makefile b/stage1/Makefile new file mode 100644 index 000000000..c920e22b0 --- /dev/null +++ b/stage1/Makefile @@ -0,0 +1,20 @@ +# +# GRUB stage1 makefile +# + +CFLAGS= $(SHARED_FLAGS) + +all: ../bin/stage1 + +stage1.o: stage1.S Makefile ../Makefile + $(CC) $(CFLAGS) -c -o stage1.o stage1.S + +stage1.exec: stage1.o Makefile ../Makefile + $(LD) -N -Ttext 7C00 -o stage1.exec stage1.o + +../bin/stage1: stage1.exec Makefile ../Makefile + $(OBJCOPY) -O binary stage1.exec ../bin/stage1 + +clean: + rm -f stage1.o stage1.exec + diff --git a/stage2/Makefile b/stage2/Makefile new file mode 100644 index 000000000..7fc864c2b --- /dev/null +++ b/stage2/Makefile @@ -0,0 +1,70 @@ +# +# GRUB stage2 makefile +# + +CFLAGS= $(SHARED_FLAGS) -I../shared_src + +# "asm.o" absolutely must come first!!! +SHARED_OBJS= asm.o common.o char_io.o boot.o cmdline.o gunzip.o \ + disk_io.o stage2.o fsys_ffs.o fsys_ext2fs.o fsys_fat.o + +all: ../bin/stage2 + +asm.o: ../shared_src/asm.S ../shared_src/shared.h Makefile ../Makefile + $(CC) $(CFLAGS) -c ../shared_src/asm.S + +boot.o: ../shared_src/boot.c ../shared_src/shared.h Makefile ../Makefile + $(CC) $(CFLAGS) -c ../shared_src/boot.c + +char_io.o: ../shared_src/char_io.c ../shared_src/shared.h Makefile \ + ../Makefile + $(CC) $(CFLAGS) -c ../shared_src/char_io.c + +cmdline.o: ../shared_src/cmdline.c ../shared_src/shared.h Makefile \ + ../Makefile + $(CC) $(CFLAGS) -c ../shared_src/cmdline.c + +common.o: ../shared_src/common.c ../shared_src/shared.h Makefile \ + ../Makefile + $(CC) $(CFLAGS) -c ../shared_src/common.c + +gunzip.o: ../shared_src/gunzip.c ../shared_src/shared.h Makefile \ + ../Makefile + $(CC) $(CFLAGS) -c ../shared_src/gunzip.c + +disk_io.o: ../shared_src/disk_io.c ../shared_src/filesys.h \ + ../shared_src/pc_slice.h ../shared_src/shared.h Makefile \ + ../Makefile + $(CC) $(CFLAGS) -c ../shared_src/disk_io.c + +stage2.o: ../shared_src/stage2.c ../shared_src/shared.h Makefile \ + ../Makefile + $(CC) $(CFLAGS) -c ../shared_src/stage2.c + +fsys_ffs.o: ../shared_src/fsys_ffs.c ../shared_src/filesys.h \ + ../shared_src/pc_slice.h ../shared_src/shared.h \ + ../shared_src/defs.h ../shared_src/disk_inode.h \ + ../shared_src/disk_inode_ffs.h ../shared_src/dir.h \ + ../shared_src/fs.h Makefile ../Makefile + $(CC) $(CFLAGS) -c ../shared_src/fsys_ffs.c + +fsys_ext2fs.o: ../shared_src/fsys_ext2fs.c ../shared_src/filesys.h \ + ../shared_src/pc_slice.h ../shared_src/shared.h Makefile \ + ../Makefile + $(CC) $(CFLAGS) -c ../shared_src/fsys_ext2fs.c + +fsys_fat.o: ../shared_src/fsys_fat.c ../shared_src/filesys.h \ + ../shared_src/pc_slice.h ../shared_src/shared.h \ + ../shared_src/fat.h Makefile ../Makefile + $(CC) $(CFLAGS) -c ../shared_src/fsys_fat.c + +# "asm.o" absolutely has to come first in the link line! +stage2.exec: $(SHARED_OBJS) Makefile ../Makefile + $(LD) -N -Ttext 8000 -o stage2.exec $(SHARED_OBJS) + +../bin/stage2: stage2.exec Makefile ../Makefile + $(OBJCOPY) -O binary stage2.exec ../bin/stage2 + +clean: + rm -f $(SHARED_OBJS) stage2.exec + diff --git a/stage2_debug/Makefile b/stage2_debug/Makefile new file mode 100644 index 000000000..1931644e8 --- /dev/null +++ b/stage2_debug/Makefile @@ -0,0 +1,70 @@ +# +# GRUB stage2 DEBUG makefile +# + +CFLAGS= $(SHARED_FLAGS) -DDEBUG -I../shared_src + +# "asm.o" absolutely must come first!!! +SHARED_OBJS= asm.o common.o char_io.o boot.o cmdline.o gunzip.o \ + disk_io.o stage2.o fsys_ffs.o fsys_ext2fs.o fsys_fat.o + +all: ../bin/stage2_debug + +asm.o: ../shared_src/asm.S ../shared_src/shared.h Makefile ../Makefile + $(CC) $(CFLAGS) -c ../shared_src/asm.S + +boot.o: ../shared_src/boot.c ../shared_src/shared.h Makefile ../Makefile + $(CC) $(CFLAGS) -c ../shared_src/boot.c + +char_io.o: ../shared_src/char_io.c ../shared_src/shared.h Makefile \ + ../Makefile + $(CC) $(CFLAGS) -c ../shared_src/char_io.c + +cmdline.o: ../shared_src/cmdline.c ../shared_src/shared.h Makefile \ + ../Makefile + $(CC) $(CFLAGS) -c ../shared_src/cmdline.c + +common.o: ../shared_src/common.c ../shared_src/shared.h Makefile \ + ../Makefile + $(CC) $(CFLAGS) -c ../shared_src/common.c + +gunzip.o: ../shared_src/gunzip.c ../shared_src/shared.h Makefile \ + ../Makefile + $(CC) $(CFLAGS) -c ../shared_src/gunzip.c + +disk_io.o: ../shared_src/disk_io.c ../shared_src/filesys.h \ + ../shared_src/pc_slice.h ../shared_src/shared.h Makefile \ + ../Makefile + $(CC) $(CFLAGS) -c ../shared_src/disk_io.c + +stage2.o: ../shared_src/stage2.c ../shared_src/shared.h Makefile \ + ../Makefile + $(CC) $(CFLAGS) -c ../shared_src/stage2.c + +fsys_ffs.o: ../shared_src/fsys_ffs.c ../shared_src/filesys.h \ + ../shared_src/pc_slice.h ../shared_src/shared.h \ + ../shared_src/defs.h ../shared_src/disk_inode.h \ + ../shared_src/disk_inode_ffs.h ../shared_src/dir.h \ + ../shared_src/fs.h Makefile ../Makefile + $(CC) $(CFLAGS) -c ../shared_src/fsys_ffs.c + +fsys_ext2fs.o: ../shared_src/fsys_ext2fs.c ../shared_src/filesys.h \ + ../shared_src/pc_slice.h ../shared_src/shared.h Makefile \ + ../Makefile + $(CC) $(CFLAGS) -c ../shared_src/fsys_ext2fs.c + +fsys_fat.o: ../shared_src/fsys_fat.c ../shared_src/filesys.h \ + ../shared_src/pc_slice.h ../shared_src/shared.h \ + ../shared_src/fat.h Makefile ../Makefile + $(CC) $(CFLAGS) -c ../shared_src/fsys_fat.c + +# "asm.o" absolutely has to come first in the link line! +stage2.exec: $(SHARED_OBJS) Makefile ../Makefile + $(LD) -N -Ttext 8000 -o stage2.exec $(SHARED_OBJS) + +../bin/stage2_debug: stage2.exec Makefile ../Makefile + $(OBJCOPY) -O binary stage2.exec ../bin/stage2_debug + +clean: + rm -f $(SHARED_OBJS) stage2.exec +