Compare commits

..

28 Commits

Author SHA1 Message Date
Martin Fuchs
13a047a566 Remove wrong folder copy
svn path=/branches/ros-branch-0_2_5/; revision=13827
2005-03-05 15:33:41 +00:00
Robert Kopferl
834ee7b3fe made a copy
svn path=/branches/ros-branch-0_2_5/; revision=13498
2005-02-11 22:49:44 +00:00
Robert Kopferl
607690ba55 changes for release of 0.2.5
svn path=/branches/ros-branch-0_2_5/; revision=12919
2005-01-10 19:44:47 +00:00
Filip Navara
88e0297e69 Don't flush cache on ATAPI devices.
svn path=/branches/ros-branch-0_2_5/; revision=12733
2005-01-02 19:36:33 +00:00
Gé van Geldorp
a627f8d061 Need freeldr for 0.2.5
svn path=/branches/ros-branch-0_2_5/; revision=12701
2005-01-01 13:35:12 +00:00
Gé van Geldorp
820c67f8ba Code freeze for 0.2.5
svn path=/branches/ros-branch-0_2_5/; revision=12386
2004-12-29 09:24:21 +00:00
Filip Navara
73f101de0b - Free all memory in error case of GetClassInfoExCommon.
- Fix RegisterClassExA for menu-less window classes.

svn path=/branches/ros-branch-0_2_5/; revision=12356
2004-12-27 00:44:11 +00:00
Filip Navara
1c7116cc73 - Fix size returned by NtUserGetClassInfo.
svn path=/branches/ros-branch-0_2_5/; revision=12355
2004-12-27 00:39:23 +00:00
Filip Navara
40528bf1be DceResetActiveDCEs fixes:
- Don't check ownership because window DCs are global now.
- Correctly reposition client DCs (if window style changes).

svn path=/branches/ros-branch-0_2_5/; revision=12354
2004-12-27 00:39:02 +00:00
Gé van Geldorp
ee1890ff77 Don't write outside buffer
svn path=/branches/ros-branch-0_2_5/; revision=12351
2004-12-26 23:35:27 +00:00
Thomas Bluemel
7fe7da7475 revert my class hacks as they cause some trouble - this may make abiword not to work anymore though
svn path=/branches/ros-branch-0_2_5/; revision=12318
2004-12-24 17:43:23 +00:00
Royce Mitchell III
5a10cf1de5 IntEngGradientFill() fix ASSERT statements
svn path=/branches/ros-branch-0_2_5/; revision=12313
2004-12-24 06:01:13 +00:00
Gé van Geldorp
b192bb32af Nowadays ReactOS is unable to handle the same classname used by two
different apps. Use WFS__Tree in winefile since Explorer already uses
WFS_Tree.

svn path=/branches/ros-branch-0_2_5/; revision=12304
2004-12-23 21:50:55 +00:00
Royce Mitchell III
501c4bcc5c MiQueryVirtualMemory(): created because ZwQueryVirtualMemory() didn't work for me, added cases for memory area types that I needed to walk stack traces.\nStack traces now use MiQueryVirtualMemory to make sure they never step outside the allocated stack they started in ( this prevents page faults at high irql ) - for some reason this patch eliminates the NtW32Callback() crash everybody is seeing with GDI_DEBUG enabled, tho I don't understand why.
svn path=/branches/ros-branch-0_2_5/; revision=12287
2004-12-22 05:18:26 +00:00
Royce Mitchell III
09b7ae5383 wrap stack walks in SEH - this doesn't fix page faults tho, so something else is going to have to be done :(
svn path=/branches/ros-branch-0_2_5/; revision=12284
2004-12-22 03:44:52 +00:00
Royce Mitchell III
add1e4db72 blasted sym files just aren't always in address-order, must search entire sym file to find correct function for our offset.
svn path=/branches/ros-branch-0_2_5/; revision=12283
2004-12-22 03:02:53 +00:00
Eric Kohl
291ec67723 Disable the 'Locale Page' and 'Progress Page' because they are not usable yet.
svn path=/branches/ros-branch-0_2_5/; revision=12271
2004-12-21 08:34:49 +00:00
Gé van Geldorp
e97e0f5976 Set ownership to NULL for both color and mask bitmaps
svn path=/branches/ros-branch-0_2_5/; revision=12259
2004-12-20 21:40:55 +00:00
Thomas Bluemel
583e4a7baf disable gdi debugging for 0.2.5 as it may bsod the system
svn path=/branches/ros-branch-0_2_5/; revision=12234
2004-12-19 21:14:32 +00:00
Robert Kopferl
fdc1ba6a56 Changed version info to conform to an RC1 build
svn path=/branches/ros-branch-0_2_5/; revision=12231
2004-12-19 20:01:34 +00:00
The ReactOS Team
1b2fc59dc1 This commit was manufactured by cvs2svn to create branch
'ros-branch-0_2_5'.

svn path=/branches/ros-branch-0_2_5/; revision=12229
2004-12-19 17:28:07 +00:00
The ReactOS Team
d4a3555442 This commit was manufactured by cvs2svn to create branch 'avendor'.
svn path=/branches/avendor/; revision=8047
2004-02-06 08:21:52 +00:00
The ReactOS Team
abc01da30c This commit was manufactured by cvs2svn to create branch 'avendor'.
svn path=/branches/avendor/; revision=2401
2001-11-28 01:38:00 +00:00
The ReactOS Team
7aeca22fed This commit was manufactured by cvs2svn to create branch 'avendor'.
svn path=/branches/avendor/; revision=2398
2001-11-27 14:24:15 +00:00
The ReactOS Team
36e1bb60e8 This commit was manufactured by cvs2svn to create branch 'avendor'.
svn path=/branches/avendor/; revision=2320
2001-10-25 23:22:09 +00:00
The ReactOS Team
74e77bb16f This commit was manufactured by cvs2svn to create branch 'avendor'.
svn path=/branches/avendor/; revision=2316
2001-10-23 21:15:45 +00:00
Casper Hornstrup
e3a75fb4da no message
svn path=/branches/avendor/; revision=1279
2000-08-01 18:43:38 +00:00
The ReactOS Team
ce122bcdea This commit was manufactured by cvs2svn to create branch 'avendor'.
svn path=/branches/avendor/; revision=1278
2000-08-01 18:43:38 +00:00
26934 changed files with 2008392 additions and 7635046 deletions

339
freeldr/COPYING Normal file
View File

@@ -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.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) 19yy <name of author>
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.
<signature of Ty Coon>, 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.

View File

@@ -51,7 +51,8 @@
; [OS-General] Section Commands:
;
; BootType - sets the boot type: ReactOS, Linux, BootSector, Partition, Drive
; BootPath - ARC path e.g. multi(0)disk(0)rdisk(x)partition(y)
; BootDrive - sets the boot drive: 0 - first floppy, 1 - second floppy, 0x80 - first hard disk, 0x81 - second hard disk
; BootPartition - sets the boot partition
; DriveMap - maps a BIOS drive number to another (i.e. DriveMap=hd1,hd0 maps harddisk1 to harddisk0 or DriveMap=fd1,fd0)
; [BootSector OSType] Section Commands:
@@ -83,7 +84,7 @@ TimeOut=10
; 0x503C for 80x60
[Display]
DisplayMode=NORMAL_VGA
TitleText=Brians Custom FreeLoader Boot Disk
TitleText=Brians Custom FreeLoader Boot Disk
StatusBarColor=Cyan
StatusBarTextColor=Black
BackdropTextColor=White
@@ -133,7 +134,8 @@ Hal=\reactos\HAL.DLL
[Linux]
BootType=Linux
BootPath=multi(0)disk(0)rdisk(1)partition(1)
BootDrive=hd1
BootPartition=1
Kernel=/vmlinuz
Initrd=/initrd.img
CommandLine="root=/dev/sdb1"
@@ -144,11 +146,13 @@ BootDrive=fd0
[MSWinders]
BootType=Partition
BootPath=multi(0)disk(0)rdisk(0)partition(1)
BootDrive=hd0
BootPartition=1
;DriveMap=hd1,hd0
;DriveMap=hd2,hd0
;DriveMap=hd3,hd0
[DriveD]
BootType=Partition
BootPath=multi(0)disk(0)rdisk(1)partition(1)
BootDrive=hd1
BootPartition=1

45
freeldr/Makefile Normal file
View File

@@ -0,0 +1,45 @@
#
# FreeLoader
# Copyright (C) 1999, 2000, 2001 Brian Palmer <brianp@sginet.com>
#
# 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.
#
# Windows is default host environment
ifeq ($(HOST),)
HOST = mingw32-windows
endif
include rules.mak
all:
$(MAKE) -C tools
$(MAKE) -C bootsect
$(MAKE) -C freeldr
$(MAKE) -C install
$(MAKE) -C fdebug
freeldr:
$(MAKE) -C freeldr
.PHONY : freeldr
clean:
$(MAKE) -C bootsect clean
$(MAKE) -C freeldr clean
$(MAKE) -C install clean
$(MAKE) -C fdebug clean
$(MAKE) -C tools clean
.PHONY : clean

View File

@@ -0,0 +1,3 @@
*.exe
*.bin
*.h

76
freeldr/bootsect/Makefile Normal file
View File

@@ -0,0 +1,76 @@
#
# FreeLoader
# Copyright (C) 1999, 2000, 2001 Brian Palmer <brianp@sginet.com>
#
# 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.
#
BOOTCD_DIR = ../../bootcd
.PHONY : clean bootcd
all: $(BIN2C) dosmbr.bin fat.bin fat32.bin isoboot.bin ext2.bin
$(BIN2C) :
@$(MAKE) --no-print-directory -C $(TOOLSDIR)
dosmbr.bin : dosmbr.asm
@echo ===================================================== Assembling dosmbr
@$(NASM_CMD) $(NFLAGS) -o dosmbr.bin -f bin dosmbr.asm
fat.bin : fat.asm $(BIN2C)
@echo ===================================================== Assembling fat
@$(NASM_CMD) $(NFLAGS) -o fat.bin -f bin fat.asm
@$(BIN2C) fat.bin fat.h fat_data
fat32.bin : fat32.asm $(BIN2C)
@echo ===================================================== Assembling fat32
@$(NASM_CMD) $(NFLAGS) -o fat32.bin -f bin fat32.asm
@$(BIN2C) fat32.bin fat32.h fat32_data
isoboot.bin : isoboot.asm
@echo ===================================================== Assembling isoboot
@$(NASM_CMD) $(NFLAGS) -o isoboot.bin -f bin isoboot.asm
ext2.bin : ext2.asm
@echo ===================================================== Assembling ext2
@$(NASM_CMD) $(NFLAGS) -o ext2.bin -f bin ext2.asm
@$(BIN2C) ext2.bin ext2.h ext2_data
.PHONY : bootcd
bootcd: bootcd_dirs isoboot.bin
$(CP) isoboot.bin $(BOOTCD_DIR)
$(CP) dosmbr.bin $(BOOTCD_DIR)/disk/loader
$(CP) ext2.bin $(BOOTCD_DIR)/disk/loader
$(CP) fat.bin $(BOOTCD_DIR)/disk/loader
$(CP) fat32.bin $(BOOTCD_DIR)/disk/loader
$(CP) isoboot.bin $(BOOTCD_DIR)/disk/loader
.PHONY : bootcd_dirs
bootcd_dirs:
$(MKDIR) $(BOOTCD_DIR)
$(MKDIR) $(BOOTCD_DIR)/disk
$(MKDIR) $(BOOTCD_DIR)/disk/reactos
$(MKDIR) $(BOOTCD_DIR)/disk/install
$(MKDIR) $(BOOTCD_DIR)/disk/bootdisk
$(MKDIR) $(BOOTCD_DIR)/disk/loader
clean:
@-$(RM) *.bin
@-$(RM) *.h
@echo Clean ALL done.

View File

@@ -438,11 +438,9 @@ LoadFreeLoader:
mov dl,[BYTE bp+BootDrive]
mov dh,[BYTE bp+BootPartition]
push 0 ; push segment (0x0000)
mov eax, [0x8000 + 0xA8] ; load the RVA of the EntryPoint into eax
add eax, 0x8000 ; RVA -> VA
push ax ; push offset
retf ; Transfer control to FreeLoader
push byte 0 ; We loaded at 0000:8000
push WORD 8000h ; We will do a far return to 0000:8000h
retf ; Transfer control to FreeLoader

View File

@@ -73,7 +73,7 @@ SectorsPerTrack dw 18
NumberOfHeads dw 2
HiddenSectors dd 0
TotalSectorsBig dd 0
BootDrive db 0xff
BootDrive db 0
Reserved db 0
ExtendSig db 29h
SerialNumber dd 00000000h
@@ -208,12 +208,8 @@ FoundFreeLoader:
; to the helper code. Skip the first three bytes
; because they contain a jump instruction to skip
; over the helper code in the FreeLoader image.
;jmp 0000:9003h
push 0 ; push segment (0x0000)
mov bx, [0x8000 + 0xA8] ; load the RVA of the EntryPoint into eax
add bx, 0x8003 ; RVA -> VA and skip 3 bytes (jump to fathelper code)
push bx ; push offset
retf ; Transfer control to FreeLoader
;jmp 0000:8003h
jmp 8003h
@@ -391,10 +387,10 @@ NoCarryCHS:
msgDiskError db 'Disk error',0dh,0ah,0
msgFreeLdr db 'ldr not found',0dh,0ah,0
msgFreeLdr db 'freeldr.sys not found',0dh,0ah,0
; Sorry, need the space...
;msgAnyKey db 'Press any key to restart',0dh,0ah,0
msgAnyKey db 'Press a key',0dh,0ah,0
msgAnyKey db 'Press any key',0dh,0ah,0
filename db 'FREELDR SYS'
times 509-($-$$) db 0 ; Pad to 509 bytes

View File

@@ -390,12 +390,11 @@ LoadFile:
LoadFileDone:
mov dl,[BYTE bp+BootDrive] ; Load boot drive into DL
mov dh,[BootPartition] ; Load boot partition into DH
xor ax,ax
push ax ; We loaded at 0000:8000
push WORD 8000h ; We will do a far return to 0000:8000h
retf ; Transfer control to ROSLDR
push 0 ; push segment (0x0000)
mov eax, [0x8000 + 0xA8] ; load the RVA of the EntryPoint into eax
add eax, 0x8000 ; RVA -> VA
push ax ; push offset
retf ; Transfer control to FreeLoader
; Returns the FAT entry for a given cluster number
; On entry EAX has cluster number

View File

@@ -132,23 +132,20 @@ relocate:
; Make sure the keyboard buffer is empty
%ifdef WAIT_FOR_KEY
call pollchar_and_empty
.kbd_buffer_test:
call pollchar
jz .kbd_buffer_empty
call getchar
jmp .kbd_buffer_test
.kbd_buffer_empty:
; Check for MBR on harddisk
; Check if there is harddisk
pusha
mov ax, 0201h
mov ax, 0800h
mov dx, 0080h
mov cx, 0001h
mov bx, trackbuf
int 13h
popa
jc .boot_cdrom ; could not read hdd
push ax
mov ax, word [trackbuf]
cmp ax, 0
je .boot_cdrom ; no boot sector found (hopefully there are no weird bootsectors which begin with 0)
pop ax
jc .boot_cdrom
; Display the 'Press key' message and wait for a maximum of 5 seconds
call crlf
@@ -161,7 +158,7 @@ relocate:
add eax, 19 ;
.poll_again:
call pollchar_and_empty
call pollchar
jnz .boot_cdrom
mov ebx, [BIOS_timer]
@@ -373,11 +370,7 @@ get_fs_structures:
mov dl, [DriveNo] ; dl = boot drive
mov dh, 0 ; dh = boot partition
push 0 ; push segment (0x0000)
mov eax, [0x8000 + 0xA8] ; load the RVA of the EntryPoint into eax
add eax, 0x8000 ; RVA -> VA
push ax ; push offset
retf ; Transfer control to ROSLDR
jmp 0:0x8000 ; jump into OSLoader
@@ -902,62 +895,68 @@ kaboom:
sti
mov si, err_bootfailed
call writestr
xor ax, ax ; Wait for keypress
int 16h
call getchar
cli
mov word [BIOS_magic], 0 ; Cold reboot
jmp 0F000h:0FFF0h ; Reset vector address
getchar:
.again:
mov ah, 1 ; Poll keyboard
int 16h
jz .again
.kbd:
xor ax, ax ; Get keyboard input
int 16h
.func_key:
ret
;
; pollchar_and_empty: check if we have an input character pending (ZF = 0) and empty the input buffer afterwards
; pollchar: check if we have an input character pending (ZF = 0)
;
pollchar_and_empty:
pollchar:
pushad
mov ah, 1 ; Did the user press a key?
mov ah,1 ; Poll keyboard
int 16h
jz .end ; No, then we're done
mov ah, 0 ; Otherwise empty the buffer by reading it
int 16h
.end:
popad
ret
isolinux_banner db CR, LF, 'Loading IsoBoot...', CR, LF, 0
copyright_str db ' (C) 1994-2002 H. Peter Anvin', CR, LF, 0
copyright_str db ' Copyright (C) 1994-2002 H. Peter Anvin', CR, LF, 0
presskey_msg db 'Press any key to boot from CD', 0
dot_msg db '.',0
%ifdef DEBUG_MESSAGES
startup_msg: db 'Startup, DL = ', 0
spec_ok_msg: db 'packet OK, drive = ', 0
secsize_msg: db 'size appears to be ', 0
rootloc_msg: db 'Root dir loc: ', 0
rootlen_msg: db 'Root dir len: ', 0
rootsect_msg: db 'Root dir len(sect): ', 0
fileloc_msg: db 'SETUPLDR loc: ', 0
filelen_msg: db 'SETUPLDR len: ', 0
filesect_msg: db 'SETUPLDR len(sect): ', 0
startup_msg: db 'Starting up, DL = ', 0
spec_ok_msg: db 'Loaded spec packet OK, drive = ', 0
secsize_msg: db 'Sector size appears to be ', 0
rootloc_msg: db 'Root directory location: ', 0
rootlen_msg: db 'Root directory length: ', 0
rootsect_msg: db 'Root directory length(sectors): ', 0
fileloc_msg: db 'SETUPLDR.SYS location: ', 0
filelen_msg: db 'SETUPLDR.SYS length: ', 0
filesect_msg: db 'SETUPLDR.SYS length(sectors): ', 0
findfail_msg: db 'Failed to find file!', 0
startldr_msg: db 'Starting SETUPLDR.SYS', 0
%endif
nosecsize_msg: db 'No sector size, assume 0800', CR, LF, 0
spec_err_msg: db 'Load spec failed, trying wing ...', CR, LF, 0
maybe_msg: db 'Found smth at drive = ', 0
alright_msg: db 'might be ok, continuing...', CR, LF, 0
nothing_msg: db 'Failed locate CD-ROM; boot failed.', CR, LF, 0
nosecsize_msg: db 'Failed to get sector size, assuming 0800', CR, LF, 0
spec_err_msg: db 'Loading spec packet failed, trying to wing it...', CR, LF, 0
maybe_msg: db 'Found something at drive = ', 0
alright_msg: db 'Looks like it might be right, continuing...', CR, LF, 0
nothing_msg: db 'Failed to locate CD-ROM device; boot failed.', CR, LF, 0
isolinux_str db 'IsoBoot: ', 0
crlf_msg db CR, LF, 0
diskerr_msg: db 'Disk error ', 0
ondrive_str: db ', drive ', 0
err_bootfailed db CR, LF, 'failed..', 0
err_bootfailed db CR, LF, 'Boot failed: press a key to retry...'
isolinux_dir db '\LOADER', 0
no_dir_msg db 'LOADER dir not found.', CR, LF, 0
no_dir_msg db 'Could not find the LOADER directory.', CR, LF, 0
isolinux_bin db 'SETUPLDR.SYS', 0
no_isolinux_msg db 'SETUPLDR not found.', CR, LF, 0
no_isolinux_msg db 'Could not find SETUPLDR.SYS.', CR, LF, 0
;
; El Torito spec packet

1
freeldr/fdebug/.cvsignore Executable file
View File

@@ -0,0 +1 @@
*.res

49
freeldr/fdebug/Makefile Normal file
View File

@@ -0,0 +1,49 @@
#
# FreeLoader
# Copyright (C) 1999 - 2003 Brian Palmer <brianp@sginet.com>
#
# 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.
#
FLAGS = -Wall
OBJS = rs232.o fdebug.o fdebug.res
.PHONY : clean
all: fdebug.exe
fdebug.exe: $(OBJS)
@echo ===================================================== LINKING fdebug
$(CC) $(FLAGS) -o fdebug.exe $(OBJS) -lgdi32 -lcomdlg32 -Wl,--subsystem,windows
fdebug.res: fdebug.rc resource.h
@echo ===================================================== Compiling $*
$(WINDRES) -o fdebug.res fdebug.rc -O coff
fdebug.o: fdebug.c rs232.h
@echo ===================================================== Compiling $*
$(CC) $(FLAGS) -o fdebug.o -c fdebug.c
rs232.o: rs232.c rs232.h
@echo ===================================================== Compiling $*
$(CC) $(FLAGS) -o rs232.o -c rs232.c
clean:
@-$(RM) *.o
@-$(RM) *.res
@-$(RM) *.exe
@echo Clean ALL done.

View File

@@ -35,29 +35,29 @@ LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK ConnectionDialogProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK CaptureDialogProc(HWND, UINT, WPARAM, LPARAM);
VOID EnableFileMenuItemByID(UINT Id, BOOL Enable);
VOID EnableConnectMenuItem(BOOL Enable);
VOID EnableDisconnectMenuItem(BOOL Enable);
VOID EnableStartCaptureMenuItem(BOOL Enable);
VOID EnableStopCaptureMenuItem(BOOL Enable);
VOID CheckLocalEchoMenuItem(BOOL Checked);
VOID Rs232Thread(VOID* Parameter);
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// TODO: Place code here.
MSG msg;
HACCEL hAccelTable;
UNREFERENCED_PARAMETER(lpCmdLine);
UNREFERENCED_PARAMETER(hPrevInstance);
// Initialize global strings
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_FDEBUG, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
// Perform application initialization:
if (!InitInstance (hInstance, nCmdShow))
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
@@ -65,16 +65,16 @@ int APIENTRY _tWinMain(HINSTANCE hInstance,
hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_FDEBUG);
// Main message loop:
while (GetMessage(&msg, NULL, 0, 0))
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return (int)msg.wParam;
return msg.wParam;
}
@@ -96,24 +96,19 @@ ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = (WNDPROC)WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_FDEBUG));
wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_FDEBUG);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = NULL;//(HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = MAKEINTRESOURCE(IDC_FDEBUG);
wcex.lpszMenuName = (LPCSTR)IDC_FDEBUG;
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = (HICON)LoadImage(hInstance,
MAKEINTRESOURCE(IDI_FDEBUG),
IMAGE_ICON,
16,
16,
LR_SHARED);
wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);
return RegisterClassEx(&wcex);
}
@@ -161,12 +156,12 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
NONCLIENTMETRICS ncm;
HFONT hFont;
switch (message)
switch (message)
{
case WM_CREATE:
hEditWnd = CreateWindowEx(WS_EX_CLIENTEDGE, TEXT("EDIT"), TEXT(""), WS_CHILD|WS_VISIBLE|WS_VSCROLL|ES_AUTOHSCROLL|ES_LEFT|ES_MULTILINE, 0, 0, 0, 0, hWnd, NULL, hInst, NULL);
hDisplayWnd = CreateWindowEx(WS_EX_CLIENTEDGE, TEXT("EDIT"), TEXT(""), WS_CHILD|WS_VISIBLE|WS_HSCROLL|WS_VSCROLL|ES_MULTILINE, 0, 0, 0, 0, hWnd, NULL, hInst, NULL);
hEditWnd = CreateWindowEx(WS_EX_CLIENTEDGE, TEXT("EDIT"), "", WS_CHILD|WS_VISIBLE|WS_VSCROLL|ES_AUTOHSCROLL|ES_LEFT|ES_MULTILINE, 0, 0, 0, 0, hWnd, NULL, hInst, NULL);
hDisplayWnd = CreateWindowEx(WS_EX_CLIENTEDGE, TEXT("EDIT"), "", WS_CHILD|WS_VISIBLE|WS_HSCROLL|WS_VSCROLL|ES_MULTILINE, 0, 0, 0, 0, hWnd, NULL, hInst, NULL);
memset(&ncm, 0, sizeof(NONCLIENTMETRICS));
ncm.cbSize = sizeof(NONCLIENTMETRICS);
@@ -179,7 +174,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
break;
case WM_COMMAND:
wmId = LOWORD(wParam);
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
if (lParam == (LPARAM)hEditWnd && wmEvent == EN_CHANGE)
@@ -215,10 +210,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
case IDM_EXIT:
DestroyWindow(hWnd);
break;
case IDM_FILE_CLEARDISPLAY:
SetWindowText(hDisplayWnd, TEXT(""));
break;
case IDM_FILE_CONNECT:
case ID_FILE_CONNECT:
if (bConnected)
{
MessageBox(hWnd, TEXT("You are already connected!"), TEXT("Error"), MB_OK|MB_ICONSTOP);
@@ -228,44 +220,44 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
if (DialogBox(hInst, (LPCTSTR)IDD_CONNECTION, hWnd, (DLGPROC)ConnectionDialogProc) == IDOK)
{
bConnected = TRUE;
EnableFileMenuItemByID(IDM_FILE_DISCONNECT, TRUE);
EnableFileMenuItemByID(IDM_FILE_CONNECT, FALSE);
EnableDisconnectMenuItem(TRUE);
EnableConnectMenuItem(FALSE);
_beginthread(Rs232Thread, 0, NULL);
}
}
break;
case IDM_FILE_DISCONNECT:
case ID_FILE_DISCONNECT:
if (bConnected)
{
bConnected = FALSE;
EnableFileMenuItemByID(IDM_FILE_DISCONNECT, FALSE);
EnableFileMenuItemByID(IDM_FILE_CONNECT, TRUE);
EnableDisconnectMenuItem(FALSE);
EnableConnectMenuItem(TRUE);
}
else
{
MessageBox(hWnd, TEXT("You are not currently connected!"), TEXT("Error"), MB_OK|MB_ICONSTOP);
}
break;
case IDM_FILE_STARTCAPTURE:
case ID_FILE_STARTCAPTURE:
if (DialogBox(hInst, (LPCTSTR)IDD_CAPTURE, hWnd, (DLGPROC)CaptureDialogProc) == IDOK)
{
bCapturing = TRUE;
EnableFileMenuItemByID(IDM_FILE_STOPCAPTURE, TRUE);
EnableFileMenuItemByID(IDM_FILE_STARTCAPTURE, FALSE);
EnableStopCaptureMenuItem(TRUE);
EnableStartCaptureMenuItem(FALSE);
hCaptureFile = CreateFile(strCaptureFileName, FILE_APPEND_DATA, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
}
break;
case IDM_FILE_STOPCAPTURE:
case ID_FILE_STOPCAPTURE:
if (bCapturing)
{
bCapturing = FALSE;
EnableFileMenuItemByID(IDM_FILE_STOPCAPTURE, FALSE);
EnableFileMenuItemByID(IDM_FILE_STARTCAPTURE, TRUE);
EnableStopCaptureMenuItem(FALSE);
EnableStartCaptureMenuItem(TRUE);
CloseHandle(hCaptureFile);
hCaptureFile = NULL;
}
break;
case IDM_FILE_LOCALECHO:
case ID_FILE_LOCALECHO:
if (bLocalEcho)
{
bLocalEcho = FALSE;
@@ -307,8 +299,6 @@ LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
HWND hLicenseEditWnd;
TCHAR strLicense[0x1000];
UNREFERENCED_PARAMETER(lParam);
switch (message)
{
case WM_INITDIALOG:
@@ -322,7 +312,7 @@ LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
return TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return TRUE;
@@ -334,8 +324,6 @@ LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
LRESULT CALLBACK ConnectionDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
UNREFERENCED_PARAMETER(lParam);
switch (message)
{
case WM_INITDIALOG:
@@ -352,7 +340,7 @@ LRESULT CALLBACK ConnectionDialogProc(HWND hDlg, UINT message, WPARAM wParam, LP
GetWindowText(GetDlgItem(hDlg, IDC_BAUTRATE), strBaudRate, MAX_PATH);
}
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return TRUE;
@@ -366,8 +354,6 @@ LRESULT CALLBACK CaptureDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARA
{
OPENFILENAME ofn;
UNREFERENCED_PARAMETER(lParam);
switch (message)
{
case WM_INITDIALOG:
@@ -406,7 +392,7 @@ LRESULT CALLBACK CaptureDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARA
GetWindowText(GetDlgItem(hDlg, IDC_CAPTUREFILENAME), strCaptureFileName, MAX_PATH);
}
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return TRUE;
@@ -416,14 +402,76 @@ LRESULT CALLBACK CaptureDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARA
return FALSE;
}
VOID EnableFileMenuItemByID(UINT Id, BOOL Enable)
VOID EnableConnectMenuItem(BOOL Enable)
{
HMENU hMenuBar;
HMENU hFileMenu;
hMenuBar = GetMenu(hMainWnd);
hFileMenu = GetSubMenu(hMenuBar, 0);
EnableMenuItem(hFileMenu, Id, MF_BYCOMMAND|(Enable ? MF_ENABLED : MF_GRAYED));
if (Enable)
{
EnableMenuItem(hFileMenu, ID_FILE_CONNECT, MF_BYCOMMAND|MF_ENABLED);
}
else
{
EnableMenuItem(hFileMenu, ID_FILE_CONNECT, MF_BYCOMMAND|MF_GRAYED);
}
}
VOID EnableDisconnectMenuItem(BOOL Enable)
{
HMENU hMenuBar;
HMENU hFileMenu;
hMenuBar = GetMenu(hMainWnd);
hFileMenu = GetSubMenu(hMenuBar, 0);
if (Enable)
{
EnableMenuItem(hFileMenu, ID_FILE_DISCONNECT, MF_BYCOMMAND|MF_ENABLED);
}
else
{
EnableMenuItem(hFileMenu, ID_FILE_DISCONNECT, MF_BYCOMMAND|MF_GRAYED);
}
}
VOID EnableStartCaptureMenuItem(BOOL Enable)
{
HMENU hMenuBar;
HMENU hFileMenu;
hMenuBar = GetMenu(hMainWnd);
hFileMenu = GetSubMenu(hMenuBar, 0);
if (Enable)
{
EnableMenuItem(hFileMenu, ID_FILE_STARTCAPTURE, MF_BYCOMMAND|MF_ENABLED);
}
else
{
EnableMenuItem(hFileMenu, ID_FILE_STARTCAPTURE, MF_BYCOMMAND|MF_GRAYED);
}
}
VOID EnableStopCaptureMenuItem(BOOL Enable)
{
HMENU hMenuBar;
HMENU hFileMenu;
hMenuBar = GetMenu(hMainWnd);
hFileMenu = GetSubMenu(hMenuBar, 0);
if (Enable)
{
EnableMenuItem(hFileMenu, ID_FILE_STOPCAPTURE, MF_BYCOMMAND|MF_ENABLED);
}
else
{
EnableMenuItem(hFileMenu, ID_FILE_STOPCAPTURE, MF_BYCOMMAND|MF_GRAYED);
}
}
VOID CheckLocalEchoMenuItem(BOOL Checked)
@@ -433,7 +481,15 @@ VOID CheckLocalEchoMenuItem(BOOL Checked)
hMenuBar = GetMenu(hMainWnd);
hFileMenu = GetSubMenu(hMenuBar, 0);
CheckMenuItem(hFileMenu, IDM_FILE_LOCALECHO, MF_BYCOMMAND|(Checked ? MF_CHECKED : MF_UNCHECKED));
if (Checked)
{
CheckMenuItem(hFileMenu, ID_FILE_LOCALECHO, MF_BYCOMMAND|MF_CHECKED);
}
else
{
CheckMenuItem(hFileMenu, ID_FILE_LOCALECHO, MF_BYCOMMAND|MF_UNCHECKED);
}
}
VOID Rs232Thread(VOID* Parameter)
@@ -443,8 +499,6 @@ VOID Rs232Thread(VOID* Parameter)
MSG msg;
DWORD dwNumberOfBytesWritten;
UNREFERENCED_PARAMETER(Parameter);
dwThreadId = GetCurrentThreadId();
if (!Rs232OpenPortWin32(strComPort))

BIN
freeldr/fdebug/fdebug.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

215
freeldr/fdebug/fdebug.rc Normal file
View File

@@ -0,0 +1,215 @@
//Microsoft Developer Studio generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#define APSTUDIO_HIDDEN_SYMBOLS
#include "windows.h"
#undef APSTUDIO_HIDDEN_SYMBOLS
#include "resource.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
/////////////////////////////////////////////////////////////////////////////
//
// Icon
//
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDI_FDEBUG ICON DISCARDABLE "fdebug.ico"
/////////////////////////////////////////////////////////////////////////////
//
// Menu
//
IDC_FDEBUG MENU DISCARDABLE
BEGIN
POPUP "&File"
BEGIN
MENUITEM "&Connect", ID_FILE_CONNECT
MENUITEM "&Disconnect", ID_FILE_DISCONNECT, GRAYED
MENUITEM SEPARATOR
MENUITEM "&Start Capture", ID_FILE_STARTCAPTURE
MENUITEM "S&top Capture", ID_FILE_STOPCAPTURE, GRAYED
MENUITEM SEPARATOR
MENUITEM "&Local Echo", ID_FILE_LOCALECHO
MENUITEM SEPARATOR
MENUITEM "E&xit", IDM_EXIT
END
POPUP "&Help"
BEGIN
MENUITEM "&About ...", IDM_ABOUT
END
END
/////////////////////////////////////////////////////////////////////////////
//
// Accelerator
//
IDC_FDEBUG ACCELERATORS MOVEABLE PURE
BEGIN
"?", IDM_ABOUT, ASCII, ALT
"/", IDM_ABOUT, ASCII, ALT
END
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
2 TEXTINCLUDE DISCARDABLE
BEGIN
"#define APSTUDIO_HIDDEN_SYMBOLS\r\n"
"#include ""windows.h""\r\n"
"#undef APSTUDIO_HIDDEN_SYMBOLS\r\n"
"#include ""resource.h""\r\n"
"\0"
END
3 TEXTINCLUDE DISCARDABLE
BEGIN
"\r\n"
"\0"
END
1 TEXTINCLUDE DISCARDABLE
BEGIN
"resource.h\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO DISCARDABLE
BEGIN
IDD_ABOUTBOX, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 252
TOPMARGIN, 7
BOTTOMMARGIN, 203
END
IDD_CONNECTION, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 189
TOPMARGIN, 7
BOTTOMMARGIN, 93
END
IDD_CAPTURE, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 244
TOPMARGIN, 7
BOTTOMMARGIN, 88
END
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_ABOUTBOX DIALOG DISCARDABLE 22, 17, 259, 210
STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU
CAPTION "About FreeLoader Debugger"
FONT 8, "Tahoma"
BEGIN
CONTROL "FreeLoader Debugger v1.0\nCopyright (C) 2003\nby Brian Palmer (brianp@reactos.org)",
IDC_STATIC,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,53,28,
122,26
DEFPUSHBUTTON "OK",IDOK,183,189,44,14,WS_GROUP
ICON IDI_FDEBUG,IDC_STATIC,19,30,20,20
EDITTEXT IDC_LICENSE_EDIT,53,63,174,107,ES_MULTILINE |
ES_READONLY | WS_VSCROLL
END
IDD_CONNECTION DIALOG DISCARDABLE 0, 0, 196, 100
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Connection Options"
FONT 8, "Tahoma"
BEGIN
LTEXT "Enter the COM port (e.g. COM1):",IDC_STATIC,7,7,108,8
EDITTEXT IDC_COMPORT,7,17,182,14,ES_AUTOHSCROLL
LTEXT "Enter the baud rate (e.g. 115200):",IDC_STATIC,7,38,114,
8
EDITTEXT IDC_BAUTRATE,7,48,182,14,ES_AUTOHSCROLL
DEFPUSHBUTTON "OK",IDOK,45,79,50,14
PUSHBUTTON "Cancel",IDCANCEL,100,79,50,14
END
IDD_CAPTURE DIALOG DISCARDABLE 0, 0, 251, 95
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Capture File"
FONT 8, "Tahoma"
BEGIN
LTEXT "Capture File Name:",IDC_STATIC,7,17,62,8
EDITTEXT IDC_CAPTUREFILENAME,7,26,181,14,ES_AUTOHSCROLL
PUSHBUTTON "&Browse",IDC_BROWSE,194,26,50,14
DEFPUSHBUTTON "OK",IDOK,139,74,50,14
PUSHBUTTON "Cancel",IDCANCEL,194,74,50,14
END
/////////////////////////////////////////////////////////////////////////////
//
// String Table
//
STRINGTABLE DISCARDABLE
BEGIN
IDS_APP_TITLE "fdebug"
IDS_HELLO "Hello World!"
IDC_FDEBUG "FDEBUG"
END
STRINGTABLE DISCARDABLE
BEGIN
IDS_LICENSE "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.\r\n\r\nThis 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.\r\n\r\nYou should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA."
END
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

40
freeldr/fdebug/resource.h Normal file
View File

@@ -0,0 +1,40 @@
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by fdebug.rc
//
#define IDC_MYICON 2
#define IDD_FDEBUG_DIALOG 102
#define IDD_ABOUTBOX 103
#define IDS_APP_TITLE 103
#define IDM_ABOUT 104
#define IDM_EXIT 105
#define IDS_HELLO 106
#define IDI_FDEBUG 107
#define IDI_SMALL 108
#define IDC_FDEBUG 109
#define IDR_MAINFRAME 128
#define IDD_CONNECTION 130
#define IDD_CAPTURE 131
#define IDC_COMPORT 1000
#define IDC_BAUTRATE 1001
#define IDC_CAPTUREFILENAME 1002
#define IDC_BROWSE 1003
#define IDC_LICENSE_EDIT 1029
#define ID_FILE_CONNECT 32771
#define ID_FILE_DISCONNECT 32772
#define ID_FILE_STARTCAPTURE 32773
#define ID_FILE_STOPCAPTURE 32774
#define ID_FILE_LOCALECHO 32775
#define IDS_LICENSE 32815
#define IDC_STATIC -1
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 132
#define _APS_NEXT_COMMAND_VALUE 32776
#define _APS_NEXT_CONTROL_VALUE 1004
#define _APS_NEXT_SYMED_VALUE 110
#endif
#endif

257
freeldr/fdebug/rs232.c Normal file
View File

@@ -0,0 +1,257 @@
/*
* FreeLoader - rs232.c
*
* Copyright (C) 2003 Brian Palmer <brianp@sginet.com>
*
* 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.
*/
#include <windows.h>
#include <winioctl.h>
#include <tchar.h>
#include <stdio.h>
#include "rs232.h"
HANDLE hPortHandle = NULL;
BOOL Rs232OpenPortWin32(TCHAR* CommPort)
{
TCHAR PortName[MAX_PATH];
DWORD ErrorCode;
// First check and make sure they don't already have the
// OBD2 connection open. We don't want to open things twice.
if (hPortHandle != NULL)
{
_tprintf(TEXT("Port handle not NULL. Must be already open. Returning FALSE...\n"));
return FALSE;
}
_stprintf(PortName, TEXT("\\\\.\\%s"), CommPort);
hPortHandle = CreateFile(PortName,
GENERIC_READ|GENERIC_WRITE,
0,
0,
OPEN_EXISTING,
0,
0);
if (hPortHandle == INVALID_HANDLE_VALUE)
{
hPortHandle = NULL;
ErrorCode = GetLastError();
_tprintf(TEXT("CreateFile(\"%s\") failed. GetLastError() = %lu.\n"), PortName, ErrorCode);
return FALSE;
}
return TRUE;
}
BOOL Rs232ClosePortWin32(VOID)
{
HANDLE hTempPortHandle = hPortHandle;
hPortHandle = NULL;
if (hTempPortHandle == NULL)
{
return FALSE;
}
return CloseHandle(hTempPortHandle);
}
// DeviceControlString
// [in] Pointer to a null-terminated string that specifies device-control information.
// The string must have the same form as the mode command's command-line arguments.
//
// For example, the following string specifies a baud rate of 1200, no parity, 8 data bits, and 1 stop bit:
// "baud=1200 parity=N data=8 stop=1"
//
// The following string specifies a baud rate of 115200, no parity, 8 data bits, and 1 stop bit:
// "115200,n,8,1"
//
// The device name is ignored if it is included in the string, but it must specify a valid device, as follows:
// "COM1: baud=1200 parity=N data=8 stop=1"
//
// For further information on mode command syntax, refer to the end-user documentation for your operating system.
BOOL Rs232ConfigurePortWin32(TCHAR* DeviceControlString)
{
DCB dcb;
DWORD ErrorCode;
/*if (!GetCommState(hPortHandle, &dcb))
{
ErrorCode = GetLastError();
_tprintf(TEXT("GetCommState() failed. GetLastError() = %lu.\n"), ErrorCode);
return FALSE;
}
dcb.BaudRate = BaudRate;
dcb.ByteSize = DataBits;
dcb.Parity = Parity;
dcb.StopBits = StopBits;
dcb.fBinary = TRUE;
dcb.fDsrSensitivity = FALSE;
dcb.fParity = (Parity == NOPARITY) ? FALSE : TRUE;
dcb.fOutX = FALSE;
dcb.fInX = FALSE;
dcb.fNull = FALSE;
dcb.fAbortOnError = TRUE;
dcb.fOutxCtsFlow = FALSE;
dcb.fOutxDsrFlow = FALSE;
dcb.fDtrControl = DTR_CONTROL_DISABLE;
dcb.fDsrSensitivity = FALSE;
dcb.fRtsControl = RTS_CONTROL_DISABLE;
dcb.fOutxCtsFlow = FALSE;
dcb.fOutxCtsFlow = FALSE;*/
memset(&dcb, 0, sizeof(DCB));
dcb.DCBlength = sizeof(dcb);
if (!BuildCommDCB(DeviceControlString, &dcb))
{
ErrorCode = GetLastError();
_tprintf(TEXT("BuildCommDCB() failed. GetLastError() = %lu.\n"), ErrorCode);
return FALSE;
}
if (!SetCommState(hPortHandle, &dcb))
{
ErrorCode = GetLastError();
_tprintf(TEXT("SetCommState() failed. GetLastError() = %lu.\n"), ErrorCode);
return FALSE;
}
// Set the timeouts
if (!Rs232SetCommunicationTimeoutsWin32(MAXDWORD, 0, 0, 0, 0))
{
return FALSE;
}
return TRUE;
}
// Members
// ReadIntervalTimeout
// Specifies the maximum time, in milliseconds, allowed to elapse between the arrival of two characters on the communications line. During a ReadFile operation, the time period begins when the first character is received. If the interval between the arrival of any two characters exceeds this amount, the ReadFile operation is completed and any buffered data is returned. A value of zero indicates that interval time-outs are not used.
// A value of MAXDWORD, combined with zero values for both the ReadTotalTimeoutConstant and ReadTotalTimeoutMultiplier members, specifies that the read operation is to return immediately with the characters that have already been received, even if no characters have been received.
//
// ReadTotalTimeoutMultiplier
// Specifies the multiplier, in milliseconds, used to calculate the total time-out period for read operations. For each read operation, this value is multiplied by the requested number of bytes to be read.
// ReadTotalTimeoutConstant
// Specifies the constant, in milliseconds, used to calculate the total time-out period for read operations. For each read operation, this value is added to the product of the ReadTotalTimeoutMultiplier member and the requested number of bytes.
// A value of zero for both the ReadTotalTimeoutMultiplier and ReadTotalTimeoutConstant members indicates that total time-outs are not used for read operations.
//
// WriteTotalTimeoutMultiplier
// Specifies the multiplier, in milliseconds, used to calculate the total time-out period for write operations. For each write operation, this value is multiplied by the number of bytes to be written.
// WriteTotalTimeoutConstant
// Specifies the constant, in milliseconds, used to calculate the total time-out period for write operations. For each write operation, this value is added to the product of the WriteTotalTimeoutMultiplier member and the number of bytes to be written.
// A value of zero for both the WriteTotalTimeoutMultiplier and WriteTotalTimeoutConstant members indicates that total time-outs are not used for write operations.
//
// Remarks
// If an application sets ReadIntervalTimeout and ReadTotalTimeoutMultiplier to MAXDWORD and sets ReadTotalTimeoutConstant to a value greater than zero and less than MAXDWORD, one of the following occurs when the ReadFile function is called:
//
// If there are any characters in the input buffer, ReadFile returns immediately with the characters in the buffer.
// If there are no characters in the input buffer, ReadFile waits until a character arrives and then returns immediately.
// If no character arrives within the time specified by ReadTotalTimeoutConstant, ReadFile times out.
BOOL Rs232SetCommunicationTimeoutsWin32(DWORD ReadIntervalTimeout, DWORD ReadTotalTimeoutMultiplier, DWORD ReadTotalTimeoutConstant, DWORD WriteTotalTimeoutMultiplier, DWORD WriteTotalTimeoutConstant)
{
COMMTIMEOUTS ct;
DWORD ErrorCode;
if (!GetCommTimeouts(hPortHandle, &ct))
{
ErrorCode = GetLastError();
_tprintf(TEXT("GetCommTimeouts() failed. GetLastError() = %lu.\n"), ErrorCode);
return FALSE;
}
ct.ReadIntervalTimeout = ReadIntervalTimeout;
ct.ReadTotalTimeoutConstant = ReadTotalTimeoutConstant;
ct.ReadTotalTimeoutMultiplier = ReadTotalTimeoutMultiplier;
ct.WriteTotalTimeoutConstant = WriteTotalTimeoutConstant;
ct.WriteTotalTimeoutMultiplier = WriteTotalTimeoutMultiplier;
if (!SetCommTimeouts(hPortHandle, &ct))
{
ErrorCode = GetLastError();
_tprintf(TEXT("SetCommTimeouts() failed. GetLastError() = %lu.\n"), ErrorCode);
return FALSE;
}
return TRUE;
}
BOOL Rs232ReadByteWin32(BYTE* DataByte)
{
DWORD BytesRead = 0;
DWORD ErrorCode;
// If ReadFile() fails then report error
if (!ReadFile(hPortHandle, DataByte, 1, &BytesRead, NULL))
{
ErrorCode = GetLastError();
_tprintf(TEXT("ReadFile() failed. GetLastError() = %lu.\n"), ErrorCode);
return FALSE;
}
// If ReadFile() succeeds, but BytesRead isn't 1
// then a timeout occurred.
if (BytesRead != 1)
{
return FALSE;
}
return TRUE;
}
BOOL Rs232WriteByteWin32(BYTE DataByte)
{
DWORD BytesWritten = 0;
BOOL Success;
DWORD ErrorCode;
Success = WriteFile(hPortHandle, &DataByte, 1, &BytesWritten, NULL);
if (!Success || BytesWritten != 1)
{
ErrorCode = GetLastError();
_tprintf(TEXT("WriteFile() failed. GetLastError() = %lu.\n"), ErrorCode);
return FALSE;
}
return TRUE;
}

View File

@@ -13,13 +13,15 @@
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
* 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.
*/
#pragma once
#ifndef __RS232_H
#define __RS232_H
#ifdef __cplusplus
extern "C" {
@@ -40,3 +42,5 @@ BOOL Rs232WriteByteWin32(BYTE DataByte);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif // !defined(__RS232_H)

View File

@@ -0,0 +1 @@
obj

View File

@@ -1,25 +1,3 @@
Changes in v3.0.0 (11/12/2007) (fball)
- Support for building an ARC Tree.
- Removal of registry write code.
- Removal of HARDWARE registry building code.
- Working WinLDR branch for booting NT4.
Changes in v2.5.0 (??/??/2007) (ion)
- Memory layout fixes to support NT boot
- Refactor PTE/PDE setup code
- Identity mapping support
- Set 0x80000000 as kernel base address, and all physical addresses with the high bit off (KSEG0_BASE) so that physical->virtual translation can be done with an OR.
Changes in v2.1.0 (??/??/2006) (ion)
- PE loading fixups and full NT-style driver loading
Changes in v2.0.0 (02/07/2005) (ion)
- Remove Multi-boot booting of ReactOS
Changes in v1.8.26 (10/30/2004) (chorns)
- Print stack frames on crashes.

413
freeldr/freeldr/Makefile Normal file
View File

@@ -0,0 +1,413 @@
#
# FreeLoader
# Copyright (C) 1998-2002 Brian Palmer <brianp@sginet.com>
#
# 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.
#
#############################################
# CHANGE THESE FOR YOUR OUTPUT
#
TARGET = i386
ifeq ($(DEBUG),)
# Debugging information on (bigger binary)
#DEBUG = yes
# Debugging information off (smaller binary)
DEBUG = no
endif
OBJDIR = obj
OUTPUT_DIR = $(OBJDIR)/$(TARGET)
BOOTCD_DIR = ../../bootcd
#############################################
# COMPILER AND LINKER PROGRAMS
#
TOOLSDIR = $(SRCDIR)/../tools
RM = $(subst /,$(SEP),$(TOOLSDIR))$(SEP)rdel
CP = $(subst /,$(SEP),$(TOOLSDIR))$(SEP)rcopy
MKDIR = $(subst /,$(SEP),$(TOOLSDIR))$(SEP)rmkdir
RMDIR = $(subst /,$(SEP),$(TOOLSDIR))$(SEP)rrmdir
OBJCOPY = objcopy
NM = nm
OBJDUMP = objdump
DEPTOOL = $(subst /,$(SEP),$(TOOLSDIR))$(SEP)deptool
HOSTTOOL = $(subst /,$(SEP),$(TOOLSDIR))$(SEP)hosttype
TOOLS = $(DEPTOOL) $(HOSTTOOL)
HOSTTYPE = $(shell $(HOSTTOOL))
#-----------------------------------------------------------------------------------------------------
# TEST IF WE ARE IN THE TARGET DIRECTORY
# IF NOT WE WILL CHANGE TO THE TARGET DIRECTORY AND RUN MAKE FROM THERE
#-----------------------------------------------------------------------------------------------------
#ifeq (,$(filter $(CURDIR)/$(OUTPUT_DIR),$(notdir $(CURDIR))))
ifneq ($(CURDIR), $(SRCDIR)/$(OUTPUT_DIR))
SRCDIR = $(CURDIR)
.SUFFIXES:
#############################################
# VARIABLE TO CHANGE TO TARGET DIRECTORY AND INVOKE MAKE FROM THERE
#
MAKETARGET = $(MAKE) --no-print-directory -C $(OUTPUT_DIR) \
-f ../../Makefile SRCDIR=$(CURDIR) $(MAKECMDGOALS)
.PHONY: CHANGE_TO_TARGET
CHANGE_TO_TARGET setupldr : BUILD_TOOLS $(OBJDIR) $(OBJDIR)/$(TARGET)
@echo Calculating source file dependencies...
+@$(MAKETARGET)
.PHONY: BUILD_TOOLS
BUILD_TOOLS:
@$(MAKE) --no-print-directory -C $(TOOLSDIR)
$(OBJDIR):
@echo Creating directory: $(OBJDIR)
@$(MKDIR) $(OBJDIR)
$(OBJDIR)/$(TARGET): $(OBJDIR)
@echo Creating directory: $(OBJDIR)/$(TARGET)
@$(MKDIR) $(OBJDIR)/$(TARGET)
Makefile : ;
% :: CHANGE_TO_TARGET
#############################################
.PHONY : clean
clean:
@$(MAKE) --no-print-directory -C $(TOOLSDIR)
@echo Cleaning directory $(OBJDIR)/$(TARGET)
@-$(RM) $(OBJDIR)/$(TARGET)/*
@echo Removing directory $(OBJDIR)/$(TARGET)
@-$(RMDIR) $(OBJDIR)/$(TARGET)
@-$(RMDIR) $(OBJDIR)
@echo Clean ALL done.
#############################################
.PHONY : bootcd
bootcd : bootcd_dirs setup_loader boot_loader
.PHONY : bootcd_dirs
bootcd_dirs:
$(MKDIR) $(BOOTCD_DIR)
$(MKDIR) $(BOOTCD_DIR)/disk
$(MKDIR) $(BOOTCD_DIR)/disk/reactos
$(MKDIR) $(BOOTCD_DIR)/disk/install
$(MKDIR) $(BOOTCD_DIR)/disk/bootdisk
$(MKDIR) $(BOOTCD_DIR)/disk/loader
.PHONY : boot_loader
boot_loader : $(OBJDIR)/$(TARGET)/freeldr.sys
$(CP) $(OBJDIR)/$(TARGET)/freeldr.sys $(BOOTCD_DIR)/disk/loader/freeldr.sys
$(CP) ../freeldr.ini $(BOOTCD_DIR)/disk/loader/freeldr.ini
.PHONY : setup_loader
setup_loader : $(OBJDIR)/$(TARGET)/setupldr.sys
$(CP) $(OBJDIR)/$(TARGET)/setupldr.sys $(BOOTCD_DIR)/disk/loader/setupldr.sys
#############################################
#-----------------------------------------------------------------------------------------------------
# END MAGIC TARGET DIRECTORY CHANGE STUFF
#-----------------------------------------------------------------------------------------------------
else
#############################################
# COMPILER COMMAND LINE OPTIONS
#
COMPILER_OPTIONS = -Wall -Werror -nostdlib -nostdinc -ffreestanding -fno-builtin -fno-inline \
-fno-zero-initialized-in-bss -O1 -MD
# FreeLoader does not use any of the standard libraries, includes, or built-in functions
#############################################
# COMPILER DEFINES
#
ifeq ($(DEBUG),yes)
COMPILER_DEBUG_DEFINES = -DDEBUG
else
COMPILER_DEBUG_DEFINES =
endif
COMPILER_DEFINES = -D__$(TARGET)__ $(COMPILER_DEBUG_DEFINES)
#############################################
# INCLUDE DIRECTORY OPTIONS
#
COMPILER_INCLUDES = -I$(SRCDIR)/include
#############################################
# COMPILER FLAGS
#
CFLAGS = $(COMPILER_OPTIONS) \
$(COMPILER_DEFINES) \
$(COMPILER_INCLUDES)
#############################################
# LINKER COMMAND LINE OPTIONS
#
#LINKER_OPTIONS = -N -Ttext=0x8000 --oformat=binary -s
LINKER_OPTIONS = -N -Ttext=0x8000
#############################################
# LINKER FLAGS
#
LFLAGS = $(LINKER_OPTIONS)
#############################################
# NASM FLAGS
#
ifeq ($(HOSTTYPE), dos)
NASMFLAGS = -f coff
else
ifeq ($(HOSTTYPE), win32)
NASMFLAGS = -f win32
else
NASMFLAGS = -f elf
endif
endif
#############################################
# LIST ALL THE OBJECT FILE GROUPS
#
# fathelp.o must come first in the link line because it contains bootsector helper code
# arch.o must come second in the link line because it contains the startup code
ARCH_OBJS = fathelp.o \
arch.o \
i386idt.o \
i386trap.o \
i386cpu.o \
i386pnp.o \
boot.o \
linux.o \
mb.o \
i386rtl.o \
i386vid.o \
drvmap.o \
int386.o \
i386disk.o \
portio.o \
hardware.o \
hwacpi.o \
hwapm.o \
hwcpu.o \
hwpci.o \
archmach.o \
machpc.o \
machxbox.o \
pccons.o \
pcdisk.o \
pcmem.o \
pcrtc.o \
pcvideo.o \
xboxcons.o \
xboxdisk.o \
xboxfont.o \
xboxhw.o \
xboxmem.o \
xboxrtc.o \
xboxvideo.o \
_alloca.o # For Mingw32 builds
RTL_OBJS = print.o \
stdlib.o \
string.o \
list.o \
memcmp.o \
memcpy.o \
memmove.o \
memset.o
FS_OBJS = fs.o \
fat.o \
iso.o \
ext2.o \
ntfs.o \
fsrec.o
UI_OBJS = tui.o \
tuimenu.o \
ui.o \
gui.o
REACTOS_OBJS= arcname.o \
binhive.o \
registry.o
COMM_OBJS = rs232.o
DISK_OBJS = disk.o \
partition.o
MM_OBJS = mm.o \
meminit.o
CACHE_OBJS = cache.o \
blocklist.o
INIFILE_OBJS= inifile.o \
ini_init.o \
parse.o
INFFILE_OBJS= inffile.o
VIDEO_OBJS = video.o \
fade.o \
palette.o \
pixel.o \
bank.o
# libgcc2.o contains code (__udivdi3, __umoddi3) necessary to do
# 64-bit division on the i386 (and other 32-bit) architectures
# This code was taken from the GCC v3.1 source
MATH_OBJS = libgcc2.o
BASE_OBJS = freeldr.o \
debug.o \
multiboot.o \
version.o \
cmdline.o \
machine.o
FREELDR_OBJS= bootmgr.o \
drivemap.o \
miscboot.o \
options.o \
linuxboot.o \
oslist.o \
custom.o
ROSLDR_OBJS = reactos.o
SETUPLDR_OBJS= setupldr.o
COMMON_OBJS = $(ARCH_OBJS) \
$(RTL_OBJS) \
$(FS_OBJS) \
$(UI_OBJS) \
$(REACTOS_OBJS) \
$(COMM_OBJS) \
$(DISK_OBJS) \
$(MM_OBJS) \
$(CACHE_OBJS) \
$(VIDEO_OBJS) \
$(MATH_OBJS) \
$(BASE_OBJS)
SPECIAL_OBJS = $(INIFILE_OBJS) \
$(INFFILE_OBJS) \
$(FREELDR_OBJS) \
$(ROSLDR_OBJS) \
$(SETUPLDR_OBJS)
F_OBJS = $(COMMON_OBJS) \
$(INIFILE_OBJS) \
$(ROSLDR_OBJS) \
$(FREELDR_OBJS)
S_OBJS = $(COMMON_OBJS) \
$(INIFILE_OBJS) \
$(INFFILE_OBJS) \
$(SETUPLDR_OBJS)
#############################################
# ALL THE OBJECTS
#
ALL_OBJS = $(COMMON_OBJS) \
$(SPECIAL_OBJS)
#############################################
# SET THE VPATH SO MAKE CAN FIND THE SOURCE FILES
#
VPATH = $(SRCDIR)/ \
$(SRCDIR)/arch/$(TARGET) \
$(SRCDIR)/rtl \
$(SRCDIR)/fs \
$(SRCDIR)/ui \
$(SRCDIR)/reactos \
$(SRCDIR)/comm \
$(SRCDIR)/disk \
$(SRCDIR)/mm \
$(SRCDIR)/cache \
$(SRCDIR)/inifile \
$(SRCDIR)/inffile \
$(SRCDIR)/video \
$(SRCDIR)/math \
$(SRCDIR)/include
#############################################
all : freeldr.sys setupldr.sys
@echo Make ALL done.
#############################################
freeldr.sys : $(ALL_OBJS)
@echo ===================================================== LINKING $@
@$(LD) $(LFLAGS) -o freeldr.exe $(F_OBJS)
ifeq ($(FULL_MAP),yes)
@$(OBJDUMP) -d -S freeldr.exe > freeldr.map
else
@$(NM) --numeric-sort freeldr.exe > freeldr.map
endif
@$(OBJCOPY) -O binary freeldr.exe freeldr.sys
#############################################
setupldr.sys : $(ALL_OBJS)
@echo ===================================================== LINKING $@
@$(LD) $(LFLAGS) -Map setupldr.map -o setupldr.exe $(S_OBJS)
ifeq ($(FULL_MAP),yes)
@$(OBJDUMP) -d -S setupldr.exe > setupldr.map
else
@$(NM) --numeric-sort setupldr.exe > setupldr.map
endif
@$(OBJCOPY) -O binary setupldr.exe setupldr.sys
#############################################
%.o :: %.c
@echo ===================================================== Compiling $*
@$(CC) $(CFLAGS) -o $@ -c $<
@$(DEPTOOL) $*.d
%.o :: %.S
@echo ===================================================== Assembling $*
@$(CC) $(CFLAGS) -o $@ -c $<
@$(DEPTOOL) $*.d
%.o :: %.asm
@echo ===================================================== Assembling $*
@$(NASM_CMD) $(NASMFLAGS) -o $@ $<
#############################################
# Include the automagically generated dependencies
-include $(ALL_OBJS:%.o=%.d)
#############################################
endif

View File

@@ -0,0 +1,469 @@
/*
* FreeLoader
* Copyright (C) 1998-2002 Brian Palmer <brianp@sginet.com>
*
* 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.
*/
.text
.code16
#define ASM
#include <arch.h>
#include <multiboot.h>
EXTERN(RealEntryPoint)
cli
/* Setup segment registers */
xorw %ax,%ax
movw %ax,%ds
movw %ax,%es
movw %ax,%fs
movw %ax,%gs
movw %ax,%ss
/* Setup a stack */
movw stack16,%sp
sti
/* Init pmode */
call switch_to_prot
.code32
/* Store the boot drive */
movb %dl,(_BootDrive)
/* Store the boot partition */
movb %dh,(_BootPartition)
/* GO! */
xorl %eax,%eax
pushl %eax
call _BootMain
call switch_to_real
.code16
int $0x19
/* We should never get here */
stop:
jmp stop
nop
nop
/*
* Switches the processor to protected mode
* it destroys eax
*/
EXTERN(switch_to_prot)
.code16
cli /* None of these */
/* We don't know what values are currently */
/* in the segment registers. So we are */
/* going to reload them with sane values. */
/* Of course CS has to already be valid. */
/* We are currently in real-mode so we */
/* need real-mode segment values. */
movw $0x0000,%ax
movw %ax,%ds
movw %ax,%es
movw %ax,%fs
movw %ax,%gs
movw %ax,%ss
/* Get the return address off the stack */
popw (code32ret)
/* Save 16-bit stack pointer */
movw %sp,stack16
/* Load the GDT */
lgdt gdtptr
/* Load the IDT */
lidt i386idtptr
/* Enable Protected Mode */
mov %cr0,%eax
orl $CR0_PE_SET,%eax
mov %eax,%cr0
/* Clear prefetch queue & correct CS */
ljmp $PMODE_CS, $inpmode
.code32
inpmode:
/* Setup segment selectors */
movw $PMODE_DS,%ax
movw %ax,%ds
movw %ax,%es
movw %ax,%fs
movw %ax,%gs
movw %ax,%ss
movl stack32,%esp
/* Put the return address back onto the stack */
pushl (code32ret)
/* Now return in p-mode! */
ret
/*
* Switches the processor back to real mode
* it destroys eax
*/
EXTERN(switch_to_real)
.code32
/* We don't know what values are currently */
/* in the segment registers. So we are */
/* going to reload them with sane values. */
/* Of course CS has to already be valid. */
/* We are currently in protected-mode so we */
/* need protected-mode segment values. */
movw $PMODE_DS,%ax
movw %ax,%ds
movw %ax,%es
movw %ax,%fs
movw %ax,%gs
movw %ax,%ss
/* Get the return address off the stack */
popl (code16ret)
/* Save 32-bit stack pointer */
movl %esp,stack32
/* jmp to 16-bit segment to set the limit correctly */
ljmp $RMODE_CS, $switch_to_real16
switch_to_real16:
.code16
/* Restore segment registers to correct limit */
movw $RMODE_DS,%ax
movw %ax,%ds
movw %ax,%es
movw %ax,%fs
movw %ax,%gs
movw %ax,%ss
/* Disable Protected Mode */
mov %cr0,%eax
andl $CR0_PE_CLR,%eax
mov %eax,%cr0
/* Clear prefetch queue & correct CS */
ljmp $0, $inrmode
inrmode:
movw %cs,%ax
movw %ax,%ds
movw %ax,%es
movw %ax,%fs
movw %ax,%gs
movw %ax,%ss
/* Clear out the high 16-bits of ESP */
/* This is needed because I have one */
/* machine that hangs when booted to dos if */
/* anything other than 0x0000 is in the high */
/* 16-bits of ESP. Even though real-mode */
/* code should only use SP and not ESP. */
xorl %esp,%esp
movw stack16,%sp
/* Put the return address back onto the stack */
pushw (code16ret)
/* Load IDTR with real mode value */
lidt rmode_idtptr
sti /* These are ok now */
/* Now return in r-mode! */
ret
/*
* Needed for enabling the a20 address line
*/
.code16
empty_8042:
.word 0x00eb,0x00eb // jmp $+2, jmp $+2
inb $0x64,%al
testb $0x02,%al
jnz empty_8042
ret
/*
* Enable the A20 address line (to allow access to over 1mb)
*/
EXTERN(_EnableA20)
.code32
pushal
call switch_to_real
.code16
call empty_8042
movb $0xD1,%al // command write
outb %al,$0x64
call empty_8042
mov $0xDF,%al // A20 on
out %al,$0x60
call empty_8042
call switch_to_prot
.code32
popal
ret
/*
* Disable the A20 address line
*/
EXTERN(_DisableA20)
.code32
pushal
call switch_to_real
.code16
call empty_8042
movb $0xD1,%al // command write
outb %al,$0x64
call empty_8042
mov $0xDD,%al // A20 off
out %al,$0x60
call empty_8042
call switch_to_prot
.code32
popal
ret
/* Multiboot support
*
* Allows freeldr to be loaded as a "multiboot kernel" by
* other boot loaders like Grub
*/
#define MB_INFO_FLAGS_OFFSET 0
#define MB_INFO_BOOT_DEVICE_OFFSET 12
#define MB_INFO_COMMAND_LINE_OFFSET 16
/*
* We want to execute at 0x8000 (to be compatible with bootsector
* loading), but Grub only allows loading of multiboot kernels
* above 1MB. So we let Grub load us there and then relocate
* ourself to 0x8000
*/
#define CMDLINE_BASE 0x7000
#define FREELDR_BASE 0x8000
#define INITIAL_BASE 0x200000
/* Align 32 bits boundary */
.align 4
/* Multiboot header */
MultibootHeader:
/* magic */
.long MULTIBOOT_HEADER_MAGIC
/* flags */
.long MULTIBOOT_HEADER_FLAGS
/* checksum */
.long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)
/* header_addr */
.long INITIAL_BASE + MultibootHeader - FREELDR_BASE
/* load_addr */
.long INITIAL_BASE
/* load_end_addr */
.long INITIAL_BASE + __bss_start__ - FREELDR_BASE
/* bss_end_addr */
.long INITIAL_BASE + __bss_end__ - FREELDR_BASE
/* entry_addr */
.long INITIAL_BASE + MultibootEntry - FREELDR_BASE
MultibootEntry:
cli /* Even after setting up the our IDT below we are
* not ready to handle hardware interrupts (no entries
* in IDT), so there's no sti here. Interrupts will be
* enabled in due time */
/* Although the multiboot spec says we should be called with the
* segment registers set to 4GB flat mode, let's be sure and set up
* our own */
lgdt gdtptrhigh + INITIAL_BASE - FREELDR_BASE
/* Reload segment selectors */
ljmp $PMODE_CS, $(mb1 + INITIAL_BASE - FREELDR_BASE)
mb1:
movw $PMODE_DS,%dx
movw %dx,%ds
movw %dx,%es
/* Copy to low mem */
movl $INITIAL_BASE,%esi
movl $FREELDR_BASE,%edi
movl $(__bss_end__ - FREELDR_BASE),%ecx
addl $3,%ecx
shrl $2,%ecx
rep movsl
/* Load the GDT and IDT */
lgdt gdtptr
lidt i386idtptr
/* Clear prefetch queue & correct CS,
* jump to low mem */
ljmp $PMODE_CS, $mb2
mb2:
/* Reload segment selectors */
movw $PMODE_DS,%dx
movw %dx,%ds
movw %dx,%es
movw %dx,%fs
movw %dx,%gs
movw %dx,%ss
movl $STACK32ADDR,%esp
/* Check for valid multiboot signature */
cmpl $MULTIBOOT_BOOTLOADER_MAGIC,%eax
jne mbfail
/* See if the boot device was passed in */
movl MB_INFO_FLAGS_OFFSET(%ebx),%edx
testl $MB_INFO_FLAG_BOOT_DEVICE,%edx
jz mb3
/* Retrieve boot device info */
movl MB_INFO_BOOT_DEVICE_OFFSET(%ebx),%eax
shrl $16,%eax
incb %al
movb %al,_BootPartition
movb %ah,_BootDrive
jmp mb4
mb3: /* No boot device known, assume first partition of first harddisk */
movb $0x80,_BootDrive
movb $1,_BootPartition
mb4:
/* Check for a command line */
xorl %eax,%eax
testl $MB_INFO_FLAG_COMMAND_LINE,%edx
jz mb6
/* Copy command line to low mem*/
movl MB_INFO_COMMAND_LINE_OFFSET(%ebx),%esi
movl $CMDLINE_BASE,%edi
mb5: lodsb
stosb
testb %al,%al
jnz mb5
movl $CMDLINE_BASE,%eax
mb6:
/* GO! */
pushl %eax
call _BootMain
mbfail: call switch_to_real
.code16
int $0x19
mbstop: jmp mbstop /* We should never get here */
.code32
/* 16-bit stack pointer */
stack16:
.word STACK16ADDR
/* 32-bit stack pointer */
stack32:
.long STACK32ADDR
/* 16-bit return address */
code16ret:
.long 0
/* 32-bit return address */
code32ret:
.long 0
.p2align 2 /* force 4-byte alignment */
gdt:
/* NULL Descriptor */
.word 0x0000
.word 0x0000
.word 0x0000
.word 0x0000
/* 32-bit flat CS */
.word 0xFFFF
.word 0x0000
.word 0x9A00
.word 0x00CF
/* 32-bit flat DS */
.word 0xFFFF
.word 0x0000
.word 0x9200
.word 0x00CF
/* 16-bit real mode CS */
.word 0xFFFF
.word 0x0000
.word 0x9E00
.word 0x0000
/* 16-bit real mode DS */
.word 0xFFFF
.word 0x0000
.word 0x9200
.word 0x0000
/* GDT table pointer */
gdtptr:
.word 0x27 /* Limit */
.long gdt /* Base Address */
/* Initial GDT table pointer for multiboot */
gdtptrhigh:
.word 0x27 /* Limit */
.long gdt + INITIAL_BASE - FREELDR_BASE /* Base Address */
/* Real-mode IDT pointer */
rmode_idtptr:
.word 0x3ff /* Limit */
.long 0 /* Base Address */
EXTERN(_BootDrive)
.long 0
EXTERN(_BootPartition)
.long 0

View File

@@ -0,0 +1,52 @@
/* $Id: archmach.c,v 1.2 2004/11/09 23:36:19 gvg Exp $
*
* FreeLoader
*
* 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.
*/
#include "freeldr.h"
#include "mm.h"
#include "machine.h"
#include "machpc.h"
#include "machxbox.h"
#include "portio.h"
#include "hardware.h"
#include "rtl.h"
VOID
MachInit(VOID)
{
U32 PciId;
memset(&MachVtbl, 0, sizeof(MACHVTBL));
/* Check for Xbox by identifying device at PCI 0:0:0, if it's
* 0x10de/0x02a5 then we're running on an Xbox */
WRITE_PORT_ULONG((U32*) 0xcf8, CONFIG_CMD(0, 0, 0));
PciId = READ_PORT_ULONG((U32*) 0xcfc);
if (0x02a510de == PciId)
{
XboxMachInit();
}
else
{
PcMachInit();
}
HalpCalibrateStallExecution();
}
/* EOF */

View File

@@ -0,0 +1,62 @@
/*
* FreeLoader
* Copyright (C) 1998-2002 Brian Palmer <brianp@sginet.com>
*
* 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.
*/
.text
.code16
#define ASM
#include <arch.h>
EXTERN(_ChainLoadBiosBootSectorCode)
.code32
call switch_to_real
.code16
/* Set the boot drive */
movb (_BootDrive),%dl
/* Load segment registers */
cli
movw $0x0000,%bx
movw %bx,%ds
movw %bx,%es
movw %bx,%fs
movw %bx,%gs
movw %bx,%ss
movw $0x7C00,%sp
ljmpl $0x0000,$0x7C00
EXTERN(_SoftReboot)
.code32
call switch_to_real
.code16
movw $0x40,%ax
movw %ax,%ds
movw $0x72,%si
// Set the word at location 40:72 to 1234h
movw $0x1234,(%si)
// and jump to location FFFF:0 in ROM
ljmpl $0xFFFF,$0x0000

View File

@@ -0,0 +1,132 @@
/*
* FreeLoader
* Copyright (C) 1998-2002 Brian Palmer <brianp@sginet.com>
*
* 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.
*/
.text
.code16
#define ASM
#include <arch.h>
EXTERN(_DriveMapInt13HandlerStart)
Int13Handler:
pushw %bp
movw %sp,%bp
pushw %ax
pushw %cx
pushw %si
cld
/* Get callers flags from stack */
movw 0x06(%bp),%ax
movw %ax,%cs:(CallersFlags - Int13Handler)
/* Save the drive number they passed in */
movb %dl,%cs:(PassedInDriveNumber - Int13Handler)
/* Now we need to perform the mapping */
xorw %cx,%cx
movw $(Int13HandlerMapCount - Int13Handler),%si
/* Get the count of drives in the map list */
movb %cs:(%si),%cl
incw %si
/* If the map list is empty then just call the old int 13h handler */
cmpb $0,%cl
jz CallOldInt13Handler
GetMappedDriveNumberLoop:
/* Get the next drive number in the list */
lodsw %cs:(%si),%ax
/* Check to see if it's the one they are calling int 13h for */
cmpb %al,%dl
/* If not get the next one */
jne GetMappedDriveNumberLoopNext
/* If we get here then we have found a mapped drive */
/* Send new drive number on to the old int 13h handler */
movb %ah,%dl
/* Call BIOS Int 13 Handler */
jmp CallOldInt13Handler
GetMappedDriveNumberLoopNext:
loop GetMappedDriveNumberLoop
CallOldInt13Handler:
/* Restore the registers we changed off the stack */
popw %si
popw %cx
popw %ax
/* Put flags onto stack */
pushw %cs:(CallersFlags - Int13Handler)
/* Call old int 13h handler with new drive number */
.byte 0x9a /* lcall */
EXTERN(_DriveMapOldInt13HandlerAddress)
.word 0
.word 0
/* Update the callers flags with the values the BIOS returned */
pushw %ax
pushf
popw %ax
movw %ax,0x06(%bp)
popw %ax
/* Restore the callers drive number */
movb %cs:(PassedInDriveNumber - Int13Handler),%dl
popw %bp
iret
CallersFlags:
.word 0
PassedInDriveNumber:
.byte 0
EXTERN(_DriveMapInt13HandlerMapList)
Int13HandlerMapCount:
.byte 0
Int13HandlerDrive1:
.byte 0
Int13HandlerDriveNew1:
.byte 0
Int13HandlerDrive2:
.byte 0
Int13HandlerDriveNew2:
.byte 0
Int13HandlerDrive3:
.byte 0
Int13HandlerDriveNew3:
.byte 0
Int13HandlerDrive4:
.byte 0
Int13HandlerDriveNew4:
.byte 0
EXTERN(_DriveMapInt13HandlerEnd)

View File

@@ -125,12 +125,10 @@ LoadFile5:
LoadFile_Done:
mov dl,BYTE [BYTE bp+BootDrive] ; Load the boot drive into DL
mov dh,[BootPartition] ; Load the boot partition into DH
push WORD 0x0000
push WORD 0x8000 ; We will do a far return to 0000:8000h
retf ; Transfer control to ROSLDR
push 0 ; push segment (0x0000)
mov bx, [0x8000 + 0xA8] ; load the RVA of the EntryPoint into eax
add bx, 0x8000 ; RVA -> VA and skip 3 bytes (jump to fathelper code)
push bx ; push offset
retf ; Transfer control to FreeLoader
; Reads the entire FAT into memory at 7000:0000
ReadFatIntoMemory:

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,200 @@
/*
* FreeLoader
*
* Copyright (C) 2003 Eric Kohl
*
* 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.
*/
#ifndef __I386_HARDWARE_H_
#define __I386_HARDWARE_H_
#ifndef __REGISTRY_H
#include "../../reactos/registry.h"
#endif
typedef enum
{
InterfaceTypeUndefined = -1,
Internal,
Isa,
Eisa,
MicroChannel,
TurboChannel,
PCIBus,
VMEBus,
NuBus,
PCMCIABus,
CBus,
MPIBus,
MPSABus,
ProcessorInternal,
InternalPowerBus,
PNPISABus,
MaximumInterfaceType
} INTERFACE_TYPE, *PINTERFACE_TYPE;
typedef enum _CM_RESOURCE_TYPE
{
CmResourceTypeNull = 0,
CmResourceTypePort,
CmResourceTypeInterrupt,
CmResourceTypeMemory,
CmResourceTypeDma,
CmResourceTypeDeviceSpecific,
CmResourceTypeMaximum
} CM_RESOURCE_TYPE;
typedef enum _CM_SHARE_DISPOSITION
{
CmResourceShareUndetermined = 0,
CmResourceShareDeviceExclusive,
CmResourceShareDriverExclusive,
CmResourceShareShared
} CM_SHARE_DISPOSITION;
typedef U64 PHYSICAL_ADDRESS;
typedef struct
{
U8 Type;
U8 ShareDisposition;
U16 Flags;
union
{
struct
{
PHYSICAL_ADDRESS Start;
U32 Length;
} __attribute__((packed)) Port;
struct
{
U32 Level;
U32 Vector;
U32 Affinity;
} __attribute__((packed)) Interrupt;
struct
{
PHYSICAL_ADDRESS Start;
U32 Length;
} __attribute__((packed)) Memory;
struct
{
U32 Channel;
U32 Port;
U32 Reserved1;
} __attribute__((packed)) Dma;
struct
{
U32 DataSize;
U32 Reserved1;
U32 Reserved2;
} __attribute__((packed)) DeviceSpecificData;
} __attribute__((packed)) u;
} __attribute__((packed)) CM_PARTIAL_RESOURCE_DESCRIPTOR, *PCM_PARTIAL_RESOURCE_DESCRIPTOR;
/* CM_PARTIAL_RESOURCE_DESCRIPTOR.Flags */
#define CM_RESOURCE_PORT_MEMORY 0x0000
#define CM_RESOURCE_PORT_IO 0x0001
#define CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE 0x0000
#define CM_RESOURCE_INTERRUPT_LATCHED 0x0001
typedef struct
{
U16 Version;
U16 Revision;
U32 Count;
CM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptors[1];
} __attribute__((packed))CM_PARTIAL_RESOURCE_LIST, *PCM_PARTIAL_RESOURCE_LIST;
typedef struct
{
INTERFACE_TYPE InterfaceType;
U32 BusNumber;
CM_PARTIAL_RESOURCE_LIST PartialResourceList;
} __attribute__((packed)) CM_FULL_RESOURCE_DESCRIPTOR, *PCM_FULL_RESOURCE_DESCRIPTOR;
typedef struct _CM_COMPONENT_INFORMATION
{
U32 Flags;
U32 Version;
U32 Key;
U32 Affinity;
} __attribute__((packed)) CM_COMPONENT_INFORMATION, *PCM_COMPONENT_INFORMATION;
/* CM_COMPONENT_INFORMATION.Flags */
#define Failed 0x00000001
#define ReadOnly 0x00000002
#define Removable 0x00000004
#define ConsoleIn 0x00000008
#define ConsoleOut 0x00000010
#define Input 0x00000020
#define Output 0x00000040
#define CONFIG_CMD(bus, dev_fn, where) \
(0x80000000 | (((U32)(bus)) << 16) | (((dev_fn) & 0x1F) << 11) | (((dev_fn) & 0xE0) << 3) | ((where) & ~3))
/* PROTOTYPES ***************************************************************/
/* hardware.c */
VOID HalpCalibrateStallExecution(VOID);
VOID KeStallExecutionProcessor(U32 Microseconds);
VOID SetComponentInformation(HKEY ComponentKey,
U32 Flags,
U32 Key,
U32 Affinity);
/* hwacpi.c */
VOID DetectAcpiBios(HKEY SystemKey, U32 *BusNumber);
/* hwapm.c */
VOID DetectApmBios(HKEY SystemKey, U32 *BusNumber);
/* hwcpu.c */
VOID DetectCPUs(HKEY SystemKey);
/* hwpci.c */
VOID DetectPciBios(HKEY SystemKey, U32 *BusNumber);
/* i386cpu.S */
U32 CpuidSupported(VOID);
VOID GetCpuid(U32 Level,
U32 *eax,
U32 *ebx,
U32 *ecx,
U32 *edx);
U64 RDTSC(VOID);
/* i386pnp.S */
U32 PnpBiosSupported(VOID);
U32 PnpBiosGetDeviceNodeCount(U32 *NodeSize,
U32 *NodeCount);
U32 PnpBiosGetDeviceNode(U8 *NodeId,
U8 *NodeBuffer);
#endif /* __I386_HARDWARE_H_ */
/* EOF */

View File

@@ -0,0 +1,104 @@
/*
* FreeLoader
*
* Copyright (C) 2004 Eric Kohl
*
* 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.
*/
#include <freeldr.h>
#include <arch.h>
#include <rtl.h>
#include <debug.h>
#include <mm.h>
#include <portio.h>
#include "../../reactos/registry.h"
#include "hardware.h"
static BOOL
FindAcpiBios(VOID)
{
PU8 Ptr;
/* Find the 'Root System Descriptor Table Pointer' */
Ptr = (PU8)0xE0000;
while ((U32)Ptr < 0x100000)
{
if (!memcmp(Ptr, "RSD PTR ", 8))
{
DbgPrint((DPRINT_HWDETECT, "ACPI supported\n"));
return TRUE;
}
Ptr = (PU8)((U32)Ptr + 0x10);
}
DbgPrint((DPRINT_HWDETECT, "ACPI not supported\n"));
return FALSE;
}
VOID
DetectAcpiBios(HKEY SystemKey, U32 *BusNumber)
{
char Buffer[80];
HKEY BiosKey;
S32 Error;
if (FindAcpiBios())
{
/* Create new bus key */
sprintf(Buffer,
"MultifunctionAdapter\\%u", *BusNumber);
Error = RegCreateKey(SystemKey,
Buffer,
&BiosKey);
if (Error != ERROR_SUCCESS)
{
DbgPrint((DPRINT_HWDETECT, "RegCreateKey() failed (Error %u)\n", (int)Error));
return;
}
#if 0
/* Set 'Component Information' */
SetComponentInformation(BiosKey,
0x0,
0x0,
0xFFFFFFFF);
#endif
/* Increment bus number */
(*BusNumber)++;
/* Set 'Identifier' value */
Error = RegSetValue(BiosKey,
"Identifier",
REG_SZ,
(PU8)"ACPI BIOS",
10);
if (Error != ERROR_SUCCESS)
{
DbgPrint((DPRINT_HWDETECT, "RegSetValue() failed (Error %u)\n", (int)Error));
return;
}
}
}
/* EOF */

View File

@@ -0,0 +1,111 @@
/*
* FreeLoader
*
* Copyright (C) 2004 Eric Kohl
*
* 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.
*/
#include <freeldr.h>
#include <arch.h>
#include <rtl.h>
#include <debug.h>
#include <mm.h>
#include <portio.h>
#include "../../reactos/registry.h"
#include "hardware.h"
static BOOL
FindApmBios(VOID)
{
REGS RegsIn;
REGS RegsOut;
RegsIn.b.ah = 0x53;
RegsIn.b.al = 0x00;
RegsIn.w.bx = 0x0000;
Int386(0x15, &RegsIn, &RegsOut);
if (INT386_SUCCESS(RegsOut))
{
DbgPrint((DPRINT_HWDETECT, "Found APM BIOS\n"));
DbgPrint((DPRINT_HWDETECT, "AH: %x\n", RegsOut.b.ah));
DbgPrint((DPRINT_HWDETECT, "AL: %x\n", RegsOut.b.al));
DbgPrint((DPRINT_HWDETECT, "BH: %x\n", RegsOut.b.bh));
DbgPrint((DPRINT_HWDETECT, "BL: %x\n", RegsOut.b.bl));
DbgPrint((DPRINT_HWDETECT, "CX: %x\n", RegsOut.w.cx));
return TRUE;
}
printf("No APM BIOS found\n");
return FALSE;
}
VOID
DetectApmBios(HKEY SystemKey, U32 *BusNumber)
{
char Buffer[80];
HKEY BiosKey;
S32 Error;
if (FindApmBios())
{
/* Create new bus key */
sprintf(Buffer,
"MultifunctionAdapter\\%u", *BusNumber);
Error = RegCreateKey(SystemKey,
Buffer,
&BiosKey);
if (Error != ERROR_SUCCESS)
{
DbgPrint((DPRINT_HWDETECT, "RegCreateKey() failed (Error %u)\n", (int)Error));
return;
}
#if 0
/* Set 'Component Information' */
SetComponentInformation(BiosKey,
0x0,
0x0,
0xFFFFFFFF);
#endif
/* Increment bus number */
(*BusNumber)++;
/* Set 'Identifier' value */
Error = RegSetValue(BiosKey,
"Identifier",
REG_SZ,
(PU8)"APM",
4);
if (Error != ERROR_SUCCESS)
{
DbgPrint((DPRINT_HWDETECT, "RegSetValue() failed (Error %u)\n", (int)Error));
return;
}
}
/* FIXME: Add congiguration data */
}
/* EOF */

View File

@@ -0,0 +1,635 @@
/*
* FreeLoader
*
* Copyright (C) 2003 Eric Kohl
*
* 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.
*/
#include <freeldr.h>
#include <arch.h>
#include <rtl.h>
#include <debug.h>
#include <mm.h>
#include <portio.h>
#include "../../reactos/registry.h"
#include "hardware.h"
#define MP_FP_SIGNATURE 0x5F504D5F /* "_MP_" */
#define MP_CT_SIGNATURE 0x504D4350 /* "PCMP" */
typedef struct _MP_FLOATING_POINT_TABLE
{
U32 Signature; /* "_MP_" */
U32 PhysicalAddressPointer;
U8 Length;
U8 SpecRev;
U8 Checksum;
U8 FeatureByte[5];
} PACKED MP_FLOATING_POINT_TABLE, *PMP_FLOATING_POINT_TABLE;
typedef struct _MPS_CONFIG_TABLE_HEADER
{
U32 Signature; /* "PCMP" */
U16 BaseTableLength;
U8 SpecRev;
U8 Checksum;
U8 OemIdString[8];
U8 ProductIdString[12];
U32 OemTablePointer;
U16 OemTableLength;
U16 EntryCount;
U32 AddressOfLocalAPIC;
U16 ExtendedTableLength;
U8 ExtendedTableChecksum;
U8 Reserved;
} PACKED MP_CONFIGURATION_TABLE, *PMP_CONFIGURATION_TABLE;
typedef struct _MP_PROCESSOR_ENTRY
{
U8 EntryType;
U8 LocalApicId;
U8 LocalApicVersion;
U8 CpuFlags;
U32 CpuSignature;
U32 FeatureFlags;
U32 Reserved1;
U32 Reserved2;
} PACKED MP_PROCESSOR_ENTRY, *PMP_PROCESSOR_ENTRY;
/* FUNCTIONS ****************************************************************/
static U32
GetCpuSpeed(VOID)
{
U64 Timestamp1;
U64 Timestamp2;
U64 Diff;
/* Read TSC (Time Stamp Counter) */
Timestamp1 = RDTSC();
/* Wait for 0.1 seconds (= 100 milliseconds = 100000 microseconds)*/
KeStallExecutionProcessor(100000);
/* Read TSC (Time Stamp Counter) again */
Timestamp2 = RDTSC();
/* Calculate elapsed time (check for counter overrun) */
if (Timestamp2 > Timestamp1)
{
Diff = Timestamp2 - Timestamp1;
}
else
{
Diff = Timestamp2 + (((U64)-1) - Timestamp1);
}
return (U32)(Diff / 100000);
}
static VOID
DetectCPU(HKEY CpuKey,
HKEY FpuKey)
{
char VendorIdentifier[13];
char Identifier[64];
U32 FeatureSet;
HKEY CpuInstKey;
HKEY FpuInstKey;
U32 eax = 0;
U32 ebx = 0;
U32 ecx = 0;
U32 edx = 0;
U32 *Ptr;
S32 Error;
BOOL SupportTSC = FALSE;
U32 CpuSpeed;
/* Create the CPU instance key */
Error = RegCreateKey(CpuKey,
"0",
&CpuInstKey);
if (Error != ERROR_SUCCESS)
{
DbgPrint((DPRINT_HWDETECT, "RegCreateKey() failed (Error %u)\n", (int)Error));
return;
}
/* Create the FPU instance key */
Error = RegCreateKey(FpuKey,
"0",
&FpuInstKey);
if (Error != ERROR_SUCCESS)
{
DbgPrint((DPRINT_HWDETECT, "RegCreateKey() failed (Error %u)\n", (int)Error));
return;
}
eax = CpuidSupported();
if (eax & 1)
{
DbgPrint((DPRINT_HWDETECT, "CPUID supported\n"));
/* Get vendor identifier */
GetCpuid(0, &eax, &ebx, &ecx, &edx);
VendorIdentifier[12] = 0;
Ptr = (U32*)&VendorIdentifier[0];
*Ptr = ebx;
Ptr++;
*Ptr = edx;
Ptr++;
*Ptr = ecx;
/* Get Identifier */
GetCpuid(1, &eax, &ebx, &ecx, &edx);
sprintf(Identifier,
"x86 Family %u Model %u Stepping %u",
(unsigned int)((eax >> 8) & 0x0F),
(unsigned int)((eax >> 4) & 0x0F),
(unsigned int)(eax & 0x0F));
FeatureSet = edx;
if (((eax >> 8) & 0x0F) >= 5)
SupportTSC = TRUE;
}
else
{
DbgPrint((DPRINT_HWDETECT, "CPUID not supported\n"));
strcpy(VendorIdentifier, "Unknown");
sprintf(Identifier,
"x86 Family %u Model %u Stepping %u",
(unsigned int)((eax >> 8) & 0x0F),
(unsigned int)((eax >> 4) & 0x0F),
(unsigned int)(eax & 0x0F));
FeatureSet = 0;
}
/* Set 'Conmponent Information' value (CPU and FPU) */
SetComponentInformation(CpuInstKey, 0, 0, 1);
SetComponentInformation(FpuInstKey, 0, 0, 1);
/* Set 'FeatureSet' value (CPU only) */
DbgPrint((DPRINT_HWDETECT, "FeatureSet: %x\n", FeatureSet));
Error = RegSetValue(CpuInstKey,
"FeatureSet",
REG_DWORD,
(PU8)&FeatureSet,
sizeof(U32));
if (Error != ERROR_SUCCESS)
{
DbgPrint((DPRINT_HWDETECT, "RegSetValue() failed (Error %u)\n", (int)Error));
}
/* Set 'Identifier' value (CPU and FPU) */
DbgPrint((DPRINT_HWDETECT, "Identifier: %s\n", Identifier));
Error = RegSetValue(CpuInstKey,
"Identifier",
REG_SZ,
(PU8)Identifier,
strlen(Identifier) + 1);
if (Error != ERROR_SUCCESS)
{
DbgPrint((DPRINT_HWDETECT, "RegSetValue() failed (Error %u)\n", (int)Error));
}
Error = RegSetValue(FpuInstKey,
"Identifier",
REG_SZ,
(PU8)Identifier,
strlen(Identifier) + 1);
if (Error != ERROR_SUCCESS)
{
DbgPrint((DPRINT_HWDETECT, "RegSetValue() failed (Error %u)\n", (int)Error));
}
/* Set 'VendorIdentifier' value (CPU only) */
DbgPrint((DPRINT_HWDETECT, "Vendor Identifier: %s\n", VendorIdentifier));
Error = RegSetValue(CpuInstKey,
"VendorIdentifier",
REG_SZ,
(PU8)VendorIdentifier,
strlen(VendorIdentifier) + 1);
if (Error != ERROR_SUCCESS)
{
DbgPrint((DPRINT_HWDETECT, "RegSetValue() failed (Error %u)\n", (int)Error));
}
/* FIXME: Set 'Update Signature' value (CPU only) */
/* FIXME: Set 'Update Status' value (CPU only) */
/* Set '~MHz' value (CPU only) */
if (SupportTSC)
{
CpuSpeed = GetCpuSpeed();
Error = RegSetValue(CpuInstKey,
"~MHz",
REG_DWORD,
(PU8)&CpuSpeed,
sizeof(U32));
if (Error != ERROR_SUCCESS)
{
DbgPrint((DPRINT_HWDETECT, "RegSetValue() failed (Error %u)\n", (int)Error));
}
}
}
static VOID
SetMpsProcessor(HKEY CpuKey,
HKEY FpuKey,
PMP_PROCESSOR_ENTRY CpuEntry)
{
char VendorIdentifier[13];
char Identifier[64];
char Buffer[8];
U32 FeatureSet;
HKEY CpuInstKey;
HKEY FpuInstKey;
U32 eax = 0;
U32 ebx = 0;
U32 ecx = 0;
U32 edx = 0;
U32 *Ptr;
S32 Error;
U32 CpuSpeed;
/* Get processor instance number */
sprintf(Buffer, "%u", CpuEntry->LocalApicId);
/* Create the CPU instance key */
Error = RegCreateKey(CpuKey,
Buffer,
&CpuInstKey);
if (Error != ERROR_SUCCESS)
{
DbgPrint((DPRINT_HWDETECT, "RegCreateKey() failed (Error %u)\n", (int)Error));
return;
}
/* Create the FPU instance key */
Error = RegCreateKey(FpuKey,
Buffer,
&FpuInstKey);
if (Error != ERROR_SUCCESS)
{
DbgPrint((DPRINT_HWDETECT, "RegCreateKey() failed (Error %u)\n", (int)Error));
return;
}
/* Get 'VendorIdentifier' */
GetCpuid(0, &eax, &ebx, &ecx, &edx);
VendorIdentifier[12] = 0;
Ptr = (U32*)&VendorIdentifier[0];
*Ptr = ebx;
Ptr++;
*Ptr = edx;
Ptr++;
*Ptr = ecx;
/* Get 'Identifier' */
sprintf(Identifier,
"x86 Family %u Model %u Stepping %u",
(U32)((CpuEntry->CpuSignature >> 8) & 0x0F),
(U32)((CpuEntry->CpuSignature >> 4) & 0x0F),
(U32)(CpuEntry->CpuSignature & 0x0F));
/* Get FeatureSet */
FeatureSet = CpuEntry->FeatureFlags;
/* Set 'Configuration Data' value (CPU and FPU) */
SetComponentInformation(CpuInstKey,
0,
CpuEntry->LocalApicId,
1 << CpuEntry->LocalApicId);
SetComponentInformation(FpuInstKey,
0,
CpuEntry->LocalApicId,
1 << CpuEntry->LocalApicId);
/* Set 'FeatureSet' value (CPU only) */
DbgPrint((DPRINT_HWDETECT, "FeatureSet: %x\n", FeatureSet));
Error = RegSetValue(CpuInstKey,
"FeatureSet",
REG_DWORD,
(PU8)&FeatureSet,
sizeof(U32));
if (Error != ERROR_SUCCESS)
{
DbgPrint((DPRINT_HWDETECT, "RegSetValue() failed (Error %u)\n", (int)Error));
}
/* Set 'Identifier' value (CPU and FPU) */
DbgPrint((DPRINT_HWDETECT, "Identifier: %s\n", Identifier));
Error = RegSetValue(CpuInstKey,
"Identifier",
REG_SZ,
(PU8)Identifier,
strlen(Identifier) + 1);
if (Error != ERROR_SUCCESS)
{
DbgPrint((DPRINT_HWDETECT, "RegSetValue() failed (Error %u)\n", (int)Error));
}
Error = RegSetValue(FpuInstKey,
"Identifier",
REG_SZ,
(PU8)Identifier,
strlen(Identifier) + 1);
if (Error != ERROR_SUCCESS)
{
DbgPrint((DPRINT_HWDETECT, "RegSetValue() failed (Error %u)\n", (int)Error));
}
/* Set 'VendorIdentifier' value (CPU only) */
DbgPrint((DPRINT_HWDETECT, "Vendor Identifier: %s\n", VendorIdentifier));
Error = RegSetValue(CpuInstKey,
"VendorIdentifier",
REG_SZ,
(PU8)VendorIdentifier,
strlen(VendorIdentifier) + 1);
if (Error != ERROR_SUCCESS)
{
DbgPrint((DPRINT_HWDETECT, "RegSetValue() failed (Error %u)\n", (int)Error));
}
/* FIXME: Set 'Update Signature' value (CPU only) */
/* FIXME: Set 'Update Status' value (CPU only) */
/* Set '~MHz' value (CPU only) */
if (((CpuEntry->CpuSignature >> 8) & 0x0F) >= 5)
{
CpuSpeed = GetCpuSpeed();
Error = RegSetValue(CpuInstKey,
"~MHz",
REG_DWORD,
(PU8)&CpuSpeed,
sizeof(U32));
if (Error != ERROR_SUCCESS)
{
DbgPrint((DPRINT_HWDETECT, "RegSetValue() failed (Error %u)\n", (int)Error));
}
}
}
static PMP_FLOATING_POINT_TABLE
GetMpFloatingPointTable(VOID)
{
PMP_FLOATING_POINT_TABLE FpTable;
char *Ptr;
U8 Sum;
U32 Length;
U32 i;
FpTable = (PMP_FLOATING_POINT_TABLE)0xF0000;
while ((U32)FpTable < 0x100000)
{
if (FpTable->Signature == MP_FP_SIGNATURE)
{
Length = FpTable->Length * 0x10;
Ptr = (char *)FpTable;
Sum = 0;
for (i = 0; i < Length; i++)
{
Sum += Ptr[i];
}
DbgPrint((DPRINT_HWDETECT,
"Checksum: %u\n",
Sum));
if (Sum != 0)
{
DbgPrint((DPRINT_HWDETECT,
"Invalid MP floating point checksum: %u\n",
Sum));
return NULL;
}
return FpTable;
}
FpTable = (PMP_FLOATING_POINT_TABLE)((U32)FpTable + 0x10);
}
return NULL;
}
static PMP_CONFIGURATION_TABLE
GetMpConfigurationTable(PMP_FLOATING_POINT_TABLE FpTable)
{
PMP_CONFIGURATION_TABLE ConfigTable;
char *Ptr;
U8 Sum;
U32 Length;
U32 i;
if (FpTable->FeatureByte[0] != 0 ||
FpTable->PhysicalAddressPointer == 0)
return NULL;
ConfigTable = (PMP_CONFIGURATION_TABLE)FpTable->PhysicalAddressPointer;
if (ConfigTable->Signature != MP_CT_SIGNATURE)
return NULL;
DbgPrint((DPRINT_HWDETECT,
"MP Configuration Table at: %x\n",
(U32)ConfigTable));
/* Calculate base table checksum */
Length = ConfigTable->BaseTableLength;
Ptr = (char *)ConfigTable;
Sum = 0;
for (i = 0; i < Length; i++)
{
Sum += Ptr[i];
}
DbgPrint((DPRINT_HWDETECT,
"MP Configuration Table base checksum: %u\n",
Sum));
if (Sum != 0)
{
DbgPrint((DPRINT_HWDETECT,
"Invalid MP Configuration Table base checksum: %u\n",
Sum));
return NULL;
}
if (ConfigTable->ExtendedTableLength != 0)
{
/* FIXME: Check extended table */
}
return ConfigTable;
}
static BOOL
DetectMps(HKEY CpuKey,
HKEY FpuKey)
{
PMP_FLOATING_POINT_TABLE FpTable;
PMP_CONFIGURATION_TABLE ConfigTable;
PMP_PROCESSOR_ENTRY CpuEntry;
char *Ptr;
U32 Offset;
/* Get floating point table */
FpTable = GetMpFloatingPointTable();
if (FpTable == NULL)
return FALSE;
DbgPrint((DPRINT_HWDETECT,
"MP Floating Point Table at: %x\n",
(U32)FpTable));
if (FpTable->FeatureByte[0] == 0)
{
/* Get configuration table */
ConfigTable = GetMpConfigurationTable(FpTable);
if (ConfigTable == NULL)
{
DbgPrint((DPRINT_HWDETECT,
"Failed to find the MP Configuration Table\n"));
return FALSE;
}
Offset = sizeof(MP_CONFIGURATION_TABLE);
while (Offset < ConfigTable->BaseTableLength)
{
Ptr = (char*)((U32)ConfigTable + Offset);
switch (*Ptr)
{
case 0:
CpuEntry = (PMP_PROCESSOR_ENTRY)Ptr;
DbgPrint((DPRINT_HWDETECT, "Processor Entry\n"));
DbgPrint((DPRINT_HWDETECT,
"APIC Id %u APIC Version %u Flags %x Signature %x Feature %x\n",
CpuEntry->LocalApicId,
CpuEntry->LocalApicVersion,
CpuEntry->CpuFlags,
CpuEntry->CpuSignature,
CpuEntry->FeatureFlags));
DbgPrint((DPRINT_HWDETECT,
"Processor %u: x86 Family %u Model %u Stepping %u\n",
CpuEntry->LocalApicId,
(U32)((CpuEntry->CpuSignature >> 8) & 0x0F),
(U32)((CpuEntry->CpuSignature >> 4) & 0x0F),
(U32)(CpuEntry->CpuSignature & 0x0F)));
SetMpsProcessor(CpuKey, FpuKey, CpuEntry);
Offset += 0x14;
break;
case 1:
DbgPrint((DPRINT_HWDETECT, "Bus Entry\n"));
Offset += 0x08;
break;
case 2:
DbgPrint((DPRINT_HWDETECT, "I/0 APIC Entry\n"));
Offset += 0x08;
break;
case 3:
DbgPrint((DPRINT_HWDETECT, "I/0 Interrupt Assignment Entry\n"));
Offset += 0x08;
break;
case 4:
DbgPrint((DPRINT_HWDETECT, "Local Interrupt Assignment Entry\n"));
Offset += 0x08;
break;
default:
DbgPrint((DPRINT_HWDETECT, "Unknown Entry %u\n",(U32)*Ptr));
return FALSE;
}
}
}
else
{
DbgPrint((DPRINT_HWDETECT,
"Unsupported MPS configuration: %x\n",
FpTable->FeatureByte[0]));
/* FIXME: Identify default configurations */
return FALSE;
}
return TRUE;
}
VOID
DetectCPUs(HKEY SystemKey)
{
HKEY CpuKey;
HKEY FpuKey;
S32 Error;
/* Create the 'CentralProcessor' key */
Error = RegCreateKey(SystemKey,
"CentralProcessor",
&CpuKey);
if (Error != ERROR_SUCCESS)
{
DbgPrint((DPRINT_HWDETECT, "RegCreateKey() failed (Error %u)\n", (int)Error));
return;
}
/* Create the 'FloatingPointProcessor' key */
Error = RegCreateKey(SystemKey,
"FloatingPointProcessor",
&FpuKey);
if (Error != ERROR_SUCCESS)
{
DbgPrint((DPRINT_HWDETECT, "RegCreateKey() failed (Error %u)\n", (int)Error));
return;
}
/* Detect CPUs */
if (!DetectMps(CpuKey, FpuKey))
{
DetectCPU(CpuKey, FpuKey);
}
}
/* EOF */

View File

@@ -0,0 +1,366 @@
/*
* FreeLoader
*
* Copyright (C) 2004 Eric Kohl
*
* 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.
*/
#include <freeldr.h>
#include <arch.h>
#include <rtl.h>
#include <debug.h>
#include <mm.h>
#include <portio.h>
#include "../../reactos/registry.h"
#include "hardware.h"
typedef struct _ROUTING_SLOT
{
U8 BusNumber;
U8 DeviceNumber;
U8 LinkA;
U16 BitmapA;
U8 LinkB;
U16 BitmapB;
U8 LinkC;
U16 BitmapC;
U8 LinkD;
U16 BitmapD;
U8 SlotNumber;
U8 Reserved;
} __attribute__((packed)) ROUTING_SLOT, *PROUTING_SLOT;
typedef struct _PCI_IRQ_ROUTING_TABLE
{
U32 Signature;
U16 Version;
U16 Size;
U8 RouterBus;
U8 RouterSlot;
U16 ExclusiveIRQs;
U32 CompatibleRouter;
U32 MiniportData;
U8 Reserved[11];
U8 Checksum;
ROUTING_SLOT Slot[1];
} __attribute__((packed)) PCI_IRQ_ROUTING_TABLE, *PPCI_IRQ_ROUTING_TABLE;
typedef struct _CM_PCI_BUS_DATA
{
U8 BusCount;
U16 PciVersion;
U8 HardwareMechanism;
} __attribute__((packed)) CM_PCI_BUS_DATA, *PCM_PCI_BUS_DATA;
static PPCI_IRQ_ROUTING_TABLE
GetPciIrqRoutingTable(VOID)
{
PPCI_IRQ_ROUTING_TABLE Table;
PU8 Ptr;
U32 Sum;
U32 i;
Table = (PPCI_IRQ_ROUTING_TABLE)0xF0000;
while ((U32)Table < 0x100000)
{
if (Table->Signature == 0x52495024)
{
DbgPrint((DPRINT_HWDETECT,
"Found signature\n"));
Ptr = (PU8)Table;
Sum = 0;
for (i = 0; i < Table->Size; i++)
{
Sum += Ptr[i];
}
if ((Sum & 0xFF) != 0)
{
DbgPrint((DPRINT_HWDETECT,
"Invalid routing table\n"));
return NULL;
}
DbgPrint((DPRINT_HWDETECT,
"Valid checksum\n"));
return Table;
}
Table = (PPCI_IRQ_ROUTING_TABLE)((U32)Table + 0x10);
}
return NULL;
}
static BOOL
FindPciBios(PCM_PCI_BUS_DATA BusData)
{
REGS RegsIn;
REGS RegsOut;
RegsIn.b.ah = 0xB1; /* Subfunction B1h */
RegsIn.b.al = 0x01; /* PCI BIOS present */
Int386(0x1A, &RegsIn, &RegsOut);
if (INT386_SUCCESS(RegsOut) && RegsOut.d.edx == 0x20494350 && RegsOut.b.ah == 0)
{
DbgPrint((DPRINT_HWDETECT, "Found PCI bios\n"));
DbgPrint((DPRINT_HWDETECT, "AL: %x\n", RegsOut.b.al));
DbgPrint((DPRINT_HWDETECT, "BH: %x\n", RegsOut.b.bh));
DbgPrint((DPRINT_HWDETECT, "BL: %x\n", RegsOut.b.bl));
DbgPrint((DPRINT_HWDETECT, "CL: %x\n", RegsOut.b.cl));
BusData->BusCount = RegsOut.b.cl + 1;
BusData->PciVersion = RegsOut.w.bx;
BusData->HardwareMechanism = RegsOut.b.cl;
return TRUE;
}
DbgPrint((DPRINT_HWDETECT, "No PCI bios found\n"));
return FALSE;
}
static VOID
DetectPciIrqRoutingTable(HKEY BusKey)
{
PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor;
PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
PPCI_IRQ_ROUTING_TABLE Table;
HKEY TableKey;
U32 Size;
S32 Error;
Table = GetPciIrqRoutingTable();
if (Table != NULL)
{
DbgPrint((DPRINT_HWDETECT, "Table size: %u\n", Table->Size));
Error = RegCreateKey(BusKey,
"RealModeIrqRoutingTable\\0",
&TableKey);
if (Error != ERROR_SUCCESS)
{
DbgPrint((DPRINT_HWDETECT, "RegCreateKey() failed (Error %u)\n", (int)Error));
return;
}
/* Set 'Component Information' */
SetComponentInformation(TableKey,
0x0,
0x0,
0xFFFFFFFF);
/* Set 'Identifier' value */
Error = RegSetValue(TableKey,
"Identifier",
REG_SZ,
(PU8)"PCI Real-mode IRQ Routing Table",
32);
if (Error != ERROR_SUCCESS)
{
DbgPrint((DPRINT_HWDETECT, "RegSetValue() failed (Error %u)\n", (int)Error));
return;
}
/* Set 'Configuration Data' value */
Size = sizeof(CM_FULL_RESOURCE_DESCRIPTOR) +
Table->Size;
FullResourceDescriptor = MmAllocateMemory(Size);
if (FullResourceDescriptor == NULL)
{
DbgPrint((DPRINT_HWDETECT,
"Failed to allocate resource descriptor\n"));
return;
}
/* Initialize resource descriptor */
memset(FullResourceDescriptor, 0, Size);
FullResourceDescriptor->InterfaceType = Isa;
FullResourceDescriptor->BusNumber = 0;
FullResourceDescriptor->PartialResourceList.Count = 1;
PartialDescriptor = &FullResourceDescriptor->PartialResourceList.PartialDescriptors[0];
PartialDescriptor->Type = CmResourceTypeDeviceSpecific;
PartialDescriptor->ShareDisposition = CmResourceShareUndetermined;
PartialDescriptor->u.DeviceSpecificData.DataSize = Table->Size;
memcpy(((PVOID)FullResourceDescriptor) + sizeof(CM_FULL_RESOURCE_DESCRIPTOR),
Table,
Table->Size);
/* Set 'Configuration Data' value */
Error = RegSetValue(TableKey,
"Configuration Data",
REG_FULL_RESOURCE_DESCRIPTOR,
(PU8) FullResourceDescriptor,
Size);
MmFreeMemory(FullResourceDescriptor);
if (Error != ERROR_SUCCESS)
{
DbgPrint((DPRINT_HWDETECT,
"RegSetValue(Configuration Data) failed (Error %u)\n",
(int)Error));
return;
}
}
}
VOID
DetectPciBios(HKEY SystemKey, U32 *BusNumber)
{
PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor;
CM_PCI_BUS_DATA BusData;
char Buffer[80];
HKEY BiosKey;
U32 Size;
S32 Error;
#if 0
HKEY BusKey;
U32 i;
#endif
/* Report the PCI BIOS */
if (FindPciBios(&BusData))
{
/* Create new bus key */
sprintf(Buffer,
"MultifunctionAdapter\\%u", *BusNumber);
Error = RegCreateKey(SystemKey,
Buffer,
&BiosKey);
if (Error != ERROR_SUCCESS)
{
DbgPrint((DPRINT_HWDETECT, "RegCreateKey() failed (Error %u)\n", (int)Error));
return;
}
/* Set 'Component Information' */
SetComponentInformation(BiosKey,
0x0,
0x0,
0xFFFFFFFF);
/* Increment bus number */
(*BusNumber)++;
/* Set 'Identifier' value */
Error = RegSetValue(BiosKey,
"Identifier",
REG_SZ,
(PU8)"PCI BIOS",
9);
if (Error != ERROR_SUCCESS)
{
DbgPrint((DPRINT_HWDETECT, "RegSetValue() failed (Error %u)\n", (int)Error));
return;
}
/* Set 'Configuration Data' value */
Size = sizeof(CM_FULL_RESOURCE_DESCRIPTOR) -
sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);
FullResourceDescriptor = MmAllocateMemory(Size);
if (FullResourceDescriptor == NULL)
{
DbgPrint((DPRINT_HWDETECT,
"Failed to allocate resource descriptor\n"));
return;
}
/* Initialize resource descriptor */
memset(FullResourceDescriptor, 0, Size);
FullResourceDescriptor->InterfaceType = Internal;
FullResourceDescriptor->BusNumber = 0;
FullResourceDescriptor->PartialResourceList.Count = 0;
/* Set 'Configuration Data' value */
Error = RegSetValue(BiosKey,
"Configuration Data",
REG_FULL_RESOURCE_DESCRIPTOR,
(PU8) FullResourceDescriptor,
Size);
MmFreeMemory(FullResourceDescriptor);
if (Error != ERROR_SUCCESS)
{
DbgPrint((DPRINT_HWDETECT,
"RegSetValue(Configuration Data) failed (Error %u)\n",
(int)Error));
return;
}
DetectPciIrqRoutingTable(BiosKey);
#if 0
/*
* FIXME:
* Enabling this piece of code will corrupt the boot sequence!
* This is probably caused by a bug in the registry code!
*/
/* Report PCI buses */
for (i = 0; i < (U32)BusData.BusCount; i++)
{
sprintf(Buffer,
"MultifunctionAdapter\\%u", *BusNumber);
Error = RegCreateKey(SystemKey,
Buffer,
&BusKey);
if (Error != ERROR_SUCCESS)
{
DbgPrint((DPRINT_HWDETECT, "RegCreateKey() failed (Error %u)\n", (int)Error));
printf("RegCreateKey() failed (Error %u)\n", (int)Error);
return;
}
/* Set 'Component Information' */
SetComponentInformation(BusKey,
0x0,
0x0,
0xFFFFFFFF);
/* Increment bus number */
(*BusNumber)++;
/* Set 'Identifier' value */
Error = RegSetValue(BusKey,
"Identifier",
REG_SZ,
(PU8)"PCI",
4);
if (Error != ERROR_SUCCESS)
{
DbgPrint((DPRINT_HWDETECT, "RegSetValue() failed (Error %u)\n", (int)Error));
return;
}
}
#endif
}
}
/* EOF */

View File

@@ -0,0 +1,131 @@
/*
* FreeLoader
* Copyright (C) 2003 Eric Kohl <ekohl@rz-online.de>
*
* 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.
*/
.text
.code16
#define ASM
#include <arch.h>
/*
* U32 CpuidSupported(VOID);
*
* RETURNS:
* 0x00000001: CPU supports the CPUID instruction
* 0x00000300: Found 80386 CPU
* 0x00000400: Found 80486 CPU without CPUID support
*/
EXTERN(_CpuidSupported)
.code32
pushl %ecx /* save ECX */
pushfl /* push original EFLAGS */
popl %eax /* get original EFLAGS */
movl %eax,%ecx /* save original EFLAGS */
xorl $0x40000,%eax /* flip AC bit in EFLAGS */
pushl %eax /* save new EFLAGS value on stack */
popfl /* replace current EFLAGS value */
pushfl /* get new EFLAGS */
popl %eax /* store new EFLAGS in EAX */
xorl %ecx, %eax /* can't toggle AC bit, processor=80386 */
movl $0x300,%eax /* return processor id */
jz NoCpuid /* jump if 80386 processor */
pushl %ecx
popfl /* restore AC bit in EFLAGS first */
movl %ecx,%eax /* get original EFLAGS */
xorl $0x200000,%eax /* flip ID bit in EFLAGS */
pushl %eax /* save new EFLAGS value on stack */
popfl /* replace current EFLAGS value */
pushfl /* get new EFLAGS */
popl %eax /* store new EFLAGS in EAX */
xorl %ecx,%eax /* can't toggle ID bit, */
movl $0x400,%eax /* return processor id */
je NoCpuid /* processor=80486 */
movl $1,%eax /* CPUID supported */
NoCpuid:
pushl %ecx
popfl /* restore EFLAGS */
popl %ecx /* retore ECX */
ret
/*
* VOID GetCpuid(U32 Level, U32 *eax, U32 *ebx, U32 *ecx, U32 *edx);
*/
EXTERN(_GetCpuid)
.code32
pushl %ebp
movl %esp,%ebp
pushl %eax
pushl %ebx
pushl %ecx
pushl %edx
pushl %esi
movl 0x08(%ebp),%eax
cpuid
movl 0x0C(%ebp),%esi
movl %eax,(%esi)
movl 0x10(%ebp),%esi
movl %ebx,(%esi)
movl 0x14(%ebp),%esi
movl %ecx,(%esi)
movl 0x18(%ebp),%esi
movl %edx,(%esi)
popl %esi
popl %edx
popl %ecx
popl %ebx
popl %eax
movl %ebp,%esp
popl %ebp
ret
/*
* U64 RDTSC(VOID);
*/
EXTERN(_RDTSC)
.code32
rdtsc
ret
/* EOF */

View File

@@ -0,0 +1,175 @@
/*
* FreeLoader
* Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>
*
* 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.
*/
#include "freeldr.h"
#include "disk.h"
#include "rtl.h"
#include "arch.h"
#include "debug.h"
#include "portio.h"
#include "machine.h"
/////////////////////////////////////////////////////////////////////////////////////////////
// FUNCTIONS
/////////////////////////////////////////////////////////////////////////////////////////////
#ifdef __i386__
BOOL DiskResetController(U32 DriveNumber)
{
REGS RegsIn;
REGS RegsOut;
DbgPrint((DPRINT_DISK, "DiskResetController(0x%x) DISK OPERATION FAILED -- RESETTING CONTROLLER\n", DriveNumber));
// BIOS Int 13h, function 0 - Reset disk system
// AH = 00h
// DL = drive (if bit 7 is set both hard disks and floppy disks reset)
// Return:
// AH = status
// CF clear if successful
// CF set on error
RegsIn.b.ah = 0x00;
RegsIn.b.dl = DriveNumber;
// Reset the disk controller
Int386(0x13, &RegsIn, &RegsOut);
return INT386_SUCCESS(RegsOut);
}
BOOL DiskInt13ExtensionsSupported(U32 DriveNumber)
{
REGS RegsIn;
REGS RegsOut;
DbgPrint((DPRINT_DISK, "DiskInt13ExtensionsSupported()\n"));
// IBM/MS INT 13 Extensions - INSTALLATION CHECK
// AH = 41h
// BX = 55AAh
// DL = drive (80h-FFh)
// Return:
// CF set on error (extensions not supported)
// AH = 01h (invalid function)
// CF clear if successful
// BX = AA55h if installed
// AH = major version of extensions
// 01h = 1.x
// 20h = 2.0 / EDD-1.0
// 21h = 2.1 / EDD-1.1
// 30h = EDD-3.0
// AL = internal use
// CX = API subset support bitmap
// DH = extension version (v2.0+ ??? -- not present in 1.x)
//
// Bitfields for IBM/MS INT 13 Extensions API support bitmap
// Bit 0, extended disk access functions (AH=42h-44h,47h,48h) supported
// Bit 1, removable drive controller functions (AH=45h,46h,48h,49h,INT 15/AH=52h) supported
// Bit 2, enhanced disk drive (EDD) functions (AH=48h,AH=4Eh) supported
// extended drive parameter table is valid
// Bits 3-15 reserved
RegsIn.b.ah = 0x41;
RegsIn.w.bx = 0x55AA;
RegsIn.b.dl = DriveNumber;
// Reset the disk controller
Int386(0x13, &RegsIn, &RegsOut);
if (!INT386_SUCCESS(RegsOut))
{
// CF set on error (extensions not supported)
return FALSE;
}
if (RegsOut.w.bx != 0xAA55)
{
// BX = AA55h if installed
return FALSE;
}
// Note:
// The original check is too strict because some BIOSes report that
// extended disk access functions are not suported when booting
// from a CD (e.g. Phoenix BIOS v6.00PG). Argh!
#if 0
if (!(RegsOut.w.cx & 0x0001))
{
// CX = API subset support bitmap
// Bit 0, extended disk access functions (AH=42h-44h,47h,48h) supported
return FALSE;
}
#endif
// Use this relaxed check instead
if (RegsOut.w.cx == 0x0000)
{
// CX = API subset support bitmap
return FALSE;
}
return TRUE;
}
VOID DiskStopFloppyMotor(VOID)
{
WRITE_PORT_UCHAR((PUCHAR)0x3F2, 0);
}
BOOL DiskGetExtendedDriveParameters(U32 DriveNumber, PVOID Buffer, U16 BufferSize)
{
REGS RegsIn;
REGS RegsOut;
PU16 Ptr = (PU16)(BIOSCALLBUFFER);
DbgPrint((DPRINT_DISK, "DiskGetExtendedDriveParameters()\n"));
// Initialize transfer buffer
*Ptr = BufferSize;
// BIOS Int 13h, function 48h - Get drive parameters
// AH = 48h
// DL = drive (bit 7 set for hard disk)
// DS:SI = result buffer
// Return:
// CF set on error
// AH = status (07h)
// CF clear if successful
// AH = 00h
// DS:SI -> result buffer
RegsIn.b.ah = 0x48;
RegsIn.b.dl = DriveNumber;
RegsIn.x.ds = BIOSCALLBUFSEGMENT; // DS:SI -> result buffer
RegsIn.w.si = BIOSCALLBUFOFFSET;
// Get drive parameters
Int386(0x13, &RegsIn, &RegsOut);
if (!INT386_SUCCESS(RegsOut))
{
return FALSE;
}
memcpy(Buffer, Ptr, BufferSize);
return TRUE;
}
#endif // defined __i386__

View File

@@ -0,0 +1,224 @@
/*
* FreeLoader
* Copyright (C) 1998-2002 Brian Palmer <brianp@sginet.com>
*
* 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.
*/
.text
.code16
#define ASM
#include <arch.h>
.p2align 2 /* force 4-byte alignment */
EXTERN(i386idt)
/* Exception 0 - Divide By Zero */
.word i386DivideByZero /* Offset 0 - 15 */
.word 0x0008 /* Selector */
.word 0x8e00 /* Flags, Zero Byte */
.word 0x0000 /* Offset 16 - 31 */
/* Exception 1 - Debug Exception */
.word i386DebugException /* Offset 0 - 15 */
.word 0x0008 /* Selector */
.word 0x8e00 /* Zero byte, flags */
.word 0x0000 /* Offset 16 - 31 */
/* Exception 2 - NMI */
.word i386NMIException /* Offset 0 - 15 */
.word 0x0008 /* Selector */
.word 0x8e00 /* Zero byte, flags */
.word 0x0000 /* Offset 16 - 31 */
/* Exception 3 - Breakpoint (INT 3) */
.word i386Breakpoint /* Offset 0 - 15 */
.word 0x0008 /* Selector */
.word 0x8e00 /* Zero byte, flags */
.word 0x0000 /* Offset 16 - 31 */
/* Exception 4 - Overflow (INTO with EFLAGS[OF] set) */
.word i386Overflow /* Offset 0 - 15 */
.word 0x0008 /* Selector */
.word 0x8e00 /* Zero byte, flags */
.word 0x0000 /* Offset 16 - 31 */
/* Exception 5 - Bound Exception */
.word i386BoundException /* Offset 0 - 15 */
.word 0x0008 /* Selector */
.word 0x8e00 /* Zero byte, flags */
.word 0x0000 /* Offset 16 - 31 */
/* Exception 6 - Invalid Opcode */
.word i386InvalidOpcode /* Offset 0 - 15 */
.word 0x0008 /* Selector */
.word 0x8e00 /* Zero byte, flags */
.word 0x0000 /* Offset 16 - 31 */
/* Exception 7 - FPU Not Available */
.word i386FPUNotAvailable /* Offset 0 - 15 */
.word 0x0008 /* Selector */
.word 0x8e00 /* Zero byte, flags */
.word 0x0000 /* Offset 16 - 31 */
/* Exception 8 - Double Fault */
.word i386DoubleFault /* Offset 0 - 15 */
.word 0x0008 /* Selector */
.word 0x8e00 /* Zero byte, flags */
.word 0x0000 /* Offset 16 - 31 */
/* Exception 9 - Coprocessor Segment Overrun */
.word i386CoprocessorSegment /* Offset 0 - 15 */
.word 0x0008 /* Selector */
.word 0x8e00 /* Zero byte, flags */
.word 0x0000 /* Offset 16 - 31 */
/* Exception 10 (0x0A) - Invalid TSS */
.word i386InvalidTSS /* Offset 0 - 15 */
.word 0x0008 /* Selector */
.word 0x8e00 /* Zero byte, flags */
.word 0x0000 /* Offset 16 - 31 */
/* Exception 11 (0x0B) - Segment Not Present */
.word i386SegmentNotPresent /* Offset 0 - 15 */
.word 0x0008 /* Selector */
.word 0x8e00 /* Zero byte, flags */
.word 0x0000 /* Offset 16 - 31 */
/* Exception 12 (0x0C) - Stack Exception */
.word i386StackException /* Offset 0 - 15 */
.word 0x0008 /* Selector */
.word 0x8e00 /* Zero byte, flags */
.word 0x0000 /* Offset 16 - 31 */
/* Exception 13 (0x0D) - General Protection Fault */
.word i386GeneralProtectionFault /* Offset 0 - 15 */
.word 0x0008 /* Selector */
.word 0x8e00 /* Zero byte, flags */
.word 0x0000 /* Offset 16 - 31 */
/* Exception 14 (0x0E) - Page Fault */
.word i386PageFault /* Offset 0 - 15 */
.word 0x0008 /* Selector */
.word 0x8e00 /* Zero byte, flags */
.word 0x0000 /* Offset 16 - 31 */
/* Exception 15 (0x0F) - Reserved */
.word 0x0000 /* Offset 0 - 15 */
.word 0x0000 /* Selector */
.word 0x0000 /* Zero byte, flags */
.word 0x0000 /* Offset 16 - 31 */
/* Exception 16 (0x10) - Coprocessor Error */
.word i386CoprocessorError /* Offset 0 - 15 */
.word 0x0008 /* Selector */
.word 0x8e00 /* Zero byte, flags */
.word 0x0000 /* Offset 16 - 31 */
/* Exception 17 (0x11) - Alignment Check */
.word i386AlignmentCheck /* Offset 0 - 15 */
.word 0x0008 /* Selector */
.word 0x8e00 /* Zero byte, flags */
.word 0x0000 /* Offset 16 - 31 */
/* Exception 18 (0x12) - Machine Check */
.word i386MachineCheck /* Offset 0 - 15 */
.word 0x0008 /* Selector */
.word 0x8e00 /* Zero byte, flags */
.word 0x0000 /* Offset 16 - 31 */
/* Exception 19 (0x13) - Reserved */
.word 0x0000 /* Offset 0 - 15 */
.word 0x0000 /* Selector */
.word 0x0000 /* Zero byte, flags */
.word 0x0000 /* Offset 16 - 31 */
/* Exception 20 (0x14) - Reserved */
.word 0x0000 /* Offset 0 - 15 */
.word 0x0000 /* Selector */
.word 0x0000 /* Zero byte, flags */
.word 0x0000 /* Offset 16 - 31 */
/* Exception 21 (0x15) - Reserved */
.word 0x0000 /* Offset 0 - 15 */
.word 0x0000 /* Selector */
.word 0x0000 /* Zero byte, flags */
.word 0x0000 /* Offset 16 - 31 */
/* Exception 22 (0x16) - Reserved */
.word 0x0000 /* Offset 0 - 15 */
.word 0x0000 /* Selector */
.word 0x0000 /* Zero byte, flags */
.word 0x0000 /* Offset 16 - 31 */
/* Exception 23 (0x17) - Reserved */
.word 0x0000 /* Offset 0 - 15 */
.word 0x0000 /* Selector */
.word 0x0000 /* Zero byte, flags */
.word 0x0000 /* Offset 16 - 31 */
/* Exception 24 (0x18) - Reserved */
.word 0x0000 /* Offset 0 - 15 */
.word 0x0000 /* Selector */
.word 0x0000 /* Zero byte, flags */
.word 0x0000 /* Offset 16 - 31 */
/* Exception 25 (0x19) - Reserved */
.word 0x0000 /* Offset 0 - 15 */
.word 0x0000 /* Selector */
.word 0x0000 /* Zero byte, flags */
.word 0x0000 /* Offset 16 - 31 */
/* Exception 26 (0x1A) - Reserved */
.word 0x0000 /* Offset 0 - 15 */
.word 0x0000 /* Selector */
.word 0x0000 /* Zero byte, flags */
.word 0x0000 /* Offset 16 - 31 */
/* Exception 27 (0x1B) - Reserved */
.word 0x0000 /* Offset 0 - 15 */
.word 0x0000 /* Selector */
.word 0x0000 /* Zero byte, flags */
.word 0x0000 /* Offset 16 - 31 */
/* Exception 28 (0x1C) - Reserved */
.word 0x0000 /* Offset 0 - 15 */
.word 0x0000 /* Selector */
.word 0x0000 /* Zero byte, flags */
.word 0x0000 /* Offset 16 - 31 */
/* Exception 29 (0x1D) - Reserved */
.word 0x0000 /* Offset 0 - 15 */
.word 0x0000 /* Selector */
.word 0x0000 /* Zero byte, flags */
.word 0x0000 /* Offset 16 - 31 */
/* Exception 30 (0x1E) - Reserved */
.word 0x0000 /* Offset 0 - 15 */
.word 0x0000 /* Selector */
.word 0x0000 /* Zero byte, flags */
.word 0x0000 /* Offset 16 - 31 */
/* Exception 31 (0x1F) - Reserved */
.word 0x0000 /* Offset 0 - 15 */
.word 0x0000 /* Selector */
.word 0x0000 /* Zero byte, flags */
.word 0x0000 /* Offset 16 - 31 */
/* IDT table pointer */
EXTERN(i386idtptr)
.word (i386idtptr-i386idt) /* Limit */
.long i386idt /* Base Address */

View File

@@ -0,0 +1,257 @@
/*
* FreeLoader
* Copyright (C) 2003 Eric Kohl <ekohl@rz-online.de>
*
* 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.
*/
.text
.code16
#define ASM
#include <arch.h>
/*
* U32 PnpBiosSupported(VOID);
*
* RETURNS:
*/
_pnp_bios_entry_point:
.long 0
_pnp_bios_data_segment:
.word 0
EXTERN(_PnpBiosSupported)
.code32
pushl %edi
pushl %esi
pushl %ecx
pushl %edx
xorl %edi,%edi
/* init esi */
movl $0xF0000,%esi
pnp_again:
movl (%esi),%eax
cmp $0x506E5024,%eax /* "$PnP" */
je pnp_found
cmp $0xFFFF0,%esi
je pnp_not_found
pnp_add:
addl $0x10,%esi
jmp pnp_again
pnp_found:
/* first calculate the checksum */
pushl %esi
pushl $0x21
popl %ecx
xorl %edx, %edx
pnp_loop:
lodsb
addb %al,%dl
loopl pnp_loop
testb %dl, %dl
popl %esi
jnz pnp_add
movl %esi,%edi
/* Calculate the bios entry point (far pointer) */
xorl %eax,%eax
movw 0x0F(%esi),%ax
shll $16,%eax
movw 0x0D(%esi),%ax
movl %eax,_pnp_bios_entry_point
/* Store bios data segment */
movw 0x1B(%esi),%ax
movw %ax,_pnp_bios_data_segment
pnp_not_found:
movl %edi,%eax
popl %edx
popl %ecx
popl %esi
popl %edi
ret
/*
* U32 PnpBiosGetDeviceNodeCount(U32 *NodeSize, U32 *NodeCount);
*
* RETURNS:
*/
_pnp_result:
.long 0
_pnp_node_size:
.word 0
_pnp_node_count:
.word 0
EXTERN(_PnpBiosGetDeviceNodeCount)
.code32
pushl %ebp
movl %esp,%ebp
pushal
push %es
call switch_to_real
.code16
movw _pnp_bios_data_segment,%ax
pushw %ax
pushw %cs
movw $(_pnp_node_size),%ax
pushw %ax
pushw %cs
movw $(_pnp_node_count),%ax
pushw %ax
pushw $0
lcall *_pnp_bios_entry_point
addw $12,%sp
movzwl %ax,%ecx
movl %ecx,_pnp_result
call switch_to_prot
.code32
movl 0x08(%ebp),%esi
movw _pnp_node_size,%ax
movzwl %ax,%ecx
movl %ecx, (%esi)
movl 0x0C(%ebp),%esi
movw _pnp_node_count,%ax
movzwl %ax,%ecx
movl %eax, (%esi)
pop %es
popal
movl %ebp,%esp
popl %ebp
movl _pnp_result,%eax
ret
/*
* U32 PnpBiosGetDeviceNode(U8 *NodeId, U8 *NodeBuffer);
*
* RETURNS:
*/
_pnp_buffer_segment:
.word 0
_pnp_buffer_offset:
.word 0
_pnp_node_number:
.byte 0
EXTERN(_PnpBiosGetDeviceNode)
.code32
pushl %ebp
movl %esp,%ebp
pushal
push %es
/* get current node number */
movl 0x08(%ebp),%esi
movb (%esi),%al
movb %al,_pnp_node_number
/* convert pointer to node buffer to segment/offset */
movl 0x0C(%ebp),%eax
shrl $4,%eax
andl $0xf000,%eax
movw %ax,_pnp_buffer_segment
movl 0x0C(%ebp),%eax
andl $0xffff,%eax
movw %ax,_pnp_buffer_offset
call switch_to_real
.code16
/* push bios segment */
movw _pnp_bios_data_segment,%ax
pushw %ax
/* push control flag */
pushw $0x0001
/* push pointer to node buffer (segment/offset) */
movw _pnp_buffer_segment,%ax
pushw %ax
movw _pnp_buffer_offset,%ax
pushw %ax
/* push pointer to node number (segment/offset) */
pushw %cs
movw $(_pnp_node_number),%ax
pushw %ax
/* push function number */
pushw $1
/* call entry point */
lcall *_pnp_bios_entry_point
addw $14,%sp
movzwl %ax,%ecx
movl %ecx,_pnp_result
call switch_to_prot
.code32
/* update node number */
movl 0x08(%ebp),%esi
movb _pnp_node_number,%al
movb %al,(%esi)
pop %es
popal
movl %ebp,%esp
popl %ebp
movl _pnp_result,%eax
ret
/* EOF */

View File

@@ -12,14 +12,17 @@
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
* 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.
*/
#include <freeldr.h>
#include <arch.h>
#include <rtl.h>
#include <portio.h>
void PcBeep(void)
void beep(void)
{
sound(700);
delay(200);
@@ -47,12 +50,12 @@ void delay(unsigned msec)
// interrupt from the AT real-time clock chip which is available on INT 70;
// because newer BIOSes may have much more precise timers available, it is
// not possible to use this function accurately for very short delays unless
// the precise behavior of the BIOS is known (or found through testing)
// the precise behavior of the BIOS is known (or found through testing)
while (msec)
{
msec_this = msec;
if (msec_this > 4000)
{
msec_this = 4000;

View File

@@ -0,0 +1,942 @@
/*
* FreeLoader
* Copyright (C) 1998-2002 Brian Palmer <brianp@sginet.com>
*
* 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.
*/
.text
.code16
#define ASM
#include <arch.h>
#include <version.h>
#define SCREEN_ATTR 0x1f /* Bright white on blue background */
.macro SAVE_CPU_REGS
movl %eax,i386_EAX
movl %ebx,i386_EBX
movl %ecx,i386_ECX
movl %edx,i386_EDX
movl %esp,i386_ESP
movl %ebp,i386_EBP
movl %esi,i386_ESI
movl %edi,i386_EDI
movw %ds,%ax
movw %ax,i386_DS
movw %es,%ax
movw %ax,i386_ES
movw %fs,%ax
movw %ax,i386_FS
movw %gs,%ax
movw %ax,i386_GS
movw %ss,%ax
movw %ax,i386_SS
popl %eax
movl %eax,i386_EIP
popl %eax
movw %ax,i386_CS
popl %eax
movl %eax,i386_EFLAGS
movl %cr0,%eax
movl %eax,i386_CR0
//movl %cr1,%eax
//movl %eax,i386_CR1
movl %cr2,%eax
movl %eax,i386_CR2
movl %cr3,%eax
movl %eax,i386_CR3
movl %dr0,%eax
movl %eax,i386_DR0
movl %dr1,%eax
movl %eax,i386_DR1
movl %dr2,%eax
movl %eax,i386_DR2
movl %dr3,%eax
movl %eax,i386_DR3
movl %dr6,%eax
movl %eax,i386_DR6
movl %dr7,%eax
movl %eax,i386_DR7
sgdt i386_GDTR
sidt i386_IDTR
sldt i386_LDTR
str i386_TR
.endm
i386ExceptionHandlerText:
.ascii "An error occured in FreeLoader\n"
.ascii VERSION
.ascii "\n"
.asciz "Report this error to the ReactOS Development mailing list <ros-dev@reactos.com>\n\n"
i386DivideByZeroText:
.asciz "Exception 00: DIVIDE BY ZERO\n\n"
i386DebugExceptionText:
.asciz "Exception 01: DEBUG EXCEPTION\n\n"
i386NMIExceptionText:
.asciz "Exception 02: NON-MASKABLE INTERRUPT EXCEPTION\n\n"
i386BreakpointText:
.asciz "Exception 03: BREAKPOINT (INT 3)\n\n"
i386OverflowText:
.asciz "Exception 04: OVERFLOW\n\n"
i386BoundExceptionText:
.asciz "Exception 05: BOUND EXCEPTION\n\n"
i386InvalidOpcodeText:
.asciz "Exception 06: INVALID OPCODE\n\n"
i386FPUNotAvailableText:
.asciz "Exception 07: FPU NOT AVAILABLE\n\n"
i386DoubleFaultText:
.asciz "Exception 08: DOUBLE FAULT\n\n"
i386CoprocessorSegmentText:
.asciz "Exception 09: COPROCESSOR SEGMENT OVERRUN\n\n"
i386InvalidTSSText:
.asciz "Exception 0A: INVALID TSS\n\n"
i386SegmentNotPresentText:
.asciz "Exception 0B: SEGMENT NOT PRESENT\n\n"
i386StackExceptionText:
.asciz "Exception 0C: STACK EXCEPTION\n\n"
i386GeneralProtectionFaultText:
.asciz "Exception 0D: GENERAL PROTECTION FAULT\n\n"
i386PageFaultText:
.asciz "Exception 0E: PAGE FAULT\n\n"
i386CoprocessorErrorText:
.asciz "Exception 10: COPROCESSOR ERROR\n\n"
i386AlignmentCheckText:
.asciz "Exception 11: ALIGNMENT CHECK\n\n"
i386MachineCheckText:
.asciz "Exception 12: MACHINE CHECK\n\n"
i386_EAX_Text:
.asciz "EAX: "
i386_EBX_Text:
.asciz "EBX: "
i386_ECX_Text:
.asciz "ECX: "
i386_EDX_Text:
.asciz "EDX: "
i386_ESP_Text:
.asciz " ESP: "
i386_EBP_Text:
.asciz " EBP: "
i386_ESI_Text:
.asciz " ESI: "
i386_EDI_Text:
.asciz " EDI: "
i386_CS_Text:
.asciz "CS: "
i386_DS_Text:
.asciz "DS: "
i386_ES_Text:
.asciz "ES: "
i386_FS_Text:
.asciz "FS: "
i386_GS_Text:
.asciz "GS: "
i386_SS_Text:
.asciz "SS: "
i386_EFLAGS_Text:
.asciz " EFLAGS: "
i386_EIP_Text:
.asciz " EIP: "
i386_ERROR_CODE_Text:
.asciz " ERROR CODE: "
i386_CR0_Text:
.asciz " CR0: "
i386_CR1_Text:
.asciz " CR1: "
i386_CR2_Text:
.asciz " CR2: "
i386_CR3_Text:
.asciz " CR3: "
i386_DR0_Text:
.asciz " DR0: "
i386_DR1_Text:
.asciz " DR1: "
i386_DR2_Text:
.asciz " DR2: "
i386_DR3_Text:
.asciz " DR3: "
i386_DR6_Text:
.asciz " DR6: "
i386_DR7_Text:
.asciz " DR7: "
i386_GDTR_Text:
.asciz " GDTR Base: "
i386_IDTR_Text:
.asciz " IDTR Base: "
i386_Limit_Text:
.asciz " Limit: "
i386_LDTR_Text:
.asciz " LDTR: "
i386_TR_Text:
.asciz " TR: "
i386FramesText:
.asciz "Frames:\n"
/* Set by each exception handler to the address of the description text */
i386ExceptionDescriptionText:
.long 0
/* Used to store the contents of all the registers when an exception occurs */
i386_EAX:
.long 0
i386_EBX:
.long 0
i386_ECX:
.long 0
i386_EDX:
.long 0
i386_ESP:
.long 0
i386_EBP:
.long 0
i386_ESI:
.long 0
i386_EDI:
.long 0
i386_CS:
.word 0
i386_DS:
.word 0
i386_ES:
.word 0
i386_FS:
.word 0
i386_GS:
.word 0
i386_SS:
.word 0
i386_EFLAGS:
.long 0
i386_EIP:
.long 0
i386_ERROR_CODE:
.long 0
i386_CR0:
.long 0
i386_CR1:
.long 0
i386_CR2:
.long 0
i386_CR3:
.long 0
i386_DR0:
.long 0
i386_DR1:
.long 0
i386_DR2:
.long 0
i386_DR3:
.long 0
i386_DR6:
.long 0
i386_DR7:
.long 0
i386_GDTR:
.word 0
.long 0
i386_IDTR:
.word 0
.long 0
i386_LDTR:
.word 0
i386_TR:
.word 0
/* Used to store the current X and Y position on the screen */
i386_ScreenPosX:
.long 0
i386_ScreenPosY:
.long 0
/************************************************************************/
i386CommonExceptionHandler:
.code32
SAVE_CPU_REGS
pushl $SCREEN_ATTR
call _MachVideoClearScreen
add $4,%esp
movl $i386ExceptionHandlerText,%esi
call i386PrintText
movl i386ExceptionDescriptionText,%esi
call i386PrintText
movl $i386_EAX_Text,%esi
call i386PrintText
movl i386_EAX,%eax
call i386PrintHexDword // Display EAX
movl $i386_ESP_Text,%esi
call i386PrintText
movl i386_ESP,%eax
call i386PrintHexDword // Display ESP
movl $i386_CR0_Text,%esi
call i386PrintText
movl i386_CR0,%eax
call i386PrintHexDword // Display CR0
movl $i386_DR0_Text,%esi
call i386PrintText
movl i386_DR0,%eax
call i386PrintHexDword // Display DR0
movl $0,i386_ScreenPosX
incl i386_ScreenPosY
movl $i386_EBX_Text,%esi
call i386PrintText
movl i386_EBX,%eax
call i386PrintHexDword // Display EBX
movl $i386_EBP_Text,%esi
call i386PrintText
movl i386_EBP,%eax
call i386PrintHexDword // Display EBP
movl $i386_CR1_Text,%esi
call i386PrintText
movl i386_CR1,%eax
call i386PrintHexDword // Display CR1
movl $i386_DR1_Text,%esi
call i386PrintText
movl i386_DR1,%eax
call i386PrintHexDword // Display DR1
movl $0,i386_ScreenPosX
incl i386_ScreenPosY
movl $i386_ECX_Text,%esi
call i386PrintText
movl i386_ECX,%eax
call i386PrintHexDword // Display ECX
movl $i386_ESI_Text,%esi
call i386PrintText
movl i386_ESI,%eax
call i386PrintHexDword // Display ESI
movl $i386_CR2_Text,%esi
call i386PrintText
movl i386_CR2,%eax
call i386PrintHexDword // Display CR2
movl $i386_DR2_Text,%esi
call i386PrintText
movl i386_DR2,%eax
call i386PrintHexDword // Display DR2
movl $0,i386_ScreenPosX
incl i386_ScreenPosY
movl $i386_EDX_Text,%esi
call i386PrintText
movl i386_EDX,%eax
call i386PrintHexDword // Display EDX
movl $i386_EDI_Text,%esi
call i386PrintText
movl i386_EDI,%eax
call i386PrintHexDword // Display EDI
movl $i386_CR3_Text,%esi
call i386PrintText
movl i386_CR3,%eax
call i386PrintHexDword // Display CR3
movl $i386_DR3_Text,%esi
call i386PrintText
movl i386_DR3,%eax
call i386PrintHexDword // Display DR3
incl i386_ScreenPosY
movl $55,i386_ScreenPosX
movl $i386_DR6_Text,%esi
call i386PrintText
movl i386_DR6,%eax
call i386PrintHexDword // Display DR6
incl i386_ScreenPosY
movl $55,i386_ScreenPosX
movl $i386_DR7_Text,%esi
call i386PrintText
movl i386_DR7,%eax
call i386PrintHexDword // Display DR7
movl $0,i386_ScreenPosX
incl i386_ScreenPosY
incl i386_ScreenPosY
movl $i386_CS_Text,%esi
call i386PrintText
movw i386_CS,%ax
call i386PrintHexWord // Display CS
movl $i386_EIP_Text,%esi
call i386PrintText
movl i386_EIP,%eax
call i386PrintHexDword // Display EIP
movl $0,i386_ScreenPosX
incl i386_ScreenPosY
movl $i386_DS_Text,%esi
call i386PrintText
movw i386_DS,%ax
call i386PrintHexWord // Display DS
movl $i386_ERROR_CODE_Text,%esi
call i386PrintText
movl i386_ERROR_CODE,%eax
call i386PrintHexDword // Display ERROR CODE
movl $0,i386_ScreenPosX
incl i386_ScreenPosY
movl $i386_ES_Text,%esi
call i386PrintText
movw i386_ES,%ax
call i386PrintHexWord // Display ES
movl $i386_EFLAGS_Text,%esi
call i386PrintText
movl i386_EFLAGS,%eax
call i386PrintHexDword // Display EFLAGS
movl $0,i386_ScreenPosX
incl i386_ScreenPosY
movl $i386_FS_Text,%esi
call i386PrintText
movw i386_FS,%ax
call i386PrintHexWord // Display FS
movl $i386_GDTR_Text,%esi
call i386PrintText
movl i386_GDTR+2,%eax
call i386PrintHexDword // Display GDTR Base
movl $i386_Limit_Text,%esi
call i386PrintText
movw i386_GDTR,%ax
call i386PrintHexWord // Display GDTR Limit
movl $0,i386_ScreenPosX
incl i386_ScreenPosY
movl $i386_GS_Text,%esi
call i386PrintText
movw i386_GS,%ax
call i386PrintHexWord // Display GS
movl $i386_IDTR_Text,%esi
call i386PrintText
movl i386_IDTR+2,%eax
call i386PrintHexDword // Display IDTR Base
movl $i386_Limit_Text,%esi
call i386PrintText
movw i386_IDTR,%ax
call i386PrintHexWord // Display IDTR Limit
movl $0,i386_ScreenPosX
incl i386_ScreenPosY
movl $i386_SS_Text,%esi
call i386PrintText
movw i386_SS,%ax
call i386PrintHexWord // Display SS
movl $i386_LDTR_Text,%esi
call i386PrintText
movw i386_LDTR,%ax
call i386PrintHexWord // Display LDTR
movl $i386_TR_Text,%esi
call i386PrintText
movw i386_TR,%ax
call i386PrintHexWord // Display TR
movl $0,i386_ScreenPosX
incl i386_ScreenPosY
incl i386_ScreenPosY
call i386PrintFrames // Display frames
incl i386_ScreenPosY
incl i386_ScreenPosY
cli
i386ExceptionHandlerHang:
hlt
jmp i386ExceptionHandlerHang
iret
i386PrintFrames:
movl $0,i386_ScreenPosX
movl $i386FramesText,%esi
call i386PrintText
movl i386_EBP,%edi
printnextframe:
test %edi,%edi
je nomoreframes
movl $STACK32ADDR,%eax
cmpl %edi,%eax
jbe nomoreframes
movl 4(%edi),%eax
pushl %edi
call i386PrintHexDword // Display frame
popl %edi
incl i386_ScreenPosX
incl i386_ScreenPosX
movl 0(%edi),%edi
jmp printnextframe
nomoreframes:
ret
/************************************************************************/
/* AL = Char to display */
/************************************************************************/
i386PrintChar:
.code32
pushl i386_ScreenPosY
pushl i386_ScreenPosX
pushl $SCREEN_ATTR
andl $0xff,%eax
pushl %eax
call _MachVideoPutChar
addl $16,%esp
ret
/************************************************************************/
/* ESI = Address of text to display */
/************************************************************************/
i386PrintText:
.code32
i386PrintTextLoop:
lodsb
// Check for end of string char
cmp $0,%al
je i386PrintTextDone
// Check for newline char
cmp $0x0a,%al
jne i386PrintTextLoop2
incl i386_ScreenPosY
movl $0,i386_ScreenPosX
jmp i386PrintTextLoop
i386PrintTextLoop2:
call i386PrintChar
incl i386_ScreenPosX
jmp i386PrintTextLoop
i386PrintTextDone:
ret
/************************************************************************/
/* Prints the value in EAX on the screen in hex */
/************************************************************************/
i386PrintHexDword:
.code32
call i386PrintHex1
i386PrintHex1:
call i386PrintHex2
i386PrintHex2:
call i386PrintHex3
i386PrintHex3:
movb $4,%cl
rol %cl,%eax
push %eax
andb $0x0f,%al
movl $i386PrintHexTable,%ebx
xlat /*$i386PrintHexTable*/
call i386PrintChar
incl i386_ScreenPosX
pop %eax
ret
i386PrintHexTable:
.ascii "0123456789ABCDEF"
/************************************************************************/
/* Prints the value in AX on the screen in hex */
/************************************************************************/
i386PrintHexWord:
.code32
call i386PrintHexWord1
i386PrintHexWord1:
call i386PrintHexWord2
i386PrintHexWord2:
movb $4,%cl
rol %cl,%ax
push %eax
andb $0x0f,%al
movl $i386PrintHexTable,%ebx
xlat /*$i386PrintHexTable*/
call i386PrintChar
incl i386_ScreenPosX
pop %eax
ret
/************************************************************************/
/* Prints the value in AL on the screen in hex */
/************************************************************************/
i386PrintHexByte:
.code32
call i386PrintHexByte1
i386PrintHexByte1:
movb $4,%cl
rol %cl,%al
push %eax
andb $0x0f,%al
movl $i386PrintHexTable,%ebx
xlat /*$i386PrintHexTable*/
call i386PrintChar
incl i386_ScreenPosX
pop %eax
ret
/************************************************************************/
EXTERN(i386DivideByZero)
.code32
movl $i386DivideByZeroText,i386ExceptionDescriptionText
jmp i386CommonExceptionHandler
/************************************************************************/
EXTERN(i386DebugException)
.code32
movl $i386DebugExceptionText,i386ExceptionDescriptionText
jmp i386CommonExceptionHandler
/************************************************************************/
EXTERN(i386NMIException)
.code32
movl $i386NMIExceptionText,i386ExceptionDescriptionText
jmp i386CommonExceptionHandler
/************************************************************************/
EXTERN(i386Breakpoint)
.code32
movl $i386BreakpointText,i386ExceptionDescriptionText
jmp i386CommonExceptionHandler
/************************************************************************/
EXTERN(i386Overflow)
.code32
movl $i386OverflowText,i386ExceptionDescriptionText
jmp i386CommonExceptionHandler
/************************************************************************/
EXTERN(i386BoundException)
.code32
movl $i386BoundExceptionText,i386ExceptionDescriptionText
jmp i386CommonExceptionHandler
/************************************************************************/
EXTERN(i386InvalidOpcode)
.code32
movl $i386InvalidOpcodeText,i386ExceptionDescriptionText
jmp i386CommonExceptionHandler
/************************************************************************/
EXTERN(i386FPUNotAvailable)
.code32
movl $i386FPUNotAvailableText,i386ExceptionDescriptionText
jmp i386CommonExceptionHandler
/************************************************************************/
EXTERN(i386DoubleFault)
.code32
popl %eax
movl %eax,i386_ERROR_CODE
movl $i386DoubleFaultText,i386ExceptionDescriptionText
jmp i386CommonExceptionHandler
/************************************************************************/
EXTERN(i386CoprocessorSegment)
.code32
movl $i386CoprocessorSegmentText,i386ExceptionDescriptionText
jmp i386CommonExceptionHandler
/************************************************************************/
EXTERN(i386InvalidTSS)
.code32
popl %eax
movl %eax,i386_ERROR_CODE
movl $i386InvalidTSSText,i386ExceptionDescriptionText
jmp i386CommonExceptionHandler
/************************************************************************/
EXTERN(i386SegmentNotPresent)
.code32
popl %eax
movl %eax,i386_ERROR_CODE
movl $i386SegmentNotPresentText,i386ExceptionDescriptionText
jmp i386CommonExceptionHandler
/************************************************************************/
EXTERN(i386StackException)
.code32
popl %eax
movl %eax,i386_ERROR_CODE
movl $i386StackExceptionText,i386ExceptionDescriptionText
jmp i386CommonExceptionHandler
/************************************************************************/
EXTERN(i386GeneralProtectionFault)
.code32
popl %eax
movl %eax,i386_ERROR_CODE
movl $i386GeneralProtectionFaultText,i386ExceptionDescriptionText
jmp i386CommonExceptionHandler
/************************************************************************/
EXTERN(i386PageFault)
.code32
popl %eax
movl %eax,i386_ERROR_CODE
movl $i386PageFaultText,i386ExceptionDescriptionText
jmp i386CommonExceptionHandler
/************************************************************************/
EXTERN(i386CoprocessorError)
.code32
movl $i386CoprocessorErrorText,i386ExceptionDescriptionText
jmp i386CommonExceptionHandler
/************************************************************************/
EXTERN(i386AlignmentCheck)
.code32
movl $i386AlignmentCheckText,i386ExceptionDescriptionText
jmp i386CommonExceptionHandler
/************************************************************************/
EXTERN(i386MachineCheck)
.code32
movl $i386MachineCheckText,i386ExceptionDescriptionText
jmp i386CommonExceptionHandler
/************************************************************************
* DEBUGGING SUPPORT FUNCTIONS
************************************************************************/
EXTERN(_INSTRUCTION_BREAKPOINT1)
.code32
pushl %eax
movl 8(%esp),%eax
movl %eax,%dr0
movl %dr7,%eax
andl $0xfff0ffff,%eax
orl $0x00000303,%eax
movl %eax,%dr7
popl %eax
ret
EXTERN(_MEMORY_READWRITE_BREAKPOINT1)
.code32
pushl %eax
movl 8(%esp),%eax
movl %eax,%dr0
movl %dr7,%eax
andl $0xfff0ffff,%eax
orl $0x00030303,%eax
movl %eax,%dr7
popl %eax
ret
EXTERN(_MEMORY_WRITE_BREAKPOINT1)
.code32
pushl %eax
movl 8(%esp),%eax
movl %eax,%dr0
movl %dr7,%eax
andl $0xfff0ffff,%eax
orl $0x00010303,%eax
movl %eax,%dr7
popl %eax
ret
EXTERN(_INSTRUCTION_BREAKPOINT2)
.code32
pushl %eax
movl 8(%esp),%eax
movl %eax,%dr1
movl %dr7,%eax
andl $0xff0fffff,%eax
orl $0x0000030c,%eax
movl %eax,%dr7
popl %eax
ret
EXTERN(_MEMORY_READWRITE_BREAKPOINT2)
.code32
pushl %eax
movl 8(%esp),%eax
movl %eax,%dr1
movl %dr7,%eax
andl $0xff0fffff,%eax
orl $0x0030030c,%eax
movl %eax,%dr7
popl %eax
ret
EXTERN(_MEMORY_WRITE_BREAKPOINT2)
.code32
pushl %eax
movl 8(%esp),%eax
movl %eax,%dr1
movl %dr7,%eax
andl $0xff0fffff,%eax
orl $0x0010030c,%eax
movl %eax,%dr7
popl %eax
ret
EXTERN(_INSTRUCTION_BREAKPOINT3)
.code32
pushl %eax
movl 8(%esp),%eax
movl %eax,%dr2
movl %dr7,%eax
andl $0xf0ffffff,%eax
orl $0x00000330,%eax
movl %eax,%dr7
popl %eax
ret
EXTERN(_MEMORY_READWRITE_BREAKPOINT3)
.code32
pushl %eax
movl 8(%esp),%eax
movl %eax,%dr2
movl %dr7,%eax
andl $0xf0ffffff,%eax
orl $0x03000330,%eax
movl %eax,%dr7
popl %eax
ret
EXTERN(_MEMORY_WRITE_BREAKPOINT3)
.code32
pushl %eax
movl 8(%esp),%eax
movl %eax,%dr2
movl %dr7,%eax
andl $0xf0ffffff,%eax
orl $0x01000330,%eax
movl %eax,%dr7
popl %eax
ret
EXTERN(_INSTRUCTION_BREAKPOINT4)
.code32
pushl %eax
movl 8(%esp),%eax
movl %eax,%dr3
movl %dr7,%eax
andl $0x0fffffff,%eax
orl $0x000003c0,%eax
movl %eax,%dr7
popl %eax
ret
EXTERN(_MEMORY_READWRITE_BREAKPOINT4)
.code32
pushl %eax
movl 8(%esp),%eax
movl %eax,%dr3
movl %dr7,%eax
andl $0x0fffffff,%eax
orl $0x300003c0,%eax
movl %eax,%dr7
popl %eax
ret
EXTERN(_MEMORY_WRITE_BREAKPOINT4)
.code32
pushl %eax
movl 8(%esp),%eax
movl %eax,%dr3
movl %dr7,%eax
andl $0x0fffffff,%eax
orl $0x100003c0,%eax
movl %eax,%dr7
popl %eax
ret

View File

@@ -0,0 +1,251 @@
/*
* FreeLoader
* Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>
* Portions from Linux video.S - Display adapter & video mode setup, version 2.13 (14-May-99)
* Copyright (C) 1995 -- 1999 Martin Mares <mj@ucw.cz>
* Based on the original setup.S code (C) Linus Torvalds and Mats Anderson
*
* 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.
*/
#include <freeldr.h>
#include <arch.h>
#include <video.h>
#include <portio.h>
#include <rtl.h>
#include <debug.h>
typedef struct
{
U8 Signature[4]; // (ret) signature ("VESA")
// (call) VESA 2.0 request signature ("VBE2"), required to receive
// version 2.0 info
U16 VesaVersion; // VESA version number (one-digit minor version -- 0102h = v1.2)
U32 OemNamePtr; // pointer to OEM name
// "761295520" for ATI
U32 Capabilities; // capabilities flags (see #00078)
U32 SupportedModeListPtr; // pointer to list of supported VESA and OEM video modes
// (list of words terminated with FFFFh)
U16 TotalVideoMemory; // total amount of video memory in 64K blocks
// ---VBE v1.x ---
//U8 Reserved[236];
// ---VBE v2.0 ---
U16 OemSoftwareVersion; // OEM software version (BCD, high byte = major, low byte = minor)
U32 VendorNamePtr; // pointer to vendor name
U32 ProductNamePtr; // pointer to product name
U32 ProductRevisionStringPtr; // pointer to product revision string
U16 VBE_AF_Version; // (if capabilities bit 3 set) VBE/AF version (BCD)
// 0100h for v1.0P
U32 AcceleratedModeListPtr; // (if capabilities bit 3 set) pointer to list of supported
// accelerated video modes (list of words terminated with FFFFh)
U8 Reserved[216]; // reserved for VBE implementation
U8 ScratchPad[256]; // OEM scratchpad (for OEM strings, etc.)
} PACKED VESA_SVGA_INFO, *PVESA_SVGA_INFO;
// Bitfields for VESA capabilities:
//
// Bit(s) Description (Table 00078)
// 0 DAC can be switched into 8-bit mode
// 1 non-VGA controller
// 2 programmed DAC with blank bit (i.e. only during blanking interval)
// 3 (VBE v3.0) controller supports hardware stereoscopic signalling
// 3 controller supports VBE/AF v1.0P extensions
// 4 (VBE v3.0) if bit 3 set:
// =0 stereo signalling via external VESA stereo connector
// =1 stereo signalling via VESA EVC connector
// 4 (VBE/AF v1.0P) must call EnableDirectAccess to access framebuffer
// 5 (VBE/AF v1.0P) controller supports hardware mouse cursor
// 6 (VBE/AF v1.0P) controller supports hardware clipping
// 7 (VBE/AF v1.0P) controller supports transparent BitBLT
// 8-31 reserved (0)
// Notes: The list of supported video modes is stored in the reserved
// portion of the SuperVGA information record by some implementations,
// and it may thus be necessary to either copy the mode list or use a
// different buffer for all subsequent VESA calls. Not all of the video
// modes in the list of mode numbers may be supported, e.g. if they require
// more memory than currently installed or are not supported by the
// attached monitor. Check any mode you intend to use through AX=4F01h first..
// The 1.1 VESA document specifies 242 reserved bytes at the end, so the
// buffer should be 262 bytes to ensure that it is not overrun; for v2.0,
// the buffer should be 512 bytes. The S3 specific video modes will most
// likely follow the FFFFh terminator at the end of the standard modes.
// A search must then be made to find them, FFFFh will also terminate this
// second list. In some cases, only a "stub" VBE may be present, supporting
// only AX=4F00h; this case may be assumed if the list of supported video modes
// is empty (consisting of a single word of FFFFh)
VOID BiosSetVideoFont8x16(VOID)
{
REGS Regs;
// Int 10h AX=1114h
// VIDEO - TEXT-MODE CHARGEN - LOAD ROM 8x16 CHARACTER SET (VGA)
//
// AX = 1114h
// BL = block to load
// Return:
// Nothing
Regs.w.ax = 0x1114;
Regs.b.bl = 0;
Int386(0x10, &Regs, &Regs);
}
VOID VideoSetTextCursorPosition(U32 X, U32 Y)
{
}
U32 VideoGetTextCursorPositionX(VOID)
{
REGS Regs;
// Int 10h AH=03h
// VIDEO - GET CURSOR POSITION AND SIZE
//
// AH = 03h
// BH = page number
// 0-3 in modes 2&3
// 0-7 in modes 0&1
// 0 in graphics modes
// Return:
// AX = 0000h (Phoenix BIOS)
// CH = start scan line
// CL = end scan line
// DH = row (00h is top)
// DL = column (00h is left)
Regs.b.ah = 0x03;
Regs.b.bh = 0x00;
Int386(0x10, &Regs, &Regs);
return Regs.b.dl;
}
U32 VideoGetTextCursorPositionY(VOID)
{
REGS Regs;
// Int 10h AH=03h
// VIDEO - GET CURSOR POSITION AND SIZE
//
// AH = 03h
// BH = page number
// 0-3 in modes 2&3
// 0-7 in modes 0&1
// 0 in graphics modes
// Return:
// AX = 0000h (Phoenix BIOS)
// CH = start scan line
// CL = end scan line
// DH = row (00h is top)
// DL = column (00h is left)
Regs.b.ah = 0x03;
Regs.b.bh = 0x00;
Int386(0x10, &Regs, &Regs);
return Regs.b.dh;
}
U16 BiosIsVesaSupported(VOID)
{
REGS Regs;
PVESA_SVGA_INFO SvgaInfo = (PVESA_SVGA_INFO)BIOSCALLBUFFER;
#ifdef DEBUG
//U16* VideoModes;
//U16 Index;
#endif // defined DEBUG
DbgPrint((DPRINT_UI, "BiosIsVesaSupported()\n"));
RtlZeroMemory(SvgaInfo, sizeof(VESA_SVGA_INFO));
// Make sure we receive version 2.0 info
SvgaInfo->Signature[0] = 'V';
SvgaInfo->Signature[1] = 'B';
SvgaInfo->Signature[2] = 'E';
SvgaInfo->Signature[3] = '2';
// Int 10h AX=4F00h
// VESA SuperVGA BIOS (VBE) - GET SuperVGA INFORMATION
//
// AX = 4F00h
// ES:DI -> buffer for SuperVGA information (see #00077)
// Return:
// AL = 4Fh if function supported
// AH = status
// 00h successful
// ES:DI buffer filled
// 01h failed
// ---VBE v2.0---
// 02h function not supported by current hardware configuration
// 03h function invalid in current video mode
//
// Determine whether VESA BIOS extensions are present and the
// capabilities supported by the display adapter
//
// Installation check;VESA SuperVGA
Regs.w.ax = 0x4F00;
Regs.w.es = BIOSCALLBUFSEGMENT;
Regs.w.di = BIOSCALLBUFOFFSET;
Int386(0x10, &Regs, &Regs);
DbgPrint((DPRINT_UI, "AL = 0x%x\n", Regs.b.al));
DbgPrint((DPRINT_UI, "AH = 0x%x\n", Regs.b.ah));
if (Regs.w.ax != 0x004F)
{
DbgPrint((DPRINT_UI, "Failed.\n"));
return 0x0000;
}
#ifdef DEBUG
DbgPrint((DPRINT_UI, "Supported.\n"));
DbgPrint((DPRINT_UI, "SvgaInfo->Signature[4] = %c%c%c%c\n", SvgaInfo->Signature[0], SvgaInfo->Signature[1], SvgaInfo->Signature[2], SvgaInfo->Signature[3]));
DbgPrint((DPRINT_UI, "SvgaInfo->VesaVersion = v%d.%d\n", ((SvgaInfo->VesaVersion >> 8) & 0xFF), (SvgaInfo->VesaVersion & 0xFF)));
DbgPrint((DPRINT_UI, "SvgaInfo->OemNamePtr = 0x%x\n", SvgaInfo->OemNamePtr));
DbgPrint((DPRINT_UI, "SvgaInfo->Capabilities = 0x%x\n", SvgaInfo->Capabilities));
DbgPrint((DPRINT_UI, "SvgaInfo->VideoMemory = %dK\n", SvgaInfo->TotalVideoMemory * 64));
DbgPrint((DPRINT_UI, "---VBE v2.0 ---\n"));
DbgPrint((DPRINT_UI, "SvgaInfo->OemSoftwareVersion = v%d.%d\n", ((SvgaInfo->OemSoftwareVersion >> 8) & 0x0F) + (((SvgaInfo->OemSoftwareVersion >> 12) & 0x0F) * 10), (SvgaInfo->OemSoftwareVersion & 0x0F) + (((SvgaInfo->OemSoftwareVersion >> 4) & 0x0F) * 10)));
DbgPrint((DPRINT_UI, "SvgaInfo->VendorNamePtr = 0x%x\n", SvgaInfo->VendorNamePtr));
DbgPrint((DPRINT_UI, "SvgaInfo->ProductNamePtr = 0x%x\n", SvgaInfo->ProductNamePtr));
DbgPrint((DPRINT_UI, "SvgaInfo->ProductRevisionStringPtr = 0x%x\n", SvgaInfo->ProductRevisionStringPtr));
DbgPrint((DPRINT_UI, "SvgaInfo->VBE/AF Version = 0x%x (BCD WORD)\n", SvgaInfo->VBE_AF_Version));
//DbgPrint((DPRINT_UI, "\nSupported VESA and OEM video modes:\n"));
//VideoModes = (U16*)SvgaInfo->SupportedModeListPtr;
//for (Index=0; VideoModes[Index]!=0xFFFF; Index++)
//{
// DbgPrint((DPRINT_UI, "Mode %d: 0x%x\n", Index, VideoModes[Index]));
//}
//if (SvgaInfo->VesaVersion >= 0x0200)
//{
// DbgPrint((DPRINT_UI, "\nSupported accelerated video modes (VESA v2.0):\n"));
// VideoModes = (U16*)SvgaInfo->AcceleratedModeListPtr;
// for (Index=0; VideoModes[Index]!=0xFFFF; Index++)
// {
// DbgPrint((DPRINT_UI, "Mode %d: 0x%x\n", Index, VideoModes[Index]));
// }
//}
DbgPrint((DPRINT_UI, "\n"));
//getch();
#endif // defined DEBUG
return SvgaInfo->VesaVersion;
}

View File

@@ -0,0 +1,155 @@
/*
* FreeLoader
* Copyright (C) 1998-2002 Brian Palmer <brianp@sginet.com>
*
* 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.
*/
.text
.code16
#define ASM
#include <arch.h>
Int386_REGS:
Int386_eax:
.long 0
Int386_ebx:
.long 0
Int386_ecx:
.long 0
Int386_edx:
.long 0
Int386_esi:
.long 0
Int386_edi:
.long 0
Int386_ds:
.word 0
Int386_es:
.word 0
Int386_fs:
.word 0
Int386_gs:
.word 0
Int386_eflags:
.long 0
Int386_vector:
.long 0
Int386_regsin:
.long 0
Int386_regsout:
.long 0
/*
* int Int386(int ivec, REGS* in, REGS* out);
*/
EXTERN(_Int386)
.code32
/* Get the function parameters */
movl 0x04(%esp),%eax
movl %eax,Int386_vector
movb %al,Int386_vector_opcode
movl 0x08(%esp),%eax
movl %eax,Int386_regsin
movl 0x0c(%esp),%eax
movl %eax,Int386_regsout
pushal
/* Copy the input regs to our variables */
movl $Int386_REGS,%edi
movl Int386_regsin,%esi
movl $0x24,%ecx
rep
movsb
call switch_to_real
.code16
/* Setup the registers */
movw %cs:Int386_ds,%ax
movw %ax,%ds /* DS register */
movw %cs:Int386_es,%ax
movw %ax,%es /* ES register */
movw %cs:Int386_fs,%ax
movw %ax,%fs /* FS register */
movw %cs:Int386_gs,%ax
movw %ax,%gs /* GS register */
movl %cs:Int386_eax,%eax /* EAX register */
movl %cs:Int386_ebx,%ebx /* EBX register */
movl %cs:Int386_ecx,%ecx /* ECX register */
movl %cs:Int386_edx,%edx /* EDX register */
movl %cs:Int386_esi,%esi /* ESI register */
movl %cs:Int386_edi,%edi /* EDI register */
/* Do not set the flags register */
/* only return its value in regsout */
//pushl Int386_eflags
//popfl /* EFLAGS register */
/* Call the interrupt vector */
/*int Int386_vector*/
Int386_int_opcode:
.byte 0xcd
Int386_vector_opcode:
.byte 0x00
/* Save the registers */
movl %eax,%cs:Int386_eax /* EAX register */
movl %ebx,%cs:Int386_ebx /* EBX register */
movl %ecx,%cs:Int386_ecx /* ECX register */
movl %edx,%cs:Int386_edx /* EDX register */
movl %esi,%cs:Int386_esi /* ESI register */
movl %edi,%cs:Int386_edi /* EDI register */
movw %ds,%ax /* DS register */
movw %ax,%cs:Int386_ds
movw %es,%ax /* ES register */
movw %ax,%cs:Int386_es
movw %fs,%ax /* FS register */
movw %ax,%cs:Int386_fs
movw %gs,%ax /* GS register */
movw %ax,%cs:Int386_gs
pushf
popw %cs:Int386_eflags /* EFLAGS register */
call switch_to_prot
.code32
/* Copy the variables to the output regs */
movl $Int386_REGS,%esi
movl Int386_regsout,%edi
movl $0x24,%ecx
rep
movsb
popal
/* Get return value */
movl Int386_eax,%eax
ret

View File

@@ -12,9 +12,9 @@
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
* 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.
*/
.text

View File

@@ -0,0 +1,59 @@
/* $Id: machpc.c,v 1.7 2004/11/28 22:42:40 gvg Exp $
*
* FreeLoader
*
* 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.
*/
#include "freeldr.h"
#include "mm.h"
#include "arch.h"
#include "machine.h"
#include "machpc.h"
#include "rtl.h"
VOID
PcMachInit(VOID)
{
EnableA20();
/* Setup vtbl */
MachVtbl.ConsPutChar = PcConsPutChar;
MachVtbl.ConsKbHit = PcConsKbHit;
MachVtbl.ConsGetCh = PcConsGetCh;
MachVtbl.VideoClearScreen = PcVideoClearScreen;
MachVtbl.VideoSetDisplayMode = PcVideoSetDisplayMode;
MachVtbl.VideoGetDisplaySize = PcVideoGetDisplaySize;
MachVtbl.VideoGetBufferSize = PcVideoGetBufferSize;
MachVtbl.VideoSetTextCursorPosition = PcVideoSetTextCursorPosition;
MachVtbl.VideoSetTextCursorPosition = PcVideoSetTextCursorPosition;
MachVtbl.VideoHideShowTextCursor = PcVideoHideShowTextCursor;
MachVtbl.VideoPutChar = PcVideoPutChar;
MachVtbl.VideoCopyOffScreenBufferToVRAM = PcVideoCopyOffScreenBufferToVRAM;
MachVtbl.VideoIsPaletteFixed = PcVideoIsPaletteFixed;
MachVtbl.VideoSetPaletteColor = PcVideoSetPaletteColor;
MachVtbl.VideoGetPaletteColor = PcVideoGetPaletteColor;
MachVtbl.VideoSync = PcVideoSync;
MachVtbl.VideoPrepareForReactOS = PcVideoPrepareForReactOS;
MachVtbl.GetMemoryMap = PcMemGetMemoryMap;
MachVtbl.DiskReadLogicalSectors = PcDiskReadLogicalSectors;
MachVtbl.DiskGetPartitionEntry = PcDiskGetPartitionEntry;
MachVtbl.DiskGetDriveGeometry = PcDiskGetDriveGeometry;
MachVtbl.DiskGetCacheableBlockCount = PcDiskGetCacheableBlockCount;
MachVtbl.RTCGetCurrentDateTime = PcRTCGetCurrentDateTime;
MachVtbl.HwDetect = PcHwDetect;
}
/* EOF */

View File

@@ -0,0 +1,62 @@
/* $Id: machpc.h,v 1.7 2004/11/28 22:42:40 gvg Exp $
*
* FreeLoader
*
* Copyright (C) 2003 Eric Kohl
*
* 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.
*/
#ifndef __I386_MACHPC_H_
#define __I386_MACHPC_H_
#ifndef __MEMORY_H
#include "mm.h"
#endif
VOID PcMachInit(VOID);
VOID PcConsPutChar(int Ch);
BOOL PcConsKbHit();
int PcConsGetCh();
VOID PcVideoClearScreen(U8 Attr);
VIDEODISPLAYMODE PcVideoSetDisplayMode(char *DisplayMode, BOOL Init);
VOID PcVideoGetDisplaySize(PU32 Width, PU32 Height, PU32 Depth);
U32 PcVideoGetBufferSize(VOID);
VOID PcVideoSetTextCursorPosition(U32 X, U32 Y);
VOID PcVideoHideShowTextCursor(BOOL Show);
VOID PcVideoPutChar(int Ch, U8 Attr, unsigned X, unsigned Y);
VOID PcVideoCopyOffScreenBufferToVRAM(PVOID Buffer);
BOOL PcVideoIsPaletteFixed(VOID);
VOID PcVideoSetPaletteColor(U8 Color, U8 Red, U8 Green, U8 Blue);
VOID PcVideoGetPaletteColor(U8 Color, U8* Red, U8* Green, U8* Blue);
VOID PcVideoSync(VOID);
VOID PcVideoPrepareForReactOS(VOID);
U32 PcMemGetMemoryMap(PBIOS_MEMORY_MAP BiosMemoryMap, U32 MaxMemoryMapSize);
BOOL PcDiskReadLogicalSectors(U32 DriveNumber, U64 SectorNumber, U32 SectorCount, PVOID Buffer);
BOOL PcDiskGetPartitionEntry(U32 DriveNumber, U32 PartitionNumber, PPARTITION_TABLE_ENTRY PartitionTableEntry);
BOOL PcDiskGetDriveGeometry(U32 DriveNumber, PGEOMETRY DriveGeometry);
U32 PcDiskGetCacheableBlockCount(U32 DriveNumber);
VOID PcRTCGetCurrentDateTime(PU32 Year, PU32 Month, PU32 Day, PU32 Hour, PU32 Minute, PU32 Second);
VOID PcHwDetect(VOID);
#endif /* __I386_MACHPC_H_ */
/* EOF */

View File

@@ -0,0 +1,55 @@
/* $Id: machxbox.c,v 1.7 2004/11/28 22:42:40 gvg Exp $
*
* FreeLoader
*
* 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.
*/
#include "freeldr.h"
#include "mm.h"
#include "machine.h"
#include "machxbox.h"
VOID
XboxMachInit(VOID)
{
/* Initialize our stuff */
XboxMemInit();
XboxVideoInit();
/* Setup vtbl */
MachVtbl.ConsPutChar = XboxConsPutChar;
MachVtbl.ConsKbHit = XboxConsKbHit;
MachVtbl.ConsGetCh = XboxConsGetCh;
MachVtbl.VideoClearScreen = XboxVideoClearScreen;
MachVtbl.VideoSetDisplayMode = XboxVideoSetDisplayMode;
MachVtbl.VideoGetDisplaySize = XboxVideoGetDisplaySize;
MachVtbl.VideoGetBufferSize = XboxVideoGetBufferSize;
MachVtbl.VideoHideShowTextCursor = XboxVideoHideShowTextCursor;
MachVtbl.VideoPutChar = XboxVideoPutChar;
MachVtbl.VideoCopyOffScreenBufferToVRAM = XboxVideoCopyOffScreenBufferToVRAM;
MachVtbl.VideoIsPaletteFixed = XboxVideoIsPaletteFixed;
MachVtbl.VideoSetPaletteColor = XboxVideoSetPaletteColor;
MachVtbl.VideoGetPaletteColor = XboxVideoGetPaletteColor;
MachVtbl.VideoSync = XboxVideoSync;
MachVtbl.VideoPrepareForReactOS = XboxVideoPrepareForReactOS;
MachVtbl.GetMemoryMap = XboxMemGetMemoryMap;
MachVtbl.DiskReadLogicalSectors = XboxDiskReadLogicalSectors;
MachVtbl.DiskGetPartitionEntry = XboxDiskGetPartitionEntry;
MachVtbl.DiskGetDriveGeometry = XboxDiskGetDriveGeometry;
MachVtbl.DiskGetCacheableBlockCount = XboxDiskGetCacheableBlockCount;
MachVtbl.RTCGetCurrentDateTime = XboxRTCGetCurrentDateTime;
MachVtbl.HwDetect = XboxHwDetect;
}

View File

@@ -0,0 +1,65 @@
/* $Id: machxbox.h,v 1.7 2004/11/28 22:42:40 gvg Exp $
*
* FreeLoader
*
* 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.
*/
#ifndef __I386_MACHXBOX_H_
#define __I386_MACHXBOX_H_
#ifndef __MEMORY_H
#include "mm.h"
#endif
U8 XboxFont8x16[256 * 16];
VOID XboxMachInit(VOID);
VOID XboxConsPutChar(int Ch);
BOOL XboxConsKbHit();
int XboxConsGetCh();
VOID XboxVideoInit(VOID);
VOID XboxVideoClearScreen(U8 Attr);
VIDEODISPLAYMODE XboxVideoSetDisplayMode(char *DisplayModem, BOOL Init);
VOID XboxVideoGetDisplaySize(PU32 Width, PU32 Height, PU32 Depth);
U32 XboxVideoGetBufferSize(VOID);
VOID XboxVideoSetTextCursorPosition(U32 X, U32 Y);
VOID XboxVideoHideShowTextCursor(BOOL Show);
VOID XboxVideoPutChar(int Ch, U8 Attr, unsigned X, unsigned Y);
VOID XboxVideoCopyOffScreenBufferToVRAM(PVOID Buffer);
BOOL XboxVideoIsPaletteFixed(VOID);
VOID XboxVideoSetPaletteColor(U8 Color, U8 Red, U8 Green, U8 Blue);
VOID XboxVideoGetPaletteColor(U8 Color, U8* Red, U8* Green, U8* Blue);
VOID XboxVideoSync(VOID);
VOID XboxVideoPrepareForReactOS(VOID);
VOID XboxMemInit(VOID);
PVOID XboxMemReserveMemory(U32 MbToReserve);
U32 XboxMemGetMemoryMap(PBIOS_MEMORY_MAP BiosMemoryMap, U32 MaxMemoryMapSize);
BOOL XboxDiskReadLogicalSectors(U32 DriveNumber, U64 SectorNumber, U32 SectorCount, PVOID Buffer);
BOOL XboxDiskGetPartitionEntry(U32 DriveNumber, U32 PartitionNumber, PPARTITION_TABLE_ENTRY PartitionTableEntry);
BOOL XboxDiskGetDriveGeometry(U32 DriveNumber, PGEOMETRY DriveGeometry);
U32 XboxDiskGetCacheableBlockCount(U32 DriveNumber);
VOID XboxRTCGetCurrentDateTime(PU32 Year, PU32 Month, PU32 Day, PU32 Hour, PU32 Minute, PU32 Second);
VOID XboxHwDetect(VOID);
#endif /* __I386_HWXBOX_H_ */
/* EOF */

View File

@@ -0,0 +1,153 @@
/*
* FreeLoader
* Copyright (C) 1998-2002 Brian Palmer <brianp@sginet.com>
*
* 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.
*/
.text
.code16
#define ASM
#include <arch.h>
#include <multiboot.h>
/*
* Here we assume the kernel is loaded at 1mb
* This boots the kernel
*/
.code32
EXTERN(_boot_reactos)
call _MachVideoPrepareForReactOS
call _multi_boot
// Should never get here
cli
bootloop:
hlt
jmp bootloop
/*
* After you have setup the _mb_header and _mb_info structures
* then call this routine to transfer control to the kernel.
*/
EXTERN(_multi_boot)
cli
/*
* Load the absolute address of the multiboot information structure
*/
movl $_mb_info,%ebx
/*
* Initalize eflags
*/
pushl $0
popfl
/*
* Load the multiboot magic value into eax
*/
movl $0x2badb002,%eax
/*
* Jump to start of 32 bit code at 0xc0000000 + 0x1000
*/
pushl $KERNEL_CS
pushl _mb_entry_addr
lretl
EXTERN(_mb_header)
_mb_magic:
.long 0 // unsigned long magic;
_mb_flags:
.long 0 // unsigned long flags;
_mb_checksum:
.long 0 // unsigned long checksum;
_mb_header_addr:
.long 0 // unsigned long header_addr;
_mb_load_addr:
.long 0 // unsigned long load_addr;
_mb_load_end_addr:
.long 0 // unsigned long load_end_addr;
_mb_bss_end_addr:
.long 0 // unsigned long bss_end_addr;
_mb_entry_addr:
.long 0 // unsigned long entry_addr;
//
// Boot information structure
//
EXTERN(_mb_info)
_multiboot_flags:
.long 0
_multiboot_mem_lower:
.long 0
_multiboot_mem_upper:
.long 0
_multiboot_boot_device:
.long 0
_multiboot_cmdline:
.long 0
_multiboot_mods_count:
.long 0
_multiboot_mods_addr:
.long 0
_multiboot_syms:
.rept 12
.byte 0
.endr
_multiboot_mmap_length:
.long 0
_multiboot_mmap_addr:
.long 0
_multiboot_drives_count:
.long 0
_multiboot_drives_addr:
.long 0
_multiboot_config_table:
.long 0
_multiboot_boot_loader_name:
.long 0
_multiboot_apm_table:
.long 0
EXTERN(_multiboot_modules)
.rept (64 * /*multiboot_module_size*/ 16)
.byte 0
.endr
EXTERN(_multiboot_module_strings)
.rept (64*256)
.byte 0
.endr
EXTERN(_multiboot_memory_map_descriptor_size)
.long 0
EXTERN(_multiboot_memory_map)
.rept (32 * /*sizeof(memory_map_t)*/24)
.byte 0
.endr
EXTERN(_multiboot_kernel_cmdline)
.rept 255
.byte 0
.endr

View File

@@ -1,4 +1,4 @@
/* $Id$
/* $Id: pccons.c,v 1.3 2004/11/14 22:04:38 gvg Exp $
*
* FreeLoader
*
@@ -12,12 +12,17 @@
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
* 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.
*/
#include <freeldr.h>
#include "freeldr.h"
#include "machine.h"
#include "arch.h"
#include "debug.h"
#include "machpc.h"
#include "rtl.h"
#define TEXTMODE_BUFFER 0xb8000
#define TEXTMODE_BUFFER_SIZE 0x8000
@@ -66,7 +71,7 @@ PcConsPutChar(int Ch)
Int386(0x10, &Regs, &Regs);
}
BOOLEAN
BOOL
PcConsKbHit(VOID)
{
REGS Regs;
@@ -91,7 +96,7 @@ int
PcConsGetCh(void)
{
REGS Regs;
static BOOLEAN ExtendedKey = FALSE;
static BOOL ExtendedKey = FALSE;
static char ExtendedScanCode = 0;
/* If the last time we were called an

View File

@@ -0,0 +1,466 @@
/*
* FreeLoader
* Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>
*
* 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.
*/
#include "freeldr.h"
#include "disk.h"
#include "rtl.h"
#include "arch.h"
#include "debug.h"
#include "portio.h"
#include "machine.h"
#include "machpc.h"
typedef struct
{
U8 PacketSize; // 00h - Size of packet (10h or 18h)
U8 Reserved; // 01h - Reserved (0)
U16 LBABlockCount; // 02h - Number of blocks to transfer (max 007Fh for Phoenix EDD)
U16 TransferBufferOffset; // 04h - Transfer buffer offset (seg:off)
U16 TransferBufferSegment; // Transfer buffer segment (seg:off)
U64 LBAStartBlock; // 08h - Starting absolute block number
U64 TransferBuffer64; // 10h - (EDD-3.0, optional) 64-bit flat address of transfer buffer
// used if DWORD at 04h is FFFFh:FFFFh
} PACKED I386_DISK_ADDRESS_PACKET, *PI386_DISK_ADDRESS_PACKET;
/////////////////////////////////////////////////////////////////////////////////////////////
// FUNCTIONS
/////////////////////////////////////////////////////////////////////////////////////////////
static BOOL PcDiskResetController(U32 DriveNumber)
{
REGS RegsIn;
REGS RegsOut;
DbgPrint((DPRINT_DISK, "PcDiskResetController(0x%x) DISK OPERATION FAILED -- RESETTING CONTROLLER\n", DriveNumber));
// BIOS Int 13h, function 0 - Reset disk system
// AH = 00h
// DL = drive (if bit 7 is set both hard disks and floppy disks reset)
// Return:
// AH = status
// CF clear if successful
// CF set on error
RegsIn.b.ah = 0x00;
RegsIn.b.dl = DriveNumber;
// Reset the disk controller
Int386(0x13, &RegsIn, &RegsOut);
return INT386_SUCCESS(RegsOut);
}
static BOOL PcDiskReadLogicalSectorsLBA(U32 DriveNumber, U64 SectorNumber, U32 SectorCount, PVOID Buffer)
{
REGS RegsIn;
REGS RegsOut;
U32 RetryCount;
PI386_DISK_ADDRESS_PACKET Packet = (PI386_DISK_ADDRESS_PACKET)(BIOSCALLBUFFER);
DbgPrint((DPRINT_DISK, "PcDiskReadLogicalSectorsLBA() DriveNumber: 0x%x SectorNumber: %I64d SectorCount: %d Buffer: 0x%x\n", DriveNumber, SectorNumber, SectorCount, Buffer));
// BIOS int 0x13, function 42h - IBM/MS INT 13 Extensions - EXTENDED READ
RegsIn.b.ah = 0x42; // Subfunction 42h
RegsIn.b.dl = DriveNumber; // Drive number in DL (0 - floppy, 0x80 - harddisk)
RegsIn.x.ds = BIOSCALLBUFSEGMENT; // DS:SI -> disk address packet
RegsIn.w.si = BIOSCALLBUFOFFSET;
// Setup disk address packet
RtlZeroMemory(Packet, sizeof(I386_DISK_ADDRESS_PACKET));
Packet->PacketSize = sizeof(I386_DISK_ADDRESS_PACKET);
Packet->Reserved = 0;
Packet->LBABlockCount = SectorCount;
Packet->TransferBufferOffset = ((U32)Buffer) & 0x0F;
Packet->TransferBufferSegment = ((U32)Buffer) >> 4;
Packet->LBAStartBlock = SectorNumber;
Packet->TransferBuffer64 = 0;
// BIOS int 0x13, function 42h - IBM/MS INT 13 Extensions - EXTENDED READ
// Return:
// CF clear if successful
// AH = 00h
// CF set on error
// AH = error code
// disk address packet's block count field set to the
// number of blocks successfully transferred
// Retry 3 times
for (RetryCount=0; RetryCount<3; RetryCount++)
{
Int386(0x13, &RegsIn, &RegsOut);
// If it worked return TRUE
if (INT386_SUCCESS(RegsOut))
{
return TRUE;
}
// If it was a corrected ECC error then the data is still good
else if (RegsOut.b.ah == 0x11)
{
return TRUE;
}
// If it failed the do the next retry
else
{
PcDiskResetController(DriveNumber);
continue;
}
}
// If we get here then the read failed
DiskError("Disk Read Failed", RegsOut.b.ah);
return FALSE;
}
static BOOL PcDiskReadLogicalSectorsCHS(U32 DriveNumber, U64 SectorNumber, U32 SectorCount, PVOID Buffer)
{
U32 PhysicalSector;
U32 PhysicalHead;
U32 PhysicalTrack;
GEOMETRY DriveGeometry;
U32 NumberOfSectorsToRead;
REGS RegsIn;
REGS RegsOut;
U32 RetryCount;
DbgPrint((DPRINT_DISK, "PcDiskReadLogicalSectorsCHS()\n"));
//
// Get the drive geometry
//
if (!MachDiskGetDriveGeometry(DriveNumber, &DriveGeometry))
{
return FALSE;
}
while (SectorCount)
{
//
// Calculate the physical disk offsets
//
PhysicalSector = 1 + (SectorNumber % DriveGeometry.Sectors);
PhysicalHead = (SectorNumber / DriveGeometry.Sectors) % DriveGeometry.Heads;
PhysicalTrack = (SectorNumber / DriveGeometry.Sectors) / DriveGeometry.Heads;
//
// Calculate how many sectors we need to read this round
//
if (PhysicalSector > 1)
{
if (SectorCount >= (DriveGeometry.Sectors - (PhysicalSector - 1)))
NumberOfSectorsToRead = (DriveGeometry.Sectors - (PhysicalSector - 1));
else
NumberOfSectorsToRead = SectorCount;
}
else
{
if (SectorCount >= DriveGeometry.Sectors)
NumberOfSectorsToRead = DriveGeometry.Sectors;
else
NumberOfSectorsToRead = SectorCount;
}
//
// Make sure the read is within the geometry boundaries
//
if ((PhysicalHead >= DriveGeometry.Heads) ||
(PhysicalTrack >= DriveGeometry.Cylinders) ||
((NumberOfSectorsToRead + PhysicalSector) > (DriveGeometry.Sectors + 1)) ||
(PhysicalSector > DriveGeometry.Sectors))
{
DiskError("Disk read exceeds drive geometry limits.", 0);
return FALSE;
}
// BIOS Int 13h, function 2 - Read Disk Sectors
// AH = 02h
// AL = number of sectors to read (must be nonzero)
// CH = low eight bits of cylinder number
// CL = sector number 1-63 (bits 0-5)
// high two bits of cylinder (bits 6-7, hard disk only)
// DH = head number
// DL = drive number (bit 7 set for hard disk)
// ES:BX -> data buffer
// Return:
// CF set on error
// if AH = 11h (corrected ECC error), AL = burst length
// CF clear if successful
// AH = status
// AL = number of sectors transferred
// (only valid if CF set for some BIOSes)
RegsIn.b.ah = 0x02;
RegsIn.b.al = NumberOfSectorsToRead;
RegsIn.b.ch = (PhysicalTrack & 0xFF);
RegsIn.b.cl = (PhysicalSector + ((PhysicalTrack & 0x300) >> 2));
RegsIn.b.dh = PhysicalHead;
RegsIn.b.dl = DriveNumber;
RegsIn.w.es = ((U32)Buffer) >> 4;
RegsIn.w.bx = ((U32)Buffer) & 0x0F;
//
// Perform the read
// Retry 3 times
//
for (RetryCount=0; RetryCount<3; RetryCount++)
{
Int386(0x13, &RegsIn, &RegsOut);
// If it worked break out
if (INT386_SUCCESS(RegsOut))
{
break;
}
// If it was a corrected ECC error then the data is still good
else if (RegsOut.b.ah == 0x11)
{
break;
}
// If it failed the do the next retry
else
{
PcDiskResetController(DriveNumber);
continue;
}
}
// If we retried 3 times then fail
if (RetryCount >= 3)
{
DiskError("Disk Read Failed", RegsOut.b.ah);
return FALSE;
}
// I have learned that not all bioses return
// the sector read count in the AL register (at least mine doesn't)
// even if the sectors were read correctly. So instead
// of checking the sector read count we will rely solely
// on the carry flag being set on error
Buffer += (NumberOfSectorsToRead * DriveGeometry.BytesPerSector);
SectorCount -= NumberOfSectorsToRead;
SectorNumber += NumberOfSectorsToRead;
}
return TRUE;
}
static BOOL PcDiskInt13ExtensionsSupported(U32 DriveNumber)
{
static U32 LastDriveNumber = 0xffffffff;
static BOOL LastSupported;
REGS RegsIn;
REGS RegsOut;
DbgPrint((DPRINT_DISK, "PcDiskInt13ExtensionsSupported()\n"));
if (DriveNumber == LastDriveNumber)
{
DbgPrint((DPRINT_DISK, "Using cached value %s for drive 0x%x\n", LastSupported ? "TRUE" : "FALSE", DriveNumber));
return LastSupported;
}
LastDriveNumber = DriveNumber;
// IBM/MS INT 13 Extensions - INSTALLATION CHECK
// AH = 41h
// BX = 55AAh
// DL = drive (80h-FFh)
// Return:
// CF set on error (extensions not supported)
// AH = 01h (invalid function)
// CF clear if successful
// BX = AA55h if installed
// AH = major version of extensions
// 01h = 1.x
// 20h = 2.0 / EDD-1.0
// 21h = 2.1 / EDD-1.1
// 30h = EDD-3.0
// AL = internal use
// CX = API subset support bitmap
// DH = extension version (v2.0+ ??? -- not present in 1.x)
//
// Bitfields for IBM/MS INT 13 Extensions API support bitmap
// Bit 0, extended disk access functions (AH=42h-44h,47h,48h) supported
// Bit 1, removable drive controller functions (AH=45h,46h,48h,49h,INT 15/AH=52h) supported
// Bit 2, enhanced disk drive (EDD) functions (AH=48h,AH=4Eh) supported
// extended drive parameter table is valid
// Bits 3-15 reserved
RegsIn.b.ah = 0x41;
RegsIn.w.bx = 0x55AA;
RegsIn.b.dl = DriveNumber;
// Reset the disk controller
Int386(0x13, &RegsIn, &RegsOut);
if (!INT386_SUCCESS(RegsOut))
{
// CF set on error (extensions not supported)
LastSupported = FALSE;
return FALSE;
}
if (RegsOut.w.bx != 0xAA55)
{
// BX = AA55h if installed
LastSupported = FALSE;
return FALSE;
}
// Note:
// The original check is too strict because some BIOSes report that
// extended disk access functions are not suported when booting
// from a CD (e.g. Phoenix BIOS v6.00PG). Argh!
#if 0
if (!(RegsOut.w.cx & 0x0001))
{
// CX = API subset support bitmap
// Bit 0, extended disk access functions (AH=42h-44h,47h,48h) supported
LastSupported = FALSE;
return FALSE;
}
#endif
// Use this relaxed check instead (most BIOSes seem to use 0x9f as CD-Rom)
if (RegsOut.w.cx == 0x0000 && DriveNumber != 0x9f)
{
// CX = API subset support bitmap
printf("Suspicious API subset support bitmap 0x%x on device 0x%x\n", RegsOut.w.cx, DriveNumber);
LastSupported = FALSE;
return LastSupported;
}
LastSupported = TRUE;
return TRUE;
}
BOOL PcDiskReadLogicalSectors(U32 DriveNumber, U64 SectorNumber, U32 SectorCount, PVOID Buffer)
{
DbgPrint((DPRINT_DISK, "PcDiskReadLogicalSectors() DriveNumber: 0x%x SectorNumber: %I64d SectorCount: %d Buffer: 0x%x\n", DriveNumber, SectorNumber, SectorCount, Buffer));
//
// Check to see if it is a fixed disk drive
// If so then check to see if Int13 extensions work
// If they do then use them, otherwise default back to BIOS calls
//
if ((DriveNumber >= 0x80) && PcDiskInt13ExtensionsSupported(DriveNumber))
{
DbgPrint((DPRINT_DISK, "Using Int 13 Extensions for read. PcDiskInt13ExtensionsSupported(%d) = %s\n", DriveNumber, PcDiskInt13ExtensionsSupported(DriveNumber) ? "TRUE" : "FALSE"));
//
// LBA is easy, nothing to calculate
// Just do the read
//
return PcDiskReadLogicalSectorsLBA(DriveNumber, SectorNumber, SectorCount, Buffer);
}
else
{
// LBA is not supported default to the CHS calls
return PcDiskReadLogicalSectorsCHS(DriveNumber, SectorNumber, SectorCount, Buffer);
}
return TRUE;
}
BOOL
PcDiskGetPartitionEntry(U32 DriveNumber, U32 PartitionNumber, PPARTITION_TABLE_ENTRY PartitionTableEntry)
{
/* Just use the standard routine */
return DiskGetPartitionEntry(DriveNumber, PartitionNumber, PartitionTableEntry);
}
BOOL
PcDiskGetDriveGeometry(U32 DriveNumber, PGEOMETRY Geometry)
{
REGS RegsIn;
REGS RegsOut;
U32 Cylinders;
DbgPrint((DPRINT_DISK, "DiskGetDriveGeometry()\n"));
/* BIOS Int 13h, function 08h - Get drive parameters
* AH = 08h
* DL = drive (bit 7 set for hard disk)
* ES:DI = 0000h:0000h to guard against BIOS bugs
* Return:
* CF set on error
* AH = status (07h)
* CF clear if successful
* AH = 00h
* AL = 00h on at least some BIOSes
* BL = drive type (AT/PS2 floppies only)
* CH = low eight bits of maximum cylinder number
* CL = maximum sector number (bits 5-0)
* high two bits of maximum cylinder number (bits 7-6)
* DH = maximum head number
* DL = number of drives
* ES:DI -> drive parameter table (floppies only)
*/
RegsIn.b.ah = 0x08;
RegsIn.b.dl = DriveNumber;
RegsIn.w.es = 0x0000;
RegsIn.w.di = 0x0000;
/* Get drive parameters */
Int386(0x13, &RegsIn, &RegsOut);
if (! INT386_SUCCESS(RegsOut))
{
return FALSE;
}
Cylinders = (RegsOut.b.cl & 0xC0) << 2;
Cylinders += RegsOut.b.ch;
Cylinders++;
Geometry->Cylinders = Cylinders;
Geometry->Heads = RegsOut.b.dh + 1;
Geometry->Sectors = RegsOut.b.cl & 0x3F;
Geometry->BytesPerSector = 512; /* Just assume 512 bytes per sector */
return TRUE;
}
U32
PcDiskGetCacheableBlockCount(U32 DriveNumber)
{
GEOMETRY Geometry;
/* If LBA is supported then the block size will be 64 sectors (32k)
* If not then the block size is the size of one track */
if (DiskInt13ExtensionsSupported(DriveNumber))
{
return 64;
}
/* Get the disk geometry
* If this fails then we will just return 1 sector to be safe */
else if (! PcDiskGetDriveGeometry(DriveNumber, &Geometry))
{
return 1;
}
else
{
return Geometry.Sectors;
}
}
/* EOF */

View File

@@ -0,0 +1,252 @@
/* $Id: pcmem.c,v 1.2 2004/11/10 23:45:37 gvg Exp $
*
* FreeLoader
*
* 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.
*
* Note: Most of this code comes from the old file "i386mem.c", which
* was Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>
*/
#include "freeldr.h"
#include "arch.h"
#include "debug.h"
#include "machine.h"
#include "machpc.h"
#include "portio.h"
#include "rtl.h"
static U32
PcMemGetExtendedMemorySize(VOID)
{
REGS RegsIn;
REGS RegsOut;
U32 MemorySize;
DbgPrint((DPRINT_MEMORY, "GetExtendedMemorySize()\n"));
/* Int 15h AX=E801h
* Phoenix BIOS v4.0 - GET MEMORY SIZE FOR >64M CONFIGURATIONS
*
* AX = E801h
* Return:
* CF clear if successful
* AX = extended memory between 1M and 16M, in K (max 3C00h = 15MB)
* BX = extended memory above 16M, in 64K blocks
* CX = configured memory 1M to 16M, in K
* DX = configured memory above 16M, in 64K blocks
* CF set on error
*/
RegsIn.w.ax = 0xE801;
Int386(0x15, &RegsIn, &RegsOut);
DbgPrint((DPRINT_MEMORY, "Int15h AX=E801h\n"));
DbgPrint((DPRINT_MEMORY, "AX = 0x%x\n", RegsOut.w.ax));
DbgPrint((DPRINT_MEMORY, "BX = 0x%x\n", RegsOut.w.bx));
DbgPrint((DPRINT_MEMORY, "CX = 0x%x\n", RegsOut.w.cx));
DbgPrint((DPRINT_MEMORY, "DX = 0x%x\n", RegsOut.w.dx));
DbgPrint((DPRINT_MEMORY, "CF set = %s\n\n", (RegsOut.x.eflags & I386FLAG_CF) ? "TRUE" : "FALSE"));
if (INT386_SUCCESS(RegsOut))
{
/* If AX=BX=0000h the use CX and DX */
if (RegsOut.w.ax == 0)
{
/* Return extended memory size in K */
MemorySize = RegsOut.w.dx * 64;
MemorySize += RegsOut.w.cx;
return MemorySize;
}
else
{
/* Return extended memory size in K */
MemorySize = RegsOut.w.bx * 64;
MemorySize += RegsOut.w.ax;
return MemorySize;
}
}
/* If we get here then Int15 Func E801h didn't work */
/* So try Int15 Func 88h */
/* Int 15h AH=88h
* SYSTEM - GET EXTENDED MEMORY SIZE (286+)
*
* AH = 88h
* Return:
* CF clear if successful
* AX = number of contiguous KB starting at absolute address 100000h
* CF set on error
* AH = status
* 80h invalid command (PC,PCjr)
* 86h unsupported function (XT,PS30)
*/
RegsIn.b.ah = 0x88;
Int386(0x15, &RegsIn, &RegsOut);
DbgPrint((DPRINT_MEMORY, "Int15h AH=88h\n"));
DbgPrint((DPRINT_MEMORY, "AX = 0x%x\n", RegsOut.w.ax));
DbgPrint((DPRINT_MEMORY, "CF set = %s\n\n", (RegsOut.x.eflags & I386FLAG_CF) ? "TRUE" : "FALSE"));
if (INT386_SUCCESS(RegsOut) && RegsOut.w.ax != 0)
{
MemorySize = RegsOut.w.ax;
return MemorySize;
}
/* If we get here then Int15 Func 88h didn't work */
/* So try reading the CMOS */
WRITE_PORT_UCHAR((PUCHAR)0x70, 0x31);
MemorySize = READ_PORT_UCHAR((PUCHAR)0x71);
MemorySize = (MemorySize & 0xFFFF);
MemorySize = (MemorySize << 8);
DbgPrint((DPRINT_MEMORY, "Int15h Failed\n"));
DbgPrint((DPRINT_MEMORY, "CMOS reports: 0x%x\n", MemorySize));
return MemorySize;
}
static U32
PcMemGetConventionalMemorySize(VOID)
{
REGS Regs;
DbgPrint((DPRINT_MEMORY, "GetConventionalMemorySize()\n"));
/* Int 12h
* BIOS - GET MEMORY SIZE
*
* Return:
* AX = kilobytes of contiguous memory starting at absolute address 00000h
*
* This call returns the contents of the word at 0040h:0013h;
* in PC and XT, this value is set from the switches on the motherboard
*/
Regs.w.ax = 0;
Int386(0x12, &Regs, &Regs);
DbgPrint((DPRINT_MEMORY, "Int12h\n"));
DbgPrint((DPRINT_MEMORY, "AX = 0x%x\n\n", Regs.w.ax));
return (U32)Regs.w.ax;
}
static U32
PcMemGetBiosMemoryMap(PBIOS_MEMORY_MAP BiosMemoryMap, U32 MaxMemoryMapSize)
{
REGS Regs;
U32 MapCount;
DbgPrint((DPRINT_MEMORY, "GetBiosMemoryMap()\n"));
/* Int 15h AX=E820h
* Newer BIOSes - GET SYSTEM MEMORY MAP
*
* AX = E820h
* EAX = 0000E820h
* EDX = 534D4150h ('SMAP')
* EBX = continuation value or 00000000h to start at beginning of map
* ECX = size of buffer for result, in bytes (should be >= 20 bytes)
* ES:DI -> buffer for result
* Return:
* CF clear if successful
* EAX = 534D4150h ('SMAP')
* ES:DI buffer filled
* EBX = next offset from which to copy or 00000000h if all done
* ECX = actual length returned in bytes
* CF set on error
* AH = error code (86h)
*/
Regs.x.eax = 0x0000E820;
Regs.x.edx = 0x534D4150; /* ('SMAP') */
Regs.x.ebx = 0x00000000;
Regs.x.ecx = sizeof(BIOS_MEMORY_MAP);
Regs.w.es = BIOSCALLBUFSEGMENT;
Regs.w.di = BIOSCALLBUFOFFSET;
for (MapCount = 0; MapCount < MaxMemoryMapSize; MapCount++)
{
Int386(0x15, &Regs, &Regs);
DbgPrint((DPRINT_MEMORY, "Memory Map Entry %d\n", MapCount));
DbgPrint((DPRINT_MEMORY, "Int15h AX=E820h\n"));
DbgPrint((DPRINT_MEMORY, "EAX = 0x%x\n", Regs.x.eax));
DbgPrint((DPRINT_MEMORY, "EBX = 0x%x\n", Regs.x.ebx));
DbgPrint((DPRINT_MEMORY, "ECX = 0x%x\n", Regs.x.ecx));
DbgPrint((DPRINT_MEMORY, "CF set = %s\n", (Regs.x.eflags & I386FLAG_CF) ? "TRUE" : "FALSE"));
/* If the BIOS didn't return 'SMAP' in EAX then
* it doesn't support this call */
if (Regs.x.eax != 0x534D4150)
{
break;
}
/* Copy data to caller's buffer */
RtlCopyMemory(&BiosMemoryMap[MapCount], (PVOID)BIOSCALLBUFFER, Regs.x.ecx);
DbgPrint((DPRINT_MEMORY, "BaseAddress: 0x%x%x\n", BiosMemoryMap[MapCount].BaseAddress));
DbgPrint((DPRINT_MEMORY, "Length: 0x%x%x\n", BiosMemoryMap[MapCount].Length));
DbgPrint((DPRINT_MEMORY, "Type: 0x%x\n", BiosMemoryMap[MapCount].Type));
DbgPrint((DPRINT_MEMORY, "Reserved: 0x%x\n", BiosMemoryMap[MapCount].Reserved));
DbgPrint((DPRINT_MEMORY, "\n"));
/* If the continuation value is zero or the
* carry flag is set then this was
* the last entry so we're done */
if (Regs.x.ebx == 0x00000000 || !INT386_SUCCESS(Regs))
{
MapCount++;
DbgPrint((DPRINT_MEMORY, "End Of System Memory Map!\n\n"));
break;
}
/* Setup the registers for the next call */
Regs.x.eax = 0x0000E820;
Regs.x.edx = 0x534D4150; /* ('SMAP') */
/* Regs.x.ebx = 0x00000001; Continuation value already set by the BIOS */
Regs.x.ecx = sizeof(BIOS_MEMORY_MAP);
Regs.w.es = BIOSCALLBUFSEGMENT;
Regs.w.di = BIOSCALLBUFOFFSET;
}
return MapCount;
}
U32
PcMemGetMemoryMap(PBIOS_MEMORY_MAP BiosMemoryMap, U32 MaxMemoryMapSize)
{
U32 EntryCount;
EntryCount = PcMemGetBiosMemoryMap(BiosMemoryMap, MaxMemoryMapSize);
/* If the BIOS didn't provide a memory map, synthesize one */
if (0 == EntryCount && 2 <= MaxMemoryMapSize)
{
/* Conventional memory */
BiosMemoryMap[0].BaseAddress = 0;
BiosMemoryMap[0].Length = PcMemGetConventionalMemorySize() * 1024;
BiosMemoryMap[0].Type = MEMTYPE_USABLE;
/* Extended memory */
BiosMemoryMap[1].BaseAddress = 1024 * 1024;
BiosMemoryMap[1].Length = PcMemGetExtendedMemorySize() * 1024;
BiosMemoryMap[1].Type = MEMTYPE_USABLE;
EntryCount = 2;
}
return EntryCount;
}
/* EOF */

View File

@@ -0,0 +1,107 @@
/* $Id: pcrtc.c,v 1.1 2004/11/14 22:04:38 gvg Exp $
*
* FreeLoader
*
* 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.
*/
#include "freeldr.h"
#include "arch.h"
#include "machine.h"
#include "machpc.h"
#define BCD_INT(bcd) (((bcd & 0xf0) >> 4) * 10 + (bcd &0x0f))
VOID
PcRTCGetCurrentDateTime(PU32 Year, PU32 Month, PU32 Day, PU32 Hour, PU32 Minute, PU32 Second)
{
REGS Regs;
if (NULL != Year || NULL != Month || NULL != Day)
{
/* Some BIOSes, such es the 1998/07/25 system ROM
* in the Compaq Deskpro EP/SB, leave CF unchanged
* if successful, so CF should be cleared before
* calling this function. */
__asm__ ("clc");
/* Int 1Ah AH=04h
* TIME - GET REAL-TIME CLOCK DATE (AT,XT286,PS)
*
* AH = 04h
* CF clear to avoid bug
* Return:
* CF clear if successful
* CH = century (BCD)
* CL = year (BCD)
* DH = month (BCD)
* DL = day (BCD)
* CF set on error
*/
Regs.b.ah = 0x04;
Int386(0x1A, &Regs, &Regs);
if (NULL != Year)
{
*Year = 100 * BCD_INT(Regs.b.cl) + BCD_INT(Regs.b.ch);
}
if (NULL != Month)
{
*Month = BCD_INT(Regs.b.dh);
}
if (NULL != Day)
{
*Day = BCD_INT(Regs.b.dl);
}
}
if (NULL != Hour || NULL != Minute || NULL != Second)
{
/* Some BIOSes leave CF unchanged if successful,
* so CF should be cleared before calling this function. */
__asm__ ("clc");
/* Int 1Ah AH=02h
* TIME - GET REAL-TIME CLOCK TIME (AT,XT286,PS)
*
* AH = 02h
* CF clear to avoid bug
* Return:
* CF clear if successful
* CH = hour (BCD)
* CL = minutes (BCD)
* DH = seconds (BCD)
* DL = daylight savings flag (00h standard time, 01h daylight time)
* CF set on error (i.e. clock not running or in middle of update)
*/
Regs.b.ah = 0x02;
Int386(0x1A, &Regs, &Regs);
if (NULL != Hour)
{
*Hour = BCD_INT(Regs.b.ch);
}
if (NULL != Minute)
{
*Minute = BCD_INT(Regs.b.cl);
}
if (NULL != Second)
{
*Second = BCD_INT(Regs.b.dh);
}
}
}
/* EOF */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,183 @@
/* $Id: portio.c,v 1.1 2003/01/19 01:03:58 bpalmer Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/hal/x86/portio.c
* PURPOSE: Port I/O functions
* PROGRAMMER: Eric Kohl (ekohl@abo.rhein-zeitung.de)
* UPDATE HISTORY:
* Created 18/10/99
*/
//#include <ddk/ntddk.h>
#include <freeldr.h>
/* FUNCTIONS ****************************************************************/
/*
* This file contains the definitions for the x86 IO instructions
* inb/inw/inl/outb/outw/outl and the "string versions" of the same
* (insb/insw/insl/outsb/outsw/outsl). You can also use "pausing"
* versions of the single-IO instructions (inb_p/inw_p/..).
*
* This file is not meant to be obfuscating: it's just complicated
* to (a) handle it all in a way that makes gcc able to optimize it
* as well as possible and (b) trying to avoid writing the same thing
* over and over again with slight variations and possibly making a
* mistake somewhere.
*/
/*
* Thanks to James van Artsdalen for a better timing-fix than
* the two short jumps: using outb's to a nonexistent port seems
* to guarantee better timings even on fast machines.
*
* On the other hand, I'd like to be sure of a non-existent port:
* I feel a bit unsafe about using 0x80 (should be safe, though)
*
* Linus
*/
#ifdef SLOW_IO_BY_JUMPING
#define __SLOW_DOWN_IO __asm__ __volatile__("jmp 1f\n1:\tjmp 1f\n1:")
#else
#define __SLOW_DOWN_IO __asm__ __volatile__("outb %al,$0x80")
#endif
#ifdef REALLY_SLOW_IO
#define SLOW_DOWN_IO { __SLOW_DOWN_IO; __SLOW_DOWN_IO; __SLOW_DOWN_IO; __SLOW_DOWN_IO; }
#else
#define SLOW_DOWN_IO __SLOW_DOWN_IO
#endif
VOID /*STDCALL*/
READ_PORT_BUFFER_UCHAR (PUCHAR Port,
PUCHAR Buffer,
U32 Count)
{
__asm__ __volatile__ ("cld ; rep ; insb\n\t"
: "=D" (Buffer), "=c" (Count)
: "d" (Port),"0" (Buffer),"1" (Count));
}
VOID /*STDCALL*/
READ_PORT_BUFFER_USHORT (U16* Port,
U16* Buffer,
U32 Count)
{
__asm__ __volatile__ ("cld ; rep ; insw"
: "=D" (Buffer), "=c" (Count)
: "d" (Port),"0" (Buffer),"1" (Count));
}
VOID /*STDCALL*/
READ_PORT_BUFFER_ULONG (U32* Port,
U32* Buffer,
U32 Count)
{
__asm__ __volatile__ ("cld ; rep ; insl"
: "=D" (Buffer), "=c" (Count)
: "d" (Port),"0" (Buffer),"1" (Count));
}
UCHAR /*STDCALL*/
READ_PORT_UCHAR (PUCHAR Port)
{
UCHAR Value;
__asm__("inb %w1, %0\n\t"
: "=a" (Value)
: "d" (Port));
SLOW_DOWN_IO;
return(Value);
}
U16 /*STDCALL*/
READ_PORT_USHORT (U16* Port)
{
U16 Value;
__asm__("inw %w1, %0\n\t"
: "=a" (Value)
: "d" (Port));
SLOW_DOWN_IO;
return(Value);
}
U32 /*STDCALL*/
READ_PORT_ULONG (U32* Port)
{
U32 Value;
__asm__("inl %w1, %0\n\t"
: "=a" (Value)
: "d" (Port));
SLOW_DOWN_IO;
return(Value);
}
VOID /*STDCALL*/
WRITE_PORT_BUFFER_UCHAR (PUCHAR Port,
PUCHAR Buffer,
U32 Count)
{
__asm__ __volatile__ ("cld ; rep ; outsb"
: "=S" (Buffer), "=c" (Count)
: "d" (Port),"0" (Buffer),"1" (Count));
}
VOID /*STDCALL*/
WRITE_PORT_BUFFER_USHORT (U16* Port,
U16* Buffer,
U32 Count)
{
__asm__ __volatile__ ("cld ; rep ; outsw"
: "=S" (Buffer), "=c" (Count)
: "d" (Port),"0" (Buffer),"1" (Count));
}
VOID /*STDCALL*/
WRITE_PORT_BUFFER_ULONG (U32* Port,
U32* Buffer,
U32 Count)
{
__asm__ __volatile__ ("cld ; rep ; outsl"
: "=S" (Buffer), "=c" (Count)
: "d" (Port),"0" (Buffer),"1" (Count));
}
VOID /*STDCALL*/
WRITE_PORT_UCHAR (PUCHAR Port,
UCHAR Value)
{
__asm__("outb %0, %w1\n\t"
:
: "a" (Value),
"d" (Port));
SLOW_DOWN_IO;
}
VOID /*STDCALL*/
WRITE_PORT_USHORT (U16* Port,
U16 Value)
{
__asm__("outw %0, %w1\n\t"
:
: "a" (Value),
"d" (Port));
SLOW_DOWN_IO;
}
VOID /*STDCALL*/
WRITE_PORT_ULONG (U32* Port,
U32 Value)
{
__asm__("outl %0, %w1\n\t"
:
: "a" (Value),
"d" (Port));
SLOW_DOWN_IO;
}
/* EOF */

View File

@@ -1,4 +1,4 @@
/* $Id$
/* $Id: xboxcons.c,v 1.1 2004/11/14 22:04:38 gvg Exp $
*
* FreeLoader
*
@@ -12,12 +12,14 @@
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
* 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.
*/
#include <freeldr.h>
#include "freeldr.h"
#include "machine.h"
#include "machxbox.h"
static unsigned CurrentCursorX = 0;
static unsigned CurrentCursorY = 0;
@@ -26,9 +28,9 @@ static unsigned CurrentAttr = 0x0f;
VOID
XboxConsPutChar(int c)
{
ULONG Width;
ULONG Height;
ULONG Depth;
U32 Width;
U32 Height;
U32 Depth;
if ('\r' == c)
{
@@ -56,7 +58,7 @@ XboxConsPutChar(int c)
}
}
BOOLEAN
BOOL
XboxConsKbHit(VOID)
{
/* No keyboard support yet */
@@ -71,8 +73,6 @@ XboxConsGetCh(void)
{
;
}
return 0;
}
/* EOF */

View File

@@ -0,0 +1,575 @@
/* $Id: xboxdisk.c,v 1.3 2004/11/12 17:17:07 gvg Exp $
*
* FreeLoader
*
* 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.
*
* Note: mostly ripped from atapi.c
* Some of this code was based on knowledge and/or code developed
* by the Xbox Linux group: http://www.xbox-linux.org
*
*/
#include "freeldr.h"
#include "debug.h"
#include "hardware.h"
#include "machine.h"
#include "machxbox.h"
#include "portio.h"
#include "rtl.h"
#define XBOX_IDE_COMMAND_PORT 0x1f0
#define XBOX_IDE_CONTROL_PORT 0x170
#define XBOX_SIGNATURE_SECTOR 3
#define XBOX_SIGNATURE ('B' | ('R' << 8) | ('F' << 16) | ('R' << 24))
static struct
{
U32 SectorCountBeforePartition;
U32 PartitionSectorCount;
U8 SystemIndicator;
} XboxPartitions[] =
{
/* This is in the \Device\Harddisk0\Partition.. order used by the Xbox kernel */
{ 0x0055F400, 0x0098f800, PARTITION_FAT32 }, /* Store, E: */
{ 0x00465400, 0x000FA000, PARTITION_FAT_16 }, /* System, C: */
{ 0x00000400, 0x00177000, PARTITION_FAT_16 }, /* Cache1, X: */
{ 0x00177400, 0x00177000, PARTITION_FAT_16 }, /* Cache2, Y: */
{ 0x002EE400, 0x00177000, PARTITION_FAT_16 } /* Cache3, Z: */
};
#define IDE_SECTOR_BUF_SZ 512
#define IDE_MAX_POLL_RETRIES 100000
#define IDE_MAX_BUSY_RETRIES 50000
/* Control Block offsets and masks */
#define IDE_REG_ALT_STATUS 0x0000
#define IDE_REG_DEV_CNTRL 0x0000 /* device control register */
#define IDE_DC_SRST 0x04 /* drive reset (both drives) */
#define IDE_DC_nIEN 0x02 /* IRQ enable (active low) */
#define IDE_REG_DRV_ADDR 0x0001
/* Command Block offsets and masks */
#define IDE_REG_DATA_PORT 0x0000
#define IDE_REG_ERROR 0x0001 /* error register */
#define IDE_ER_AMNF 0x01 /* addr mark not found */
#define IDE_ER_TK0NF 0x02 /* track 0 not found */
#define IDE_ER_ABRT 0x04 /* command aborted */
#define IDE_ER_MCR 0x08 /* media change requested */
#define IDE_ER_IDNF 0x10 /* ID not found */
#define IDE_ER_MC 0x20 /* Media changed */
#define IDE_ER_UNC 0x40 /* Uncorrectable data error */
#define IDE_REG_PRECOMP 0x0001
#define IDE_REG_SECTOR_CNT 0x0002
#define IDE_REG_SECTOR_NUM 0x0003
#define IDE_REG_CYL_LOW 0x0004
#define IDE_REG_CYL_HIGH 0x0005
#define IDE_REG_DRV_HEAD 0x0006
#define IDE_DH_FIXED 0xA0
#define IDE_DH_LBA 0x40
#define IDE_DH_HDMASK 0x0F
#define IDE_DH_DRV0 0x00
#define IDE_DH_DRV1 0x10
#define IDE_REG_STATUS 0x0007
#define IDE_SR_BUSY 0x80
#define IDE_SR_DRDY 0x40
#define IDE_SR_WERR 0x20
#define IDE_SR_DRQ 0x08
#define IDE_SR_ERR 0x01
#define IDE_REG_COMMAND 0x0007
/* IDE/ATA commands */
#define IDE_CMD_RESET 0x08
#define IDE_CMD_READ 0x20
#define IDE_CMD_READ_RETRY 0x21
#define IDE_CMD_WRITE 0x30
#define IDE_CMD_WRITE_RETRY 0x31
#define IDE_CMD_PACKET 0xA0
#define IDE_CMD_READ_MULTIPLE 0xC4
#define IDE_CMD_WRITE_MULTIPLE 0xC5
#define IDE_CMD_READ_DMA 0xC8
#define IDE_CMD_WRITE_DMA 0xCA
#define IDE_CMD_FLUSH_CACHE 0xE7
#define IDE_CMD_FLUSH_CACHE_EXT 0xEA
#define IDE_CMD_IDENT_ATA_DRV 0xEC
#define IDE_CMD_IDENT_ATAPI_DRV 0xA1
#define IDE_CMD_GET_MEDIA_STATUS 0xDA
/*
* Access macros for command registers
* Each macro takes an address of the command port block, and data
*/
#define IDEReadError(Address) \
(READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_ERROR)))
#define IDEWritePrecomp(Address, Data) \
(WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_PRECOMP), (Data)))
#define IDEReadSectorCount(Address) \
(READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_SECTOR_CNT)))
#define IDEWriteSectorCount(Address, Data) \
(WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_SECTOR_CNT), (Data)))
#define IDEReadSectorNum(Address) \
(READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_SECTOR_NUM)))
#define IDEWriteSectorNum(Address, Data) \
(WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_SECTOR_NUM), (Data)))
#define IDEReadCylinderLow(Address) \
(READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_CYL_LOW)))
#define IDEWriteCylinderLow(Address, Data) \
(WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_CYL_LOW), (Data)))
#define IDEReadCylinderHigh(Address) \
(READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_CYL_HIGH)))
#define IDEWriteCylinderHigh(Address, Data) \
(WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_CYL_HIGH), (Data)))
#define IDEReadDriveHead(Address) \
(READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_DRV_HEAD)))
#define IDEWriteDriveHead(Address, Data) \
(WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_DRV_HEAD), (Data)))
#define IDEReadStatus(Address) \
(READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_STATUS)))
#define IDEWriteCommand(Address, Data) \
(WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_COMMAND), (Data)))
#define IDEReadDMACommand(Address) \
(READ_PORT_UCHAR((PUCHAR)((Address))))
#define IDEWriteDMACommand(Address, Data) \
(WRITE_PORT_UCHAR((PUCHAR)((Address)), (Data)))
#define IDEReadDMAStatus(Address) \
(READ_PORT_UCHAR((PUCHAR)((Address) + 2)))
#define IDEWriteDMAStatus(Address, Data) \
(WRITE_PORT_UCHAR((PUCHAR)((Address) + 2), (Data)))
#define IDEWritePRDTable(Address, Data) \
(WRITE_PORT_ULONG((PULONG)((Address) + 4), (Data)))
/*
* Data block read and write commands
*/
#define IDEReadBlock(Address, Buffer, Count) \
(READ_PORT_BUFFER_USHORT((PU16)((Address) + IDE_REG_DATA_PORT), (PU16)(Buffer), (Count) / 2))
#define IDEWriteBlock(Address, Buffer, Count) \
(WRITE_PORT_BUFFER_USHORT((PU16)((Address) + IDE_REG_DATA_PORT), (PU16)(Buffer), (Count) / 2))
#define IDEReadBlock32(Address, Buffer, Count) \
(READ_PORT_BUFFER_ULONG((PU32)((Address) + IDE_REG_DATA_PORT), (PU32)(Buffer), (Count) / 4))
#define IDEWriteBlock32(Address, Buffer, Count) \
(WRITE_PORT_BUFFER_ULONG((PU32)((Address) + IDE_REG_DATA_PORT), (PU32)(Buffer), (Count) / 4))
#define IDEReadWord(Address) \
(READ_PORT_USHORT((PU16)((Address) + IDE_REG_DATA_PORT)))
/*
* Access macros for control registers
* Each macro takes an address of the control port blank and data
*/
#define IDEReadAltStatus(Address) \
(READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_ALT_STATUS)))
#define IDEWriteDriveControl(Address, Data) \
(WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_DEV_CNTRL), (Data)))
/* IDE_DRIVE_IDENTIFY */
typedef struct _IDE_DRIVE_IDENTIFY
{
U16 ConfigBits; /*00*/
U16 LogicalCyls; /*01*/
U16 Reserved02; /*02*/
U16 LogicalHeads; /*03*/
U16 BytesPerTrack; /*04*/
U16 BytesPerSector; /*05*/
U16 SectorsPerTrack; /*06*/
U8 InterSectorGap; /*07*/
U8 InterSectorGapSize;
U8 Reserved08H; /*08*/
U8 BytesInPLO;
U16 VendorUniqueCnt; /*09*/
char SerialNumber[20]; /*10*/
U16 ControllerType; /*20*/
U16 BufferSize; /*21*/
U16 ECCByteCnt; /*22*/
char FirmwareRev[8]; /*23*/
char ModelNumber[40]; /*27*/
U16 RWMultImplemented; /*47*/
U16 DWordIo; /*48*/
U16 Capabilities; /*49*/
#define IDE_DRID_STBY_SUPPORTED 0x2000
#define IDE_DRID_IORDY_SUPPORTED 0x0800
#define IDE_DRID_IORDY_DISABLE 0x0400
#define IDE_DRID_LBA_SUPPORTED 0x0200
#define IDE_DRID_DMA_SUPPORTED 0x0100
U16 Reserved50; /*50*/
U16 MinPIOTransTime; /*51*/
U16 MinDMATransTime; /*52*/
U16 TMFieldsValid; /*53*/
U16 TMCylinders; /*54*/
U16 TMHeads; /*55*/
U16 TMSectorsPerTrk; /*56*/
U16 TMCapacityLo; /*57*/
U16 TMCapacityHi; /*58*/
U16 RWMultCurrent; /*59*/
U16 TMSectorCountLo; /*60*/
U16 TMSectorCountHi; /*61*/
U16 DmaModes; /*62*/
U16 MultiDmaModes; /*63*/
U16 Reserved64[5]; /*64*/
U16 Reserved69[2]; /*69*/
U16 Reserved71[4]; /*71*/
U16 MaxQueueDepth; /*75*/
U16 Reserved76[4]; /*76*/
U16 MajorRevision; /*80*/
U16 MinorRevision; /*81*/
U16 SupportedFeatures82; /*82*/
U16 SupportedFeatures83; /*83*/
U16 SupportedFeatures84; /*84*/
U16 EnabledFeatures85; /*85*/
U16 EnabledFeatures86; /*86*/
U16 EnabledFeatures87; /*87*/
U16 UltraDmaModes; /*88*/
U16 Reserved89[11]; /*89*/
U16 Max48BitAddress[4]; /*100*/
U16 Reserved104[151]; /*104*/
U16 Checksum; /*255*/
} IDE_DRIVE_IDENTIFY, *PIDE_DRIVE_IDENTIFY;
/* XboxDiskPolledRead
*
* DESCRIPTION:
* Read a sector of data from the drive in a polled fashion.
*
* RUN LEVEL:
* PASSIVE_LEVEL
*
* ARGUMENTS:
* U32 CommandPort Address of command port for drive
* U32 ControlPort Address of control port for drive
* U8 PreComp Value to write to precomp register
* U8 SectorCnt Value to write to sectorCnt register
* U8 SectorNum Value to write to sectorNum register
* U8 CylinderLow Value to write to CylinderLow register
* U8 CylinderHigh Value to write to CylinderHigh register
* U8 DrvHead Value to write to Drive/Head register
* U8 Command Value to write to Command register
* PVOID Buffer Buffer for output data
*
* RETURNS:
* BOOL: TRUE success, FALSE error
*/
static BOOL
XboxDiskPolledRead(U32 CommandPort,
U32 ControlPort,
U8 PreComp,
U8 SectorCnt,
U8 SectorNum,
U8 CylinderLow,
U8 CylinderHigh,
U8 DrvHead,
U8 Command,
PVOID Buffer)
{
U32 SectorCount = 0;
U32 RetryCount;
BOOL Junk = FALSE;
U8 Status;
/* Wait for BUSY to clear */
for (RetryCount = 0; RetryCount < IDE_MAX_BUSY_RETRIES; RetryCount++)
{
Status = IDEReadStatus(CommandPort);
if (!(Status & IDE_SR_BUSY))
{
break;
}
KeStallExecutionProcessor(10);
}
DbgPrint((DPRINT_DISK, "status=0x%x\n", Status));
DbgPrint((DPRINT_DISK, "waited %d usecs for busy to clear\n", RetryCount * 10));
if (RetryCount >= IDE_MAX_BUSY_RETRIES)
{
DbgPrint((DPRINT_DISK, "Drive is BUSY for too long\n"));
return FALSE;
}
/* Write Drive/Head to select drive */
IDEWriteDriveHead(CommandPort, IDE_DH_FIXED | DrvHead);
KeStallExecutionProcessor(500);
/* Disable interrupts */
IDEWriteDriveControl(ControlPort, IDE_DC_nIEN);
KeStallExecutionProcessor(500);
/* Issue command to drive */
if (DrvHead & IDE_DH_LBA)
{
DbgPrint((DPRINT_DISK, "READ:DRV=%d:LBA=1:BLK=%d:SC=0x%x:CM=0x%x\n",
DrvHead & IDE_DH_DRV1 ? 1 : 0,
((DrvHead & 0x0f) << 24) + (CylinderHigh << 16) + (CylinderLow << 8) + SectorNum,
SectorCnt,
Command));
}
else
{
DbgPrint((DPRINT_DISK, "READ:DRV=%d:LBA=0:CH=0x%x:CL=0x%x:HD=0x%x:SN=0x%x:SC=0x%x:CM=0x%x\n",
DrvHead & IDE_DH_DRV1 ? 1 : 0,
CylinderHigh,
CylinderLow,
DrvHead & 0x0f,
SectorNum,
SectorCnt,
Command));
}
/* Setup command parameters */
IDEWritePrecomp(CommandPort, PreComp);
IDEWriteSectorCount(CommandPort, SectorCnt);
IDEWriteSectorNum(CommandPort, SectorNum);
IDEWriteCylinderHigh(CommandPort, CylinderHigh);
IDEWriteCylinderLow(CommandPort, CylinderLow);
IDEWriteDriveHead(CommandPort, IDE_DH_FIXED | DrvHead);
/* Issue the command */
IDEWriteCommand(CommandPort, Command);
KeStallExecutionProcessor(50);
/* wait for DRQ or error */
for (RetryCount = 0; RetryCount < IDE_MAX_POLL_RETRIES; RetryCount++)
{
Status = IDEReadStatus(CommandPort);
if (!(Status & IDE_SR_BUSY))
{
if (Status & IDE_SR_ERR)
{
IDEWriteDriveControl(ControlPort, 0);
KeStallExecutionProcessor(50);
IDEReadStatus(CommandPort);
return FALSE;
}
if (Status & IDE_SR_DRQ)
{
break;
}
else
{
IDEWriteDriveControl(ControlPort, 0);
KeStallExecutionProcessor(50);
IDEReadStatus(CommandPort);
return FALSE;
}
}
KeStallExecutionProcessor(10);
}
/* timed out */
if (RetryCount >= IDE_MAX_POLL_RETRIES)
{
IDEWriteDriveControl(ControlPort, 0);
KeStallExecutionProcessor(50);
IDEReadStatus(CommandPort);
return FALSE;
}
while (1)
{
/* Read data into buffer */
if (Junk == FALSE)
{
IDEReadBlock(CommandPort, Buffer, IDE_SECTOR_BUF_SZ);
Buffer += IDE_SECTOR_BUF_SZ;
}
else
{
UCHAR JunkBuffer[IDE_SECTOR_BUF_SZ];
IDEReadBlock(CommandPort, JunkBuffer, IDE_SECTOR_BUF_SZ);
}
SectorCount++;
/* Check for error or more sectors to read */
for (RetryCount = 0; RetryCount < IDE_MAX_BUSY_RETRIES; RetryCount++)
{
Status = IDEReadStatus(CommandPort);
if (!(Status & IDE_SR_BUSY))
{
if (Status & IDE_SR_ERR)
{
IDEWriteDriveControl(ControlPort, 0);
KeStallExecutionProcessor(50);
IDEReadStatus(CommandPort);
return FALSE;
}
if (Status & IDE_SR_DRQ)
{
if (SectorCount >= SectorCnt)
{
DbgPrint((DPRINT_DISK, "Buffer size exceeded!\n"));
Junk = TRUE;
}
break;
}
else
{
if (SectorCount > SectorCnt)
{
DbgPrint((DPRINT_DISK, "Read %lu sectors of junk!\n",
SectorCount - SectorCnt));
}
IDEWriteDriveControl(ControlPort, 0);
KeStallExecutionProcessor(50);
IDEReadStatus(CommandPort);
return TRUE;
}
}
}
}
}
BOOL
XboxDiskReadLogicalSectors(U32 DriveNumber, U64 SectorNumber, U32 SectorCount, PVOID Buffer)
{
U32 StartSector;
U8 Count;
if (DriveNumber < 0x80 || 2 <= (DriveNumber & 0x0f))
{
/* Xbox has only 1 IDE controller and no floppy */
DbgPrint((DPRINT_DISK, "Invalid drive number\n"));
return FALSE;
}
if (UINT64_C(0) != ((SectorNumber + SectorCount) & UINT64_C(0xfffffffff0000000)))
{
DbgPrint((DPRINT_DISK, "48bit LBA required but not implemented\n"));
return FALSE;
}
StartSector = (U32) SectorNumber;
while (0 < SectorCount)
{
Count = (SectorCount <= 255 ? SectorCount : 255);
if (! XboxDiskPolledRead(XBOX_IDE_COMMAND_PORT,
XBOX_IDE_CONTROL_PORT,
0, Count,
StartSector & 0xff,
(StartSector >> 8) & 0xff,
(StartSector >> 16) & 0xff,
((StartSector >> 24) & 0x0f) | IDE_DH_LBA |
(0 == (DriveNumber & 0x0f) ? IDE_DH_DRV0 : IDE_DH_DRV1),
IDE_CMD_READ,
Buffer))
{
return FALSE;
}
SectorCount -= Count;
Buffer = (PVOID) ((PCHAR) Buffer + Count * IDE_SECTOR_BUF_SZ);
}
return TRUE;
}
BOOL
XboxDiskGetPartitionEntry(U32 DriveNumber, U32 PartitionNumber, PPARTITION_TABLE_ENTRY PartitionTableEntry)
{
U8 SectorData[IDE_SECTOR_BUF_SZ];
/* This is the Xbox, chances are that there is a Xbox-standard partitionless
* disk in it so let's check that first */
if (1 <= PartitionNumber && PartitionNumber <= sizeof(XboxPartitions) / sizeof(XboxPartitions[0]) &&
MachDiskReadLogicalSectors(DriveNumber, XBOX_SIGNATURE_SECTOR, 1, SectorData))
{
if (*((PU32) SectorData) == XBOX_SIGNATURE)
{
memset(PartitionTableEntry, 0, sizeof(PARTITION_TABLE_ENTRY));
PartitionTableEntry->SystemIndicator = XboxPartitions[PartitionNumber - 1].SystemIndicator;
PartitionTableEntry->SectorCountBeforePartition = XboxPartitions[PartitionNumber - 1].SectorCountBeforePartition;
PartitionTableEntry->PartitionSectorCount = XboxPartitions[PartitionNumber - 1].PartitionSectorCount;
return TRUE;
}
}
/* No magic Xbox partitions. Maybe there's a MBR */
return DiskGetPartitionEntry(DriveNumber, PartitionNumber, PartitionTableEntry);
}
BOOL
XboxDiskGetDriveGeometry(U32 DriveNumber, PGEOMETRY Geometry)
{
IDE_DRIVE_IDENTIFY DrvParms;
U32 i;
BOOL Atapi;
Atapi = FALSE; /* FIXME */
/* Get the Drive Identify block from drive or die */
if (! XboxDiskPolledRead(XBOX_IDE_COMMAND_PORT,
XBOX_IDE_CONTROL_PORT,
0,
1,
0,
0,
0,
(0 == (DriveNumber & 0x0f) ? IDE_DH_DRV0 : IDE_DH_DRV1),
(Atapi ? IDE_CMD_IDENT_ATAPI_DRV : IDE_CMD_IDENT_ATA_DRV),
(PUCHAR) &DrvParms))
{
DbgPrint((DPRINT_DISK, "XboxDiskPolledRead() failed\n"));
return FALSE;
}
Geometry->Cylinders = DrvParms.LogicalCyls;
Geometry->Heads = DrvParms.LogicalHeads;
Geometry->Sectors = DrvParms.SectorsPerTrack;
if (! Atapi && 0 != (DrvParms.Capabilities & IDE_DRID_LBA_SUPPORTED))
{
/* LBA ATA drives always have a sector size of 512 */
Geometry->BytesPerSector = 512;
}
else
{
DbgPrint((DPRINT_DISK, "BytesPerSector %d\n", DrvParms.BytesPerSector));
if (DrvParms.BytesPerSector == 0)
{
Geometry->BytesPerSector = 512;
}
else
{
for (i = 15; i >= 0; i--)
{
if (0 != (DrvParms.BytesPerSector & (1 << i)))
{
Geometry->BytesPerSector = 1 << i;
break;
}
}
}
}
DbgPrint((DPRINT_DISK, "Cylinders %d\n", Geometry->Cylinders));
DbgPrint((DPRINT_DISK, "Heads %d\n", Geometry->Heads));
DbgPrint((DPRINT_DISK, "Sectors %d\n", Geometry->Sectors));
DbgPrint((DPRINT_DISK, "BytesPerSector %d\n", Geometry->BytesPerSector));
return TRUE;
}
U32
XboxDiskGetCacheableBlockCount(U32 DriveNumber)
{
/* 64 seems a nice number, it is used by the machpc code for LBA devices */
return 64;
}
/* EOF */

View File

@@ -1,4 +1,4 @@
/* $Id$
/* $Id: xboxfont.c,v 1.2 2004/11/10 23:45:37 gvg Exp $
*
* FreeLoader
*
@@ -12,16 +12,18 @@
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
* 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.
*
* Note: Converted from the XFree vga.bdf font
*/
#include <freeldr.h>
#include "freeldr.h"
#include "machine.h"
#include "machxbox.h"
UCHAR XboxFont8x16[256 * 16] =
U8 XboxFont8x16[256 * 16] =
{
0x00,0x00,0x00,0x7c,0xc6,0xc6,0xde,0xde,0xde,0xdc,0xc0,0x7c,0x00,0x00,0x00,0x00, /* 0x00 */
0x00,0x00,0x7e,0x81,0xa5,0x81,0x81,0xa5,0x99,0x81,0x81,0x7e,0x00,0x00,0x00,0x00, /* 0x01 */

View File

@@ -0,0 +1,29 @@
/* $Id: xboxhw.c,v 1.1 2004/11/28 22:42:40 gvg Exp $
*
* FreeLoader
*
* 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.
*/
#include "freeldr.h"
#include "machine.h"
#include "machxbox.h"
VOID
XboxHwDetect(VOID)
{
}
/* EOF */

View File

@@ -0,0 +1,133 @@
/* $Id: xboxmem.c,v 1.3 2004/11/10 23:45:37 gvg Exp $
*
* FreeLoader
*
* 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.
*
* Note: much of this code was based on knowledge and/or code developed
* by the Xbox Linux group: http://www.xbox-linux.org
*/
#include "freeldr.h"
#include "debug.h"
#include "mm.h"
#include "rtl.h"
#include "hardware.h"
#include "machine.h"
#include "machxbox.h"
#include "portio.h"
static U32 InstalledMemoryMb = 0;
static U32 AvailableMemoryMb = 0;
#define TEST_SIZE 0x200
#define TEST_PATTERN1 0xaa
#define TEST_PATTERN2 0x55
VOID
XboxMemInit(VOID)
{
U8 ControlRegion[TEST_SIZE];
PVOID MembaseTop = (PVOID)(64 * 1024 * 1024);
PVOID MembaseLow = (PVOID)0;
(*(PU32)(0xfd000000 + 0x100200)) = 0x03070103 ;
(*(PU32)(0xfd000000 + 0x100204)) = 0x11448000 ;
WRITE_PORT_ULONG((U32*) 0xcf8, CONFIG_CMD(0, 0, 0x84));
WRITE_PORT_ULONG((U32*) 0xcfc, 0x7ffffff); /* Prep hardware for 128 Mb */
InstalledMemoryMb = 64;
memset(ControlRegion, TEST_PATTERN1, TEST_SIZE);
memset(MembaseTop, TEST_PATTERN1, TEST_SIZE);
__asm__ ("wbinvd\n");
if (0 == memcmp(MembaseTop, ControlRegion, TEST_SIZE))
{
/* Looks like there is memory .. maybe a 128MB box */
memset(ControlRegion, TEST_PATTERN2, TEST_SIZE);
memset(MembaseTop, TEST_PATTERN2, TEST_SIZE);
__asm__ ("wbinvd\n");
if (0 == memcmp(MembaseTop, ControlRegion, TEST_SIZE))
{
/* Definitely looks like there is memory */
if (0 == memcmp(MembaseLow, ControlRegion, TEST_SIZE))
{
/* Hell, we find the Test-string at 0x0 too ! */
InstalledMemoryMb = 64;
}
else
{
InstalledMemoryMb = 128;
}
}
}
/* Set hardware for amount of memory detected */
WRITE_PORT_ULONG((U32*) 0xcf8, CONFIG_CMD(0, 0, 0x84));
WRITE_PORT_ULONG((U32*) 0xcfc, InstalledMemoryMb * 1024 * 1024 - 1);
AvailableMemoryMb = InstalledMemoryMb;
}
U32
XboxMemGetMemoryMap(PBIOS_MEMORY_MAP BiosMemoryMap, U32 MaxMemoryMapSize)
{
U32 EntryCount = 0;
/* Synthesize memory map */
if (1 <= MaxMemoryMapSize)
{
/* Available RAM block */
BiosMemoryMap[0].BaseAddress = 0;
BiosMemoryMap[0].Length = AvailableMemoryMb * 1024 * 1024;
BiosMemoryMap[0].Type = MEMTYPE_USABLE;
EntryCount = 1;
}
if (2 <= MaxMemoryMapSize)
{
/* Video memory */
BiosMemoryMap[1].BaseAddress = AvailableMemoryMb * 1024 * 1024;
BiosMemoryMap[1].Length = (InstalledMemoryMb - AvailableMemoryMb) * 1024 * 1024;
BiosMemoryMap[1].Type = MEMTYPE_RESERVED;
EntryCount = 2;
}
return EntryCount;
}
PVOID
XboxMemReserveMemory(U32 MbToReserve)
{
if (0 == InstalledMemoryMb)
{
/* Hmm, seems we're not initialized yet */
XboxMemInit();
}
if (AvailableMemoryMb < MbToReserve)
{
/* Can't satisfy the request */
return NULL;
}
AvailableMemoryMb -= MbToReserve;
/* Top of available memory points to the space just reserved */
return (PVOID) (AvailableMemoryMb * 1024 * 1024);
}
/* EOF */

View File

@@ -0,0 +1,85 @@
/* $Id: xboxrtc.c,v 1.1 2004/11/14 22:04:38 gvg Exp $
*
* FreeLoader
*
* 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.
*/
#include "freeldr.h"
#include "machine.h"
#include "machxbox.h"
#include "portio.h"
#define RTC_REGISTER_A 0x0A
#define RTC_REG_A_UIP 0x80 /* Update In Progress bit */
#define BCD_INT(bcd) (((bcd & 0xf0) >> 4) * 10 + (bcd &0x0f))
static UCHAR
HalpQueryCMOS(UCHAR Reg)
{
UCHAR Val;
Reg |= 0x80;
WRITE_PORT_UCHAR((PUCHAR)0x70, Reg);
Val = READ_PORT_UCHAR((PUCHAR)0x71);
WRITE_PORT_UCHAR((PUCHAR)0x70, 0);
return(Val);
}
VOID
XboxRTCGetCurrentDateTime(PU32 Year, PU32 Month, PU32 Day, PU32 Hour, PU32 Minute, PU32 Second)
{
while (HalpQueryCMOS (RTC_REGISTER_A) & RTC_REG_A_UIP)
{
;
}
if (NULL != Second)
{
*Second = BCD_INT(HalpQueryCMOS(0));
}
if (NULL != Minute)
{
*Minute = BCD_INT(HalpQueryCMOS(2));
}
if (NULL != Hour)
{
*Hour = BCD_INT(HalpQueryCMOS(4));
}
if (NULL != Day)
{
*Day = BCD_INT(HalpQueryCMOS(7));
}
if (NULL != Month)
{
*Month = BCD_INT(HalpQueryCMOS(8));
}
if (NULL != Year)
{
*Year = BCD_INT(HalpQueryCMOS(9));
if (*Year > 80)
{
*Year += 1900;
}
else
{
*Year += 2000;
}
}
}
/* EOF */

View File

@@ -0,0 +1,332 @@
/* $Id: xboxvideo.c,v 1.5 2004/11/28 21:54:11 gvg Exp $
*
* FreeLoader
*
* 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.
*
* Note: much of this code was based on knowledge and/or code developed
* by the Xbox Linux group: http://www.xbox-linux.org
*/
#include "freeldr.h"
#include "debug.h"
#include "rtl.h"
#include "machine.h"
#include "machxbox.h"
#include "portio.h"
#define I2C_IO_BASE 0xc000
static PVOID FrameBuffer;
static U32 ScreenWidth;
static U32 ScreenHeight;
static U32 BytesPerPixel;
static U32 Delta;
#define CHAR_WIDTH 8
#define CHAR_HEIGHT 16
#define TOP_BOTTOM_LINES 0
#define FB_SIZE_MB 4
#define MAKE_COLOR(Red, Green, Blue) (0xff000000 | (((Red) & 0xff) << 16) | (((Green) & 0xff) << 8) | ((Blue) & 0xff))
static VOID
XboxVideoOutputChar(U8 Char, unsigned X, unsigned Y, U32 FgColor, U32 BgColor)
{
PU8 FontPtr;
PU32 Pixel;
U8 Mask;
unsigned Line;
unsigned Col;
FontPtr = XboxFont8x16 + Char * 16;
Pixel = (PU32) ((char *) FrameBuffer + (Y * CHAR_HEIGHT + TOP_BOTTOM_LINES) * Delta
+ X * CHAR_WIDTH * BytesPerPixel);
for (Line = 0; Line < CHAR_HEIGHT; Line++)
{
Mask = 0x80;
for (Col = 0; Col < CHAR_WIDTH; Col++)
{
Pixel[Col] = (0 != (FontPtr[Line] & Mask) ? FgColor : BgColor);
Mask = Mask >> 1;
}
Pixel = (PU32) ((char *) Pixel + Delta);
}
}
static U32
XboxVideoAttrToSingleColor(U8 Attr)
{
U8 Intensity;
Intensity = (0 == (Attr & 0x08) ? 127 : 255);
return 0xff000000 |
(0 == (Attr & 0x04) ? 0 : (Intensity << 16)) |
(0 == (Attr & 0x02) ? 0 : (Intensity << 8)) |
(0 == (Attr & 0x01) ? 0 : Intensity);
}
static VOID
XboxVideoAttrToColors(U8 Attr, U32 *FgColor, U32 *BgColor)
{
*FgColor = XboxVideoAttrToSingleColor(Attr & 0xf);
*BgColor = XboxVideoAttrToSingleColor((Attr >> 4) & 0xf);
}
static VOID
XboxVideoClearScreenColor(U32 Color, BOOL FullScreen)
{
U32 Line, Col;
PU32 p;
for (Line = 0; Line < ScreenHeight - (FullScreen ? 0 : 2 * TOP_BOTTOM_LINES); Line++)
{
p = (PU32) ((char *) FrameBuffer + (Line + (FullScreen ? 0 : TOP_BOTTOM_LINES)) * Delta);
for (Col = 0; Col < ScreenWidth; Col++)
{
*p++ = Color;
}
}
}
VOID
XboxVideoClearScreen(U8 Attr)
{
U32 FgColor, BgColor;
XboxVideoAttrToColors(Attr, &FgColor, &BgColor);
XboxVideoClearScreenColor(BgColor, FALSE);
}
VOID
XboxVideoPutChar(int Ch, U8 Attr, unsigned X, unsigned Y)
{
U32 FgColor, BgColor;
XboxVideoAttrToColors(Attr, &FgColor, &BgColor);
XboxVideoOutputChar(Ch, X, Y, FgColor, BgColor);
}
static BOOL
ReadfromSMBus(UCHAR Address, UCHAR bRegister, UCHAR Size, U32 *Data_to_smbus)
{
int nRetriesToLive=50;
while (0 != (READ_PORT_USHORT((PU16) (I2C_IO_BASE + 0)) & 0x0800))
{
; /* Franz's spin while bus busy with any master traffic */
}
while (0 != nRetriesToLive--)
{
UCHAR b;
int temp;
WRITE_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 4), (Address << 1) | 1);
WRITE_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 8), bRegister);
temp = READ_PORT_USHORT((U16 *) (I2C_IO_BASE + 0));
WRITE_PORT_USHORT((PU16) (I2C_IO_BASE + 0), temp); /* clear down all preexisting errors */
switch (Size)
{
case 4:
WRITE_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 2), 0x0d); /* DWORD modus ? */
break;
case 2:
WRITE_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 2), 0x0b); /* WORD modus */
break;
default:
WRITE_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 2), 0x0a); // BYTE
break;
}
b = 0;
while (0 == (b & 0x36))
{
b = READ_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 0));
}
if (0 != (b & 0x24))
{
/* printf("I2CTransmitByteGetReturn error %x\n", b); */
}
if(0 == (b & 0x10))
{
/* printf("I2CTransmitByteGetReturn no complete, retry\n"); */
}
else
{
switch (Size)
{
case 4:
READ_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 6));
READ_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 9));
READ_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 9));
READ_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 9));
READ_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 9));
break;
case 2:
*Data_to_smbus = READ_PORT_USHORT((U16 *) (I2C_IO_BASE + 6));
break;
default:
*Data_to_smbus = READ_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 6));
break;
}
return TRUE;
}
}
return FALSE;
}
static BOOL
I2CTransmitByteGetReturn(UCHAR bPicAddressI2cFormat, UCHAR bDataToWrite, U32 *Return)
{
return ReadfromSMBus(bPicAddressI2cFormat, bDataToWrite, 1, Return);
}
VOID
XboxVideoInit(VOID)
{
U32 AvMode;
FrameBuffer = (PVOID)((U32) XboxMemReserveMemory(FB_SIZE_MB) | 0xf0000000);
if (I2CTransmitByteGetReturn(0x10, 0x04, &AvMode))
{
if (1 == AvMode) /* HDTV */
{
ScreenWidth = 720;
}
else
{
/* FIXME Other possible values of AvMode:
* 0 - AV_SCART_RGB
* 2 - AV_VGA_SOG
* 4 - AV_SVIDEO
* 6 - AV_COMPOSITE
* 7 - AV_VGA
* other AV_COMPOSITE
*/
ScreenWidth = 640;
}
}
else
{
ScreenWidth = 640;
}
ScreenHeight = 480;
BytesPerPixel = 4;
Delta = (ScreenWidth * BytesPerPixel + 3) & ~ 0x3;
XboxVideoClearScreenColor(MAKE_COLOR(0, 0, 0), TRUE);
/* Tell the nVidia controller about the framebuffer */
*((PU32) 0xfd600800) = (U32) FrameBuffer;
}
VIDEODISPLAYMODE
XboxVideoSetDisplayMode(char *DisplayMode, BOOL Init)
{
/* We only have one mode, semi-text */
return VideoTextMode;
}
VOID
XboxVideoGetDisplaySize(PU32 Width, PU32 Height, PU32 Depth)
{
*Width = ScreenWidth / CHAR_WIDTH;
*Height = (ScreenHeight - 2 * TOP_BOTTOM_LINES) / CHAR_HEIGHT;
*Depth = 0;
}
U32
XboxVideoGetBufferSize(VOID)
{
return (ScreenHeight - 2 * TOP_BOTTOM_LINES) / CHAR_HEIGHT * (ScreenWidth / CHAR_WIDTH) * 2;
}
VOID
XboxVideoSetTextCursorPosition(U32 X, U32 Y)
{
/* We don't have a cursor yet */
}
VOID
XboxVideoHideShowTextCursor(BOOL Show)
{
/* We don't have a cursor yet */
}
VOID
XboxVideoCopyOffScreenBufferToVRAM(PVOID Buffer)
{
PU8 OffScreenBuffer = (PU8) Buffer;
U32 Col, Line;
for (Line = 0; Line < (ScreenHeight - 2 * TOP_BOTTOM_LINES) / CHAR_HEIGHT; Line++)
{
for (Col = 0; Col < ScreenWidth / CHAR_WIDTH; Col++)
{
XboxVideoPutChar(OffScreenBuffer[0], OffScreenBuffer[1], Col, Line);
OffScreenBuffer += 2;
}
}
}
BOOL
XboxVideoIsPaletteFixed(VOID)
{
return FALSE;
}
VOID
XboxVideoSetPaletteColor(U8 Color, U8 Red, U8 Green, U8 Blue)
{
/* Not supported */
}
VOID
XboxVideoGetPaletteColor(U8 Color, U8* Red, U8* Green, U8* Blue)
{
/* Not supported */
}
VOID
XboxVideoSync()
{
/* Not supported */
}
VOID
XboxVideoPrepareForReactOS(VOID)
{
XboxVideoClearScreenColor(MAKE_COLOR(0, 0, 0), TRUE);
}
/* EOF */

239
freeldr/freeldr/bootmgr.c Normal file
View File

@@ -0,0 +1,239 @@
/*
* FreeLoader
* Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>
*
* 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.
*/
#include <freeldr.h>
#include <rtl.h>
#include <fs.h>
#include <reactos.h>
#include <ui.h>
#include <arch.h>
#include <miscboot.h>
#include <linux.h>
#include <mm.h>
#include <inifile.h>
#include <debug.h>
#include <options.h>
#include <oslist.h>
#include <video.h>
#include <bootmgr.h>
#include <drivemap.h>
#include <keycodes.h>
#include <cmdline.h>
#include <machine.h>
VOID RunLoader(VOID)
{
UCHAR SettingName[80];
UCHAR SettingValue[80];
U32 SectionId;
U32 OperatingSystemCount;
PUCHAR *OperatingSystemSectionNames;
PUCHAR *OperatingSystemDisplayNames;
U32 DefaultOperatingSystem;
S32 TimeOut;
U32 SelectedOperatingSystem;
if (!IniFileInitialize())
{
printf("Press any key to reboot.\n");
MachConsGetCh();
return;
}
if (!IniOpenSection("FreeLoader", &SectionId))
{
printf("Section [FreeLoader] not found in freeldr.ini.\n");
MachConsGetCh();
return;
}
TimeOut = GetTimeOut();
if (!UiInitialize(TimeOut))
{
printf("Press any key to reboot.\n");
MachConsGetCh();
return;
}
if (!InitOperatingSystemList(&OperatingSystemSectionNames, &OperatingSystemDisplayNames, &OperatingSystemCount))
{
UiMessageBox("Press ENTER to reboot.\n");
goto reboot;
}
if (OperatingSystemCount == 0)
{
UiMessageBox("There were no operating systems listed in freeldr.ini.\nPress ENTER to reboot.");
goto reboot;
}
DefaultOperatingSystem = GetDefaultOperatingSystem(OperatingSystemSectionNames, OperatingSystemCount);
//
// Find all the message box settings and run them
//
UiShowMessageBoxesInSection("FreeLoader");
for (;;)
{
/* If Timeout is 0, don't even bother loading any gui */
if (!UserInterfaceUp) {
goto NoGui;
}
// Redraw the backdrop
UiDrawBackdrop();
// Show the operating system list menu
if (!UiDisplayMenu(OperatingSystemDisplayNames, OperatingSystemCount, DefaultOperatingSystem, TimeOut, &SelectedOperatingSystem, FALSE, MainBootMenuKeyPressFilter))
{
UiMessageBox("Press ENTER to reboot.\n");
goto reboot;
}
NoGui:
TimeOut = -1;
DefaultOperatingSystem = SelectedOperatingSystem;
// Try to open the operating system section in the .ini file
if (!IniOpenSection(OperatingSystemSectionNames[SelectedOperatingSystem], &SectionId))
{
sprintf(SettingName, "Section [%s] not found in freeldr.ini.\n", OperatingSystemSectionNames[SelectedOperatingSystem]);
UiMessageBox(SettingName);
continue;
}
// Try to read the boot type
if (!IniReadSettingByName(SectionId, "BootType", SettingValue, 80))
{
sprintf(SettingName, "BootType= line not found in section [%s] in freeldr.ini.\n", OperatingSystemSectionNames[SelectedOperatingSystem]);
UiMessageBox(SettingName);
continue;
}
// Install the drive mapper according to this sections drive mappings
DriveMapMapDrivesInSection(OperatingSystemSectionNames[SelectedOperatingSystem]);
if (stricmp(SettingValue, "ReactOS") == 0)
{
LoadAndBootReactOS(OperatingSystemSectionNames[SelectedOperatingSystem]);
}
else if (stricmp(SettingValue, "Linux") == 0)
{
LoadAndBootLinux(OperatingSystemSectionNames[SelectedOperatingSystem], OperatingSystemDisplayNames[SelectedOperatingSystem]);
}
else if (stricmp(SettingValue, "BootSector") == 0)
{
LoadAndBootBootSector(OperatingSystemSectionNames[SelectedOperatingSystem]);
}
else if (stricmp(SettingValue, "Partition") == 0)
{
LoadAndBootPartition(OperatingSystemSectionNames[SelectedOperatingSystem]);
}
else if (stricmp(SettingValue, "Drive") == 0)
{
LoadAndBootDrive(OperatingSystemSectionNames[SelectedOperatingSystem]);
}
}
reboot:
UiUnInitialize("Rebooting...");
return;
}
U32 GetDefaultOperatingSystem(PUCHAR OperatingSystemList[], U32 OperatingSystemCount)
{
UCHAR DefaultOSText[80];
char* DefaultOSName;
U32 SectionId;
U32 DefaultOS = 0;
U32 Idx;
if (!IniOpenSection("FreeLoader", &SectionId))
{
return 0;
}
DefaultOSName = CmdLineGetDefaultOS();
if (NULL == DefaultOSName)
{
if (IniReadSettingByName(SectionId, "DefaultOS", DefaultOSText, 80))
{
DefaultOSName = DefaultOSText;
}
}
if (NULL != DefaultOSName)
{
for (Idx=0; Idx<OperatingSystemCount; Idx++)
{
if (stricmp(DefaultOSName, OperatingSystemList[Idx]) == 0)
{
DefaultOS = Idx;
break;
}
}
}
return DefaultOS;
}
S32 GetTimeOut(VOID)
{
UCHAR TimeOutText[20];
S32 TimeOut;
U32 SectionId;
TimeOut = CmdLineGetTimeOut();
if (0 <= TimeOut)
{
return TimeOut;
}
if (!IniOpenSection("FreeLoader", &SectionId))
{
return -1;
}
if (IniReadSettingByName(SectionId, "TimeOut", TimeOutText, 20))
{
TimeOut = atoi(TimeOutText);
}
else
{
TimeOut = -1;
}
return TimeOut;
}
BOOL MainBootMenuKeyPressFilter(U32 KeyPress)
{
if (KeyPress == KEY_F8)
{
DoOptionsMenu();
return TRUE;
}
// We didn't handle the key
return FALSE;
}

260
freeldr/freeldr/cache/blocklist.c vendored Normal file
View File

@@ -0,0 +1,260 @@
/*
* FreeLoader
* Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>
*
* 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.
*/
#include <freeldr.h>
#include "cm.h"
#include <mm.h>
#include <disk.h>
#include <rtl.h>
#include <debug.h>
#include <arch.h>
#include <machine.h>
// Returns a pointer to a CACHE_BLOCK structure
// Adds the block to the cache manager block list
// in cache memory if it isn't already there
PCACHE_BLOCK CacheInternalGetBlockPointer(PCACHE_DRIVE CacheDrive, U32 BlockNumber)
{
PCACHE_BLOCK CacheBlock = NULL;
DbgPrint((DPRINT_CACHE, "CacheInternalGetBlockPointer() BlockNumber = %d\n", BlockNumber));
CacheBlock = CacheInternalFindBlock(CacheDrive, BlockNumber);
if (CacheBlock != NULL)
{
DbgPrint((DPRINT_CACHE, "Cache hit! BlockNumber: %d CacheBlock->BlockNumber: %d\n", BlockNumber, CacheBlock->BlockNumber));
return CacheBlock;
}
DbgPrint((DPRINT_CACHE, "Cache miss! BlockNumber: %d\n", BlockNumber));
CacheBlock = CacheInternalAddBlockToCache(CacheDrive, BlockNumber);
// Optimize the block list so it has a LRU structure
CacheInternalOptimizeBlockList(CacheDrive, CacheBlock);
return CacheBlock;
}
PCACHE_BLOCK CacheInternalFindBlock(PCACHE_DRIVE CacheDrive, U32 BlockNumber)
{
PCACHE_BLOCK CacheBlock = NULL;
DbgPrint((DPRINT_CACHE, "CacheInternalFindBlock() BlockNumber = %d\n", BlockNumber));
//
// Make sure the block list has entries before I start searching it.
//
if (!RtlListIsEmpty((PLIST_ITEM)CacheDrive->CacheBlockHead))
{
//
// Search the list and find the BIOS drive number
//
CacheBlock = CacheDrive->CacheBlockHead;
while (CacheBlock != NULL)
{
//
// We found the block, so return it
//
if (CacheBlock->BlockNumber == BlockNumber)
{
//
// Increment the blocks access count
//
CacheBlock->AccessCount++;
return CacheBlock;
}
CacheBlock = (PCACHE_BLOCK)RtlListGetNext((PLIST_ITEM)CacheBlock);
}
}
return NULL;
}
PCACHE_BLOCK CacheInternalAddBlockToCache(PCACHE_DRIVE CacheDrive, U32 BlockNumber)
{
PCACHE_BLOCK CacheBlock = NULL;
DbgPrint((DPRINT_CACHE, "CacheInternalAddBlockToCache() BlockNumber = %d\n", BlockNumber));
// Check the size of the cache so we don't exceed our limits
CacheInternalCheckCacheSizeLimits(CacheDrive);
// We will need to add the block to the
// drive's list of cached blocks. So allocate
// the block memory.
CacheBlock = MmAllocateMemory(sizeof(CACHE_BLOCK));
if (CacheBlock == NULL)
{
return NULL;
}
// Now initialize the structure and
// allocate room for the block data
RtlZeroMemory(CacheBlock, sizeof(CACHE_BLOCK));
CacheBlock->BlockNumber = BlockNumber;
CacheBlock->BlockData = MmAllocateMemory(CacheDrive->BlockSize * CacheDrive->BytesPerSector);
if (CacheBlock->BlockData ==NULL)
{
MmFreeMemory(CacheBlock);
return NULL;
}
// Now try to read in the block
if (!MachDiskReadLogicalSectors(CacheDrive->DriveNumber, (BlockNumber * CacheDrive->BlockSize), CacheDrive->BlockSize, (PVOID)DISKREADBUFFER))
{
MmFreeMemory(CacheBlock->BlockData);
MmFreeMemory(CacheBlock);
return NULL;
}
RtlCopyMemory(CacheBlock->BlockData, (PVOID)DISKREADBUFFER, CacheDrive->BlockSize * CacheDrive->BytesPerSector);
// Add it to our list of blocks managed by the cache
if (CacheDrive->CacheBlockHead == NULL)
{
CacheDrive->CacheBlockHead = CacheBlock;
}
else
{
RtlListInsertTail((PLIST_ITEM)CacheDrive->CacheBlockHead, (PLIST_ITEM)CacheBlock);
}
// Update the cache data
CacheBlockCount++;
CacheSizeCurrent = CacheBlockCount * (CacheDrive->BlockSize * CacheDrive->BytesPerSector);
CacheInternalDumpBlockList(CacheDrive);
return CacheBlock;
}
BOOL CacheInternalFreeBlock(PCACHE_DRIVE CacheDrive)
{
PCACHE_BLOCK CacheBlockToFree;
DbgPrint((DPRINT_CACHE, "CacheInternalFreeBlock()\n"));
// Get a pointer to the last item in the block list
// that isn't forced to be in the cache and remove
// it from the list
CacheBlockToFree = (PCACHE_BLOCK)RtlListGetTail((PLIST_ITEM)CacheDrive->CacheBlockHead);
while (CacheBlockToFree != NULL && CacheBlockToFree->LockedInCache == TRUE)
{
CacheBlockToFree = (PCACHE_BLOCK)RtlListGetPrevious((PLIST_ITEM)CacheBlockToFree);
}
// No blocks left in cache that can be freed
// so just return
if (CacheBlockToFree == NULL)
{
return FALSE;
}
//
// If we are freeing the head of the list then update it's pointer
//
if (CacheBlockToFree == CacheDrive->CacheBlockHead)
{
CacheDrive->CacheBlockHead = (PCACHE_BLOCK)RtlListGetNext((PLIST_ITEM)CacheBlockToFree);
}
RtlListRemoveEntry((PLIST_ITEM)CacheBlockToFree);
// Free the block memory and the block structure
MmFreeMemory(CacheBlockToFree->BlockData);
MmFreeMemory(CacheBlockToFree);
// Update the cache data
CacheBlockCount--;
CacheSizeCurrent = CacheBlockCount * (CacheDrive->BlockSize * CacheDrive->BytesPerSector);
return TRUE;
}
VOID CacheInternalCheckCacheSizeLimits(PCACHE_DRIVE CacheDrive)
{
U32 NewCacheSize;
DbgPrint((DPRINT_CACHE, "CacheInternalCheckCacheSizeLimits()\n"));
// Calculate the size of the cache if we added a block
NewCacheSize = (CacheBlockCount + 1) * (CacheDrive->BlockSize * CacheDrive->BytesPerSector);
// Check the new size against the cache size limit
if (NewCacheSize > CacheSizeLimit)
{
CacheInternalFreeBlock(CacheDrive);
CacheInternalDumpBlockList(CacheDrive);
}
}
VOID CacheInternalDumpBlockList(PCACHE_DRIVE CacheDrive)
{
PCACHE_BLOCK CacheBlock;
DbgPrint((DPRINT_CACHE, "Dumping block list for BIOS drive 0x%x.\n", CacheDrive->DriveNumber));
DbgPrint((DPRINT_CACHE, "BytesPerSector: %d.\n", CacheDrive->BytesPerSector));
DbgPrint((DPRINT_CACHE, "BlockSize: %d.\n", CacheDrive->BlockSize));
DbgPrint((DPRINT_CACHE, "CacheSizeLimit: %d.\n", CacheSizeLimit));
DbgPrint((DPRINT_CACHE, "CacheSizeCurrent: %d.\n", CacheSizeCurrent));
DbgPrint((DPRINT_CACHE, "CacheBlockCount: %d.\n", CacheBlockCount));
DbgPrint((DPRINT_CACHE, "Dumping %d cache blocks.\n", RtlListCountEntries((PLIST_ITEM)CacheDrive->CacheBlockHead)));
CacheBlock = CacheDrive->CacheBlockHead;
while (CacheBlock != NULL)
{
DbgPrint((DPRINT_CACHE, "Cache Block: CacheBlock: 0x%x\n", CacheBlock));
DbgPrint((DPRINT_CACHE, "Cache Block: Block Number: %d\n", CacheBlock->BlockNumber));
DbgPrint((DPRINT_CACHE, "Cache Block: Access Count: %d\n", CacheBlock->AccessCount));
DbgPrint((DPRINT_CACHE, "Cache Block: Block Data: 0x%x\n", CacheBlock->BlockData));
DbgPrint((DPRINT_CACHE, "Cache Block: Locked In Cache: %d\n", CacheBlock->LockedInCache));
if (CacheBlock->BlockData == NULL)
{
BugCheck((DPRINT_CACHE, "What the heck?!?\n"));
}
CacheBlock = (PCACHE_BLOCK)RtlListGetNext((PLIST_ITEM)CacheBlock);
}
}
VOID CacheInternalOptimizeBlockList(PCACHE_DRIVE CacheDrive, PCACHE_BLOCK CacheBlock)
{
DbgPrint((DPRINT_CACHE, "CacheInternalOptimizeBlockList()\n"));
// Don't do this if this block is already at the head of the list
if (CacheBlock != CacheDrive->CacheBlockHead)
{
// Remove this item from the block list
RtlListRemoveEntry((PLIST_ITEM)CacheBlock);
// Re-insert it at the head of the list
RtlListInsertHead((PLIST_ITEM)CacheDrive->CacheBlockHead, (PLIST_ITEM)CacheBlock);
// Update the head pointer
CacheDrive->CacheBlockHead = CacheBlock;
}
}

325
freeldr/freeldr/cache/cache.c vendored Normal file
View File

@@ -0,0 +1,325 @@
/*
* FreeLoader
* Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>
*
* 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.
*/
#include <freeldr.h>
#include "cm.h"
#include <mm.h>
#include <disk.h>
#include <machine.h>
#include <rtl.h>
#include <debug.h>
///////////////////////////////////////////////////////////////////////////////////////
//
// Internal data
//
///////////////////////////////////////////////////////////////////////////////////////
CACHE_DRIVE CacheManagerDrive;
BOOL CacheManagerInitialized = FALSE;
BOOL CacheManagerDataInvalid = FALSE;
U32 CacheBlockCount = 0;
U32 CacheSizeLimit = 0;
U32 CacheSizeCurrent = 0;
BOOL CacheInitializeDrive(U32 DriveNumber)
{
PCACHE_BLOCK NextCacheBlock;
GEOMETRY DriveGeometry;
// If we already have a cache for this drive then
// by all means lets keep it, unless it is a removable
// drive, in which case we'll invalidate the cache
if ((CacheManagerInitialized == TRUE) &&
(DriveNumber == CacheManagerDrive.DriveNumber) &&
(DriveNumber >= 0x80) &&
(CacheManagerDataInvalid != TRUE))
{
return TRUE;
}
CacheManagerDataInvalid = FALSE;
//
// If we have already been initialized then free
// the old data
//
if (CacheManagerInitialized)
{
CacheManagerInitialized = FALSE;
DbgPrint((DPRINT_CACHE, "CacheBlockCount: %d\n", CacheBlockCount));
DbgPrint((DPRINT_CACHE, "CacheSizeLimit: %d\n", CacheSizeLimit));
DbgPrint((DPRINT_CACHE, "CacheSizeCurrent: %d\n", CacheSizeCurrent));
//
// Loop through and free the cache blocks
//
while (CacheManagerDrive.CacheBlockHead != NULL)
{
NextCacheBlock = (PCACHE_BLOCK)RtlListGetNext((PLIST_ITEM)CacheManagerDrive.CacheBlockHead);
MmFreeMemory(CacheManagerDrive.CacheBlockHead->BlockData);
MmFreeMemory(CacheManagerDrive.CacheBlockHead);
CacheManagerDrive.CacheBlockHead = NextCacheBlock;
}
}
// Initialize the structure
RtlZeroMemory(&CacheManagerDrive, sizeof(CACHE_DRIVE));
CacheManagerDrive.DriveNumber = DriveNumber;
if (!MachDiskGetDriveGeometry(DriveNumber, &DriveGeometry))
{
return FALSE;
}
CacheManagerDrive.BytesPerSector = DriveGeometry.BytesPerSector;
// Get the number of sectors in each cache block
CacheManagerDrive.BlockSize = MachDiskGetCacheableBlockCount(DriveNumber);
CacheBlockCount = 0;
CacheSizeLimit = GetSystemMemorySize() / 8;
CacheSizeCurrent = 0;
if (CacheSizeLimit < (64 * 1024))
{
CacheSizeLimit = (64 * 1024);
}
CacheManagerInitialized = TRUE;
DbgPrint((DPRINT_CACHE, "Initializing BIOS drive 0x%x.\n", DriveNumber));
DbgPrint((DPRINT_CACHE, "BytesPerSector: %d.\n", CacheManagerDrive.BytesPerSector));
DbgPrint((DPRINT_CACHE, "BlockSize: %d.\n", CacheManagerDrive.BlockSize));
DbgPrint((DPRINT_CACHE, "CacheSizeLimit: %d.\n", CacheSizeLimit));
return TRUE;
}
VOID CacheInvalidateCacheData(VOID)
{
CacheManagerDataInvalid = TRUE;
}
BOOL CacheReadDiskSectors(U32 DiskNumber, U32 StartSector, U32 SectorCount, PVOID Buffer)
{
PCACHE_BLOCK CacheBlock;
U32 StartBlock;
U32 SectorOffsetInStartBlock;
U32 CopyLengthInStartBlock;
U32 EndBlock;
U32 SectorOffsetInEndBlock;
U32 BlockCount;
U32 Idx;
DbgPrint((DPRINT_CACHE, "CacheReadDiskSectors() DiskNumber: 0x%x StartSector: %d SectorCount: %d Buffer: 0x%x\n", DiskNumber, StartSector, SectorCount, Buffer));
// If we aren't initialized yet then they can't do this
if (CacheManagerInitialized == FALSE)
{
return FALSE;
}
//
// Caculate which blocks we must cache
//
StartBlock = StartSector / CacheManagerDrive.BlockSize;
SectorOffsetInStartBlock = StartSector % CacheManagerDrive.BlockSize;
CopyLengthInStartBlock = (SectorCount > (CacheManagerDrive.BlockSize - SectorOffsetInStartBlock)) ? (CacheManagerDrive.BlockSize - SectorOffsetInStartBlock) : SectorCount;
EndBlock = (StartSector + (SectorCount - 1)) / CacheManagerDrive.BlockSize;
SectorOffsetInEndBlock = (StartSector + SectorCount) % CacheManagerDrive.BlockSize;
BlockCount = (EndBlock - StartBlock) + 1;
DbgPrint((DPRINT_CACHE, "StartBlock: %d SectorOffsetInStartBlock: %d CopyLengthInStartBlock: %d EndBlock: %d SectorOffsetInEndBlock: %d BlockCount: %d\n", StartBlock, SectorOffsetInStartBlock, CopyLengthInStartBlock, EndBlock, SectorOffsetInEndBlock, BlockCount));
//
// Read the first block into the buffer
//
if (BlockCount > 0)
{
//
// Get cache block pointer (this forces the disk sectors into the cache memory)
//
CacheBlock = CacheInternalGetBlockPointer(&CacheManagerDrive, StartBlock);
if (CacheBlock == NULL)
{
return FALSE;
}
//
// Copy the portion requested into the buffer
//
RtlCopyMemory(Buffer,
(CacheBlock->BlockData + (SectorOffsetInStartBlock * CacheManagerDrive.BytesPerSector)),
(CopyLengthInStartBlock * CacheManagerDrive.BytesPerSector));
DbgPrint((DPRINT_CACHE, "1 - RtlCopyMemory(0x%x, 0x%x, %d)\n", Buffer, (CacheBlock->BlockData + (SectorOffsetInStartBlock * CacheManagerDrive.BytesPerSector)), (CopyLengthInStartBlock * CacheManagerDrive.BytesPerSector)));
//
// Update the buffer address
//
Buffer += (CopyLengthInStartBlock * CacheManagerDrive.BytesPerSector);
//
// Update the block count
//
BlockCount--;
}
//
// Loop through the middle blocks and read them into the buffer
//
for (Idx=StartBlock+1; BlockCount>1; Idx++)
{
//
// Get cache block pointer (this forces the disk sectors into the cache memory)
//
CacheBlock = CacheInternalGetBlockPointer(&CacheManagerDrive, Idx);
if (CacheBlock == NULL)
{
return FALSE;
}
//
// Copy the portion requested into the buffer
//
RtlCopyMemory(Buffer,
CacheBlock->BlockData,
CacheManagerDrive.BlockSize * CacheManagerDrive.BytesPerSector);
DbgPrint((DPRINT_CACHE, "2 - RtlCopyMemory(0x%x, 0x%x, %d)\n", Buffer, CacheBlock->BlockData, CacheManagerDrive.BlockSize * CacheManagerDrive.BytesPerSector));
//
// Update the buffer address
//
Buffer += CacheManagerDrive.BlockSize * CacheManagerDrive.BytesPerSector;
//
// Update the block count
//
BlockCount--;
}
//
// Read the last block into the buffer
//
if (BlockCount > 0)
{
//
// Get cache block pointer (this forces the disk sectors into the cache memory)
//
CacheBlock = CacheInternalGetBlockPointer(&CacheManagerDrive, EndBlock);
if (CacheBlock == NULL)
{
return FALSE;
}
//
// Copy the portion requested into the buffer
//
RtlCopyMemory(Buffer,
CacheBlock->BlockData,
SectorOffsetInEndBlock * CacheManagerDrive.BytesPerSector);
DbgPrint((DPRINT_CACHE, "3 - RtlCopyMemory(0x%x, 0x%x, %d)\n", Buffer, CacheBlock->BlockData, SectorOffsetInEndBlock * CacheManagerDrive.BytesPerSector));
//
// Update the buffer address
//
Buffer += SectorOffsetInEndBlock * CacheManagerDrive.BytesPerSector;
//
// Update the block count
//
BlockCount--;
}
return TRUE;
}
BOOL CacheForceDiskSectorsIntoCache(U32 DiskNumber, U32 StartSector, U32 SectorCount)
{
PCACHE_BLOCK CacheBlock;
U32 StartBlock;
U32 EndBlock;
U32 BlockCount;
U32 Idx;
DbgPrint((DPRINT_CACHE, "CacheForceDiskSectorsIntoCache() DiskNumber: 0x%x StartSector: %d SectorCount: %d\n", DiskNumber, StartSector, SectorCount));
// If we aren't initialized yet then they can't do this
if (CacheManagerInitialized == FALSE)
{
return FALSE;
}
//
// Caculate which blocks we must cache
//
StartBlock = StartSector / CacheManagerDrive.BlockSize;
EndBlock = (StartSector + SectorCount) / CacheManagerDrive.BlockSize;
BlockCount = (EndBlock - StartBlock) + 1;
//
// Loop through and cache them
//
for (Idx=StartBlock; Idx<(StartBlock+BlockCount); Idx++)
{
//
// Get cache block pointer (this forces the disk sectors into the cache memory)
//
CacheBlock = CacheInternalGetBlockPointer(&CacheManagerDrive, Idx);
if (CacheBlock == NULL)
{
return FALSE;
}
//
// Lock the sectors into the cache
//
CacheBlock->LockedInCache = TRUE;
}
return TRUE;
}
BOOL CacheReleaseMemory(U32 MinimumAmountToRelease)
{
U32 AmountReleased;
DbgPrint((DPRINT_CACHE, "CacheReleaseMemory() MinimumAmountToRelease = %d\n", MinimumAmountToRelease));
// If we aren't initialized yet then they can't do this
if (CacheManagerInitialized == FALSE)
{
return FALSE;
}
// Loop through and try to free the requested amount of memory
for (AmountReleased=0; AmountReleased<MinimumAmountToRelease; )
{
// Try to free a block
// If this fails then break out of the loop
if (!CacheInternalFreeBlock(&CacheManagerDrive))
{
break;
}
// It succeeded so increment the amount of memory we have freed
AmountReleased += CacheManagerDrive.BlockSize * CacheManagerDrive.BytesPerSector;
}
// Return status
return (AmountReleased >= MinimumAmountToRelease);
}

92
freeldr/freeldr/cache/cm.h vendored Normal file
View File

@@ -0,0 +1,92 @@
/*
* FreeLoader
* Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>
*
* 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.
*/
#include <freeldr.h>
#include <rtl.h>
#include <disk.h>
#ifndef __CM_H
#define __CM_H
///////////////////////////////////////////////////////////////////////////////////////
//
// This structure describes a cached block element. The disk is divided up into
// cache blocks. For disks which LBA is not supported each block is the size of
// one track. This will force the cache manager to make track sized reads, and
// therefore maximizes throughput. For disks which support LBA the block size
// is 64k because they have no cylinder, head, or sector boundaries.
//
///////////////////////////////////////////////////////////////////////////////////////
typedef struct
{
LIST_ITEM ListEntry; // Doubly linked list synchronization member
U32 BlockNumber; // Track index for CHS, 64k block index for LBA
BOOL LockedInCache; // Indicates that this block is locked in cache memory
U32 AccessCount; // Access count for this block
PVOID BlockData; // Pointer to block data
} CACHE_BLOCK, *PCACHE_BLOCK;
///////////////////////////////////////////////////////////////////////////////////////
//
// This structure describes a cached drive. It contains the BIOS drive number
// and indicates whether or not LBA is supported. If LBA is not supported then
// the drive's geometry is described here.
//
///////////////////////////////////////////////////////////////////////////////////////
typedef struct
{
U32 DriveNumber;
U32 BytesPerSector;
U32 BlockSize; // Block size (in sectors)
PCACHE_BLOCK CacheBlockHead;
} CACHE_DRIVE, *PCACHE_DRIVE;
///////////////////////////////////////////////////////////////////////////////////////
//
// Internal data
//
///////////////////////////////////////////////////////////////////////////////////////
extern CACHE_DRIVE CacheManagerDrive;
extern BOOL CacheManagerInitialized;
extern U32 CacheBlockCount;
extern U32 CacheSizeLimit;
extern U32 CacheSizeCurrent;
///////////////////////////////////////////////////////////////////////////////////////
//
// Internal functions
//
///////////////////////////////////////////////////////////////////////////////////////
PCACHE_BLOCK CacheInternalGetBlockPointer(PCACHE_DRIVE CacheDrive, U32 BlockNumber); // Returns a pointer to a CACHE_BLOCK structure given a block number
PCACHE_BLOCK CacheInternalFindBlock(PCACHE_DRIVE CacheDrive, U32 BlockNumber); // Searches the block list for a particular block
PCACHE_BLOCK CacheInternalAddBlockToCache(PCACHE_DRIVE CacheDrive, U32 BlockNumber); // Adds a block to the cache's block list
BOOL CacheInternalFreeBlock(PCACHE_DRIVE CacheDrive); // Removes a block from the cache's block list & frees the memory
VOID CacheInternalCheckCacheSizeLimits(PCACHE_DRIVE CacheDrive); // Checks the cache size limits to see if we can add a new block, if not calls CacheInternalFreeBlock()
VOID CacheInternalDumpBlockList(PCACHE_DRIVE CacheDrive); // Dumps the list of cached blocks to the debug output port
VOID CacheInternalOptimizeBlockList(PCACHE_DRIVE CacheDrive, PCACHE_BLOCK CacheBlock); // Moves the specified block to the head of the list
#endif // defined __CM_H

122
freeldr/freeldr/cmdline.c Normal file
View File

@@ -0,0 +1,122 @@
/* $Id: cmdline.c,v 1.1 2004/11/01 20:49:32 gvg Exp $
*
* FreeLoader
* Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>
*
* 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.
*/
#include <freeldr.h>
#include <cmdline.h>
#include <rtl.h>
static CMDLINEINFO CmdLineInfo;
static char *
SkipWhitespace(char *s)
{
while ('\0' != *s && isspace(*s))
{
s++;
}
return s;
}
void
CmdLineParse(char *CmdLine)
{
char *s;
char *Name;
char *Value;
char *End;
CmdLineInfo.DefaultOperatingSystem = NULL;
CmdLineInfo.TimeOut = -1;
if (NULL == CmdLine)
{
return;
}
/* Skip over "kernel name" */
s = CmdLine;
while ('\0' != *s && ! isspace(*s))
{
s++;
}
s = SkipWhitespace(s);
while ('\0' != *s)
{
Name = s;
while (! isspace(*s) && '=' != *s && '\0' != *s)
{
s++;
}
End = s;
s = SkipWhitespace(s);
if ('=' == *s)
{
s++;
*End = '\0';
s = SkipWhitespace(s);
if ('"' == *s)
{
s++;
Value = s;
while ('"' != *s && '\0' != *s)
{
s++;
}
}
else
{
Value = s;
while (! isspace(*s) && '\0' != *s)
{
s++;
}
}
if ('\0' != *s)
{
*s++ = '\0';
}
if (0 == stricmp(Name, "defaultos"))
{
CmdLineInfo.DefaultOperatingSystem = Value;
}
else if (0 == stricmp(Name, "timeout"))
{
CmdLineInfo.TimeOut = atoi(Value);
}
}
}
}
char *
CmdLineGetDefaultOS(void)
{
return CmdLineInfo.DefaultOperatingSystem;
}
S32
CmdLineGetTimeOut(void)
{
return CmdLineInfo.TimeOut;
}
/* EOF */

View File

@@ -0,0 +1,277 @@
/*
* FreeLoader
* Copyright (C) 2001 Brian Palmer <brianp@sginet.com>
* Copyright (C) 2001 Eric Kohl
* Copyright (C) 2001 Emanuele Aliberti
*
* 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.
*/
#include <freeldr.h>
#include <comm.h>
#include <portio.h>
/* MACROS *******************************************************************/
#define DEFAULT_BAUD_RATE 19200
#define SER_RBR(x) ((x)+0)
#define SER_THR(x) ((x)+0)
#define SER_DLL(x) ((x)+0)
#define SER_IER(x) ((x)+1)
#define SER_DLM(x) ((x)+1)
#define SER_IIR(x) ((x)+2)
#define SER_LCR(x) ((x)+3)
#define SR_LCR_CS5 0x00
#define SR_LCR_CS6 0x01
#define SR_LCR_CS7 0x02
#define SR_LCR_CS8 0x03
#define SR_LCR_ST1 0x00
#define SR_LCR_ST2 0x04
#define SR_LCR_PNO 0x00
#define SR_LCR_POD 0x08
#define SR_LCR_PEV 0x18
#define SR_LCR_PMK 0x28
#define SR_LCR_PSP 0x38
#define SR_LCR_BRK 0x40
#define SR_LCR_DLAB 0x80
#define SER_MCR(x) ((x)+4)
#define SR_MCR_DTR 0x01
#define SR_MCR_RTS 0x02
#define SER_LSR(x) ((x)+5)
#define SR_LSR_DR 0x01
#define SR_LSR_TBE 0x20
#define SER_MSR(x) ((x)+6)
#define SR_MSR_CTS 0x10
#define SR_MSR_DSR 0x20
#define SER_SCR(x) ((x)+7)
/* STATIC VARIABLES *********************************************************/
static U32 Rs232ComPort = 0;
static U32 Rs232BaudRate = 0;
static PUCHAR Rs232PortBase = (PUCHAR)0;
/* The com port must only be initialized once! */
static BOOLEAN PortInitialized = FALSE;
/* STATIC FUNCTIONS *********************************************************/
static BOOL Rs232DoesComPortExist(PUCHAR BaseAddress)
{
BOOLEAN found;
U8 mcr;
U8 msr;
found = FALSE;
/* save Modem Control Register (MCR) */
mcr = READ_PORT_UCHAR (SER_MCR(BaseAddress));
/* enable loop mode (set Bit 4 of the MCR) */
WRITE_PORT_UCHAR (SER_MCR(BaseAddress), 0x10);
/* clear all modem output bits */
WRITE_PORT_UCHAR (SER_MCR(BaseAddress), 0x10);
/* read the Modem Status Register */
msr = READ_PORT_UCHAR (SER_MSR(BaseAddress));
/*
* the upper nibble of the MSR (modem output bits) must be
* equal to the lower nibble of the MCR (modem input bits)
*/
if ((msr & 0xF0) == 0x00)
{
/* set all modem output bits */
WRITE_PORT_UCHAR (SER_MCR(BaseAddress), 0x1F);
/* read the Modem Status Register */
msr = READ_PORT_UCHAR (SER_MSR(BaseAddress));
/*
* the upper nibble of the MSR (modem output bits) must be
* equal to the lower nibble of the MCR (modem input bits)
*/
if ((msr & 0xF0) == 0xF0)
found = TRUE;
}
/* restore MCR */
WRITE_PORT_UCHAR (SER_MCR(BaseAddress), mcr);
return (found);
}
/* FUNCTIONS *********************************************************/
BOOL Rs232PortInitialize(U32 ComPort, U32 BaudRate)
{
U32 BaseArray[5] = {0, 0x3F8, 0x2F8, 0x3E8, 0x2E8};
//char buffer[80];
U32 divisor;
U8 lcr;
if (PortInitialized == FALSE)
{
if (BaudRate != 0)
{
Rs232BaudRate = BaudRate;
}
else
{
Rs232BaudRate = DEFAULT_BAUD_RATE;
}
if (ComPort == 0)
{
if (Rs232DoesComPortExist ((PUCHAR)BaseArray[2]))
{
Rs232PortBase = (PUCHAR)BaseArray[2];
Rs232ComPort = 2;
/*#ifndef NDEBUG
sprintf (buffer,
"\nSerial port COM%ld found at 0x%lx\n",
ComPort,
(U32)PortBase);
HalDisplayString (buffer);
#endif*/ /* NDEBUG */
}
else if (Rs232DoesComPortExist ((PUCHAR)BaseArray[1]))
{
Rs232PortBase = (PUCHAR)BaseArray[1];
Rs232ComPort = 1;
/*#ifndef NDEBUG
sprintf (buffer,
"\nSerial port COM%ld found at 0x%lx\n",
ComPort,
(U32)PortBase);
HalDisplayString (buffer);
#endif*/ /* NDEBUG */
}
else
{
/*sprintf (buffer,
"\nKernel Debugger: No COM port found!!!\n\n");
HalDisplayString (buffer);*/
return FALSE;
}
}
else
{
if (Rs232DoesComPortExist ((PUCHAR)BaseArray[ComPort]))
{
Rs232PortBase = (PUCHAR)BaseArray[ComPort];
Rs232ComPort = ComPort;
/*#ifndef NDEBUG
sprintf (buffer,
"\nSerial port COM%ld found at 0x%lx\n",
ComPort,
(U32)PortBase);
HalDisplayString (buffer);
#endif*/ /* NDEBUG */
}
else
{
/*sprintf (buffer,
"\nKernel Debugger: No serial port found!!!\n\n");
HalDisplayString (buffer);*/
return FALSE;
}
}
PortInitialized = TRUE;
}
/*
* set baud rate and data format (8N1)
*/
/* turn on DTR and RTS */
WRITE_PORT_UCHAR (SER_MCR(Rs232PortBase), SR_MCR_DTR | SR_MCR_RTS);
/* set DLAB */
lcr = READ_PORT_UCHAR (SER_LCR(Rs232PortBase)) | SR_LCR_DLAB;
WRITE_PORT_UCHAR (SER_LCR(Rs232PortBase), lcr);
/* set baud rate */
divisor = 115200 / BaudRate;
WRITE_PORT_UCHAR (SER_DLL(Rs232PortBase), divisor & 0xff);
WRITE_PORT_UCHAR (SER_DLM(Rs232PortBase), (divisor >> 8) & 0xff);
/* reset DLAB and set 8N1 format */
WRITE_PORT_UCHAR (SER_LCR(Rs232PortBase),
SR_LCR_CS8 | SR_LCR_ST1 | SR_LCR_PNO);
/* read junk out of the RBR */
lcr = READ_PORT_UCHAR (SER_RBR(Rs232PortBase));
/*
* set global info
*/
//KdComPortInUse = (U32)PortBase;
/*
* print message to blue screen
*/
/*sprintf (buffer,
"\nKernel Debugger: COM%ld (Port 0x%lx) BaudRate %ld\n\n",
ComPort,
(U32)PortBase,
BaudRate);
HalDisplayString (buffer);*/
return TRUE;
}
BOOL Rs232PortGetByte(PUCHAR ByteRecieved)
{
if (PortInitialized == FALSE)
return FALSE;
if ((READ_PORT_UCHAR (SER_LSR(Rs232PortBase)) & SR_LSR_DR))
{
*ByteRecieved = READ_PORT_UCHAR (SER_RBR(Rs232PortBase));
return TRUE;
}
return FALSE;
}
BOOL Rs232PortPollByte(PUCHAR ByteRecieved)
{
if (PortInitialized == FALSE)
return FALSE;
while ((READ_PORT_UCHAR (SER_LSR(Rs232PortBase)) & SR_LSR_DR) == 0)
;
*ByteRecieved = READ_PORT_UCHAR (SER_RBR(Rs232PortBase));
return TRUE;
}
VOID Rs232PortPutByte(UCHAR ByteToSend)
{
if (PortInitialized == FALSE)
return;
while ((READ_PORT_UCHAR (SER_LSR(Rs232PortBase)) & SR_LSR_TBE) == 0)
;
WRITE_PORT_UCHAR (SER_THR(Rs232PortBase), ByteToSend);
}

411
freeldr/freeldr/custom.c Normal file
View File

@@ -0,0 +1,411 @@
/*
* FreeLoader
* Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>
*
* 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.
*/
#include <freeldr.h>
#include <rtl.h>
#include <ui.h>
#include <options.h>
#include <miscboot.h>
#include <debug.h>
#include <disk.h>
#include <arch.h>
#include <inifile.h>
#include <linux.h>
#include <reactos.h>
#include <drivemap.h>
#include <machine.h>
UCHAR BootDrivePrompt[] = "Enter the boot drive.\n\nExamples:\nfd0 - first floppy drive\nhd0 - first hard drive\nhd1 - second hard drive\ncd0 - first CD-ROM drive.\n\nBIOS drive numbers may also be used:\n0 - first floppy drive\n0x80 - first hard drive\n0x81 - second hard drive";
UCHAR BootPartitionPrompt[] = "Enter the boot partition.\n\nEnter 0 for the active (bootable) partition.";
UCHAR BootSectorFilePrompt[] = "Enter the boot sector file path.\n\nExamples:\n\\BOOTSECT.DOS\n/boot/bootsect.dos";
UCHAR LinuxKernelPrompt[] = "Enter the Linux kernel image path.\n\nExamples:\n/vmlinuz\n/boot/vmlinuz-2.4.18";
UCHAR LinuxInitrdPrompt[] = "Enter the initrd image path.\n\nExamples:\n/initrd.gz\n/boot/root.img.gz\n\nLeave blank for no initial ram disk.";
UCHAR LinuxCommandLinePrompt[] = "Enter the Linux kernel command line.\n\nExamples:\nroot=/dev/hda1\nroot=/dev/fd0 read-only\nroot=/dev/sdb1 init=/sbin/init";
UCHAR ReactOSSystemPathPrompt[] = "Enter the path to your ReactOS system directory.\n\nExamples:\n\\REACTOS\n\\ROS";
UCHAR ReactOSOptionsPrompt[] = "Enter the options you want passed to the kernel.\n\nExamples:\n/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200\n/FASTDETECT /SOS /NOGUIBOOT\n/BASEVIDEO /MAXMEM=64\n/KERNEL=NTKRNLMP.EXE /HAL=HALMPS.DLL";
UCHAR CustomBootPrompt[] = "Press ENTER to boot your custom boot setup.";
VOID OptionMenuCustomBoot(VOID)
{
PUCHAR CustomBootMenuList[] = { "Disk", "Partition", "Boot Sector File", "ReactOS", "Linux" };
U32 CustomBootMenuCount = sizeof(CustomBootMenuList) / sizeof(CustomBootMenuList[0]);
U32 SelectedMenuItem;
if (!UiDisplayMenu(CustomBootMenuList, CustomBootMenuCount, 0, -1, &SelectedMenuItem, TRUE, NULL))
{
// The user pressed ESC
return;
}
switch (SelectedMenuItem)
{
case 0: // Disk
OptionMenuCustomBootDisk();
break;
case 1: // Partition
OptionMenuCustomBootPartition();
break;
case 2: // Boot Sector File
OptionMenuCustomBootBootSectorFile();
break;
case 3: // ReactOS
OptionMenuCustomBootReactOS();
break;
case 4: // Linux
OptionMenuCustomBootLinux();
break;
}
}
VOID OptionMenuCustomBootDisk(VOID)
{
UCHAR SectionName[100];
UCHAR BootDriveString[20];
U32 SectionId;
U32 Year, Month, Day, Hour, Minute, Second;
RtlZeroMemory(SectionName, sizeof(SectionName));
RtlZeroMemory(BootDriveString, sizeof(BootDriveString));
if (!UiEditBox(BootDrivePrompt, BootDriveString, 20))
{
return;
}
// Generate a unique section name
MachRTCGetCurrentDateTime(&Year, &Month, &Day, &Hour, &Minute, &Second);
sprintf(SectionName, "CustomBootDisk%d%d%d%d%d%d", Year, Day, Month, Hour, Minute, Second);
// Add the section
if (!IniAddSection(SectionName, &SectionId))
{
return;
}
// Add the BootType
if (!IniAddSettingValueToSection(SectionId, "BootType", "Drive"))
{
return;
}
// Add the BootDrive
if (!IniAddSettingValueToSection(SectionId, "BootDrive", BootDriveString))
{
return;
}
UiMessageBox(CustomBootPrompt);
LoadAndBootDrive(SectionName);
}
VOID OptionMenuCustomBootPartition(VOID)
{
UCHAR SectionName[100];
UCHAR BootDriveString[20];
UCHAR BootPartitionString[20];
U32 SectionId;
U32 Year, Month, Day, Hour, Minute, Second;
RtlZeroMemory(SectionName, sizeof(SectionName));
RtlZeroMemory(BootDriveString, sizeof(BootDriveString));
RtlZeroMemory(BootPartitionString, sizeof(BootPartitionString));
if (!UiEditBox(BootDrivePrompt, BootDriveString, 20))
{
return;
}
if (!UiEditBox(BootPartitionPrompt, BootPartitionString, 20))
{
return;
}
// Generate a unique section name
MachRTCGetCurrentDateTime(&Year, &Month, &Day, &Hour, &Minute, &Second);
sprintf(SectionName, "CustomBootPartition%d%d%d%d%d%d", Year, Day, Month, Hour, Minute, Second);
// Add the section
if (!IniAddSection(SectionName, &SectionId))
{
return;
}
// Add the BootType
if (!IniAddSettingValueToSection(SectionId, "BootType", "Partition"))
{
return;
}
// Add the BootDrive
if (!IniAddSettingValueToSection(SectionId, "BootDrive", BootDriveString))
{
return;
}
// Add the BootPartition
if (!IniAddSettingValueToSection(SectionId, "BootPartition", BootPartitionString))
{
return;
}
UiMessageBox(CustomBootPrompt);
LoadAndBootPartition(SectionName);
}
VOID OptionMenuCustomBootBootSectorFile(VOID)
{
UCHAR SectionName[100];
UCHAR BootDriveString[20];
UCHAR BootPartitionString[20];
UCHAR BootSectorFileString[200];
U32 SectionId;
U32 Year, Month, Day, Hour, Minute, Second;
RtlZeroMemory(SectionName, sizeof(SectionName));
RtlZeroMemory(BootDriveString, sizeof(BootDriveString));
RtlZeroMemory(BootPartitionString, sizeof(BootPartitionString));
RtlZeroMemory(BootSectorFileString, sizeof(BootSectorFileString));
if (!UiEditBox(BootDrivePrompt, BootDriveString, 20))
{
return;
}
if (!UiEditBox(BootPartitionPrompt, BootPartitionString, 20))
{
return;
}
if (!UiEditBox(BootSectorFilePrompt, BootSectorFileString, 200))
{
return;
}
// Generate a unique section name
MachRTCGetCurrentDateTime(&Year, &Month, &Day, &Hour, &Minute, &Second);
sprintf(SectionName, "CustomBootSectorFile%d%d%d%d%d%d", Year, Day, Month, Hour, Minute, Second);
// Add the section
if (!IniAddSection(SectionName, &SectionId))
{
return;
}
// Add the BootType
if (!IniAddSettingValueToSection(SectionId, "BootType", "BootSector"))
{
return;
}
// Add the BootDrive
if (!IniAddSettingValueToSection(SectionId, "BootDrive", BootDriveString))
{
return;
}
// Add the BootPartition
if (!IniAddSettingValueToSection(SectionId, "BootPartition", BootPartitionString))
{
return;
}
// Add the BootSectorFile
if (!IniAddSettingValueToSection(SectionId, "BootSectorFile", BootSectorFileString))
{
return;
}
UiMessageBox(CustomBootPrompt);
LoadAndBootBootSector(SectionName);
}
VOID OptionMenuCustomBootReactOS(VOID)
{
UCHAR SectionName[100];
UCHAR BootDriveString[20];
UCHAR BootPartitionString[20];
UCHAR ReactOSSystemPath[200];
UCHAR ReactOSARCPath[200];
UCHAR ReactOSOptions[200];
U32 SectionId;
U32 Year, Month, Day, Hour, Minute, Second;
RtlZeroMemory(SectionName, sizeof(SectionName));
RtlZeroMemory(BootDriveString, sizeof(BootDriveString));
RtlZeroMemory(BootPartitionString, sizeof(BootPartitionString));
RtlZeroMemory(ReactOSSystemPath, sizeof(ReactOSSystemPath));
RtlZeroMemory(ReactOSOptions, sizeof(ReactOSOptions));
if (!UiEditBox(BootDrivePrompt, BootDriveString, 20))
{
return;
}
if (!UiEditBox(BootPartitionPrompt, BootPartitionString, 20))
{
return;
}
if (!UiEditBox(ReactOSSystemPathPrompt, ReactOSSystemPath, 200))
{
return;
}
if (!UiEditBox(ReactOSOptionsPrompt, ReactOSOptions, 200))
{
return;
}
// Generate a unique section name
MachRTCGetCurrentDateTime(&Year, &Month, &Day, &Hour, &Minute, &Second);
sprintf(SectionName, "CustomReactOS%d%d%d%d%d%d", Year, Day, Month, Hour, Minute, Second);
// Add the section
if (!IniAddSection(SectionName, &SectionId))
{
return;
}
// Add the BootType
if (!IniAddSettingValueToSection(SectionId, "BootType", "ReactOS"))
{
return;
}
// Construct the ReactOS ARC system path
ConstructArcPath(ReactOSARCPath, ReactOSSystemPath, DriveMapGetBiosDriveNumber(BootDriveString), atoi(BootPartitionString));
// Add the system path
if (!IniAddSettingValueToSection(SectionId, "SystemPath", ReactOSARCPath))
{
return;
}
// Add the CommandLine
if (!IniAddSettingValueToSection(SectionId, "Options", ReactOSOptions))
{
return;
}
UiMessageBox(CustomBootPrompt);
LoadAndBootReactOS(SectionName);
}
VOID OptionMenuCustomBootLinux(VOID)
{
UCHAR SectionName[100];
UCHAR BootDriveString[20];
UCHAR BootPartitionString[20];
UCHAR LinuxKernelString[200];
UCHAR LinuxInitrdString[200];
UCHAR LinuxCommandLineString[200];
U32 SectionId;
U32 Year, Month, Day, Hour, Minute, Second;
RtlZeroMemory(SectionName, sizeof(SectionName));
RtlZeroMemory(BootDriveString, sizeof(BootDriveString));
RtlZeroMemory(BootPartitionString, sizeof(BootPartitionString));
RtlZeroMemory(LinuxKernelString, sizeof(LinuxKernelString));
RtlZeroMemory(LinuxInitrdString, sizeof(LinuxInitrdString));
RtlZeroMemory(LinuxCommandLineString, sizeof(LinuxCommandLineString));
if (!UiEditBox(BootDrivePrompt, BootDriveString, 20))
{
return;
}
if (!UiEditBox(BootPartitionPrompt, BootPartitionString, 20))
{
return;
}
if (!UiEditBox(LinuxKernelPrompt, LinuxKernelString, 200))
{
return;
}
if (!UiEditBox(LinuxInitrdPrompt, LinuxInitrdString, 200))
{
return;
}
if (!UiEditBox(LinuxCommandLinePrompt, LinuxCommandLineString, 200))
{
return;
}
// Generate a unique section name
MachRTCGetCurrentDateTime(&Year, &Month, &Day, &Hour, &Minute, &Second);
sprintf(SectionName, "CustomLinux%d%d%d%d%d%d", Year, Day, Month, Hour, Minute, Second);
// Add the section
if (!IniAddSection(SectionName, &SectionId))
{
return;
}
// Add the BootType
if (!IniAddSettingValueToSection(SectionId, "BootType", "Linux"))
{
return;
}
// Add the BootDrive
if (!IniAddSettingValueToSection(SectionId, "BootDrive", BootDriveString))
{
return;
}
// Add the BootPartition
if (!IniAddSettingValueToSection(SectionId, "BootPartition", BootPartitionString))
{
return;
}
// Add the Kernel
if (!IniAddSettingValueToSection(SectionId, "Kernel", LinuxKernelString))
{
return;
}
// Add the Initrd
if (strlen(LinuxInitrdString) > 0)
{
if (!IniAddSettingValueToSection(SectionId, "Initrd", LinuxInitrdString))
{
return;
}
}
// Add the CommandLine
if (!IniAddSettingValueToSection(SectionId, "CommandLine", LinuxCommandLineString))
{
return;
}
UiMessageBox(CustomBootPrompt);
LoadAndBootLinux(SectionName, "Custom Linux Setup");
}

411
freeldr/freeldr/debug.c Normal file
View File

@@ -0,0 +1,411 @@
/*
* FreeLoader
* Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>
*
* 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.
*/
#include <freeldr.h>
#include <debug.h>
#include <rtl.h>
#include <comm.h>
#include <portio.h>
#include <machine.h>
#ifdef DEBUG
//#define DEBUG_ALL
//#define DEBUG_INIFILE
//#define DEBUG_REACTOS
//#define DEBUG_CUSTOM
#define DEBUG_NONE
#if defined (DEBUG_ALL)
U32 DebugPrintMask = DPRINT_WARNING | DPRINT_MEMORY | DPRINT_FILESYSTEM |
DPRINT_UI | DPRINT_DISK | DPRINT_CACHE | DPRINT_REACTOS |
DPRINT_LINUX;
#elif defined (DEBUG_INIFILE)
U32 DebugPrintMask = DPRINT_INIFILE;
#elif defined (DEBUG_REACTOS)
U32 DebugPrintMask = DPRINT_REACTOS | DPRINT_REGISTRY;
#elif defined (DEBUG_CUSTOM)
U32 DebugPrintMask = DPRINT_WARNING|DPRINT_FILESYSTEM|DPRINT_MEMORY|DPRINT_LINUX;
#else //#elif defined (DEBUG_NONE)
U32 DebugPrintMask = 0;
#endif
#define SCREEN 0
#define RS232 1
#define BOCHS 2
#define COM1 1
#define COM2 2
#define COM3 3
#define COM4 4
#define BOCHS_OUTPUT_PORT 0xe9
U32 DebugPort = RS232;
//U32 DebugPort = SCREEN;
//U32 DebugPort = BOCHS;
U32 ComPort = COM1;
//U32 BaudRate = 19200;
U32 BaudRate = 115200;
BOOL DebugStartOfLine = TRUE;
VOID DebugInit(VOID)
{
if (DebugPort == RS232)
{
Rs232PortInitialize(ComPort, BaudRate);
}
}
VOID DebugPrintChar(UCHAR Character)
{
if (Character == '\n')
{
DebugStartOfLine = TRUE;
}
if (DebugPort == RS232)
{
if (Character == '\n')
{
Rs232PortPutByte('\r');
}
Rs232PortPutByte(Character);
}
else if (DebugPort == BOCHS)
{
WRITE_PORT_UCHAR((PUCHAR)BOCHS_OUTPUT_PORT, Character);
}
else
{
MachConsPutChar(Character);
}
}
VOID DebugPrintHeader(U32 Mask)
{
/* No header */
if (Mask == 0)
return;
switch (Mask)
{
case DPRINT_WARNING:
DebugPrintChar('W');
DebugPrintChar('A');
DebugPrintChar('R');
DebugPrintChar('N');
DebugPrintChar('I');
DebugPrintChar('N');
DebugPrintChar('G');
DebugPrintChar(':');
DebugPrintChar(' ');
break;
case DPRINT_MEMORY:
DebugPrintChar('M');
DebugPrintChar('E');
DebugPrintChar('M');
DebugPrintChar('O');
DebugPrintChar('R');
DebugPrintChar('Y');
DebugPrintChar(':');
DebugPrintChar(' ');
break;
case DPRINT_FILESYSTEM:
DebugPrintChar('F');
DebugPrintChar('I');
DebugPrintChar('L');
DebugPrintChar('E');
DebugPrintChar('S');
DebugPrintChar('Y');
DebugPrintChar('S');
DebugPrintChar(':');
DebugPrintChar(' ');
break;
case DPRINT_INIFILE:
DebugPrintChar('I');
DebugPrintChar('N');
DebugPrintChar('I');
DebugPrintChar('F');
DebugPrintChar('I');
DebugPrintChar('L');
DebugPrintChar('E');
DebugPrintChar(':');
DebugPrintChar(' ');
break;
case DPRINT_UI:
DebugPrintChar('U');
DebugPrintChar('I');
DebugPrintChar(':');
DebugPrintChar(' ');
break;
case DPRINT_DISK:
DebugPrintChar('D');
DebugPrintChar('I');
DebugPrintChar('S');
DebugPrintChar('K');
DebugPrintChar(':');
DebugPrintChar(' ');
break;
case DPRINT_CACHE:
DebugPrintChar('C');
DebugPrintChar('A');
DebugPrintChar('C');
DebugPrintChar('H');
DebugPrintChar('E');
DebugPrintChar(':');
DebugPrintChar(' ');
break;
case DPRINT_REGISTRY:
DebugPrintChar('R');
DebugPrintChar('E');
DebugPrintChar('G');
DebugPrintChar('I');
DebugPrintChar('S');
DebugPrintChar('T');
DebugPrintChar('R');
DebugPrintChar('Y');
DebugPrintChar(':');
DebugPrintChar(' ');
break;
case DPRINT_REACTOS:
DebugPrintChar('R');
DebugPrintChar('E');
DebugPrintChar('A');
DebugPrintChar('C');
DebugPrintChar('T');
DebugPrintChar('O');
DebugPrintChar('S');
DebugPrintChar(':');
DebugPrintChar(' ');
break;
case DPRINT_LINUX:
DebugPrintChar('L');
DebugPrintChar('I');
DebugPrintChar('N');
DebugPrintChar('U');
DebugPrintChar('X');
DebugPrintChar(':');
DebugPrintChar(' ');
break;
case DPRINT_HWDETECT:
DebugPrintChar('H');
DebugPrintChar('W');
DebugPrintChar('D');
DebugPrintChar('E');
DebugPrintChar('T');
DebugPrintChar('E');
DebugPrintChar('C');
DebugPrintChar('T');
DebugPrintChar(':');
DebugPrintChar(' ');
break;
default:
DebugPrintChar('U');
DebugPrintChar('N');
DebugPrintChar('K');
DebugPrintChar('N');
DebugPrintChar('O');
DebugPrintChar('W');
DebugPrintChar('N');
DebugPrintChar(':');
DebugPrintChar(' ');
break;
}
}
static VOID DebugPrintV(char *format, int *dataptr)
{
char c, *ptr, str[16];
int ll;
ll = 0;
while ((c = *(format++)))
{
if (c != '%')
{
DebugPrintChar(c);
}
else
{
if (*format == 'I' && *(format+1) == '6' && *(format+2) == '4')
{
ll = 1;
format += 3;
}
else
{
ll = 0;
}
switch (c = *(format++))
{
case 'd': case 'u': case 'x':
if (ll)
{
*convert_i64_to_ascii(str, c, *((unsigned long long*) dataptr)) = 0;
dataptr += 2;
}
else
{
*convert_to_ascii(str, c, *((unsigned long *) dataptr++)) = 0;
}
ptr = str;
while (*ptr)
{
DebugPrintChar(*(ptr++));
}
break;
case 'c':
DebugPrintChar((*(dataptr++))&0xff);
break;
case 's':
ptr = (char *)(*(dataptr++));
while ((c = *(ptr++)))
{
DebugPrintChar(c);
}
break;
case '%':
DebugPrintChar(c);
break;
default:
DebugPrint(DPRINT_WARNING, "\nDebugPrint() invalid format specifier - %%%c\n", c);
break;
}
}
}
if (DebugPort == SCREEN)
{
//getch();
}
}
VOID DebugPrint(U32 Mask, char *format, ...)
{
int *dataptr = (int *) &format;
// Mask out unwanted debug messages
if (!(Mask & DebugPrintMask))
{
return;
}
// Print the header if we have started a new line
if (DebugStartOfLine)
{
DebugPrintHeader(Mask);
DebugStartOfLine = FALSE;
}
DebugPrintV(format, ++dataptr);
}
VOID DebugPrint1(char *format, ...)
{
int *dataptr = (int *) &format;
DebugPrintV(format, ++dataptr);
}
VOID DebugDumpBuffer(U32 Mask, PVOID Buffer, U32 Length)
{
PUCHAR BufPtr = (PUCHAR)Buffer;
U32 Idx;
U32 Idx2;
// Mask out unwanted debug messages
if (!(Mask & DebugPrintMask))
{
return;
}
DebugStartOfLine = FALSE; // We don't want line headers
DebugPrint(Mask, "Dumping buffer at 0x%x with length of %d bytes:\n", Buffer, Length);
for (Idx=0; Idx<Length; )
{
DebugStartOfLine = FALSE; // We don't want line headers
if (Idx < 0x0010)
{
DebugPrint(Mask, "000%x:\t", Idx);
}
else if (Idx < 0x0100)
{
DebugPrint(Mask, "00%x:\t", Idx);
}
else if (Idx < 0x1000)
{
DebugPrint(Mask, "0%x:\t", Idx);
}
else
{
DebugPrint(Mask, "%x:\t", Idx);
}
for (Idx2=0; Idx2<16; Idx2++,Idx++)
{
if (BufPtr[Idx] < 0x10)
{
DebugPrint(Mask, "0");
}
DebugPrint(Mask, "%x", BufPtr[Idx]);
if (Idx2 == 7)
{
DebugPrint(Mask, "-");
}
else
{
DebugPrint(Mask, " ");
}
}
Idx -= 16;
DebugPrint(Mask, " ");
for (Idx2=0; Idx2<16; Idx2++,Idx++)
{
if ((BufPtr[Idx] > 20) && (BufPtr[Idx] < 0x80))
{
DebugPrint(Mask, "%c", BufPtr[Idx]);
}
else
{
DebugPrint(Mask, ".");
}
}
DebugPrint(Mask, "\n");
}
}
#endif // defined DEBUG

112
freeldr/freeldr/disk/disk.c Normal file
View File

@@ -0,0 +1,112 @@
/*
* FreeLoader
* Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>
*
* 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.
*/
#include <freeldr.h>
#include <disk.h>
#include <arch.h>
#include <rtl.h>
#include <ui.h>
#include <debug.h>
#undef UNIMPLEMENTED
#define UNIMPLEMENTED BugCheck((DPRINT_WARNING, "Unimplemented\n"));
static BOOL bReportError = TRUE;
/////////////////////////////////////////////////////////////////////////////////////////////
// FUNCTIONS
/////////////////////////////////////////////////////////////////////////////////////////////
VOID DiskReportError (BOOL bError)
{
bReportError = bError;
}
VOID DiskError(PUCHAR ErrorString, U32 ErrorCode)
{
UCHAR ErrorCodeString[200];
if (bReportError == FALSE)
return;
sprintf(ErrorCodeString, "%s\n\nError Code: 0x%x\nError: %s", ErrorString, ErrorCode, DiskGetErrorCodeString(ErrorCode));
DbgPrint((DPRINT_DISK, "%s\n", ErrorCodeString));
UiMessageBox(ErrorCodeString);
}
PUCHAR DiskGetErrorCodeString(U32 ErrorCode)
{
switch (ErrorCode)
{
case 0x00: return "no error";
case 0x01: return "bad command passed to driver";
case 0x02: return "address mark not found or bad sector";
case 0x03: return "diskette write protect error";
case 0x04: return "sector not found";
case 0x05: return "fixed disk reset failed";
case 0x06: return "diskette changed or removed";
case 0x07: return "bad fixed disk parameter table";
case 0x08: return "DMA overrun";
case 0x09: return "DMA access across 64k boundary";
case 0x0A: return "bad fixed disk sector flag";
case 0x0B: return "bad fixed disk cylinder";
case 0x0C: return "unsupported track/invalid media";
case 0x0D: return "invalid number of sectors on fixed disk format";
case 0x0E: return "fixed disk controlled data address mark detected";
case 0x0F: return "fixed disk DMA arbitration level out of range";
case 0x10: return "ECC/CRC error on disk read";
case 0x11: return "recoverable fixed disk data error, data fixed by ECC";
case 0x20: return "controller error (NEC for floppies)";
case 0x40: return "seek failure";
case 0x80: return "time out, drive not ready";
case 0xAA: return "fixed disk drive not ready";
case 0xBB: return "fixed disk undefined error";
case 0xCC: return "fixed disk write fault on selected drive";
case 0xE0: return "fixed disk status error/Error reg = 0";
case 0xFF: return "sense operation failed";
default: return "unknown error code";
}
}
// This function is in arch/i386/i386disk.c
//BOOL DiskReadLogicalSectors(U32 DriveNumber, U64 SectorNumber, U32 SectorCount, PVOID Buffer)
BOOL DiskIsDriveRemovable(U32 DriveNumber)
{
// Hard disks use drive numbers >= 0x80
// So if the drive number indicates a hard disk
// then return FALSE
if (DriveNumber >= 0x80)
{
return FALSE;
}
// Drive is a floppy diskette so return TRUE
return TRUE;
}
// This function is in arch/i386/i386disk.c
//VOID DiskStopFloppyMotor(VOID)
// This function is in arch/i386/i386disk.c
//U32 DiskGetCacheableBlockCount(U32 DriveNumber)

View File

@@ -0,0 +1,247 @@
/*
* FreeLoader
* Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>
*
* 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.
*/
#include <freeldr.h>
#include <disk.h>
#include <rtl.h>
#include <mm.h>
#include <debug.h>
#include <arch.h>
#include <machine.h>
BOOL DiskGetActivePartitionEntry(U32 DriveNumber, PPARTITION_TABLE_ENTRY PartitionTableEntry)
{
U32 BootablePartitionCount = 0;
MASTER_BOOT_RECORD MasterBootRecord;
// Read master boot record
if (!DiskReadBootRecord(DriveNumber, 0, &MasterBootRecord))
{
return FALSE;
}
// Count the bootable partitions
if (MasterBootRecord.PartitionTable[0].BootIndicator == 0x80)
{
BootablePartitionCount++;
BootPartition = 0;
}
if (MasterBootRecord.PartitionTable[1].BootIndicator == 0x80)
{
BootablePartitionCount++;
BootPartition = 1;
}
if (MasterBootRecord.PartitionTable[2].BootIndicator == 0x80)
{
BootablePartitionCount++;
BootPartition = 2;
}
if (MasterBootRecord.PartitionTable[3].BootIndicator == 0x80)
{
BootablePartitionCount++;
BootPartition = 3;
}
// Make sure there was only one bootable partition
if (BootablePartitionCount == 0)
{
DiskError("No bootable (active) partitions found.", 0);
return FALSE;
}
else if (BootablePartitionCount != 1)
{
DiskError("Too many bootable (active) partitions found.", 0);
return FALSE;
}
// Copy the partition table entry
RtlCopyMemory(PartitionTableEntry, &MasterBootRecord.PartitionTable[BootPartition], sizeof(PARTITION_TABLE_ENTRY));
return TRUE;
}
BOOL DiskGetPartitionEntry(U32 DriveNumber, U32 PartitionNumber, PPARTITION_TABLE_ENTRY PartitionTableEntry)
{
MASTER_BOOT_RECORD MasterBootRecord;
PARTITION_TABLE_ENTRY ExtendedPartitionTableEntry;
U32 ExtendedPartitionNumber;
U32 ExtendedPartitionOffset;
U32 Index;
// Read master boot record
if (!DiskReadBootRecord(DriveNumber, 0, &MasterBootRecord))
{
return FALSE;
}
// If they are asking for a primary
// partition then things are easy
if (PartitionNumber < 5)
{
// PartitionNumber is one-based and we need it zero-based
PartitionNumber--;
// Copy the partition table entry
RtlCopyMemory(PartitionTableEntry, &MasterBootRecord.PartitionTable[PartitionNumber], sizeof(PARTITION_TABLE_ENTRY));
return TRUE;
}
else
{
// They want an extended partition entry so we will need
// to loop through all the extended partitions on the disk
// and return the one they want.
ExtendedPartitionNumber = PartitionNumber - 5;
// Set the initial relative starting sector to 0
// This is because extended partition starting
// sectors a numbered relative to their parent
ExtendedPartitionOffset = 0;
for (Index=0; Index<=ExtendedPartitionNumber; Index++)
{
// Get the extended partition table entry
if (!DiskGetFirstExtendedPartitionEntry(&MasterBootRecord, &ExtendedPartitionTableEntry))
{
return FALSE;
}
// Adjust the relative starting sector of the partition
ExtendedPartitionTableEntry.SectorCountBeforePartition += ExtendedPartitionOffset;
if (ExtendedPartitionOffset == 0)
{
// Set the start of the parrent extended partition
ExtendedPartitionOffset = ExtendedPartitionTableEntry.SectorCountBeforePartition;
}
// Read the partition boot record
if (!DiskReadBootRecord(DriveNumber, ExtendedPartitionTableEntry.SectorCountBeforePartition, &MasterBootRecord))
{
return FALSE;
}
// Get the first real partition table entry
if (!DiskGetFirstPartitionEntry(&MasterBootRecord, PartitionTableEntry))
{
return FALSE;
}
// Now correct the start sector of the partition
PartitionTableEntry->SectorCountBeforePartition += ExtendedPartitionTableEntry.SectorCountBeforePartition;
}
// When we get here we should have the correct entry
// already stored in PartitionTableEntry
// so just return TRUE
return TRUE;
}
}
BOOL DiskGetFirstPartitionEntry(PMASTER_BOOT_RECORD MasterBootRecord, PPARTITION_TABLE_ENTRY PartitionTableEntry)
{
U32 Index;
for (Index=0; Index<4; Index++)
{
// Check the system indicator
// If it's not an extended or unused partition
// then we're done
if ((MasterBootRecord->PartitionTable[Index].SystemIndicator != PARTITION_ENTRY_UNUSED) &&
(MasterBootRecord->PartitionTable[Index].SystemIndicator != PARTITION_EXTENDED) &&
(MasterBootRecord->PartitionTable[Index].SystemIndicator != PARTITION_XINT13_EXTENDED))
{
RtlCopyMemory(PartitionTableEntry, &MasterBootRecord->PartitionTable[Index], sizeof(PARTITION_TABLE_ENTRY));
return TRUE;
}
}
return FALSE;
}
BOOL DiskGetFirstExtendedPartitionEntry(PMASTER_BOOT_RECORD MasterBootRecord, PPARTITION_TABLE_ENTRY PartitionTableEntry)
{
U32 Index;
for (Index=0; Index<4; Index++)
{
// Check the system indicator
// If it an extended partition then we're done
if ((MasterBootRecord->PartitionTable[Index].SystemIndicator == PARTITION_EXTENDED) ||
(MasterBootRecord->PartitionTable[Index].SystemIndicator == PARTITION_XINT13_EXTENDED))
{
RtlCopyMemory(PartitionTableEntry, &MasterBootRecord->PartitionTable[Index], sizeof(PARTITION_TABLE_ENTRY));
return TRUE;
}
}
return FALSE;
}
BOOL DiskReadBootRecord(U32 DriveNumber, U64 LogicalSectorNumber, PMASTER_BOOT_RECORD BootRecord)
{
char ErrMsg[64];
#ifdef DEBUG
U32 Index;
#endif
// Read master boot record
if (!MachDiskReadLogicalSectors(DriveNumber, LogicalSectorNumber, 1, (PVOID)DISKREADBUFFER))
{
return FALSE;
}
RtlCopyMemory(BootRecord, (PVOID)DISKREADBUFFER, sizeof(MASTER_BOOT_RECORD));
#ifdef DEBUG
DbgPrint((DPRINT_DISK, "Dumping partition table for drive 0x%x:\n", DriveNumber));
DbgPrint((DPRINT_DISK, "Boot record logical start sector = %d\n", LogicalSectorNumber));
DbgPrint((DPRINT_DISK, "sizeof(MASTER_BOOT_RECORD) = 0x%x.\n", sizeof(MASTER_BOOT_RECORD)));
for (Index=0; Index<4; Index++)
{
DbgPrint((DPRINT_DISK, "-------------------------------------------\n"));
DbgPrint((DPRINT_DISK, "Partition %d\n", (Index + 1)));
DbgPrint((DPRINT_DISK, "BootIndicator: 0x%x\n", BootRecord->PartitionTable[Index].BootIndicator));
DbgPrint((DPRINT_DISK, "StartHead: 0x%x\n", BootRecord->PartitionTable[Index].StartHead));
DbgPrint((DPRINT_DISK, "StartSector (Plus 2 cylinder bits): 0x%x\n", BootRecord->PartitionTable[Index].StartSector));
DbgPrint((DPRINT_DISK, "StartCylinder: 0x%x\n", BootRecord->PartitionTable[Index].StartCylinder));
DbgPrint((DPRINT_DISK, "SystemIndicator: 0x%x\n", BootRecord->PartitionTable[Index].SystemIndicator));
DbgPrint((DPRINT_DISK, "EndHead: 0x%x\n", BootRecord->PartitionTable[Index].EndHead));
DbgPrint((DPRINT_DISK, "EndSector (Plus 2 cylinder bits): 0x%x\n", BootRecord->PartitionTable[Index].EndSector));
DbgPrint((DPRINT_DISK, "EndCylinder: 0x%x\n", BootRecord->PartitionTable[Index].EndCylinder));
DbgPrint((DPRINT_DISK, "SectorCountBeforePartition: 0x%x\n", BootRecord->PartitionTable[Index].SectorCountBeforePartition));
DbgPrint((DPRINT_DISK, "PartitionSectorCount: 0x%x\n", BootRecord->PartitionTable[Index].PartitionSectorCount));
}
#endif // defined DEBUG
// Check the partition table magic value
if (BootRecord->MasterBootRecordMagic != 0xaa55)
{
sprintf(ErrMsg, "Invalid partition table magic 0x%x found on drive 0x%x",
BootRecord->MasterBootRecordMagic, DriveNumber);
DiskError(ErrMsg, 0);
return FALSE;
}
return TRUE;
}

227
freeldr/freeldr/drivemap.c Normal file
View File

@@ -0,0 +1,227 @@
/*
* FreeLoader
* Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>
*
* 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.
*/
#include <freeldr.h>
#include <drivemap.h>
#include <rtl.h>
#include <inifile.h>
#include <cache.h>
#include <ui.h>
#include <debug.h>
BOOL DriveMapInstalled = FALSE; // Tells us if we have already installed our drive map int 13h handler code
U32 OldInt13HandlerAddress = 0; // Address of BIOS int 13h handler
U32 DriveMapHandlerAddress = 0; // Linear address of our drive map handler
U32 DriveMapHandlerSegOff = 0; // Segment:offset style address of our drive map handler
VOID DriveMapMapDrivesInSection(PUCHAR SectionName)
{
UCHAR SettingName[80];
UCHAR SettingValue[80];
UCHAR ErrorText[260];
UCHAR Drive1[80];
UCHAR Drive2[80];
U32 SectionId;
U32 SectionItemCount;
U32 Index;
U32 Index2;
DRIVE_MAP_LIST DriveMapList;
RtlZeroMemory(&DriveMapList, sizeof(DRIVE_MAP_LIST));
if (!IniOpenSection(SectionName, &SectionId))
{
return;
}
// Get the number of items in this section
SectionItemCount = IniGetNumSectionItems(SectionId);
// Loop through each one and check if its a DriveMap= setting
for (Index=0; Index<SectionItemCount; Index++)
{
// Get the next setting from the .ini file section
if (IniReadSettingByNumber(SectionId, Index, SettingName, 80, SettingValue, 80))
{
if (stricmp(SettingName, "DriveMap") == 0)
{
// Make sure we haven't exceeded the drive map max count
if (DriveMapList.DriveMapCount >= 4)
{
sprintf(ErrorText, "Max DriveMap count exceeded in section [%s]:\n\n%s=%s", SectionName, SettingName, SettingValue);
UiMessageBox(ErrorText);
continue;
}
RtlZeroMemory(Drive1, 80);
RtlZeroMemory(Drive2, 80);
strcpy(Drive1, SettingValue);
// Parse the setting value and separate a string "hd0,hd1"
// into two strings "hd0" and "hd1"
for (Index2=0; Index2<strlen(Drive1); Index2++)
{
// Check if this character is the separater character (comma - ',')
if (Drive1[Index2] == ',')
{
Drive1[Index2] = '\0';
strcpy(Drive2, &Drive1[Index2+1]);
break;
}
}
// Make sure we got good values before we add them to the map
if (!DriveMapIsValidDriveString(Drive1) || !DriveMapIsValidDriveString(Drive2))
{
sprintf(ErrorText, "Error in DriveMap setting in section [%s]:\n\n%s=%s", SectionName, SettingName, SettingValue);
UiMessageBox(ErrorText);
continue;
}
// Add them to the map
DriveMapList.DriveMap[(DriveMapList.DriveMapCount * 2)] = DriveMapGetBiosDriveNumber(Drive1);
DriveMapList.DriveMap[(DriveMapList.DriveMapCount * 2)+1] = DriveMapGetBiosDriveNumber(Drive2);
DriveMapList.DriveMapCount++;
DbgPrint((DPRINT_WARNING, "Mapping BIOS drive 0x%x to drive 0x%x\n", DriveMapGetBiosDriveNumber(Drive1), DriveMapGetBiosDriveNumber(Drive2)));
}
}
}
if (DriveMapList.DriveMapCount)
{
DbgPrint((DPRINT_WARNING, "Installing Int13 drive map for %d drives.\n", DriveMapList.DriveMapCount));
DriveMapInstallInt13Handler(&DriveMapList);
}
else
{
DbgPrint((DPRINT_WARNING, "Removing any previously installed Int13 drive map.\n"));
DriveMapRemoveInt13Handler();
}
}
BOOL DriveMapIsValidDriveString(PUCHAR DriveString)
{
U32 Index;
// Now verify that the user has given us appropriate strings
if ((strlen(DriveString) < 3) ||
((DriveString[0] != 'f') && (DriveString[0] != 'F') && (DriveString[0] != 'h') && (DriveString[0] != 'H')) ||
((DriveString[1] != 'd') && (DriveString[1] != 'D')))
{
return FALSE;
}
// Now verify that the user has given us appropriate numbers
// Make sure that only numeric characters were given
for (Index=2; Index<strlen(DriveString); Index++)
{
if (DriveString[Index] < '0' || DriveString[Index] > '9')
{
return FALSE;
}
}
// Now make sure that they are not outrageous values (i.e. hd90874)
if ((atoi(&DriveString[2]) < 0) || (atoi(&DriveString[2]) > 0xff))
{
return FALSE;
}
return TRUE;
}
U32 DriveMapGetBiosDriveNumber(PUCHAR DeviceName)
{
U32 BiosDriveNumber = 0;
// If they passed in a number string then just
// convert it to decimal and return it
if (DeviceName[0] >= '0' && DeviceName[0] <= '9')
{
return atoi(DeviceName);
}
// Convert the drive number string into a number
// 'hd1' = 1
BiosDriveNumber = atoi(&DeviceName[2]);
// If it's a hard disk then set the high bit
if ((DeviceName[0] == 'h' || DeviceName[0] == 'H') &&
(DeviceName[1] == 'd' || DeviceName[1] == 'D'))
{
BiosDriveNumber |= 0x80;
}
return BiosDriveNumber;
}
VOID DriveMapInstallInt13Handler(PDRIVE_MAP_LIST DriveMap)
{
U32* RealModeIVT = (U32*)0x00000000;
U16* BiosLowMemorySize = (U16*)0x00000413;
if (!DriveMapInstalled)
{
// Get the old INT 13h handler address from the vector table
OldInt13HandlerAddress = RealModeIVT[0x13];
// Decrease the size of low memory
(*BiosLowMemorySize)--;
// Get linear address for drive map handler
DriveMapHandlerAddress = (U32)(*BiosLowMemorySize) << 10;
// Convert to segment:offset style address
DriveMapHandlerSegOff = (DriveMapHandlerAddress << 12) & 0xffff0000;
}
// Copy the drive map structure to the proper place
RtlCopyMemory(&DriveMapInt13HandlerMapList, DriveMap, sizeof(DRIVE_MAP_LIST));
// Set the address of the BIOS INT 13h handler
DriveMapOldInt13HandlerAddress = OldInt13HandlerAddress;
// Copy the code to our reserved area
RtlCopyMemory((PVOID)DriveMapHandlerAddress, &DriveMapInt13HandlerStart, ((U32)&DriveMapInt13HandlerEnd - (U32)&DriveMapInt13HandlerStart));
// Update the IVT
RealModeIVT[0x13] = DriveMapHandlerSegOff;
CacheInvalidateCacheData();
DriveMapInstalled = TRUE;
}
VOID DriveMapRemoveInt13Handler(VOID)
{
U32* RealModeIVT = (U32*)0x00000000;
U16* BiosLowMemorySize = (U16*)0x00000413;
if (DriveMapInstalled)
{
// Get the old INT 13h handler address from the vector table
RealModeIVT[0x13] = OldInt13HandlerAddress;
// Increase the size of low memory
(*BiosLowMemorySize)++;
CacheInvalidateCacheData();
DriveMapInstalled = FALSE;
}
}

48
freeldr/freeldr/freeldr.c Normal file
View File

@@ -0,0 +1,48 @@
/*
* FreeLoader
* Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>
*
* 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.
*/
#include <freeldr.h>
#include <rtl.h>
#include <arch.h>
#include <machine.h>
#include <mm.h>
#include <debug.h>
#include <bootmgr.h>
#include <fs.h>
#include <cmdline.h>
VOID BootMain(char *CmdLine)
{
CmdLineParse(CmdLine);
MachInit();
DebugInit();
DbgPrint((DPRINT_WARNING, "BootMain() called. BootDrive = 0x%x BootPartition = %d\n", BootDrive, BootPartition));
if (!MmInitializeMemoryManager())
{
printf("Press any key to reboot.\n");
MachConsGetCh();
return;
}
RunLoader();
}

1179
freeldr/freeldr/fs/ext2.c Normal file

File diff suppressed because it is too large Load Diff

697
freeldr/freeldr/fs/ext2.h Normal file
View File

@@ -0,0 +1,697 @@
/*
* FreeLoader
* Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>
*
* 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.
*/
#ifndef __EXT2_H
#define __EXT2_H
/*
* linux/include/linux/ext3_fs.h
*
* Copyright (C) 1992, 1993, 1994, 1995
* Remy Card (card@masi.ibp.fr)
* Laboratoire MASI - Institut Blaise Pascal
* Universite Pierre et Marie Curie (Paris VI)
*
* from
*
* linux/include/linux/minix_fs.h
*
* Copyright (C) 1991, 1992 Linus Torvalds
*/
#ifndef _LINUX_EXT3_FS_H
#define _LINUX_EXT3_FS_H
//#include <linux/types.h>
/*
* The second extended filesystem constants/structures
*/
/*
* Define EXT3FS_DEBUG to produce debug messages
*/
#undef EXT3FS_DEBUG
/*
* Define EXT3_PREALLOCATE to preallocate data blocks for expanding files
*/
#undef EXT3_PREALLOCATE /* @@@ Fix this! */
#define EXT3_DEFAULT_PREALLOC_BLOCKS 8
/*
* The second extended file system version
*/
#define EXT3FS_DATE "10 Jan 2002"
#define EXT3FS_VERSION "2.4-0.9.17"
/*
* Debug code
*/
#ifdef EXT3FS_DEBUG
#define ext3_debug(f, a...) \
do { \
printk (KERN_DEBUG "EXT3-fs DEBUG (%s, %d): %s:", \
__FILE__, __LINE__, __FUNCTION__); \
printk (KERN_DEBUG f, ## a); \
} while (0)
#else
#define ext3_debug(f, a...) do {} while (0)
#endif
/*
* Special inodes numbers
*/
#define EXT3_BAD_INO 1 /* Bad blocks inode */
#define EXT3_ROOT_INO 2 /* Root inode */
#define EXT3_ACL_IDX_INO 3 /* ACL inode */
#define EXT3_ACL_DATA_INO 4 /* ACL inode */
#define EXT3_BOOT_LOADER_INO 5 /* Boot loader inode */
#define EXT3_UNDEL_DIR_INO 6 /* Undelete directory inode */
#define EXT3_RESIZE_INO 7 /* Reserved group descriptors inode */
#define EXT3_JOURNAL_INO 8 /* Journal inode */
/* First non-reserved inode for old ext3 filesystems */
#define EXT3_GOOD_OLD_FIRST_INO 11
/*
* The second extended file system magic number
*/
#define EXT3_SUPER_MAGIC 0xEF53
/*
* Maximal count of links to a file
*/
#define EXT3_LINK_MAX 32000
/*
* Macro-instructions used to manage several block sizes
*/
#define EXT3_MIN_BLOCK_SIZE 1024
#define EXT3_MAX_BLOCK_SIZE 4096
#define EXT3_MIN_BLOCK_LOG_SIZE 10
#ifdef __KERNEL__
# define EXT3_BLOCK_SIZE(s) ((s)->s_blocksize)
#else
# define EXT3_BLOCK_SIZE(s) (EXT3_MIN_BLOCK_SIZE << (s)->s_log_block_size)
#endif
#define EXT3_ACLE_PER_BLOCK(s) (EXT3_BLOCK_SIZE(s) / sizeof (struct ext3_acl_entry))
#define EXT3_ADDR_PER_BLOCK(s) (EXT3_BLOCK_SIZE(s) / sizeof (__u32))
#ifdef __KERNEL__
# define EXT3_BLOCK_SIZE_BITS(s) ((s)->s_blocksize_bits)
#else
# define EXT3_BLOCK_SIZE_BITS(s) ((s)->s_log_block_size + 10)
#endif
#ifdef __KERNEL__
#define EXT3_ADDR_PER_BLOCK_BITS(s) ((s)->u.ext3_sb.s_addr_per_block_bits)
#define EXT3_INODE_SIZE(s) ((s)->u.ext3_sb.s_inode_size)
#define EXT3_FIRST_INO(s) ((s)->u.ext3_sb.s_first_ino)
#else
#define EXT3_INODE_SIZE(s) (((s)->s_rev_level == EXT3_GOOD_OLD_REV) ? \
EXT3_GOOD_OLD_INODE_SIZE : \
(s)->s_inode_size)
#define EXT3_FIRST_INO(s) (((s)->s_rev_level == EXT3_GOOD_OLD_REV) ? \
EXT3_GOOD_OLD_FIRST_INO : \
(s)->s_first_ino)
#endif
/*
* Macro-instructions used to manage fragments
*/
#define EXT3_MIN_FRAG_SIZE 1024
#define EXT3_MAX_FRAG_SIZE 4096
#define EXT3_MIN_FRAG_LOG_SIZE 10
#ifdef __KERNEL__
# define EXT3_FRAG_SIZE(s) ((s)->u.ext3_sb.s_frag_size)
# define EXT3_FRAGS_PER_BLOCK(s) ((s)->u.ext3_sb.s_frags_per_block)
#else
# define EXT3_FRAG_SIZE(s) (EXT3_MIN_FRAG_SIZE << (s)->s_log_frag_size)
# define EXT3_FRAGS_PER_BLOCK(s) (EXT3_BLOCK_SIZE(s) / EXT3_FRAG_SIZE(s))
#endif
/*
* ACL structures
*/
struct ext3_acl_header /* Header of Access Control Lists */
{
__u32 aclh_size;
__u32 aclh_file_count;
__u32 aclh_acle_count;
__u32 aclh_first_acle;
};
struct ext3_acl_entry /* Access Control List Entry */
{
__u32 acle_size;
__u16 acle_perms; /* Access permissions */
__u16 acle_type; /* Type of entry */
__u16 acle_tag; /* User or group identity */
__u16 acle_pad1;
__u32 acle_next; /* Pointer on next entry for the */
/* same inode or on next free entry */
};
/*
* Structure of a blocks group descriptor
*/
struct ext3_group_desc
{
__u32 bg_block_bitmap; /* Blocks bitmap block */
__u32 bg_inode_bitmap; /* Inodes bitmap block */
__u32 bg_inode_table; /* Inodes table block */
__u16 bg_free_blocks_count; /* Free blocks count */
__u16 bg_free_inodes_count; /* Free inodes count */
__u16 bg_used_dirs_count; /* Directories count */
__u16 bg_pad;
__u32 bg_reserved[3];
};
/*
* Macro-instructions used to manage group descriptors
*/
#ifdef __KERNEL__
# define EXT3_BLOCKS_PER_GROUP(s) ((s)->u.ext3_sb.s_blocks_per_group)
# define EXT3_DESC_PER_BLOCK(s) ((s)->u.ext3_sb.s_desc_per_block)
# define EXT3_INODES_PER_GROUP(s) ((s)->u.ext3_sb.s_inodes_per_group)
# define EXT3_DESC_PER_BLOCK_BITS(s) ((s)->u.ext3_sb.s_desc_per_block_bits)
#else
# define EXT3_BLOCKS_PER_GROUP(s) ((s)->s_blocks_per_group)
# define EXT3_DESC_PER_BLOCK(s) (EXT3_BLOCK_SIZE(s) / sizeof (struct ext3_group_desc))
# define EXT3_INODES_PER_GROUP(s) ((s)->s_inodes_per_group)
#endif
/*
* Constants relative to the data blocks
*/
#define EXT3_NDIR_BLOCKS 12
#define EXT3_IND_BLOCK EXT3_NDIR_BLOCKS
#define EXT3_DIND_BLOCK (EXT3_IND_BLOCK + 1)
#define EXT3_TIND_BLOCK (EXT3_DIND_BLOCK + 1)
#define EXT3_N_BLOCKS (EXT3_TIND_BLOCK + 1)
/*
* Inode flags
*/
#define EXT3_SECRM_FL 0x00000001 /* Secure deletion */
#define EXT3_UNRM_FL 0x00000002 /* Undelete */
#define EXT3_COMPR_FL 0x00000004 /* Compress file */
#define EXT3_SYNC_FL 0x00000008 /* Synchronous updates */
#define EXT3_IMMUTABLE_FL 0x00000010 /* Immutable file */
#define EXT3_APPEND_FL 0x00000020 /* writes to file may only append */
#define EXT3_NODUMP_FL 0x00000040 /* do not dump file */
#define EXT3_NOATIME_FL 0x00000080 /* do not update atime */
/* Reserved for compression usage... */
#define EXT3_DIRTY_FL 0x00000100
#define EXT3_COMPRBLK_FL 0x00000200 /* One or more compressed clusters */
#define EXT3_NOCOMPR_FL 0x00000400 /* Don't compress */
#define EXT3_ECOMPR_FL 0x00000800 /* Compression error */
/* End compression flags --- maybe not all used */
#define EXT3_INDEX_FL 0x00001000 /* hash-indexed directory */
#define EXT3_IMAGIC_FL 0x00002000 /* AFS directory */
#define EXT3_JOURNAL_DATA_FL 0x00004000 /* file data should be journaled */
#define EXT3_RESERVED_FL 0x80000000 /* reserved for ext3 lib */
#define EXT3_FL_USER_VISIBLE 0x00005FFF /* User visible flags */
#define EXT3_FL_USER_MODIFIABLE 0x000000FF /* User modifiable flags */
/*
* Inode dynamic state flags
*/
#define EXT3_STATE_JDATA 0x00000001 /* journaled data exists */
#define EXT3_STATE_NEW 0x00000002 /* inode is newly created */
/*
* ioctl commands
*/
#define EXT3_IOC_GETFLAGS _IOR('f', 1, long)
#define EXT3_IOC_SETFLAGS _IOW('f', 2, long)
#define EXT3_IOC_GETVERSION _IOR('f', 3, long)
#define EXT3_IOC_SETVERSION _IOW('f', 4, long)
#define EXT3_IOC_GETVERSION_OLD _IOR('v', 1, long)
#define EXT3_IOC_SETVERSION_OLD _IOW('v', 2, long)
#ifdef CONFIG_JBD_DEBUG
#define EXT3_IOC_WAIT_FOR_READONLY _IOR('f', 99, long)
#endif
/*
* Structure of an inode on the disk
*/
struct ext3_inode {
__u16 i_mode; /* File mode */
__u16 i_uid; /* Low 16 bits of Owner Uid */
__u32 i_size; /* Size in bytes */
__u32 i_atime; /* Access time */
__u32 i_ctime; /* Creation time */
__u32 i_mtime; /* Modification time */
__u32 i_dtime; /* Deletion Time */
__u16 i_gid; /* Low 16 bits of Group Id */
__u16 i_links_count; /* Links count */
__u32 i_blocks; /* Blocks count */
__u32 i_flags; /* File flags */
union {
struct {
__u32 l_i_reserved1;
} linux1;
struct {
__u32 h_i_translator;
} hurd1;
struct {
__u32 m_i_reserved1;
} masix1;
} osd1; /* OS dependent 1 */
__u32 i_block[EXT3_N_BLOCKS];/* Pointers to blocks */
__u32 i_generation; /* File version (for NFS) */
__u32 i_file_acl; /* File ACL */
__u32 i_dir_acl; /* Directory ACL */
__u32 i_faddr; /* Fragment address */
union {
struct {
__u8 l_i_frag; /* Fragment number */
__u8 l_i_fsize; /* Fragment size */
__u16 i_pad1;
__u16 l_i_uid_high; /* these 2 fields */
__u16 l_i_gid_high; /* were reserved2[0] */
__u32 l_i_reserved2;
} linux2;
struct {
__u8 h_i_frag; /* Fragment number */
__u8 h_i_fsize; /* Fragment size */
__u16 h_i_mode_high;
__u16 h_i_uid_high;
__u16 h_i_gid_high;
__u32 h_i_author;
} hurd2;
struct {
__u8 m_i_frag; /* Fragment number */
__u8 m_i_fsize; /* Fragment size */
__u16 m_pad1;
__u32 m_i_reserved2[2];
} masix2;
} osd2; /* OS dependent 2 */
};
#define i_size_high i_dir_acl
#if defined(__KERNEL__) || defined(__linux__)
#define i_reserved1 osd1.linux1.l_i_reserved1
#define i_frag osd2.linux2.l_i_frag
#define i_fsize osd2.linux2.l_i_fsize
#define i_uid_low i_uid
#define i_gid_low i_gid
#define i_uid_high osd2.linux2.l_i_uid_high
#define i_gid_high osd2.linux2.l_i_gid_high
#define i_reserved2 osd2.linux2.l_i_reserved2
#elif defined(__GNU__)
#define i_translator osd1.hurd1.h_i_translator
#define i_frag osd2.hurd2.h_i_frag;
#define i_fsize osd2.hurd2.h_i_fsize;
#define i_uid_high osd2.hurd2.h_i_uid_high
#define i_gid_high osd2.hurd2.h_i_gid_high
#define i_author osd2.hurd2.h_i_author
#elif defined(__masix__)
#define i_reserved1 osd1.masix1.m_i_reserved1
#define i_frag osd2.masix2.m_i_frag
#define i_fsize osd2.masix2.m_i_fsize
#define i_reserved2 osd2.masix2.m_i_reserved2
#endif /* defined(__KERNEL__) || defined(__linux__) */
/*
* File system states
*/
#define EXT3_VALID_FS 0x0001 /* Unmounted cleanly */
#define EXT3_ERROR_FS 0x0002 /* Errors detected */
#define EXT3_ORPHAN_FS 0x0004 /* Orphans being recovered */
/*
* Mount flags
*/
#define EXT3_MOUNT_CHECK 0x0001 /* Do mount-time checks */
#define EXT3_MOUNT_GRPID 0x0004 /* Create files with directory's group */
#define EXT3_MOUNT_DEBUG 0x0008 /* Some debugging messages */
#define EXT3_MOUNT_ERRORS_CONT 0x0010 /* Continue on errors */
#define EXT3_MOUNT_ERRORS_RO 0x0020 /* Remount fs ro on errors */
#define EXT3_MOUNT_ERRORS_PANIC 0x0040 /* Panic on errors */
#define EXT3_MOUNT_MINIX_DF 0x0080 /* Mimics the Minix statfs */
#define EXT3_MOUNT_NOLOAD 0x0100 /* Don't use existing journal*/
#define EXT3_MOUNT_ABORT 0x0200 /* Fatal error detected */
#define EXT3_MOUNT_DATA_FLAGS 0x0C00 /* Mode for data writes: */
#define EXT3_MOUNT_JOURNAL_DATA 0x0400 /* Write data to journal */
#define EXT3_MOUNT_ORDERED_DATA 0x0800 /* Flush data before commit */
#define EXT3_MOUNT_WRITEBACK_DATA 0x0C00 /* No data ordering */
#define EXT3_MOUNT_UPDATE_JOURNAL 0x1000 /* Update the journal format */
#define EXT3_MOUNT_NO_UID32 0x2000 /* Disable 32-bit UIDs */
/* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */
#ifndef _LINUX_EXT2_FS_H
#define clear_opt(o, opt) o &= ~EXT3_MOUNT_##opt
#define set_opt(o, opt) o |= EXT3_MOUNT_##opt
#define test_opt(sb, opt) ((sb)->u.ext3_sb.s_mount_opt & \
EXT3_MOUNT_##opt)
#else
#define EXT2_MOUNT_NOLOAD EXT3_MOUNT_NOLOAD
#define EXT2_MOUNT_ABORT EXT3_MOUNT_ABORT
#endif
#define ext3_set_bit ext2_set_bit
#define ext3_clear_bit ext2_clear_bit
#define ext3_test_bit ext2_test_bit
#define ext3_find_first_zero_bit ext2_find_first_zero_bit
#define ext3_find_next_zero_bit ext2_find_next_zero_bit
/*
* Maximal mount counts between two filesystem checks
*/
#define EXT3_DFL_MAX_MNT_COUNT 20 /* Allow 20 mounts */
#define EXT3_DFL_CHECKINTERVAL 0 /* Don't use interval check */
/*
* Behaviour when detecting errors
*/
#define EXT3_ERRORS_CONTINUE 1 /* Continue execution */
#define EXT3_ERRORS_RO 2 /* Remount fs read-only */
#define EXT3_ERRORS_PANIC 3 /* Panic */
#define EXT3_ERRORS_DEFAULT EXT3_ERRORS_CONTINUE
/*
* Structure of the super block
*/
struct ext3_super_block {
/*00*/ __u32 s_inodes_count; /* Inodes count */
__u32 s_blocks_count; /* Blocks count */
__u32 s_r_blocks_count; /* Reserved blocks count */
__u32 s_free_blocks_count; /* Free blocks count */
/*10*/ __u32 s_free_inodes_count; /* Free inodes count */
__u32 s_first_data_block; /* First Data Block */
__u32 s_log_block_size; /* Block size */
__s32 s_log_frag_size; /* Fragment size */
/*20*/ __u32 s_blocks_per_group; /* # Blocks per group */
__u32 s_frags_per_group; /* # Fragments per group */
__u32 s_inodes_per_group; /* # Inodes per group */
__u32 s_mtime; /* Mount time */
/*30*/ __u32 s_wtime; /* Write time */
__u16 s_mnt_count; /* Mount count */
__s16 s_max_mnt_count; /* Maximal mount count */
__u16 s_magic; /* Magic signature */
__u16 s_state; /* File system state */
__u16 s_errors; /* Behaviour when detecting errors */
__u16 s_minor_rev_level; /* minor revision level */
/*40*/ __u32 s_lastcheck; /* time of last check */
__u32 s_checkinterval; /* max. time between checks */
__u32 s_creator_os; /* OS */
__u32 s_rev_level; /* Revision level */
/*50*/ __u16 s_def_resuid; /* Default uid for reserved blocks */
__u16 s_def_resgid; /* Default gid for reserved blocks */
/*
* These fields are for EXT3_DYNAMIC_REV superblocks only.
*
* Note: the difference between the compatible feature set and
* the incompatible feature set is that if there is a bit set
* in the incompatible feature set that the kernel doesn't
* know about, it should refuse to mount the filesystem.
*
* e2fsck's requirements are more strict; if it doesn't know
* about a feature in either the compatible or incompatible
* feature set, it must abort and not try to meddle with
* things it doesn't understand...
*/
__u32 s_first_ino; /* First non-reserved inode */
__u16 s_inode_size; /* size of inode structure */
__u16 s_block_group_nr; /* block group # of this superblock */
__u32 s_feature_compat; /* compatible feature set */
/*60*/ __u32 s_feature_incompat; /* incompatible feature set */
__u32 s_feature_ro_compat; /* readonly-compatible feature set */
/*68*/ __u8 s_uuid[16]; /* 128-bit uuid for volume */
/*78*/ char s_volume_name[16]; /* volume name */
/*88*/ char s_last_mounted[64]; /* directory where last mounted */
/*C8*/ __u32 s_algorithm_usage_bitmap; /* For compression */
/*
* Performance hints. Directory preallocation should only
* happen if the EXT3_FEATURE_COMPAT_DIR_PREALLOC flag is on.
*/
__u8 s_prealloc_blocks; /* Nr of blocks to try to preallocate*/
__u8 s_prealloc_dir_blocks; /* Nr to preallocate for dirs */
__u16 s_padding1;
/*
* Journaling support valid if EXT3_FEATURE_COMPAT_HAS_JOURNAL set.
*/
/*D0*/ __u8 s_journal_uuid[16]; /* uuid of journal superblock */
/*E0*/ __u32 s_journal_inum; /* inode number of journal file */
__u32 s_journal_dev; /* device number of journal file */
__u32 s_last_orphan; /* start of list of inodes to delete */
/*EC*/ __u32 s_reserved[197]; /* Padding to the end of the block */
};
#ifdef __KERNEL__
#define EXT3_SB(sb) (&((sb)->u.ext3_sb))
#define EXT3_I(inode) (&((inode)->u.ext3_i))
#else
/* Assume that user mode programs are passing in an ext3fs superblock, not
* a kernel struct super_block. This will allow us to call the feature-test
* macros from user land. */
#define EXT3_SB(sb) (sb)
#endif
#define NEXT_ORPHAN(inode) (inode)->u.ext3_i.i_dtime
/*
* Codes for operating systems
*/
#define EXT3_OS_LINUX 0
#define EXT3_OS_HURD 1
#define EXT3_OS_MASIX 2
#define EXT3_OS_FREEBSD 3
#define EXT3_OS_LITES 4
/*
* Revision levels
*/
#define EXT3_GOOD_OLD_REV 0 /* The good old (original) format */
#define EXT3_DYNAMIC_REV 1 /* V2 format w/ dynamic inode sizes */
#define EXT3_CURRENT_REV EXT3_GOOD_OLD_REV
#define EXT3_MAX_SUPP_REV EXT3_DYNAMIC_REV
#define EXT3_GOOD_OLD_INODE_SIZE 128
/*
* Feature set definitions
*/
#define EXT3_HAS_COMPAT_FEATURE(sb,mask) \
( EXT3_SB(sb)->s_es->s_feature_compat & cpu_to_le32(mask) )
#define EXT3_HAS_RO_COMPAT_FEATURE(sb,mask) \
( EXT3_SB(sb)->s_es->s_feature_ro_compat & cpu_to_le32(mask) )
#define EXT3_HAS_INCOMPAT_FEATURE(sb,mask) \
( EXT3_SB(sb)->s_es->s_feature_incompat & cpu_to_le32(mask) )
#define EXT3_SET_COMPAT_FEATURE(sb,mask) \
EXT3_SB(sb)->s_es->s_feature_compat |= cpu_to_le32(mask)
#define EXT3_SET_RO_COMPAT_FEATURE(sb,mask) \
EXT3_SB(sb)->s_es->s_feature_ro_compat |= cpu_to_le32(mask)
#define EXT3_SET_INCOMPAT_FEATURE(sb,mask) \
EXT3_SB(sb)->s_es->s_feature_incompat |= cpu_to_le32(mask)
#define EXT3_CLEAR_COMPAT_FEATURE(sb,mask) \
EXT3_SB(sb)->s_es->s_feature_compat &= ~cpu_to_le32(mask)
#define EXT3_CLEAR_RO_COMPAT_FEATURE(sb,mask) \
EXT3_SB(sb)->s_es->s_feature_ro_compat &= ~cpu_to_le32(mask)
#define EXT3_CLEAR_INCOMPAT_FEATURE(sb,mask) \
EXT3_SB(sb)->s_es->s_feature_incompat &= ~cpu_to_le32(mask)
#define EXT3_FEATURE_COMPAT_DIR_PREALLOC 0x0001
#define EXT3_FEATURE_COMPAT_IMAGIC_INODES 0x0002
#define EXT3_FEATURE_COMPAT_HAS_JOURNAL 0x0004
#define EXT3_FEATURE_COMPAT_EXT_ATTR 0x0008
#define EXT3_FEATURE_COMPAT_RESIZE_INODE 0x0010
#define EXT3_FEATURE_COMPAT_DIR_INDEX 0x0020
#define EXT3_FEATURE_RO_COMPAT_SPARSE_SUPER 0x0001
#define EXT3_FEATURE_RO_COMPAT_LARGE_FILE 0x0002
#define EXT3_FEATURE_RO_COMPAT_BTREE_DIR 0x0004
#define EXT3_FEATURE_INCOMPAT_COMPRESSION 0x0001
#define EXT3_FEATURE_INCOMPAT_FILETYPE 0x0002
#define EXT3_FEATURE_INCOMPAT_RECOVER 0x0004 /* Needs recovery */
#define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV 0x0008 /* Journal device */
#define EXT3_FEATURE_COMPAT_SUPP 0
/*#define EXT3_FEATURE_INCOMPAT_SUPP (EXT3_FEATURE_INCOMPAT_FILETYPE| \
EXT3_FEATURE_INCOMPAT_RECOVER)*/
#define EXT3_FEATURE_INCOMPAT_SUPP (EXT3_FEATURE_INCOMPAT_FILETYPE)
#define EXT3_FEATURE_RO_COMPAT_SUPP (EXT3_FEATURE_RO_COMPAT_SPARSE_SUPER| \
EXT3_FEATURE_RO_COMPAT_LARGE_FILE| \
EXT3_FEATURE_RO_COMPAT_BTREE_DIR)
/*
* Default values for user and/or group using reserved blocks
*/
#define EXT3_DEF_RESUID 0
#define EXT3_DEF_RESGID 0
/*
* Structure of a directory entry
*/
#define EXT3_NAME_LEN 255
struct ext3_dir_entry {
__u32 inode; /* Inode number */
__u16 rec_len; /* Directory entry length */
__u16 name_len; /* Name length */
char name[EXT3_NAME_LEN]; /* File name */
};
/*
* The new version of the directory entry. Since EXT3 structures are
* stored in intel byte order, and the name_len field could never be
* bigger than 255 chars, it's safe to reclaim the extra byte for the
* file_type field.
*/
struct ext3_dir_entry_2 {
__u32 inode; /* Inode number */
__u16 rec_len; /* Directory entry length */
__u8 name_len; /* Name length */
__u8 file_type;
char name[EXT3_NAME_LEN]; /* File name */
};
/*
* Ext3 directory file types. Only the low 3 bits are used. The
* other bits are reserved for now.
*/
#define EXT3_FT_UNKNOWN 0
#define EXT3_FT_REG_FILE 1
#define EXT3_FT_DIR 2
#define EXT3_FT_CHRDEV 3
#define EXT3_FT_BLKDEV 4
#define EXT3_FT_FIFO 5
#define EXT3_FT_SOCK 6
#define EXT3_FT_SYMLINK 7
#define EXT3_FT_MAX 8
/*
* EXT3_DIR_PAD defines the directory entries boundaries
*
* NOTE: It must be a multiple of 4
*/
#define EXT3_DIR_PAD 4
#define EXT3_DIR_ROUND (EXT3_DIR_PAD - 1)
#define EXT3_DIR_REC_LEN(name_len) (((name_len) + 8 + EXT3_DIR_ROUND) & \
~EXT3_DIR_ROUND)
#ifdef __KERNEL__
/*
* Describe an inode's exact location on disk and in memory
*/
struct ext3_iloc
{
struct buffer_head *bh;
struct ext3_inode *raw_inode;
unsigned long block_group;
};
#endif /* __KERNEL__ */
#endif /* _LINUX_EXT3_FS_H */
typedef struct ext3_super_block EXT2_SUPER_BLOCK, *PEXT2_SUPER_BLOCK;
typedef struct ext3_inode EXT2_INODE, *PEXT2_INODE;
typedef struct ext3_group_desc EXT2_GROUP_DESC, *PEXT2_GROUP_DESC;
typedef struct ext3_dir_entry_2 EXT2_DIR_ENTRY, *PEXT2_DIR_ENTRY;
// EXT2_INODE::i_mode values
#define EXT2_S_IRWXO 0x0007 // Other mask
#define EXT2_S_IXOTH 0x0001 // ---------x execute
#define EXT2_S_IWOTH 0x0002 // --------w- write
#define EXT2_S_IROTH 0x0004 // -------r-- read
#define EXT2_S_IRWXG 0x0038 // Group mask
#define EXT2_S_IXGRP 0x0008 // ------x--- execute
#define EXT2_S_IWGRP 0x0010 // -----w---- write
#define EXT2_S_IRGRP 0x0020 // ----r----- read
#define EXT2_S_IRWXU 0x01C0 // User mask
#define EXT2_S_IXUSR 0x0040 // ---x------ execute
#define EXT2_S_IWUSR 0x0080 // --w------- write
#define EXT2_S_IRUSR 0x0100 // -r-------- read
#define EXT2_S_ISVTX 0x0200 // Sticky bit
#define EXT2_S_ISGID 0x0400 // SGID
#define EXT2_S_ISUID 0x0800 // SUID
#define EXT2_S_IFMT 0xF000 // Format mask
#define EXT2_S_IFIFO 0x1000 // FIFO buffer
#define EXT2_S_IFCHR 0x2000 // Character device
#define EXT2_S_IFDIR 0x4000 // Directory
#define EXT2_S_IFBLK 0x6000 // Block device
#define EXT2_S_IFREG 0x8000 // Regular file
#define EXT2_S_IFLNK 0xA000 // Symbolic link
#define EXT2_S_IFSOCK 0xC000 // Socket
#define FAST_SYMLINK_MAX_NAME_SIZE (EXT3_N_BLOCKS * sizeof(U32)) /* 60 bytes */
typedef struct
{
U64 FileSize; // File size
U64 FilePointer; // File pointer
U32* FileBlockList; // File block list
U8 DriveNumber; // Drive number of open file
EXT2_INODE Inode; // File's inode
} EXT2_FILE_INFO, * PEXT2_FILE_INFO;
BOOL Ext2OpenVolume(U8 DriveNumber, U64 VolumeStartSector);
FILE* Ext2OpenFile(PUCHAR FileName);
BOOL Ext2LookupFile(PUCHAR FileName, PEXT2_FILE_INFO Ext2FileInfoPointer);
BOOL Ext2SearchDirectoryBufferForFile(PVOID DirectoryBuffer, U32 DirectorySize, PUCHAR FileName, PEXT2_DIR_ENTRY DirectoryEntry);
BOOL Ext2ReadFile(FILE *FileHandle, U64 BytesToRead, U64* BytesRead, PVOID Buffer);
U64 Ext2GetFileSize(FILE *FileHandle);
VOID Ext2SetFilePointer(FILE *FileHandle, U64 NewFilePointer);
U64 Ext2GetFilePointer(FILE *FileHandle);
BOOL Ext2ReadVolumeSectors(U8 DriveNumber, U64 SectorNumber, U64 SectorCount, PVOID Buffer);
BOOL Ext2ReadSuperBlock(VOID);
BOOL Ext2ReadGroupDescriptors(VOID);
BOOL Ext2ReadDirectory(U32 Inode, PVOID* DirectoryBuffer, PEXT2_INODE InodePointer);
BOOL Ext2ReadBlock(U32 BlockNumber, PVOID Buffer);
BOOL Ext2ReadPartialBlock(U32 BlockNumber, U32 StartingOffset, U32 Length, PVOID Buffer);
U32 Ext2GetGroupDescBlockNumber(U32 Group);
U32 Ext2GetGroupDescOffsetInBlock(U32 Group);
U32 Ext2GetInodeGroupNumber(U32 Inode);
U32 Ext2GetInodeBlockNumber(U32 Inode);
U32 Ext2GetInodeOffsetInBlock(U32 Inode);
BOOL Ext2ReadInode(U32 Inode, PEXT2_INODE InodeBuffer);
BOOL Ext2ReadGroupDescriptor(U32 Group, PEXT2_GROUP_DESC GroupBuffer);
U32* Ext2ReadBlockPointerList(PEXT2_INODE Inode);
U64 Ext2GetInodeFileSize(PEXT2_INODE Inode);
BOOL Ext2CopyIndirectBlockPointers(U32* BlockList, U32* CurrentBlockInList, U32 BlockCount, U32 IndirectBlock);
BOOL Ext2CopyDoubleIndirectBlockPointers(U32* BlockList, U32* CurrentBlockInList, U32 BlockCount, U32 DoubleIndirectBlock);
BOOL Ext2CopyTripleIndirectBlockPointers(U32* BlockList, U32* CurrentBlockInList, U32 BlockCount, U32 TripleIndirectBlock);
#endif // #defined __EXT2_H

1329
freeldr/freeldr/fs/fat.c Normal file

File diff suppressed because it is too large Load Diff

192
freeldr/freeldr/fs/fat.h Normal file
View File

@@ -0,0 +1,192 @@
/*
* FreeLoader
* Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>
*
* 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.
*/
#ifndef __FAT_H
#define __FAT_H
typedef struct _FAT_BOOTSECTOR
{
U8 JumpBoot[3]; // Jump instruction to boot code
U8 OemName[8]; // "MSWIN4.1" for MS formatted volumes
U16 BytesPerSector; // Bytes per sector
U8 SectorsPerCluster; // Number of sectors in a cluster
U16 ReservedSectors; // Reserved sectors, usually 1 (the bootsector)
U8 NumberOfFats; // Number of FAT tables
U16 RootDirEntries; // Number of root directory entries (fat12/16)
U16 TotalSectors; // Number of total sectors on the drive, 16-bit
U8 MediaDescriptor; // Media descriptor byte
U16 SectorsPerFat; // Sectors per FAT table (fat12/16)
U16 SectorsPerTrack; // Number of sectors in a track
U16 NumberOfHeads; // Number of heads on the disk
U32 HiddenSectors; // Hidden sectors (sectors before the partition start like the partition table)
U32 TotalSectorsBig; // This field is the new 32-bit total count of sectors on the volume
U8 DriveNumber; // Int 0x13 drive number (e.g. 0x80)
U8 Reserved1; // Reserved (used by Windows NT). Code that formats FAT volumes should always set this byte to 0.
U8 BootSignature; // Extended boot signature (0x29). This is a signature byte that indicates that the following three fields in the boot sector are present.
U32 VolumeSerialNumber; // Volume serial number
U8 VolumeLabel[11]; // Volume label. This field matches the 11-byte volume label recorded in the root directory
U8 FileSystemType[8]; // One of the strings "FAT12 ", "FAT16 ", or "FAT "
U8 BootCodeAndData[448]; // The remainder of the boot sector
U16 BootSectorMagic; // 0xAA55
} PACKED FAT_BOOTSECTOR, *PFAT_BOOTSECTOR;
typedef struct _FAT32_BOOTSECTOR
{
U8 JumpBoot[3]; // Jump instruction to boot code
U8 OemName[8]; // "MSWIN4.1" for MS formatted volumes
U16 BytesPerSector; // Bytes per sector
U8 SectorsPerCluster; // Number of sectors in a cluster
U16 ReservedSectors; // Reserved sectors, usually 1 (the bootsector)
U8 NumberOfFats; // Number of FAT tables
U16 RootDirEntries; // Number of root directory entries (fat12/16)
U16 TotalSectors; // Number of total sectors on the drive, 16-bit
U8 MediaDescriptor; // Media descriptor byte
U16 SectorsPerFat; // Sectors per FAT table (fat12/16)
U16 SectorsPerTrack; // Number of sectors in a track
U16 NumberOfHeads; // Number of heads on the disk
U32 HiddenSectors; // Hidden sectors (sectors before the partition start like the partition table)
U32 TotalSectorsBig; // This field is the new 32-bit total count of sectors on the volume
U32 SectorsPerFatBig; // This field is the FAT32 32-bit count of sectors occupied by ONE FAT. BPB_FATSz16 must be 0
U16 ExtendedFlags; // Extended flags (fat32)
U16 FileSystemVersion; // File system version (fat32)
U32 RootDirStartCluster; // Starting cluster of the root directory (fat32)
U16 FsInfo; // Sector number of FSINFO structure in the reserved area of the FAT32 volume. Usually 1.
U16 BackupBootSector; // If non-zero, indicates the sector number in the reserved area of the volume of a copy of the boot record. Usually 6.
U8 Reserved[12]; // Reserved for future expansion
U8 DriveNumber; // Int 0x13 drive number (e.g. 0x80)
U8 Reserved1; // Reserved (used by Windows NT). Code that formats FAT volumes should always set this byte to 0.
U8 BootSignature; // Extended boot signature (0x29). This is a signature byte that indicates that the following three fields in the boot sector are present.
U32 VolumeSerialNumber; // Volume serial number
U8 VolumeLabel[11]; // Volume label. This field matches the 11-byte volume label recorded in the root directory
U8 FileSystemType[8]; // Always set to the string "FAT32 "
U8 BootCodeAndData[420]; // The remainder of the boot sector
U16 BootSectorMagic; // 0xAA55
} PACKED FAT32_BOOTSECTOR, *PFAT32_BOOTSECTOR;
typedef struct _FATX_BOOTSECTOR
{
U8 FileSystemType[4]; /* String "FATX" */
U32 VolumeSerialNumber; /* Volume serial number */
U32 SectorsPerCluster; /* Number of sectors in a cluster */
U16 NumberOfFats; /* Number of FAT tables */
U32 Unknown; /* Always 0? */
U8 Unused[494]; /* Actually size should be 4078 (boot block is 4096 bytes) */
} PACKED FATX_BOOTSECTOR, *PFATX_BOOTSECTOR;
/*
* Structure of MSDOS directory entry
*/
typedef struct //_DIRENTRY
{
UCHAR FileName[11]; /* Filename + extension */
U8 Attr; /* File attributes */
U8 ReservedNT; /* Reserved for use by Windows NT */
U8 TimeInTenths; /* Millisecond stamp at file creation */
U16 CreateTime; /* Time file was created */
U16 CreateDate; /* Date file was created */
U16 LastAccessDate; /* Date file was last accessed */
U16 ClusterHigh; /* High word of this entry's start cluster */
U16 Time; /* Time last modified */
U16 Date; /* Date last modified */
U16 ClusterLow; /* First cluster number low word */
U32 Size; /* File size */
} PACKED DIRENTRY, * PDIRENTRY;
typedef struct
{
U8 SequenceNumber; /* Sequence number for slot */
WCHAR Name0_4[5]; /* First 5 characters in name */
U8 EntryAttributes; /* Attribute byte */
U8 Reserved; /* Always 0 */
U8 AliasChecksum; /* Checksum for 8.3 alias */
WCHAR Name5_10[6]; /* 6 more characters in name */
U16 StartCluster; /* Starting cluster number */
WCHAR Name11_12[2]; /* Last 2 characters in name */
} PACKED LFN_DIRENTRY, * PLFN_DIRENTRY;
typedef struct
{
U8 FileNameSize; /* Size of filename (max 42) */
U8 Attr; /* File attributes */
UCHAR FileName[42]; /* Filename in ASCII, padded with 0xff (not zero-terminated) */
U32 StartCluster; /* Starting cluster number */
U32 Size; /* File size */
U16 Time; /* Time last modified */
U16 Date; /* Date last modified */
U16 CreateTime; /* Time file was created */
U16 CreateDate; /* Date file was created */
U16 LastAccessTime; /* Time file was last accessed */
U16 LastAccessDate; /* Date file was last accessed */
} PACKED FATX_DIRENTRY, * PFATX_DIRENTRY;
typedef struct
{
U32 FileSize; /* File size */
U32 FilePointer; /* File pointer */
U32* FileFatChain; /* File fat chain array */
U32 DriveNumber;
} FAT_FILE_INFO, * PFAT_FILE_INFO;
BOOL FatOpenVolume(U32 DriveNumber, U32 VolumeStartSector, U32 PartitionSectorCount);
U32 FatDetermineFatType(PFAT_BOOTSECTOR FatBootSector, U32 PartitionSectorCount);
PVOID FatBufferDirectory(U32 DirectoryStartCluster, U32* EntryCountPointer, BOOL RootDirectory);
BOOL FatSearchDirectoryBufferForFile(PVOID DirectoryBuffer, U32 EntryCount, PUCHAR FileName, PFAT_FILE_INFO FatFileInfoPointer);
BOOL FatLookupFile(PUCHAR FileName, PFAT_FILE_INFO FatFileInfoPointer);
void FatParseShortFileName(PUCHAR Buffer, PDIRENTRY DirEntry);
BOOL FatGetFatEntry(U32 Cluster, U32* ClusterPointer);
FILE* FatOpenFile(PUCHAR FileName);
U32 FatCountClustersInChain(U32 StartCluster);
U32* FatGetClusterChainArray(U32 StartCluster);
BOOL FatReadCluster(U32 ClusterNumber, PVOID Buffer);
BOOL FatReadClusterChain(U32 StartClusterNumber, U32 NumberOfClusters, PVOID Buffer);
BOOL FatReadPartialCluster(U32 ClusterNumber, U32 StartingOffset, U32 Length, PVOID Buffer);
BOOL FatReadFile(FILE *FileHandle, U32 BytesToRead, U32* BytesRead, PVOID Buffer);
U32 FatGetFileSize(FILE *FileHandle);
VOID FatSetFilePointer(FILE *FileHandle, U32 NewFilePointer);
U32 FatGetFilePointer(FILE *FileHandle);
BOOL FatReadVolumeSectors(U32 DriveNumber, U32 SectorNumber, U32 SectorCount, PVOID Buffer);
#define ATTR_NORMAL 0x00
#define ATTR_READONLY 0x01
#define ATTR_HIDDEN 0x02
#define ATTR_SYSTEM 0x04
#define ATTR_VOLUMENAME 0x08
#define ATTR_DIRECTORY 0x10
#define ATTR_ARCHIVE 0x20
#define ATTR_LONG_NAME (ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM | ATTR_VOLUMENAME)
#define FAT12 1
#define FAT16 2
#define FAT32 3
#define FATX16 4
#define FATX32 5
#define ISFATX(FT) ((FT) == FATX16 || (FT) == FATX32)
#endif // #defined __FAT_H

419
freeldr/freeldr/fs/fs.c Normal file
View File

@@ -0,0 +1,419 @@
/*
* FreeLoader
* Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>
*
* 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.
*/
#include <freeldr.h>
#include <fs.h>
#include "fat.h"
#include "iso.h"
#include "ext2.h"
#include "ntfs.h"
#include "fsrec.h"
#include <disk.h>
#include <rtl.h>
#include <ui.h>
#include <arch.h>
#include <debug.h>
#include <machine.h>
/////////////////////////////////////////////////////////////////////////////////////////////
// DATA
/////////////////////////////////////////////////////////////////////////////////////////////
U32 FileSystemType = 0; // Type of filesystem on boot device, set by FsOpenVolume()
/////////////////////////////////////////////////////////////////////////////////////////////
// FUNCTIONS
/////////////////////////////////////////////////////////////////////////////////////////////
VOID FileSystemError(PUCHAR ErrorString)
{
DbgPrint((DPRINT_FILESYSTEM, "%s\n", ErrorString));
UiMessageBox(ErrorString);
}
/*
*
* BOOL FsOpenVolume(U32 DriveNumber, U32 PartitionNumber);
*
* This function is called to open a disk volume for file access.
* It must be called before any of the file functions will work.
* It takes two parameters:
*
* Drive: The BIOS drive number of the disk to open
* Partition: This is zero for floppy drives.
* If the disk is a hard disk then this specifies
* The partition number to open (1 - 4)
* If it is zero then it opens the active (bootable) partition
*
*/
BOOL FsOpenVolume(U32 DriveNumber, U32 PartitionNumber)
{
PARTITION_TABLE_ENTRY PartitionTableEntry;
UCHAR ErrorText[80];
U8 VolumeType;
DbgPrint((DPRINT_FILESYSTEM, "FsOpenVolume() DriveNumber: 0x%x PartitionNumber: 0x%x\n", DriveNumber, PartitionNumber));
// Check and see if it is a floppy drive
// If so then just assume FAT12 file system type
if (DiskIsDriveRemovable(DriveNumber))
{
DbgPrint((DPRINT_FILESYSTEM, "Drive is a floppy diskette drive. Assuming FAT12 file system.\n"));
FileSystemType = FS_FAT;
return FatOpenVolume(DriveNumber, 0, 0);
}
// Check for ISO9660 file system type
if (DriveNumber >= 0x80 && FsRecIsIso9660(DriveNumber))
{
DbgPrint((DPRINT_FILESYSTEM, "Drive is a cdrom drive. Assuming ISO-9660 file system.\n"));
FileSystemType = FS_ISO9660;
return IsoOpenVolume(DriveNumber);
}
// Set the boot partition
BootPartition = PartitionNumber;
// Get the requested partition entry
if (PartitionNumber == 0)
{
// Partition requested was zero which means the boot partition
if (DiskGetActivePartitionEntry(DriveNumber, &PartitionTableEntry) == FALSE)
{
FileSystemError("No active partition.");
return FALSE;
}
}
else
{
// Get requested partition
if (MachDiskGetPartitionEntry(DriveNumber, PartitionNumber, &PartitionTableEntry) == FALSE)
{
FileSystemError("Partition not found.");
return FALSE;
}
}
// Check for valid partition
if (PartitionTableEntry.SystemIndicator == PARTITION_ENTRY_UNUSED)
{
FileSystemError("Invalid partition.");
return FALSE;
}
// Try to recognize the file system
if (!FsRecognizeVolume(DriveNumber, PartitionTableEntry.SectorCountBeforePartition, &VolumeType))
{
FileSystemError("Unrecognized file system.");
return FALSE;
}
//switch (PartitionTableEntry.SystemIndicator)
switch (VolumeType)
{
case PARTITION_FAT_12:
case PARTITION_FAT_16:
case PARTITION_HUGE:
case PARTITION_XINT13:
case PARTITION_FAT32:
case PARTITION_FAT32_XINT13:
FileSystemType = FS_FAT;
return FatOpenVolume(DriveNumber, PartitionTableEntry.SectorCountBeforePartition, PartitionTableEntry.PartitionSectorCount);
case PARTITION_EXT2:
FileSystemType = FS_EXT2;
return Ext2OpenVolume(DriveNumber, PartitionTableEntry.SectorCountBeforePartition);
case PARTITION_NTFS:
FileSystemType = FS_NTFS;
return NtfsOpenVolume(DriveNumber, PartitionTableEntry.SectorCountBeforePartition);
default:
FileSystemType = 0;
sprintf(ErrorText, "Unsupported file system. Type: 0x%x", VolumeType);
FileSystemError(ErrorText);
return FALSE;
}
return TRUE;
}
PFILE FsOpenFile(PUCHAR FileName)
{
PFILE FileHandle = NULL;
//
// Print status message
//
DbgPrint((DPRINT_FILESYSTEM, "Opening file '%s'...\n", FileName));
//
// Check and see if the first character is '\' or '/' and remove it if so
//
while ((*FileName == '\\') || (*FileName == '/'))
{
FileName++;
}
//
// Check file system type and pass off to appropriate handler
//
switch (FileSystemType)
{
case FS_FAT:
FileHandle = FatOpenFile(FileName);
break;
case FS_ISO9660:
FileHandle = IsoOpenFile(FileName);
break;
case FS_EXT2:
FileHandle = Ext2OpenFile(FileName);
break;
case FS_NTFS:
FileHandle = NtfsOpenFile(FileName);
break;
default:
FileSystemError("Error: Unknown filesystem.");
break;
}
#ifdef DEBUG
//
// Check return value
//
if (FileHandle != NULL)
{
DbgPrint((DPRINT_FILESYSTEM, "FsOpenFile() succeeded. FileHandle: 0x%x\n", FileHandle));
}
else
{
DbgPrint((DPRINT_FILESYSTEM, "FsOpenFile() failed.\n"));
}
#endif // defined DEBUG
return FileHandle;
}
VOID FsCloseFile(PFILE FileHandle)
{
}
/*
* ReadFile()
* returns number of bytes read or EOF
*/
BOOL FsReadFile(PFILE FileHandle, U32 BytesToRead, U32* BytesRead, PVOID Buffer)
{
U64 BytesReadBig;
BOOL Success;
//
// Set the number of bytes read equal to zero
//
if (BytesRead != NULL)
{
*BytesRead = 0;
}
switch (FileSystemType)
{
case FS_FAT:
return FatReadFile(FileHandle, BytesToRead, BytesRead, Buffer);
case FS_ISO9660:
return IsoReadFile(FileHandle, BytesToRead, BytesRead, Buffer);
case FS_EXT2:
//return Ext2ReadFile(FileHandle, BytesToRead, BytesRead, Buffer);
Success = Ext2ReadFile(FileHandle, BytesToRead, &BytesReadBig, Buffer);
*BytesRead = (U32)BytesReadBig;
return Success;
case FS_NTFS:
return NtfsReadFile(FileHandle, BytesToRead, BytesRead, Buffer);
default:
FileSystemError("Unknown file system.");
return FALSE;
}
return FALSE;
}
U32 FsGetFileSize(PFILE FileHandle)
{
switch (FileSystemType)
{
case FS_FAT:
return FatGetFileSize(FileHandle);
case FS_ISO9660:
return IsoGetFileSize(FileHandle);
case FS_EXT2:
return Ext2GetFileSize(FileHandle);
case FS_NTFS:
return NtfsGetFileSize(FileHandle);
default:
FileSystemError("Unknown file system.");
break;
}
return 0;
}
VOID FsSetFilePointer(PFILE FileHandle, U32 NewFilePointer)
{
switch (FileSystemType)
{
case FS_FAT:
FatSetFilePointer(FileHandle, NewFilePointer);
break;
case FS_ISO9660:
IsoSetFilePointer(FileHandle, NewFilePointer);
break;
case FS_EXT2:
Ext2SetFilePointer(FileHandle, NewFilePointer);
break;
case FS_NTFS:
NtfsSetFilePointer(FileHandle, NewFilePointer);
break;
default:
FileSystemError("Unknown file system.");
break;
}
}
U32 FsGetFilePointer(PFILE FileHandle)
{
switch (FileSystemType)
{
case FS_FAT:
return FatGetFilePointer(FileHandle);
break;
case FS_ISO9660:
return IsoGetFilePointer(FileHandle);
break;
case FS_EXT2:
return Ext2GetFilePointer(FileHandle);
break;
case FS_NTFS:
return NtfsGetFilePointer(FileHandle);
break;
default:
FileSystemError("Unknown file system.");
break;
}
return 0;
}
BOOL FsIsEndOfFile(PFILE FileHandle)
{
if (FsGetFilePointer(FileHandle) >= FsGetFileSize(FileHandle))
{
return TRUE;
}
else
{
return FALSE;
}
}
/*
* FsGetNumPathParts()
* This function parses a path in the form of dir1\dir2\file1.ext
* and returns the number of parts it has (i.e. 3 - dir1,dir2,file1.ext)
*/
U32 FsGetNumPathParts(PUCHAR Path)
{
U32 i;
U32 num;
for (i=0,num=0; i<(int)strlen(Path); i++)
{
if ((Path[i] == '\\') || (Path[i] == '/'))
{
num++;
}
}
num++;
DbgPrint((DPRINT_FILESYSTEM, "FatGetNumPathParts() Path = %s NumPathParts = %d\n", Path, num));
return num;
}
/*
* FsGetFirstNameFromPath()
* This function parses a path in the form of dir1\dir2\file1.ext
* and puts the first name of the path (e.g. "dir1") in buffer
* compatible with the MSDOS directory structure
*/
VOID FsGetFirstNameFromPath(PUCHAR Buffer, PUCHAR Path)
{
U32 i;
// Copy all the characters up to the end of the
// string or until we hit a '\' character
// and put them in Buffer
for (i=0; i<(int)strlen(Path); i++)
{
if ((Path[i] == '\\') || (Path[i] == '/'))
{
break;
}
else
{
Buffer[i] = Path[i];
}
}
Buffer[i] = 0;
DbgPrint((DPRINT_FILESYSTEM, "FatGetFirstNameFromPath() Path = %s FirstName = %s\n", Path, Buffer));
}

142
freeldr/freeldr/fs/fsrec.c Normal file
View File

@@ -0,0 +1,142 @@
/*
* FreeLoader
* Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>
*
* 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.
*/
#include <freeldr.h>
#include <fs.h>
#include "fsrec.h"
#include "fat.h"
#include "iso.h"
#include "ext2.h"
#include "ntfs.h"
#include <disk.h>
#include <rtl.h>
#include <arch.h>
#include <debug.h>
#include <machine.h>
/////////////////////////////////////////////////////////////////////////////////////////////
// FUNCTIONS
/////////////////////////////////////////////////////////////////////////////////////////////
/*
*
* BOOL FsRecognizeVolume(U32 DriveNumber, U32 VolumeStartSector, U8* VolumeType);
*
*/
BOOL FsRecognizeVolume(U32 DriveNumber, U32 VolumeStartSector, U8* VolumeType)
{
DbgPrint((DPRINT_FILESYSTEM, "FsRecognizeVolume() DriveNumber: 0x%x VolumeStartSector: %d\n", DriveNumber, VolumeStartSector));
if (FsRecIsExt2(DriveNumber, VolumeStartSector))
{
*VolumeType = PARTITION_EXT2;
return TRUE;
}
else if (FsRecIsFat(DriveNumber, VolumeStartSector))
{
*VolumeType = PARTITION_FAT32;
return TRUE;
}
else if (FsRecIsNtfs(DriveNumber, VolumeStartSector))
{
*VolumeType = PARTITION_NTFS;
return TRUE;
}
return FALSE;
}
BOOL FsRecIsIso9660(U32 DriveNumber)
{
PUCHAR Sector = (PUCHAR)DISKREADBUFFER;
if (!MachDiskReadLogicalSectors(DriveNumber, 16, 1, Sector))
{
FileSystemError("Failed to read the PVD.");
return FALSE;
}
return (Sector[0] == 1 &&
Sector[1] == 'C' &&
Sector[2] == 'D' &&
Sector[3] == '0' &&
Sector[4] == '0' &&
Sector[5] == '1');
}
BOOL FsRecIsExt2(U32 DriveNumber, U32 VolumeStartSector)
{
PEXT2_SUPER_BLOCK SuperBlock = (PEXT2_SUPER_BLOCK)DISKREADBUFFER;
if (!MachDiskReadLogicalSectors(DriveNumber, VolumeStartSector + 2, 2, SuperBlock))
{
FileSystemError("Failed to read the super block.");
return FALSE;
}
if (SuperBlock->s_magic == EXT3_SUPER_MAGIC)
{
return TRUE;
}
return FALSE;
}
BOOL FsRecIsFat(U32 DriveNumber, U32 VolumeStartSector)
{
PFAT_BOOTSECTOR BootSector = (PFAT_BOOTSECTOR)DISKREADBUFFER;
PFAT32_BOOTSECTOR BootSector32 = (PFAT32_BOOTSECTOR)DISKREADBUFFER;
PFATX_BOOTSECTOR BootSectorX = (PFATX_BOOTSECTOR)DISKREADBUFFER;
if (!MachDiskReadLogicalSectors(DriveNumber, VolumeStartSector, 1, BootSector))
{
FileSystemError("Failed to read the boot sector.");
return FALSE;
}
if (strncmp(BootSector->FileSystemType, "FAT12 ", 8) == 0 ||
strncmp(BootSector->FileSystemType, "FAT16 ", 8) == 0 ||
strncmp(BootSector32->FileSystemType, "FAT32 ", 8) == 0 ||
strncmp(BootSectorX->FileSystemType, "FATX", 4) == 0)
{
return TRUE;
}
return FALSE;
}
BOOL FsRecIsNtfs(U32 DriveNumber, U32 VolumeStartSector)
{
PNTFS_BOOTSECTOR BootSector = (PNTFS_BOOTSECTOR)DISKREADBUFFER;
if (!MachDiskReadLogicalSectors(DriveNumber, VolumeStartSector, 1, BootSector))
{
FileSystemError("Failed to read the boot sector.");
return FALSE;
}
if (!RtlCompareMemory(BootSector->SystemId, "NTFS", 4))
{
return TRUE;
}
return FALSE;
}

View File

@@ -0,0 +1,29 @@
/*
* FreeLoader
* Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>
*
* 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.
*/
#ifndef __FSREC_H
#define __FSREC_H
BOOL FsRecognizeVolume(U32 DriveNumber, U32 VolumeStartSector, U8* VolumeType);
BOOL FsRecIsIso9660(U32 DriveNumber);
BOOL FsRecIsExt2(U32 DriveNumber, U32 VolumeStartSector);
BOOL FsRecIsFat(U32 DriveNumber, U32 VolumeStartSector);
BOOL FsRecIsNtfs(U32 DriveNumber, U32 VolumeStartSector);
#endif // #defined __FSREC_H

479
freeldr/freeldr/fs/iso.c Normal file
View File

@@ -0,0 +1,479 @@
/*
* FreeLoader
* Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>
*
* 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.
*/
#include <freeldr.h>
#include <fs.h>
#include <disk.h>
#include <rtl.h>
#include <arch.h>
#include <mm.h>
#include <debug.h>
#include <cache.h>
#include <machine.h>
#include "iso.h"
#define SECTORSIZE 2048
static U32 IsoRootSector; // Starting sector of the root directory
static U32 IsoRootLength; // Length of the root directory
U32 IsoDriveNumber = 0;
BOOL IsoOpenVolume(U32 DriveNumber)
{
PPVD Pvd = (PPVD)DISKREADBUFFER;
DbgPrint((DPRINT_FILESYSTEM, "IsoOpenVolume() DriveNumber = 0x%x VolumeStartSector = 16\n", DriveNumber));
// Store the drive number
IsoDriveNumber = DriveNumber;
IsoRootSector = 0;
IsoRootLength = 0;
if (!MachDiskReadLogicalSectors(DriveNumber, 16, 1, Pvd))
{
FileSystemError("Failed to read the PVD.");
return FALSE;
}
IsoRootSector = Pvd->RootDirRecord.ExtentLocationL;
IsoRootLength = Pvd->RootDirRecord.DataLengthL;
DbgPrint((DPRINT_FILESYSTEM, "IsoRootSector = %u IsoRootLegth = %u\n", IsoRootSector, IsoRootLength));
return TRUE;
}
static BOOL IsoSearchDirectoryBufferForFile(PVOID DirectoryBuffer, U32 DirectoryLength, PUCHAR FileName, PISO_FILE_INFO IsoFileInfoPointer)
{
PDIR_RECORD Record;
U32 Offset;
U32 i;
UCHAR Name[32];
DbgPrint((DPRINT_FILESYSTEM, "IsoSearchDirectoryBufferForFile() DirectoryBuffer = 0x%x DirectoryLength = %d FileName = %s\n", DirectoryBuffer, DirectoryLength, FileName));
RtlZeroMemory(Name, 32 * sizeof(UCHAR));
Offset = 0;
Record = (PDIR_RECORD)DirectoryBuffer;
while (TRUE)
{
Offset = Offset + Record->RecordLength;
Record = (PDIR_RECORD)(DirectoryBuffer + Offset);
if (Record->RecordLength == 0)
{
Offset = ROUND_UP(Offset, SECTORSIZE);
Record = (PDIR_RECORD)(DirectoryBuffer + Offset);
}
if (Offset >= DirectoryLength)
return FALSE;
if (Record->FileIdLength == 1 && Record->FileId[0] == 0)
{
DbgPrint((DPRINT_FILESYSTEM, "Name '.'\n"));
}
else if (Record->FileIdLength == 1 && Record->FileId[0] == 1)
{
DbgPrint((DPRINT_FILESYSTEM, "Name '..'\n"));
}
else
{
for (i = 0; i < Record->FileIdLength && Record->FileId[i] != ';'; i++)
Name[i] = Record->FileId[i];
Name[i] = 0;
DbgPrint((DPRINT_FILESYSTEM, "Name '%s'\n", Name));
if (strlen(FileName) == strlen(Name) && stricmp(FileName, Name) == 0)
{
IsoFileInfoPointer->FileStart = Record->ExtentLocationL;
IsoFileInfoPointer->FileSize = Record->DataLengthL;
IsoFileInfoPointer->FilePointer = 0;
IsoFileInfoPointer->Directory = (Record->FileFlags & 0x02)?TRUE:FALSE;
return TRUE;
}
}
RtlZeroMemory(Name, 32 * sizeof(UCHAR));
}
return FALSE;
}
/*
* IsoBufferDirectory()
* This function allocates a buffer, reads the specified directory
* and returns a pointer to that buffer. The function returns NULL
* if allocation or read fails. The directory is specified by its
* starting sector and length.
*/
static PVOID IsoBufferDirectory(U32 DirectoryStartSector, U32 DirectoryLength)
{
PVOID DirectoryBuffer;
PVOID Ptr;
U32 SectorCount;
U32 i;
DbgPrint((DPRINT_FILESYSTEM, "IsoBufferDirectory() DirectoryStartSector = %d DirectoryLength = %d\n", DirectoryStartSector, DirectoryLength));
SectorCount = ROUND_UP(DirectoryLength, SECTORSIZE) / SECTORSIZE;
DbgPrint((DPRINT_FILESYSTEM, "Trying to read (DirectoryCount) %d sectors.\n", SectorCount));
//
// Attempt to allocate memory for directory buffer
//
DbgPrint((DPRINT_FILESYSTEM, "Trying to allocate (DirectoryLength) %d bytes.\n", DirectoryLength));
DirectoryBuffer = MmAllocateMemory(DirectoryLength);
if (DirectoryBuffer == NULL)
{
return NULL;
}
//
// Now read directory contents into DirectoryBuffer
//
for (i = 0, Ptr = DirectoryBuffer; i < SectorCount; i++, Ptr += SECTORSIZE)
{
if (!MachDiskReadLogicalSectors(IsoDriveNumber, DirectoryStartSector + i, 1, (PVOID)DISKREADBUFFER))
{
MmFreeMemory(DirectoryBuffer);
return NULL;
}
RtlCopyMemory(Ptr, (PVOID)DISKREADBUFFER, SECTORSIZE);
}
return DirectoryBuffer;
}
/*
* IsoLookupFile()
* This function searches the file system for the
* specified filename and fills in an ISO_FILE_INFO structure
* with info describing the file, etc. returns true
* if the file exists or false otherwise
*/
static BOOL IsoLookupFile(PUCHAR FileName, PISO_FILE_INFO IsoFileInfoPointer)
{
int i;
U32 NumberOfPathParts;
UCHAR PathPart[261];
PVOID DirectoryBuffer;
U32 DirectorySector;
U32 DirectoryLength;
ISO_FILE_INFO IsoFileInfo;
DbgPrint((DPRINT_FILESYSTEM, "IsoLookupFile() FileName = %s\n", FileName));
RtlZeroMemory(IsoFileInfoPointer, sizeof(ISO_FILE_INFO));
//
// Figure out how many sub-directories we are nested in
//
NumberOfPathParts = FsGetNumPathParts(FileName);
DirectorySector = IsoRootSector;
DirectoryLength = IsoRootLength;
//
// Loop once for each part
//
for (i=0; i<NumberOfPathParts; i++)
{
//
// Get first path part
//
FsGetFirstNameFromPath(PathPart, FileName);
//
// Advance to the next part of the path
//
for (; (*FileName != '\\') && (*FileName != '/') && (*FileName != '\0'); FileName++)
{
}
FileName++;
//
// Buffer the directory contents
//
DirectoryBuffer = IsoBufferDirectory(DirectorySector, DirectoryLength);
if (DirectoryBuffer == NULL)
{
return FALSE;
}
//
// Search for file name in directory
//
if (!IsoSearchDirectoryBufferForFile(DirectoryBuffer, DirectoryLength, PathPart, &IsoFileInfo))
{
MmFreeMemory(DirectoryBuffer);
return FALSE;
}
MmFreeMemory(DirectoryBuffer);
//
// If we have another sub-directory to go then
// grab the start sector and file size
//
if ((i+1) < NumberOfPathParts)
{
DirectorySector = IsoFileInfo.FileStart;
DirectoryLength = IsoFileInfo.FileSize;
}
}
RtlCopyMemory(IsoFileInfoPointer, &IsoFileInfo, sizeof(ISO_FILE_INFO));
return TRUE;
}
/*
* IsoOpenFile()
* Tries to open the file 'name' and returns true or false
* for success and failure respectively
*/
FILE* IsoOpenFile(PUCHAR FileName)
{
ISO_FILE_INFO TempFileInfo;
PISO_FILE_INFO FileHandle;
DbgPrint((DPRINT_FILESYSTEM, "IsoOpenFile() FileName = %s\n", FileName));
if (!IsoLookupFile(FileName, &TempFileInfo))
{
return NULL;
}
FileHandle = MmAllocateMemory(sizeof(ISO_FILE_INFO));
if (FileHandle == NULL)
{
return NULL;
}
RtlCopyMemory(FileHandle, &TempFileInfo, sizeof(ISO_FILE_INFO));
return (FILE*)FileHandle;
}
/*
* IsoReadFile()
* Reads BytesToRead from open file and
* returns the number of bytes read in BytesRead
*/
BOOL IsoReadFile(FILE *FileHandle, U32 BytesToRead, U32* BytesRead, PVOID Buffer)
{
PISO_FILE_INFO IsoFileInfo = (PISO_FILE_INFO)FileHandle;
U32 SectorNumber;
U32 OffsetInSector;
U32 LengthInSector;
U32 NumberOfSectors;
U32 i;
DbgPrint((DPRINT_FILESYSTEM, "IsoReadFile() BytesToRead = %d Buffer = 0x%x\n", BytesToRead, Buffer));
if (BytesRead != NULL)
{
*BytesRead = 0;
}
//
// If they are trying to read past the
// end of the file then return success
// with BytesRead == 0
//
if (IsoFileInfo->FilePointer >= IsoFileInfo->FileSize)
{
return TRUE;
}
//
// If they are trying to read more than there is to read
// then adjust the amount to read
//
if ((IsoFileInfo->FilePointer + BytesToRead) > IsoFileInfo->FileSize)
{
BytesToRead = (IsoFileInfo->FileSize - IsoFileInfo->FilePointer);
}
//
// Ok, now we have to perform at most 3 calculations
// I'll draw you a picture (using nifty ASCII art):
//
// CurrentFilePointer -+
// |
// +----------------+
// |
// +-----------+-----------+-----------+-----------+
// | Sector 1 | Sector 2 | Sector 3 | Sector 4 |
// +-----------+-----------+-----------+-----------+
// | |
// +---------------+--------------------+
// |
// BytesToRead -------+
//
// 1 - The first calculation (and read) will align
// the file pointer with the next sector
// boundary (if we are supposed to read that much)
// 2 - The next calculation (and read) will read
// in all the full sectors that the requested
// amount of data would cover (in this case
// sectors 2 & 3).
// 3 - The last calculation (and read) would read
// in the remainder of the data requested out of
// the last sector.
//
//
// Only do the first read if we
// aren't aligned on a cluster boundary
//
if (IsoFileInfo->FilePointer % SECTORSIZE)
{
//
// Do the math for our first read
//
SectorNumber = IsoFileInfo->FileStart + (IsoFileInfo->FilePointer / SECTORSIZE);
OffsetInSector = IsoFileInfo->FilePointer % SECTORSIZE;
LengthInSector = (BytesToRead > (SECTORSIZE - OffsetInSector)) ? (SECTORSIZE - OffsetInSector) : BytesToRead;
//
// Now do the read and update BytesRead, BytesToRead, FilePointer, & Buffer
//
if (!MachDiskReadLogicalSectors(IsoDriveNumber, SectorNumber, 1, (PVOID)DISKREADBUFFER))
{
return FALSE;
}
RtlCopyMemory(Buffer, ((PVOID)DISKREADBUFFER + OffsetInSector), LengthInSector);
if (BytesRead != NULL)
{
*BytesRead += LengthInSector;
}
BytesToRead -= LengthInSector;
IsoFileInfo->FilePointer += LengthInSector;
Buffer += LengthInSector;
}
//
// Do the math for our second read (if any data left)
//
if (BytesToRead > 0)
{
//
// Determine how many full clusters we need to read
//
NumberOfSectors = (BytesToRead / SECTORSIZE);
for (i = 0; i < NumberOfSectors; i++)
{
SectorNumber = IsoFileInfo->FileStart + (IsoFileInfo->FilePointer / SECTORSIZE);
//
// Now do the read and update BytesRead, BytesToRead, FilePointer, & Buffer
//
if (!MachDiskReadLogicalSectors(IsoDriveNumber, SectorNumber, 1, (PVOID)DISKREADBUFFER))
{
return FALSE;
}
RtlCopyMemory(Buffer, (PVOID)DISKREADBUFFER, SECTORSIZE);
if (BytesRead != NULL)
{
*BytesRead += SECTORSIZE;
}
BytesToRead -= SECTORSIZE;
IsoFileInfo->FilePointer += SECTORSIZE;
Buffer += SECTORSIZE;
}
}
//
// Do the math for our third read (if any data left)
//
if (BytesToRead > 0)
{
SectorNumber = IsoFileInfo->FileStart + (IsoFileInfo->FilePointer / SECTORSIZE);
//
// Now do the read and update BytesRead, BytesToRead, FilePointer, & Buffer
//
if (!MachDiskReadLogicalSectors(IsoDriveNumber, SectorNumber, 1, (PVOID)DISKREADBUFFER))
{
return FALSE;
}
RtlCopyMemory(Buffer, (PVOID)DISKREADBUFFER, BytesToRead);
if (BytesRead != NULL)
{
*BytesRead += BytesToRead;
}
IsoFileInfo->FilePointer += BytesToRead;
BytesToRead -= BytesToRead;
Buffer += BytesToRead;
}
DbgPrint((DPRINT_FILESYSTEM, "IsoReadFile() done\n"));
return TRUE;
}
U32 IsoGetFileSize(FILE *FileHandle)
{
PISO_FILE_INFO IsoFileHandle = (PISO_FILE_INFO)FileHandle;
DbgPrint((DPRINT_FILESYSTEM, "IsoGetFileSize() FileSize = %d\n", IsoFileHandle->FileSize));
return IsoFileHandle->FileSize;
}
VOID IsoSetFilePointer(FILE *FileHandle, U32 NewFilePointer)
{
PISO_FILE_INFO IsoFileHandle = (PISO_FILE_INFO)FileHandle;
DbgPrint((DPRINT_FILESYSTEM, "IsoSetFilePointer() NewFilePointer = %d\n", NewFilePointer));
IsoFileHandle->FilePointer = NewFilePointer;
}
U32 IsoGetFilePointer(FILE *FileHandle)
{
PISO_FILE_INFO IsoFileHandle = (PISO_FILE_INFO)FileHandle;
DbgPrint((DPRINT_FILESYSTEM, "IsoGetFilePointer() FilePointer = %d\n", IsoFileHandle->FilePointer));
return IsoFileHandle->FilePointer;
}

115
freeldr/freeldr/fs/iso.h Normal file
View File

@@ -0,0 +1,115 @@
/*
* FreeLoader
* Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>
*
* 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.
*/
#ifndef __ISO_H
#define __ISO_H
struct _DIR_RECORD
{
UCHAR RecordLength; // 1
UCHAR ExtAttrRecordLength; // 2
U32 ExtentLocationL; // 3-6
U32 ExtentLocationM; // 7-10
U32 DataLengthL; // 11-14
U32 DataLengthM; // 15-18
UCHAR Year; // 19
UCHAR Month; // 20
UCHAR Day; // 21
UCHAR Hour; // 22
UCHAR Minute; // 23
UCHAR Second; // 24
UCHAR TimeZone; // 25
UCHAR FileFlags; // 26
UCHAR FileUnitSize; // 27
UCHAR InterleaveGapSize; // 28
U32 VolumeSequenceNumber; // 29-32
UCHAR FileIdLength; // 33
UCHAR FileId[1]; // 34
} __attribute__((packed));
typedef struct _DIR_RECORD DIR_RECORD, *PDIR_RECORD;
/* Volume Descriptor header*/
struct _VD_HEADER
{
UCHAR VdType; // 1
UCHAR StandardId[5]; // 2-6
UCHAR VdVersion; // 7
} __attribute__((packed));
typedef struct _VD_HEADER VD_HEADER, *PVD_HEADER;
/* Primary Volume Descriptor */
struct _PVD
{
UCHAR VdType; // 1
UCHAR StandardId[5]; // 2-6
UCHAR VdVersion; // 7
UCHAR unused0; // 8
UCHAR SystemId[32]; // 9-40
UCHAR VolumeId[32]; // 41-72
UCHAR unused1[8]; // 73-80
U32 VolumeSpaceSizeL; // 81-84
U32 VolumeSpaceSizeM; // 85-88
UCHAR unused2[32]; // 89-120
U32 VolumeSetSize; // 121-124
U32 VolumeSequenceNumber; // 125-128
U32 LogicalBlockSize; // 129-132
U32 PathTableSizeL; // 133-136
U32 PathTableSizeM; // 137-140
U32 LPathTablePos; // 141-144
U32 LOptPathTablePos; // 145-148
U32 MPathTablePos; // 149-152
U32 MOptPathTablePos; // 153-156
DIR_RECORD RootDirRecord; // 157-190
UCHAR VolumeSetIdentifier[128]; // 191-318
UCHAR PublisherIdentifier[128]; // 319-446
/* more data ... */
} __attribute__((packed));
typedef struct _PVD PVD, *PPVD;
typedef struct
{
U32 FileStart; // File start sector
U32 FileSize; // File size
U32 FilePointer; // File pointer
BOOL Directory;
U32 DriveNumber;
} ISO_FILE_INFO, * PISO_FILE_INFO;
BOOL IsoOpenVolume(U32 DriveNumber);
FILE* IsoOpenFile(PUCHAR FileName);
BOOL IsoReadFile(FILE *FileHandle, U32 BytesToRead, U32* BytesRead, PVOID Buffer);
U32 IsoGetFileSize(FILE *FileHandle);
VOID IsoSetFilePointer(FILE *FileHandle, U32 NewFilePointer);
U32 IsoGetFilePointer(FILE *FileHandle);
#endif // #defined __FAT_H

739
freeldr/freeldr/fs/ntfs.c Normal file
View File

@@ -0,0 +1,739 @@
/*
* FreeLoader NTFS support
* Copyright (C) 2004 Filip Navara <xnavara@volny.cz>
*
* 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.
*/
/*
* Limitations:
* - No support for compressed files.
* - No attribute list support.
* - May crash on currupted filesystem.
*/
#include <freeldr.h>
#include <fs.h>
#include <disk.h>
#include <rtl.h>
#include <arch.h>
#include <mm.h>
#include <debug.h>
#include <cache.h>
#include <machine.h>
#include "ntfs.h"
PNTFS_BOOTSECTOR NtfsBootSector;
U32 NtfsClusterSize;
U32 NtfsMftRecordSize;
U32 NtfsIndexRecordSize;
U32 NtfsDriveNumber;
U32 NtfsSectorOfClusterZero;
PNTFS_MFT_RECORD NtfsMasterFileTable;
NTFS_ATTR_CONTEXT NtfsMFTContext;
PUCHAR NtfsDecodeRun(PUCHAR DataRun, S64 *DataRunOffset, U64 *DataRunLength)
{
U8 DataRunOffsetSize;
U8 DataRunLengthSize;
S8 i;
DataRunOffsetSize = (*DataRun >> 4) & 0xF;
DataRunLengthSize = *DataRun & 0xF;
*DataRunOffset = 0;
*DataRunLength = 0;
DataRun++;
for (i = 0; i < DataRunLengthSize; i++)
{
*DataRunLength += *DataRun << (i << 3);
DataRun++;
}
/* NTFS 3+ sparse files */
if (DataRunOffsetSize == 0)
{
*DataRunOffset = -1;
}
else
{
for (i = 0; i < DataRunOffsetSize - 1; i++)
{
*DataRunOffset += *DataRun << (i << 3);
DataRun++;
}
/* The last byte contains sign so we must process it different way. */
*DataRunOffset = ((S8)(*(DataRun++)) << (i << 3)) + *DataRunOffset;
}
DbgPrint((DPRINT_FILESYSTEM, "DataRunOffsetSize: %x\n", DataRunOffsetSize));
DbgPrint((DPRINT_FILESYSTEM, "DataRunLengthSize: %x\n", DataRunLengthSize));
DbgPrint((DPRINT_FILESYSTEM, "DataRunOffset: %x\n", *DataRunOffset));
DbgPrint((DPRINT_FILESYSTEM, "DataRunLength: %x\n", *DataRunLength));
return DataRun;
}
/* FIXME: Add support for attribute lists! */
BOOL NtfsFindAttribute(PNTFS_ATTR_CONTEXT Context, PNTFS_MFT_RECORD MftRecord, U32 Type, PWCHAR Name)
{
PNTFS_ATTR_RECORD AttrRecord;
PNTFS_ATTR_RECORD AttrRecordEnd;
U32 NameLength;
PWCHAR AttrName;
AttrRecord = (PNTFS_ATTR_RECORD)((PCHAR)MftRecord + MftRecord->AttributesOffset);
AttrRecordEnd = (PNTFS_ATTR_RECORD)((PCHAR)MftRecord + NtfsMftRecordSize);
for (NameLength = 0; Name[NameLength] != 0; NameLength++)
;
while (AttrRecord < AttrRecordEnd)
{
if (AttrRecord->Type == NTFS_ATTR_TYPE_END)
break;
if (AttrRecord->Type == Type)
{
if (AttrRecord->NameLength == NameLength)
{
AttrName = (PWCHAR)((PCHAR)AttrRecord + AttrRecord->NameOffset);
if (!RtlCompareMemory(AttrName, Name, NameLength << 1))
{
/* Found it, fill up the context and return. */
Context->Record = AttrRecord;
if (AttrRecord->IsNonResident)
{
S64 DataRunOffset;
U64 DataRunLength;
Context->CacheRun = (PUCHAR)Context->Record + Context->Record->NonResident.MappingPairsOffset;
Context->CacheRunOffset = 0;
Context->CacheRun = NtfsDecodeRun(Context->CacheRun, &DataRunOffset, &DataRunLength);
Context->CacheRunLength = DataRunLength;
if (DataRunOffset != -1)
{
/* Normal run. */
Context->CacheRunStartLCN =
Context->CacheRunLastLCN = DataRunOffset;
}
else
{
/* Sparse run. */
Context->CacheRunStartLCN = -1;
Context->CacheRunLastLCN = 0;
}
Context->CacheRunCurrentOffset = 0;
}
return TRUE;
}
}
}
AttrRecord = (PNTFS_ATTR_RECORD)((PCHAR)AttrRecord + AttrRecord->Length);
}
return FALSE;
}
/* FIXME: Optimize for multisector reads. */
BOOL NtfsDiskRead(U64 Offset, U64 Length, PCHAR Buffer)
{
U16 ReadLength;
DbgPrint((DPRINT_FILESYSTEM, "NtfsDiskRead - Offset: %I64d Length: %I64d\n", Offset, Length));
RtlZeroMemory((PCHAR)DISKREADBUFFER, 0x1000);
/* I. Read partial first sector if needed */
if (Offset % NtfsBootSector->BytesPerSector)
{
if (!MachDiskReadLogicalSectors(NtfsDriveNumber, NtfsSectorOfClusterZero + (Offset / NtfsBootSector->BytesPerSector), 1, (PCHAR)DISKREADBUFFER))
return FALSE;
ReadLength = min(Length, NtfsBootSector->BytesPerSector - (Offset % NtfsBootSector->BytesPerSector));
RtlCopyMemory(Buffer, (PCHAR)DISKREADBUFFER + (Offset % NtfsBootSector->BytesPerSector), ReadLength);
Buffer += ReadLength;
Length -= ReadLength;
Offset += ReadLength;
}
/* II. Read all complete 64-sector blocks. */
while (Length >= 64 * NtfsBootSector->BytesPerSector)
{
if (!MachDiskReadLogicalSectors(NtfsDriveNumber, NtfsSectorOfClusterZero + (Offset / NtfsBootSector->BytesPerSector), 64, (PCHAR)DISKREADBUFFER))
return FALSE;
RtlCopyMemory(Buffer, (PCHAR)DISKREADBUFFER, 64 * NtfsBootSector->BytesPerSector);
Buffer += 64 * NtfsBootSector->BytesPerSector;
Length -= 64 * NtfsBootSector->BytesPerSector;
Offset += 64 * NtfsBootSector->BytesPerSector;
}
/* III. Read the rest of data */
if (Length)
{
ReadLength = ((Length + NtfsBootSector->BytesPerSector - 1) / NtfsBootSector->BytesPerSector);
if (!MachDiskReadLogicalSectors(NtfsDriveNumber, NtfsSectorOfClusterZero + (Offset / NtfsBootSector->BytesPerSector), ReadLength, (PCHAR)DISKREADBUFFER))
return FALSE;
RtlCopyMemory(Buffer, (PCHAR)DISKREADBUFFER, Length);
}
return TRUE;
}
U64 NtfsReadAttribute(PNTFS_ATTR_CONTEXT Context, U64 Offset, PCHAR Buffer, U64 Length)
{
U64 LastLCN;
PUCHAR DataRun;
S64 DataRunOffset;
U64 DataRunLength;
S64 DataRunStartLCN;
U64 CurrentOffset;
U64 ReadLength;
U64 AlreadyRead;
if (!Context->Record->IsNonResident)
{
if (Offset > Context->Record->Resident.ValueLength)
return 0;
if (Offset + Length > Context->Record->Resident.ValueLength)
Length = Context->Record->Resident.ValueLength - Offset;
RtlCopyMemory(Buffer, (PCHAR)Context->Record + Context->Record->Resident.ValueOffset + Offset, Length);
return Length;
}
/*
* Non-resident attribute
*/
/*
* I. Find the corresponding start data run.
*/
if (Context->CacheRunOffset == Offset)
{
DataRun = Context->CacheRun;
LastLCN = Context->CacheRunLastLCN;
DataRunStartLCN = Context->CacheRunStartLCN;
DataRunLength = Context->CacheRunLength;
CurrentOffset = Context->CacheRunCurrentOffset;
}
else
{
LastLCN = 0;
DataRun = (PUCHAR)Context->Record + Context->Record->NonResident.MappingPairsOffset;
CurrentOffset = 0;
while (1)
{
DataRun = NtfsDecodeRun(DataRun, &DataRunOffset, &DataRunLength);
if (DataRunOffset != -1)
{
/* Normal data run. */
DataRunStartLCN = LastLCN + DataRunOffset;
LastLCN = DataRunStartLCN;
}
else
{
/* Sparse data run. */
DataRunStartLCN = -1;
}
if (Offset >= CurrentOffset &&
Offset < CurrentOffset + (DataRunLength * NtfsClusterSize))
{
break;
}
if (*DataRun == 0)
{
return 0;
}
CurrentOffset += DataRunLength * NtfsClusterSize;
}
}
/*
* II. Go through the run list and read the data
*/
AlreadyRead = 0;
while (Length > 0)
{
ReadLength = min(DataRunLength * NtfsClusterSize, Length);
if (DataRunStartLCN == -1)
RtlZeroMemory(Buffer, ReadLength);
else if (!NtfsDiskRead(DataRunStartLCN * NtfsClusterSize + Offset - CurrentOffset, ReadLength, Buffer))
break;
Length -= ReadLength;
Buffer += ReadLength;
AlreadyRead += ReadLength;
/* We finished this request, but there still data in this data run. */
if (Length == 0 && ReadLength != DataRunLength * NtfsClusterSize)
break;
/*
* Go to next run in the list.
*/
if (*DataRun == 0)
break;
DataRun = NtfsDecodeRun(DataRun, &DataRunOffset, &DataRunLength);
if (DataRunOffset != -1)
{
/* Normal data run. */
DataRunStartLCN = LastLCN + DataRunOffset;
LastLCN = DataRunStartLCN;
}
else
{
/* Sparse data run. */
DataRunStartLCN = -1;
}
CurrentOffset += DataRunLength * NtfsClusterSize;
}
Context->CacheRun = DataRun;
Context->CacheRunOffset = Offset + AlreadyRead;
Context->CacheRunStartLCN = DataRunStartLCN;
Context->CacheRunLength = DataRunLength;
Context->CacheRunLastLCN = LastLCN;
Context->CacheRunCurrentOffset = CurrentOffset;
return AlreadyRead;
}
BOOL NtfsFixupRecord(PNTFS_RECORD Record)
{
U16 *USA;
U16 USANumber;
U16 USACount;
U16 *Block;
USA = (U16*)((PCHAR)Record + Record->USAOffset);
USANumber = *(USA++);
USACount = Record->USACount - 1; /* Exclude the USA Number. */
Block = (U16*)((PCHAR)Record + NtfsBootSector->BytesPerSector - 2);
while (USACount)
{
if (*Block != USANumber)
return FALSE;
*Block = *(USA++);
Block = (U16*)((PCHAR)Block + NtfsBootSector->BytesPerSector);
USACount--;
}
return TRUE;
}
BOOL NtfsReadMftRecord(U32 MFTIndex, PNTFS_MFT_RECORD Buffer)
{
U64 BytesRead;
BytesRead = NtfsReadAttribute(&NtfsMFTContext, MFTIndex * NtfsMftRecordSize, (PCHAR)Buffer, NtfsMftRecordSize);
if (BytesRead != NtfsMftRecordSize)
return FALSE;
/* Apply update sequence array fixups. */
return NtfsFixupRecord((PNTFS_RECORD)Buffer);
}
#ifdef DEBUG
VOID NtfsPrintFile(PNTFS_INDEX_ENTRY IndexEntry)
{
PWCHAR FileName;
U8 FileNameLength;
CHAR AnsiFileName[256];
U8 i;
FileName = IndexEntry->FileName.FileName;
FileNameLength = IndexEntry->FileName.FileNameLength;
for (i = 0; i < FileNameLength; i++)
AnsiFileName[i] = FileName[i];
AnsiFileName[i] = 0;
DbgPrint((DPRINT_FILESYSTEM, "- %s (%x)\n", AnsiFileName, IndexEntry->Data.Directory.IndexedFile));
}
#endif
BOOL NtfsCompareFileName(PCHAR FileName, PNTFS_INDEX_ENTRY IndexEntry)
{
PWCHAR EntryFileName;
U8 EntryFileNameLength;
U8 i;
EntryFileName = IndexEntry->FileName.FileName;
EntryFileNameLength = IndexEntry->FileName.FileNameLength;
#ifdef DEBUG
NtfsPrintFile(IndexEntry);
#endif
if (strlen(FileName) != EntryFileNameLength)
return FALSE;
/* Do case-sensitive compares for Posix file names. */
if (IndexEntry->FileName.FileNameType == NTFS_FILE_NAME_POSIX)
{
for (i = 0; i < EntryFileNameLength; i++)
if (EntryFileName[i] != FileName[i])
return FALSE;
}
else
{
for (i = 0; i < EntryFileNameLength; i++)
if (tolower(EntryFileName[i]) != tolower(FileName[i]))
return FALSE;
}
return TRUE;
}
BOOL NtfsFindMftRecord(U32 MFTIndex, PCHAR FileName, U32 *OutMFTIndex)
{
PNTFS_MFT_RECORD MftRecord;
U32 Magic;
NTFS_ATTR_CONTEXT IndexRootCtx;
NTFS_ATTR_CONTEXT IndexBitmapCtx;
NTFS_ATTR_CONTEXT IndexAllocationCtx;
PNTFS_INDEX_ROOT IndexRoot;
U64 BitmapDataSize;
U64 IndexAllocationSize;
PCHAR BitmapData;
PCHAR IndexRecord;
PNTFS_INDEX_ENTRY IndexEntry, IndexEntryEnd;
U32 RecordOffset;
U32 IndexBlockSize;
MftRecord = MmAllocateMemory(NtfsMftRecordSize);
if (MftRecord == NULL)
{
return FALSE;
}
if (NtfsReadMftRecord(MFTIndex, MftRecord))
{
Magic = MftRecord->Magic;
if (!NtfsFindAttribute(&IndexRootCtx, MftRecord, NTFS_ATTR_TYPE_INDEX_ROOT, L"$I30"))
{
MmFreeMemory(MftRecord);
return FALSE;
}
IndexRecord = MmAllocateMemory(NtfsIndexRecordSize);
if (IndexRecord == NULL)
{
MmFreeMemory(MftRecord);
return FALSE;
}
NtfsReadAttribute(&IndexRootCtx, 0, IndexRecord, NtfsIndexRecordSize);
IndexRoot = (PNTFS_INDEX_ROOT)IndexRecord;
IndexEntry = (PNTFS_INDEX_ENTRY)((PCHAR)&IndexRoot->IndexHeader + IndexRoot->IndexHeader.EntriesOffset);
/* Index root is always resident. */
IndexEntryEnd = (PNTFS_INDEX_ENTRY)(IndexRecord + IndexRootCtx.Record->Resident.ValueLength);
DbgPrint((DPRINT_FILESYSTEM, "NtfsIndexRecordSize: %x IndexBlockSize: %x\n", NtfsIndexRecordSize, IndexRoot->IndexBlockSize));
while (IndexEntry < IndexEntryEnd &&
!(IndexEntry->Flags & NTFS_INDEX_ENTRY_END))
{
if (NtfsCompareFileName(FileName, IndexEntry))
{
*OutMFTIndex = IndexEntry->Data.Directory.IndexedFile;
MmFreeMemory(IndexRecord);
MmFreeMemory(MftRecord);
return TRUE;
}
IndexEntry = (PNTFS_INDEX_ENTRY)((PCHAR)IndexEntry + IndexEntry->Length);
}
if (IndexRoot->IndexHeader.Flags & NTFS_LARGE_INDEX)
{
DbgPrint((DPRINT_FILESYSTEM, "Large Index!\n"));
IndexBlockSize = IndexRoot->IndexBlockSize;
if (!NtfsFindAttribute(&IndexBitmapCtx, MftRecord, NTFS_ATTR_TYPE_BITMAP, L"$I30"))
{
DbgPrint((DPRINT_FILESYSTEM, "Corrupted filesystem!\n"));
MmFreeMemory(MftRecord);
return FALSE;
}
if (IndexBitmapCtx.Record->IsNonResident)
BitmapDataSize = IndexBitmapCtx.Record->NonResident.DataSize;
else
BitmapDataSize = IndexBitmapCtx.Record->Resident.ValueLength;
DbgPrint((DPRINT_FILESYSTEM, "BitmapDataSize: %x\n", BitmapDataSize));
BitmapData = MmAllocateMemory(BitmapDataSize);
if (BitmapData == NULL)
{
MmFreeMemory(IndexRecord);
MmFreeMemory(MftRecord);
return FALSE;
}
NtfsReadAttribute(&IndexBitmapCtx, 0, BitmapData, BitmapDataSize);
if (!NtfsFindAttribute(&IndexAllocationCtx, MftRecord, NTFS_ATTR_TYPE_INDEX_ALLOCATION, L"$I30"))
{
DbgPrint((DPRINT_FILESYSTEM, "Corrupted filesystem!\n"));
MmFreeMemory(BitmapData);
MmFreeMemory(IndexRecord);
MmFreeMemory(MftRecord);
return FALSE;
}
if (IndexAllocationCtx.Record->IsNonResident)
IndexAllocationSize = IndexAllocationCtx.Record->NonResident.DataSize;
else
IndexAllocationSize = IndexAllocationCtx.Record->Resident.ValueLength;
RecordOffset = 0;
for (;;)
{
DbgPrint((DPRINT_FILESYSTEM, "RecordOffset: %x IndexAllocationSize: %x\n", RecordOffset, IndexAllocationSize));
for (; RecordOffset < IndexAllocationSize;)
{
U8 Bit = 1 << ((RecordOffset / IndexBlockSize) & 7);
U32 Byte = (RecordOffset / IndexBlockSize) >> 3;
if ((BitmapData[Byte] & Bit))
break;
RecordOffset += IndexBlockSize;
}
if (RecordOffset >= IndexAllocationSize)
{
break;
}
NtfsReadAttribute(&IndexAllocationCtx, RecordOffset, IndexRecord, IndexBlockSize);
if (!NtfsFixupRecord((PNTFS_RECORD)IndexRecord))
{
break;
}
/* FIXME */
IndexEntry = (PNTFS_INDEX_ENTRY)(IndexRecord + 0x18 + *(U16 *)(IndexRecord + 0x18));
IndexEntryEnd = (PNTFS_INDEX_ENTRY)(IndexRecord + IndexBlockSize);
while (IndexEntry < IndexEntryEnd &&
!(IndexEntry->Flags & NTFS_INDEX_ENTRY_END))
{
if (NtfsCompareFileName(FileName, IndexEntry))
{
DbgPrint((DPRINT_FILESYSTEM, "File found\n"));
*OutMFTIndex = IndexEntry->Data.Directory.IndexedFile;
MmFreeMemory(BitmapData);
MmFreeMemory(IndexRecord);
MmFreeMemory(MftRecord);
return TRUE;
}
IndexEntry = (PNTFS_INDEX_ENTRY)((PCHAR)IndexEntry + IndexEntry->Length);
}
RecordOffset += IndexBlockSize;
}
MmFreeMemory(BitmapData);
}
MmFreeMemory(IndexRecord);
}
else
{
DbgPrint((DPRINT_FILESYSTEM, "Can't read MFT record\n"));
}
MmFreeMemory(MftRecord);
return FALSE;
}
BOOL NtfsLookupFile(PUCHAR FileName, PNTFS_MFT_RECORD MftRecord, PNTFS_ATTR_CONTEXT DataContext)
{
U32 NumberOfPathParts;
UCHAR PathPart[261];
U32 CurrentMFTIndex;
U8 i;
DbgPrint((DPRINT_FILESYSTEM, "NtfsLookupFile() FileName = %s\n", FileName));
CurrentMFTIndex = NTFS_FILE_ROOT;
NumberOfPathParts = FsGetNumPathParts(FileName);
for (i = 0; i < NumberOfPathParts; i++)
{
FsGetFirstNameFromPath(PathPart, FileName);
for (; (*FileName != '\\') && (*FileName != '/') && (*FileName != '\0'); FileName++)
;
FileName++;
DbgPrint((DPRINT_FILESYSTEM, "- Lookup: %s\n", PathPart));
if (!NtfsFindMftRecord(CurrentMFTIndex, PathPart, &CurrentMFTIndex))
{
DbgPrint((DPRINT_FILESYSTEM, "- Failed\n"));
return FALSE;
}
DbgPrint((DPRINT_FILESYSTEM, "- Lookup: %x\n", CurrentMFTIndex));
}
if (!NtfsReadMftRecord(CurrentMFTIndex, MftRecord))
{
DbgPrint((DPRINT_FILESYSTEM, "NtfsLookupFile: Can't read MFT record\n"));
return FALSE;
}
if (!NtfsFindAttribute(DataContext, MftRecord, NTFS_ATTR_TYPE_DATA, L""))
{
DbgPrint((DPRINT_FILESYSTEM, "NtfsLookupFile: Can't find data attribute\n"));
return FALSE;
}
return TRUE;
}
BOOL NtfsOpenVolume(U32 DriveNumber, U32 VolumeStartSector)
{
NtfsBootSector = (PNTFS_BOOTSECTOR)DISKREADBUFFER;
DbgPrint((DPRINT_FILESYSTEM, "NtfsOpenVolume() DriveNumber = 0x%x VolumeStartSector = 0x%x\n", DriveNumber, VolumeStartSector));
if (!MachDiskReadLogicalSectors(DriveNumber, VolumeStartSector, 1, (PCHAR)DISKREADBUFFER))
{
FileSystemError("Failed to read the boot sector.");
return FALSE;
}
if (RtlCompareMemory(NtfsBootSector->SystemId, "NTFS", 4))
{
FileSystemError("Invalid NTFS signature.");
return FALSE;
}
NtfsBootSector = MmAllocateMemory(NtfsBootSector->BytesPerSector);
if (NtfsBootSector == NULL)
{
return FALSE;
}
RtlCopyMemory(NtfsBootSector, (PCHAR)DISKREADBUFFER, ((PNTFS_BOOTSECTOR)DISKREADBUFFER)->BytesPerSector);
NtfsClusterSize = NtfsBootSector->SectorsPerCluster * NtfsBootSector->BytesPerSector;
if (NtfsBootSector->ClustersPerMftRecord > 0)
NtfsMftRecordSize = NtfsBootSector->ClustersPerMftRecord * NtfsClusterSize;
else
NtfsMftRecordSize = 1 << (-NtfsBootSector->ClustersPerMftRecord);
if (NtfsBootSector->ClustersPerIndexRecord > 0)
NtfsIndexRecordSize = NtfsBootSector->ClustersPerIndexRecord * NtfsClusterSize;
else
NtfsIndexRecordSize = 1 << (-NtfsBootSector->ClustersPerIndexRecord);
DbgPrint((DPRINT_FILESYSTEM, "NtfsClusterSize: 0x%x\n", NtfsClusterSize));
DbgPrint((DPRINT_FILESYSTEM, "ClustersPerMftRecord: %d\n", NtfsBootSector->ClustersPerMftRecord));
DbgPrint((DPRINT_FILESYSTEM, "ClustersPerIndexRecord: %d\n", NtfsBootSector->ClustersPerIndexRecord));
DbgPrint((DPRINT_FILESYSTEM, "NtfsMftRecordSize: 0x%x\n", NtfsMftRecordSize));
DbgPrint((DPRINT_FILESYSTEM, "NtfsIndexRecordSize: 0x%x\n", NtfsIndexRecordSize));
NtfsDriveNumber = DriveNumber;
NtfsSectorOfClusterZero = VolumeStartSector;
DbgPrint((DPRINT_FILESYSTEM, "Reading MFT index...\n"));
if (!MachDiskReadLogicalSectors(DriveNumber,
NtfsSectorOfClusterZero +
(NtfsBootSector->MftLocation * NtfsBootSector->SectorsPerCluster),
NtfsMftRecordSize / NtfsBootSector->BytesPerSector, (PCHAR)DISKREADBUFFER))
{
FileSystemError("Failed to read the Master File Table record.");
return FALSE;
}
NtfsMasterFileTable = MmAllocateMemory(NtfsMftRecordSize);
if (NtfsMasterFileTable == NULL)
{
MmFreeMemory(NtfsBootSector);
return FALSE;
}
RtlCopyMemory(NtfsMasterFileTable, (PCHAR)DISKREADBUFFER, NtfsMftRecordSize);
DbgPrint((DPRINT_FILESYSTEM, "Searching for DATA attribute...\n"));
if (!NtfsFindAttribute(&NtfsMFTContext, NtfsMasterFileTable, NTFS_ATTR_TYPE_DATA, L""))
{
FileSystemError("Can't find data attribute for Master File Table.");
return FALSE;
}
return TRUE;
}
FILE* NtfsOpenFile(PUCHAR FileName)
{
PNTFS_FILE_HANDLE FileHandle;
PNTFS_MFT_RECORD MftRecord;
FileHandle = MmAllocateMemory(sizeof(NTFS_FILE_HANDLE) + NtfsMftRecordSize);
if (FileHandle == NULL)
{
return NULL;
}
MftRecord = (PNTFS_MFT_RECORD)(FileHandle + 1);
if (!NtfsLookupFile(FileName, MftRecord, &FileHandle->DataContext))
{
MmFreeMemory(FileHandle);
return NULL;
}
FileHandle->Offset = 0;
return (FILE*)FileHandle;
}
BOOL NtfsReadFile(FILE *File, U32 BytesToRead, U32* BytesRead, PVOID Buffer)
{
PNTFS_FILE_HANDLE FileHandle = (PNTFS_FILE_HANDLE)File;
U64 BytesRead64;
BytesRead64 = NtfsReadAttribute(&FileHandle->DataContext, FileHandle->Offset, Buffer, BytesToRead);
if (BytesRead64)
{
*BytesRead = (U32)BytesRead64;
FileHandle->Offset += BytesRead64;
return TRUE;
}
return FALSE;
}
U32 NtfsGetFileSize(FILE *File)
{
PNTFS_FILE_HANDLE FileHandle = (PNTFS_FILE_HANDLE)File;
if (FileHandle->DataContext.Record->IsNonResident)
return (U32)FileHandle->DataContext.Record->NonResident.DataSize;
else
return (U32)FileHandle->DataContext.Record->Resident.ValueLength;
}
VOID NtfsSetFilePointer(FILE *File, U32 NewFilePointer)
{
PNTFS_FILE_HANDLE FileHandle = (PNTFS_FILE_HANDLE)File;
FileHandle->Offset = NewFilePointer;
}
U32 NtfsGetFilePointer(FILE *File)
{
PNTFS_FILE_HANDLE FileHandle = (PNTFS_FILE_HANDLE)File;
return FileHandle->Offset;
}

228
freeldr/freeldr/fs/ntfs.h Normal file
View File

@@ -0,0 +1,228 @@
/*
* FreeLoader NTFS support
* Copyright (C) 2004 Filip Navara <xnavara@volny.cz>
*
* 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.
*/
#ifndef __NTFS_H
#define __NTFS_H
#define NTFS_FILE_MFT 0
#define NTFS_FILE_MFTMIRR 1
#define NTFS_FILE_LOGFILE 2
#define NTFS_FILE_VOLUME 3
#define NTFS_FILE_ATTRDEF 4
#define NTFS_FILE_ROOT 5
#define NTFS_FILE_BITMAP 6
#define NTFS_FILE_BOOT 7
#define NTFS_FILE_BADCLUS 8
#define NTFS_FILE_QUOTA 9
#define NTFS_FILE_UPCASE 10
#define NTFS_ATTR_TYPE_STANDARD_INFORMATION 0x10
#define NTFS_ATTR_TYPE_ATTRIBUTE_LIST 0x20
#define NTFS_ATTR_TYPE_FILENAME 0x30
#define NTFS_ATTR_TYPE_SECURITY_DESCRIPTOR 0x50
#define NTFS_ATTR_TYPE_DATA 0x80
#define NTFS_ATTR_TYPE_INDEX_ROOT 0x90
#define NTFS_ATTR_TYPE_INDEX_ALLOCATION 0xa0
#define NTFS_ATTR_TYPE_BITMAP 0xb0
#define NTFS_ATTR_TYPE_SYMLINK 0xc0
#define NTFS_ATTR_TYPE_END 0xffffffff
#define NTFS_ATTR_NORMAL 0
#define NTFS_ATTR_COMPRESSED 1
#define NTFS_ATTR_RESIDENT 2
#define NTFS_ATTR_ENCRYPTED 0x4000
#define NTFS_SMALL_INDEX 0
#define NTFS_LARGE_INDEX 1
#define NTFS_INDEX_ENTRY_NODE 1
#define NTFS_INDEX_ENTRY_END 2
#define NTFS_FILE_NAME_POSIX 0
#define NTFS_FILE_NAME_WIN32 1
#define NTFS_FILE_NAME_DOS 2
#define NTFS_FILE_NAME_WIN32_AND_DOS 3
typedef struct
{
U8 JumpBoot[3]; // Jump to the boot loader routine
U8 SystemId[8]; // System Id ("NTFS ")
U16 BytesPerSector; // Bytes per sector
U8 SectorsPerCluster; // Number of sectors in a cluster
U8 Unused1[7];
U8 MediaDescriptor; // Media descriptor byte
U8 Unused2[2];
U16 SectorsPerTrack; // Number of sectors in a track
U16 NumberOfHeads; // Number of heads on the disk
U8 Unused3[8];
U8 DriveNumber; // Int 0x13 drive number (e.g. 0x80)
U8 CurrentHead;
U8 BootSignature; // Extended boot signature (0x80)
U8 Unused4;
U64 VolumeSectorCount; // Number of sectors in the volume
U64 MftLocation;
U64 MftMirrorLocation;
S8 ClustersPerMftRecord; // Clusters per MFT Record
U8 Unused5[3];
S8 ClustersPerIndexRecord; // Clusters per Index Record
U8 Unused6[3];
U64 VolumeSerialNumber; // Volume serial number
U8 BootCodeAndData[430]; // The remainder of the boot sector
U16 BootSectorMagic; // 0xAA55
} PACKED NTFS_BOOTSECTOR, *PNTFS_BOOTSECTOR;
typedef struct
{
U32 Magic;
U16 USAOffset; // Offset to the Update Sequence Array from the start of the ntfs record
U16 USACount;
} PACKED NTFS_RECORD, *PNTFS_RECORD;
typedef struct
{
U32 Magic;
U16 USAOffset; // Offset to the Update Sequence Array from the start of the ntfs record
U16 USACount;
U64 LogSequenceNumber;
U16 SequenceNumber;
U16 LinkCount;
U16 AttributesOffset;
U16 Flags;
U32 BytesInUse; // Number of bytes used in this mft record.
U32 BytesAllocated;
U64 BaseMFTRecord;
U16 NextAttributeInstance;
} PACKED NTFS_MFT_RECORD, *PNTFS_MFT_RECORD;
typedef struct
{
U32 Type;
U32 Length;
U8 IsNonResident;
U8 NameLength;
U16 NameOffset;
U16 Flags;
U16 Instance;
union
{
// Resident attributes
struct
{
U32 ValueLength;
U16 ValueOffset;
U16 Flags;
} PACKED Resident;
// Non-resident attributes
struct
{
U64 LowestVCN;
U64 HighestVCN;
U16 MappingPairsOffset;
U8 CompressionUnit;
U8 Reserved[5];
S64 AllocatedSize;
S64 DataSize;
S64 InitializedSize;
S64 CompressedSize;
} PACKED NonResident;
} PACKED;
} PACKED NTFS_ATTR_RECORD, *PNTFS_ATTR_RECORD;
typedef struct
{
U32 EntriesOffset;
U32 IndexLength;
U32 AllocatedSize;
U8 Flags;
U8 Reserved[3];
} PACKED NTFS_INDEX_HEADER, *PNTFS_INDEX_HEADER;
typedef struct
{
U32 Type;
U32 CollationRule;
U32 IndexBlockSize;
U8 ClustersPerIndexBlock;
U8 Reserved[3];
NTFS_INDEX_HEADER IndexHeader;
} PACKED NTFS_INDEX_ROOT, *PNTFS_INDEX_ROOT;
typedef struct
{
U64 ParentDirectory;
S64 CreationTime;
S64 LastDataChangeTime;
S64 LastMftChangeTime;
S64 LastAccessTime;
S64 AllocatedSize;
S64 DataSize;
U32 FileAttributes;
U16 PackedExtendedAttributeSize;
U16 Reserved;
U8 FileNameLength;
U8 FileNameType;
WCHAR FileName[0];
} PACKED NTFS_FILE_NAME_ATTR, *PNTFS_FILE_NAME_ATTR;
typedef struct {
union
{
struct
{
U64 IndexedFile;
} PACKED Directory;
struct
{
U16 DataOffset;
U16 DataLength;
U32 Reserved;
} PACKED ViewIndex;
} PACKED Data;
U16 Length;
U16 KeyLength;
U16 Flags;
U16 Reserved;
NTFS_FILE_NAME_ATTR FileName;
} PACKED NTFS_INDEX_ENTRY, *PNTFS_INDEX_ENTRY;
typedef struct
{
PNTFS_ATTR_RECORD Record;
PUCHAR CacheRun;
U64 CacheRunOffset;
S64 CacheRunStartLCN;
U64 CacheRunLength;
S64 CacheRunLastLCN;
U64 CacheRunCurrentOffset;
} NTFS_ATTR_CONTEXT, *PNTFS_ATTR_CONTEXT;
typedef struct
{
NTFS_ATTR_CONTEXT DataContext;
U64 Offset;
} PACKED NTFS_FILE_HANDLE, *PNTFS_FILE_HANDLE;
BOOL NtfsOpenVolume(U32 DriveNumber, U32 VolumeStartSector);
FILE* NtfsOpenFile(PUCHAR FileName);
BOOL NtfsReadFile(FILE *FileHandle, U32 BytesToRead, U32* BytesRead, PVOID Buffer);
U32 NtfsGetFileSize(FILE *FileHandle);
VOID NtfsSetFilePointer(FILE *FileHandle, U32 NewFilePointer);
U32 NtfsGetFilePointer(FILE *FileHandle);
#endif // #defined __NTFS_H

View File

@@ -12,25 +12,25 @@
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
* 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.
*/
#pragma once
#ifdef _M_AMD64
#include <arch/amd64/amd64.h>
#endif
#ifndef __ARCH_H
#define __ARCH_H
#if defined (_M_IX86)
/* Defines needed for switching between real and protected mode */
#define NULL_DESC 0x00 /* NULL descriptor */
#define PMODE_CS 0x08 /* PMode code selector, base 0 limit 4g */
#define PMODE_DS 0x10 /* PMode data selector, base 0 limit 4g */
#define RMODE_CS 0x18 /* RMode code selector, base 0 limit 64k */
#define RMODE_DS 0x20 /* RMode data selector, base 0 limit 64k */
#endif
#define KERNEL_BASE 0xC0000000
#define KERNEL_CS 0x08
#define KERNEL_DS 0x10
#define CR0_PE_SET 0x00000001 /* OR this value with CR0 to enable pmode */
#define CR0_PE_CLR 0xFFFFFFFE /* AND this value with CR0 to disable pmode */
@@ -38,44 +38,21 @@
#define STACK16ADDR 0x7000 /* The 16-bit stack top will be at 0000:7000 */
#define STACK32ADDR 0x78000 /* The 32-bit stack top will be at 7000:8000, or 0x78000 */
#if defined (_M_IX86) || defined (_M_AMD64)
#define BIOSCALLBUFFER 0x78000 /* Buffer to store temporary data for any Int386() call */
#define BIOSCALLBUFSEGMENT 0x7800 /* Buffer to store temporary data for any Int386() call */
#define BIOSCALLBUFOFFSET 0x0000 /* Buffer to store temporary data for any Int386() call */
#define FILESYSBUFFER 0x80000 /* Buffer to store file system data (e.g. cluster buffer for FAT) */
#define DISKREADBUFFER 0x90000 /* Buffer to store data read in from the disk via the BIOS */
#define DISKREADBUFFER_SIZE 512
#elif defined(_M_PPC) || defined(_M_MIPS)
#define DISKREADBUFFER 0x80000000
#define FILESYSBUFFER 0x80000000
#elif defined(_M_ARM)
extern ULONG gDiskReadBuffer, gFileSysBuffer;
#define DISKREADBUFFER gDiskReadBuffer
#define FILESYSBUFFER gFileSysBuffer
#endif
/* Makes "x" a global variable or label */
#define EXTERN(x) .global x; x:
// Flag Masks
#define I386FLAG_CF 0x0001 // Carry Flag
#define I386FLAG_RESV1 0x0002 // Reserved - Must be 1
#define I386FLAG_PF 0x0004 // Parity Flag
#define I386FLAG_RESV2 0x0008 // Reserved - Must be 0
#define I386FLAG_AF 0x0010 // Auxiliary Flag
#define I386FLAG_RESV3 0x0020 // Reserved - Must be 0
#define I386FLAG_ZF 0x0040 // Zero Flag
#define I386FLAG_SF 0x0080 // Sign Flag
#define I386FLAG_TF 0x0100 // Trap Flag (Single Step)
#define I386FLAG_IF 0x0200 // Interrupt Flag
#define I386FLAG_DF 0x0400 // Direction Flag
#define I386FLAG_OF 0x0800 // Overflow Flag
#ifndef ASM
#include <pshpack1.h>
typedef struct
{
unsigned long eax;
@@ -93,7 +70,7 @@ typedef struct
unsigned long eflags;
} DWORDREGS;
} PACKED DWORDREGS;
typedef struct
{
@@ -112,7 +89,7 @@ typedef struct
unsigned short flags, _upper_flags;
} WORDREGS;
} PACKED WORDREGS;
typedef struct
{
@@ -139,8 +116,7 @@ typedef struct
unsigned short flags, _upper_flags;
} BYTEREGS;
} PACKED BYTEREGS;
typedef union
{
@@ -149,7 +125,6 @@ typedef union
WORDREGS w;
BYTEREGS b;
} REGS;
#include <poppack.h>
// Int386()
//
@@ -161,6 +136,20 @@ typedef union
// specifically handles linear addresses.
int Int386(int ivec, REGS* in, REGS* out);
// Flag Masks
#define I386FLAG_CF 0x0001 // Carry Flag
#define I386FLAG_RESV1 0x0002 // Reserved - Must be 1
#define I386FLAG_PF 0x0004 // Parity Flag
#define I386FLAG_RESV2 0x0008 // Reserved - Must be 0
#define I386FLAG_AF 0x0010 // Auxiliary Flag
#define I386FLAG_RESV3 0x0020 // Reserved - Must be 0
#define I386FLAG_ZF 0x0040 // Zero Flag
#define I386FLAG_SF 0x0080 // Sign Flag
#define I386FLAG_TF 0x0100 // Trap Flag (Single Step)
#define I386FLAG_IF 0x0200 // Interrupt Flag
#define I386FLAG_DF 0x0400 // Direction Flag
#define I386FLAG_OF 0x0800 // Overflow Flag
// This macro tests the Carry Flag
// If CF is set then the call failed (usually)
#define INT386_SUCCESS(regs) ((regs.x.eflags & I386FLAG_CF) == 0)
@@ -173,3 +162,6 @@ VOID SoftReboot(VOID); // Implemented in boot.S
VOID DetectHardware(VOID); // Implemented in hardware.c
#endif /* ! ASM */
#endif // #defined __ARCH_H

View File

@@ -0,0 +1,29 @@
/*
* FreeLoader
* Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>
*
* 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.
*/
#ifndef __BOOTMGR_H
#define __BOOTMGR_H
U32 GetDefaultOperatingSystem(PUCHAR OperatingSystemList[], U32 OperatingSystemCount);
S32 GetTimeOut(VOID);
BOOL MainBootMenuKeyPressFilter(U32 KeyPress);
#endif // #defined __BOOTMGR_H

View File

@@ -0,0 +1,30 @@
/*
* FreeLoader
* Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>
*
* 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.
*/
#ifndef __CACHE_H
#define __CACHE_H
BOOL CacheInitializeDrive(U32 DriveNumber);
VOID CacheInvalidateCacheData(VOID);
BOOL CacheReadDiskSectors(U32 DiskNumber, U32 StartSector, U32 SectorCount, PVOID Buffer);
BOOL CacheForceDiskSectorsIntoCache(U32 DiskNumber, U32 StartSector, U32 SectorCount);
BOOL CacheReleaseMemory(U32 MinimumAmountToRelease);
#endif // defined __CACHE_H

View File

@@ -0,0 +1,37 @@
/* $Id: cmdline.h,v 1.1 2004/11/01 20:49:32 gvg Exp $
*
* FreeLdr boot loader
* Copyright (C) 2002, 2003 ReactOS Team
*
* 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.
*/
#ifndef __CMDLINE_H__
#define __CMDLINE_H__
typedef struct tagCMDLINEINFO
{
char *DefaultOperatingSystem;
S32 TimeOut;
} CMDLINEINFO, *PCMDLINEINFO;
extern void CmdLineParse(char *CmdLine);
extern char *CmdLineGetDefaultOS(void);
extern S32 CmdLineGetTimeOut(void);
#endif /* __CMDLINE_H__ */
/* EOF */

View File

@@ -0,0 +1,32 @@
/*
* FreeLoader
* Copyright (C) 2001 Brian Palmer <brianp@sginet.com>
* Copyright (C) 2001 Eric Kohl
* Copyright (C) 2001 Emanuele Aliberti
*
* 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.
*/
#ifndef __RS232_H
#define __RS232_H
BOOL Rs232PortInitialize(U32 ComPort, U32 BaudRate);
BOOL Rs232PortGetByte(PUCHAR ByteRecieved);
BOOL Rs232PortPollByte(PUCHAR ByteRecieved);
VOID Rs232PortPutByte(UCHAR ByteToSend);
#endif // defined __RS232_H

View File

@@ -0,0 +1,88 @@
/*
* FreeLoader
* Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>
*
* 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.
*/
#ifndef __DEBUG_H
#define __DEBUG_H
#ifdef DEBUG
#define DPRINT_NONE 0x00000000 // No debug print
#define DPRINT_WARNING 0x00000001 // OR this with DebugPrintMask to enable debugger messages and other misc stuff
#define DPRINT_MEMORY 0x00000002 // OR this with DebugPrintMask to enable memory management messages
#define DPRINT_FILESYSTEM 0x00000004 // OR this with DebugPrintMask to enable file system messages
#define DPRINT_INIFILE 0x00000008 // OR this with DebugPrintMask to enable .ini file messages
#define DPRINT_UI 0x00000010 // OR this with DebugPrintMask to enable user interface messages
#define DPRINT_DISK 0x00000020 // OR this with DebugPrintMask to enable disk messages
#define DPRINT_CACHE 0x00000040 // OR this with DebugPrintMask to enable cache messages
#define DPRINT_REGISTRY 0x00000080 // OR this with DebugPrintMask to enable registry messages
#define DPRINT_REACTOS 0x00000100 // OR this with DebugPrintMask to enable ReactOS messages
#define DPRINT_LINUX 0x00000200 // OR this with DebugPrintMask to enable Linux messages
#define DPRINT_HWDETECT 0x00000400 // OR this with DebugPrintMask to enable hardware detection messages
VOID DebugInit(VOID);
VOID DebugPrint(U32 Mask, char *format, ...);
VOID DebugPrint1(char *format, ...);
VOID DebugDumpBuffer(U32 Mask, PVOID Buffer, U32 Length);
#define DbgPrint(_x_) DebugPrint _x_ ;
#define DPRINT1 DebugPrint1
#define BugCheck(_x_) { DebugPrint(DPRINT_WARNING, "Fatal Error: %s:%d(%s)\n", __FILE__, __LINE__, __FUNCTION__); DebugPrint _x_ ; for (;;); }
#define DbgDumpBuffer(_x_, _y_, _z_) DebugDumpBuffer(_x_, _y_, _z_)
#ifdef __i386__
// Debugging support functions:
//
// BREAKPOINT() - Inserts an "int 3" instruction
// INSTRUCTION_BREAKPOINTX(x) - Enters exception handler right before instruction at address "x" is executed
// MEMORY_READWRITE_BREAKPOINTX(x) - Enters exception handler when a read or write occurs at address "x"
// MEMORY_WRITE_BREAKPOINTX(x) - Enters exception handler when a write occurs at address "x"
//
// You may have as many BREAKPOINT()'s as you like but you may only
// have up to four of any of the others.
#define BREAKPOINT() __asm__ ("int $3");
void INSTRUCTION_BREAKPOINT1(unsigned long addr);
void MEMORY_READWRITE_BREAKPOINT1(unsigned long addr);
void MEMORY_WRITE_BREAKPOINT1(unsigned long addr);
void INSTRUCTION_BREAKPOINT2(unsigned long addr);
void MEMORY_READWRITE_BREAKPOINT2(unsigned long addr);
void MEMORY_WRITE_BREAKPOINT2(unsigned long addr);
void INSTRUCTION_BREAKPOINT3(unsigned long addr);
void MEMORY_READWRITE_BREAKPOINT3(unsigned long addr);
void MEMORY_WRITE_BREAKPOINT3(unsigned long addr);
void INSTRUCTION_BREAKPOINT4(unsigned long addr);
void MEMORY_READWRITE_BREAKPOINT4(unsigned long addr);
void MEMORY_WRITE_BREAKPOINT4(unsigned long addr);
#endif // defined __i386__
#else
#define DebugInit()
#define DbgPrint(_x_)
#define DPRINT1(_x_)
#define BugCheck(_x_)
#define DbgDumpBuffer(_x_, _y_, _z_)
#endif // defined DEBUG
#define UNIMPLEMENTED() BugCheck((DPRINT_WARNING, "This function is unimplemented!\n"))
#endif // defined __DEBUG_H

View File

@@ -0,0 +1,139 @@
/*
* FreeLoader
* Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>
*
* 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.
*/
#ifndef __DISK_H
#define __DISK_H
typedef struct _GEOMETRY
{
U32 Cylinders; // Number of cylinders on the disk
U32 Heads; // Number of heads on the disk
U32 Sectors; // Number of sectors per track
U32 BytesPerSector; // Number of bytes per sector
} GEOMETRY, *PGEOMETRY;
//
// Extended disk geometry (Int13 / ah=48h)
//
typedef struct _EXTENDED_GEOMETRY
{
U16 Size;
U16 Flags;
U32 Cylinders;
U32 Heads;
U32 SectorsPerTrack;
U64 Sectors;
U16 BytesPerSector;
U32 PDPTE;
} __attribute__((packed)) EXTENDED_GEOMETRY, *PEXTENDED_GEOMETRY;
//
// Define the structure of a partition table entry
//
typedef struct _PARTITION_TABLE_ENTRY
{
U8 BootIndicator; // 0x00 - non-bootable partition, 0x80 - bootable partition (one partition only)
U8 StartHead; // Beginning head number
U8 StartSector; // Beginning sector (2 high bits of cylinder #)
U8 StartCylinder; // Beginning cylinder# (low order bits of cylinder #)
U8 SystemIndicator; // System indicator
U8 EndHead; // Ending head number
U8 EndSector; // Ending sector (2 high bits of cylinder #)
U8 EndCylinder; // Ending cylinder# (low order bits of cylinder #)
U32 SectorCountBeforePartition; // Number of sectors preceding the partition
U32 PartitionSectorCount; // Number of sectors in the partition
} PACKED PARTITION_TABLE_ENTRY, *PPARTITION_TABLE_ENTRY;
//
// Define the structure of the master boot record
//
typedef struct _MASTER_BOOT_RECORD
{
U8 MasterBootRecordCodeAndData[0x1b8]; /* 0x000 */
U32 Signature; /* 0x1B8 */
U16 Reserved; /* 0x1BC */
PARTITION_TABLE_ENTRY PartitionTable[4]; /* 0x1BE */
U16 MasterBootRecordMagic; /* 0x1FE */
} PACKED MASTER_BOOT_RECORD, *PMASTER_BOOT_RECORD;
//
// Partition type defines
//
#define PARTITION_ENTRY_UNUSED 0x00 // Entry unused
#define PARTITION_FAT_12 0x01 // 12-bit FAT entries
#define PARTITION_XENIX_1 0x02 // Xenix
#define PARTITION_XENIX_2 0x03 // Xenix
#define PARTITION_FAT_16 0x04 // 16-bit FAT entries
#define PARTITION_EXTENDED 0x05 // Extended partition entry
#define PARTITION_HUGE 0x06 // Huge partition MS-DOS V4
#define PARTITION_IFS 0x07 // IFS Partition
#define PARTITION_OS2BOOTMGR 0x0A // OS/2 Boot Manager/OPUS/Coherent swap
#define PARTITION_FAT32 0x0B // FAT32
#define PARTITION_FAT32_XINT13 0x0C // FAT32 using extended int13 services
#define PARTITION_XINT13 0x0E // Win95 partition using extended int13 services
#define PARTITION_XINT13_EXTENDED 0x0F // Same as type 5 but uses extended int13 services
#define PARTITION_NTFS 0x17 // NTFS
#define PARTITION_PREP 0x41 // PowerPC Reference Platform (PReP) Boot Partition
#define PARTITION_LDM 0x42 // Logical Disk Manager partition
#define PARTITION_UNIX 0x63 // Unix
#define PARTITION_LINUX_SWAP 0x82 // Linux Swap Partition
#define PARTITION_EXT2 0x83 // Linux Ext2/Ext3
///////////////////////////////////////////////////////////////////////////////////////
//
// i386 BIOS Disk Functions (i386disk.c)
//
///////////////////////////////////////////////////////////////////////////////////////
#ifdef __i386__
BOOL DiskResetController(U32 DriveNumber);
BOOL DiskInt13ExtensionsSupported(U32 DriveNumber);
//VOID DiskStopFloppyMotor(VOID);
BOOL DiskGetExtendedDriveParameters(U32 DriveNumber, PVOID Buffer, U16 BufferSize);
#endif // defined __i386__
///////////////////////////////////////////////////////////////////////////////////////
//
// FreeLoader Disk Functions
//
///////////////////////////////////////////////////////////////////////////////////////
VOID DiskReportError (BOOL bError);
VOID DiskError(PUCHAR ErrorString, U32 ErrorCode);
PUCHAR DiskGetErrorCodeString(U32 ErrorCode);
BOOL DiskReadLogicalSectors(U32 DriveNumber, U64 SectorNumber, U32 SectorCount, PVOID Buffer); // Implemented in i386disk.c
BOOL DiskIsDriveRemovable(U32 DriveNumber);
VOID DiskStopFloppyMotor(VOID); // Implemented in i386disk.c
///////////////////////////////////////////////////////////////////////////////////////
//
// Fixed Disk Partition Management Functions
//
///////////////////////////////////////////////////////////////////////////////////////
BOOL DiskGetActivePartitionEntry(U32 DriveNumber, PPARTITION_TABLE_ENTRY PartitionTableEntry);
BOOL DiskGetPartitionEntry(U32 DriveNumber, U32 PartitionNumber, PPARTITION_TABLE_ENTRY PartitionTableEntry);
BOOL DiskGetFirstPartitionEntry(PMASTER_BOOT_RECORD MasterBootRecord, PPARTITION_TABLE_ENTRY PartitionTableEntry);
BOOL DiskGetFirstExtendedPartitionEntry(PMASTER_BOOT_RECORD MasterBootRecord, PPARTITION_TABLE_ENTRY PartitionTableEntry);
BOOL DiskReadBootRecord(U32 DriveNumber, U64 LogicalSectorNumber, PMASTER_BOOT_RECORD BootRecord);
#endif // defined __DISK_H

View File

@@ -0,0 +1,43 @@
/*
* FreeLoader
* Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>
*
* 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.
*/
#ifndef __DRIVEMAP_H
#define __DRIVEMAP_H
typedef struct
{
U8 DriveMapCount; // Count of drives currently mapped
U8 DriveMap[8]; // Map of BIOS drives
} PACKED DRIVE_MAP_LIST, *PDRIVE_MAP_LIST;
VOID DriveMapMapDrivesInSection(PUCHAR SectionName);
BOOL DriveMapIsValidDriveString(PUCHAR DriveString); // Checks the drive string ("hd0") for validity
U32 DriveMapGetBiosDriveNumber(PUCHAR DeviceName); // Returns a BIOS drive number for any given device name (e.g. 0x80 for 'hd0')
VOID DriveMapInstallInt13Handler(PDRIVE_MAP_LIST DriveMap); // Installs the int 13h handler for the drive mapper
VOID DriveMapRemoveInt13Handler(VOID); // Removes a previously installed int 13h drive map handler
extern PVOID DriveMapInt13HandlerStart;
extern PVOID DriveMapInt13HandlerEnd;
extern U32 DriveMapOldInt13HandlerAddress;
extern DRIVE_MAP_LIST DriveMapInt13HandlerMapList;
#endif // #defined __DRIVEMAP_H

View File

@@ -0,0 +1,81 @@
/*
* FreeLoader
* Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>
*
* 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.
*/
#ifndef __FREELDR_H
#define __FREELDR_H
#define NULL 0
#define TRUE 1
#define FALSE 0
#define BOOL int
#define BOOLEAN int
typedef BOOLEAN *PBOOLEAN;
#define CHAR char
#define PCHAR char *
#define UCHAR unsigned char
#define PUCHAR unsigned char *
#define WCHAR unsigned short
#define PWCHAR unsigned short *
#define VOID void
#define PVOID VOID*
#ifdef __i386__
#define size_t unsigned int
typedef unsigned char U8;
typedef char S8;
typedef unsigned short U16;
typedef short S16;
typedef unsigned long U32;
typedef long S32;
typedef unsigned long long U64;
typedef long long S64;
typedef U8 __u8;
typedef S8 __s8;
typedef U16 __u16;
typedef S16 __s16;
typedef U32 __u32;
typedef S32 __s32;
typedef U64 __u64;
typedef S64 __s64;
#endif // __i386__
typedef U8 *PU8;
typedef U16 *PU16;
typedef U32 *PU32;
#define ROUND_UP(N, S) ((N) + (S) - ((N) % (S)))
#define ROUND_DOWN(N, S) ((N) - ((N) % (S)))
#define PACKED __attribute__((packed))
extern U32 BootDrive; // BIOS boot drive, 0-A:, 1-B:, 0x80-C:, 0x81-D:, etc.
extern U32 BootPartition; // Boot Partition, 1-4
extern BOOL UserInterfaceUp; // Tells us if the user interface is displayed
void BootMain(char *CmdLine);
VOID RunLoader(VOID);
#endif // defined __FREELDR_H

View File

@@ -0,0 +1,47 @@
/*
* FreeLoader
* Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>
*
* 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.
*/
#ifndef __FS_H
#define __FS_H
#define EOF -1
#define FS_FAT 1
#define FS_NTFS 2
#define FS_EXT2 3
#define FS_REISER 4
#define FS_ISO9660 5
#define FILE VOID
#define PFILE FILE *
VOID FileSystemError(PUCHAR ErrorString);
BOOL FsOpenVolume(U32 DriveNumber, U32 PartitionNumber);
PFILE FsOpenFile(PUCHAR FileName);
VOID FsCloseFile(PFILE FileHandle);
BOOL FsReadFile(PFILE FileHandle, U32 BytesToRead, U32* BytesRead, PVOID Buffer);
U32 FsGetFileSize(PFILE FileHandle);
VOID FsSetFilePointer(PFILE FileHandle, U32 NewFilePointer);
U32 FsGetFilePointer(PFILE FileHandle);
BOOL FsIsEndOfFile(PFILE FileHandle);
U32 FsGetNumPathParts(PUCHAR Path);
VOID FsGetFirstNameFromPath(PUCHAR Buffer, PUCHAR Path);
#endif // #defined __FS_H

View File

@@ -0,0 +1,130 @@
/*
* ReactOS kernel
* Copyright (C) 2002, 2003 ReactOS Team
*
* 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.
*/
/* $Id: inffile.h,v 1.1 2003/05/25 21:17:30 ekohl Exp $
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS text-mode setup
* FILE: subsys/system/usetup/infcache.h
* PURPOSE: INF file parser that caches contents of INF file in memory
* PROGRAMMER: Royce Mitchell III
* Eric Kohl
*/
#ifndef __INFCACHE_H__
#define __INFCACHE_H__
#define STATUS_BAD_SECTION_NAME_LINE (0xC0700001)
#define STATUS_SECTION_NAME_TOO_LONG (0xC0700002)
#define STATUS_WRONG_INF_STYLE (0xC0700003)
#define STATUS_NOT_ENOUGH_MEMORY (0xC0700004)
#define MAX_INF_STRING_LENGTH 512
typedef PU32 HINF, *PHINF;
typedef struct _INFCONTEXT
{
PVOID Inf;
// PVOID CurrentInf;
PVOID Section;
PVOID Line;
} INFCONTEXT, *PINFCONTEXT;
/* FUNCTIONS ****************************************************************/
BOOLEAN
InfOpenFile (PHINF InfHandle,
PCHAR FileName,
PU32 ErrorLine);
VOID
InfCloseFile (HINF InfHandle);
BOOLEAN
InfFindFirstLine (HINF InfHandle,
PCHAR Section,
PCHAR Key,
PINFCONTEXT Context);
BOOLEAN
InfFindNextLine (PINFCONTEXT ContextIn,
PINFCONTEXT ContextOut);
BOOLEAN
InfFindFirstMatchLine (PINFCONTEXT ContextIn,
PCHAR Key,
PINFCONTEXT ContextOut);
BOOLEAN
InfFindNextMatchLine (PINFCONTEXT ContextIn,
PCHAR Key,
PINFCONTEXT ContextOut);
S32
InfGetLineCount (HINF InfHandle,
PCHAR Section);
S32
InfGetFieldCount (PINFCONTEXT Context);
BOOLEAN
InfGetBinaryField (PINFCONTEXT Context,
U32 FieldIndex,
PU8 ReturnBuffer,
U32 ReturnBufferSize,
PU32 RequiredSize);
BOOLEAN
InfGetIntField (PINFCONTEXT Context,
U32 FieldIndex,
S32 *IntegerValue);
BOOLEAN
InfGetMultiSzField (PINFCONTEXT Context,
U32 FieldIndex,
PCHAR ReturnBuffer,
U32 ReturnBufferSize,
PU32 RequiredSize);
BOOLEAN
InfGetStringField (PINFCONTEXT Context,
U32 FieldIndex,
PCHAR ReturnBuffer,
U32 ReturnBufferSize,
PU32 RequiredSize);
BOOLEAN
InfGetData (PINFCONTEXT Context,
PCHAR *Key,
PCHAR *Data);
BOOLEAN
InfGetDataField (PINFCONTEXT Context,
U32 FieldIndex,
PCHAR *Data);
#endif /* __INFCACHE_H__ */
/* EOF */

View File

@@ -0,0 +1,35 @@
/*
* FreeLoader
* Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>
*
* 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.
*/
#ifndef __PARSEINI_H
#define __PARSEINI_H
BOOL IniFileInitialize(VOID);
BOOL IniOpenSection(PUCHAR SectionName, U32* SectionId);
U32 IniGetNumSectionItems(U32 SectionId);
U32 IniGetSectionSettingNameSize(U32 SectionId, U32 SettingIndex);
U32 IniGetSectionSettingValueSize(U32 SectionId, U32 SettingIndex);
BOOL IniReadSettingByNumber(U32 SectionId, U32 SettingNumber, PUCHAR SettingName, U32 NameSize, PUCHAR SettingValue, U32 ValueSize);
BOOL IniReadSettingByName(U32 SectionId, PUCHAR SettingName, PUCHAR Buffer, U32 BufferSize);
BOOL IniAddSection(PUCHAR SectionName, U32* SectionId);
BOOL IniAddSettingValueToSection(U32 SectionId, PUCHAR SettingName, PUCHAR SettingValue);
#endif // defined __PARSEINI_H

View File

@@ -0,0 +1,46 @@
/*
* FreeLoader
* Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>
*
* 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.
*/
#ifndef __KEYCODES_H
#define __KEYCODES_H
// Key codes
#define KEY_EXTENDED 0x00
#define KEY_ENTER 0x0D
#define KEY_BACKSPACE 0x08
#define KEY_SPACE 0x20
#define KEY_UP 0x48
#define KEY_DOWN 0x50
#define KEY_LEFT 0x4B
#define KEY_RIGHT 0x4D
#define KEY_ESC 0x1B
#define KEY_F1 0x3B
#define KEY_F2 0x3C
#define KEY_F3 0x3D
#define KEY_F4 0x3E
#define KEY_F5 0x3F
#define KEY_F6 0x40
#define KEY_F7 0x41
#define KEY_F8 0x42
#define KEY_F9 0x43
#define KEY_F10 0x44
#endif // #defined __KEYCODES_H

View File

@@ -0,0 +1,139 @@
/*
* FreeLoader
* Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>
*
* 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.
*/
#include <fs.h>
#ifndef __LINUX_H
#define __LINUX_H
#define LINUX_LOADER_TYPE_LILO 0x01
#define LINUX_LOADER_TYPE_LOADLIN 0x11
#define LINUX_LOADER_TYPE_BOOTSECT 0x21
#define LINUX_LOADER_TYPE_SYSLINUX 0x31
#define LINUX_LOADER_TYPE_ETHERBOOT 0x41
#define LINUX_LOADER_TYPE_FREELOADER 0x81
#define LINUX_COMMAND_LINE_MAGIC 0xA33F
#define LINUX_SETUP_HEADER_ID 0x53726448 // 'HdrS'
#define LINUX_BOOT_SECTOR_MAGIC 0xAA55
#define LINUX_KERNEL_LOAD_ADDRESS 0x100000
#define LINUX_FLAG_LOAD_HIGH 0x01
#define LINUX_FLAG_CAN_USE_HEAP 0x80
#define LINUX_MAX_INITRD_ADDRESS 0x38000000
typedef struct
{
U8 BootCode1[0x20];
U16 CommandLineMagic;
U16 CommandLineOffset;
U8 BootCode2[0x1CD];
U8 SetupSectors;
U16 RootFlags;
U16 SystemSize;
U16 SwapDevice;
U16 RamSize;
U16 VideoMode;
U16 RootDevice;
U16 BootFlag; // 0xAA55
} PACKED LINUX_BOOTSECTOR, *PLINUX_BOOTSECTOR;
typedef struct
{
U8 JumpInstruction[2];
U32 SetupHeaderSignature; // Signature for SETUP-header
U16 Version; // Version number of header format
U16 RealModeSwitch; // Default switch
U16 SetupSeg; // SETUPSEG
U16 StartSystemSeg;
U16 KernelVersion; // Offset to kernel version string
U8 TypeOfLoader; // Loader ID
// =0, old one (LILO, Loadlin,
// Bootlin, SYSLX, bootsect...)
// else it is set by the loader:
// 0xTV: T=0 for LILO
// T=1 for Loadlin
// T=2 for bootsect-loader
// T=3 for SYSLX
// T=4 for ETHERBOOT
// V = version
U8 LoadFlags; // flags, unused bits must be zero (RFU)
// LOADED_HIGH = 1
// bit within loadflags,
// if set, then the kernel is loaded high
// CAN_USE_HEAP = 0x80
// if set, the loader also has set heap_end_ptr
// to tell how much space behind setup.S
// can be used for heap purposes.
// Only the loader knows what is free!
U16 SetupMoveSize; // size to move, when we (setup) are not
// loaded at 0x90000. We will move ourselves
// to 0x90000 then just before jumping into
// the kernel. However, only the loader
// know how much of data behind us also needs
// to be loaded.
U32 Code32Start; // here loaders can put a different
// start address for 32-bit code.
//
// 0x1000 = default for zImage
//
// 0x100000 = default for big kernel
U32 RamdiskAddress; // address of loaded ramdisk image
// Here the loader (or kernel generator) puts
// the 32-bit address were it loaded the image.
U32 RamdiskSize; // its size in bytes
U16 BootSectKludgeOffset;
U16 BootSectKludgeSegment;
U16 HeapEnd; // space from here (exclusive) down to
// end of setup code can be used by setup
// for local heap purposes.
U16 Pad1;
U32 CommandLinePointer; // 32-bit pointer to the kernel command line
U32 InitrdAddressMax; // Highest legal initrd address
} PACKED LINUX_SETUPSECTOR, *PLINUX_SETUPSECTOR;
VOID BootNewLinuxKernel(VOID); // Implemented in linux.S
VOID BootOldLinuxKernel(U32 KernelSize); // Implemented in linux.S
VOID LoadAndBootLinux(PUCHAR OperatingSystemName, PUCHAR Description);
BOOL LinuxParseIniSection(PUCHAR OperatingSystemName);
BOOL LinuxReadBootSector(PFILE LinuxKernelFile);
BOOL LinuxReadSetupSector(PFILE LinuxKernelFile);
BOOL LinuxReadKernel(PFILE LinuxKernelFile);
BOOL LinuxCheckKernelVersion(VOID);
BOOL LinuxReadInitrd(PFILE LinuxInitrdFile);
#endif // defined __LINUX_H

View File

@@ -0,0 +1,99 @@
/* $Id: machine.h,v 1.7 2004/11/28 22:42:40 gvg Exp $
*
* FreeLoader
*
* 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.
*/
#ifndef __MACHINE_H_
#define __MACHINE_H_
#ifndef __DISK_H
#include "disk.h"
#endif
#ifndef __MEMORY_H
#include "mm.h"
#endif
typedef enum tagVIDEODISPLAYMODE
{
VideoTextMode,
VideoGraphicsMode
} VIDEODISPLAYMODE, *PVIDEODISPLAYMODE;
typedef struct tagMACHVTBL
{
VOID (*ConsPutChar)(int Ch);
BOOL (*ConsKbHit)(VOID);
int (*ConsGetCh)(VOID);
VOID (*VideoClearScreen)(U8 Attr);
VIDEODISPLAYMODE (*VideoSetDisplayMode)(char *DisplayMode, BOOL Init);
VOID (*VideoGetDisplaySize)(PU32 Width, PU32 Height, PU32 Depth);
U32 (*VideoGetBufferSize)(VOID);
VOID (*VideoSetTextCursorPosition)(U32 X, U32 Y);
VOID (*VideoHideShowTextCursor)(BOOL Show);
VOID (*VideoPutChar)(int Ch, U8 Attr, unsigned X, unsigned Y);
VOID (*VideoCopyOffScreenBufferToVRAM)(PVOID Buffer);
BOOL (*VideoIsPaletteFixed)(VOID);
VOID (*VideoSetPaletteColor)(U8 Color, U8 Red, U8 Green, U8 Blue);
VOID (*VideoGetPaletteColor)(U8 Color, U8* Red, U8* Green, U8* Blue);
VOID (*VideoSync)(VOID);
VOID (*VideoPrepareForReactOS)(VOID);
U32 (*GetMemoryMap)(PBIOS_MEMORY_MAP BiosMemoryMap, U32 MaxMemoryMapSize);
BOOL (*DiskReadLogicalSectors)(U32 DriveNumber, U64 SectorNumber, U32 SectorCount, PVOID Buffer);
BOOL (*DiskGetPartitionEntry)(U32 DriveNumber, U32 PartitionNumber, PPARTITION_TABLE_ENTRY PartitionTableEntry);
BOOL (*DiskGetDriveGeometry)(U32 DriveNumber, PGEOMETRY DriveGeometry);
U32 (*DiskGetCacheableBlockCount)(U32 DriveNumber);
VOID (*RTCGetCurrentDateTime)(PU32 Year, PU32 Month, PU32 Day, PU32 Hour, PU32 Minute, PU32 Second);
VOID (*HwDetect)(VOID);
} MACHVTBL, *PMACHVTBL;
VOID MachInit(VOID);
extern MACHVTBL MachVtbl;
#define MachConsPutChar(Ch) MachVtbl.ConsPutChar(Ch)
#define MachConsKbHit() MachVtbl.ConsKbHit()
#define MachConsGetCh() MachVtbl.ConsGetCh()
#define MachVideoClearScreen(Attr) MachVtbl.VideoClearScreen(Attr)
#define MachVideoSetDisplayMode(Mode, Init) MachVtbl.VideoSetDisplayMode((Mode), (Init))
#define MachVideoGetDisplaySize(W, H, D) MachVtbl.VideoGetDisplaySize((W), (H), (D))
#define MachVideoGetBufferSize() MachVtbl.VideoGetBufferSize()
#define MachVideoSetTextCursorPosition(X, Y) MachVtbl.VideoSetTextCursorPosition((X), (Y))
#define MachVideoHideShowTextCursor(Show) MachVtbl.VideoHideShowTextCursor(Show)
#define MachVideoPutChar(Ch, Attr, X, Y) MachVtbl.VideoPutChar((Ch), (Attr), (X), (Y))
#define MachVideoCopyOffScreenBufferToVRAM(Buf) MachVtbl.VideoCopyOffScreenBufferToVRAM(Buf)
#define MachVideoIsPaletteFixed() MachVtbl.VideoIsPaletteFixed()
#define MachVideoSetPaletteColor(Col, R, G, B) MachVtbl.VideoSetPaletteColor((Col), (R), (G), (B))
#define MachVideoGetPaletteColor(Col, R, G, B) MachVtbl.VideoGetPaletteColor((Col), (R), (G), (B))
#define MachVideoSync() MachVtbl.VideoSync()
#define MachVideoPrepareForReactOS() MachVtbl.VideoPrepareForReactOS()
#define MachGetMemoryMap(MMap, Size) MachVtbl.GetMemoryMap((MMap), (Size))
#define MachDiskReadLogicalSectors(Drive, Start, Count, Buf) MachVtbl.DiskReadLogicalSectors((Drive), (Start), (Count), (Buf))
#define MachDiskGetPartitionEntry(Drive, Part, Entry) MachVtbl.DiskGetPartitionEntry((Drive), (Part), (Entry))
#define MachDiskGetDriveGeometry(Drive, Geom) MachVtbl.DiskGetDriveGeometry((Drive), (Geom))
#define MachDiskGetCacheableBlockCount(Drive) MachVtbl.DiskGetCacheableBlockCount(Drive)
#define MachRTCGetCurrentDateTime(Y, Mo, D, H, Mi, S) MachVtbl.RTCGetCurrentDateTime((Y), (Mo), (D), (H), (Mi), (S));
#define MachHwDetect() MachVtbl.HwDetect()
#endif /* __MACHINE_H_ */
/* EOF */

Some files were not shown because too many files have changed in this diff Show More