APPLE PUBLIC SOURCE LICENSE
-Version 1.1 - April 19,1999
+Version 2.0 - August 6, 2003
Please read this License carefully before downloading this software.
-By downloading and using this software, you are agreeing to be bound
-by the terms of this License. If you do not or cannot agree to the
-terms of this License, please do not download or use the software.
-
-1. General; Definitions. This License applies to any program or other
-work which Apple Computer, Inc. ("Apple") publicly announces as
-subject to this Apple Public Source License and which contains a
-notice placed by Apple identifying such program or work as "Original
-Code" and stating that it is subject to the terms of this Apple Public
-Source License version 1.1 (or subsequent version thereof), as it may
-be revised from time to time by Apple ("License"). As used in this
-License:
-
-1.1 "Affected Original Code" means only those specific portions of
-Original Code that allegedly infringe upon any party's intellectual
-property rights or are otherwise the subject of a claim of
-infringement.
-
-1.2 "Applicable Patent Rights" mean: (a) in the case where Apple is
+By downloading or using this software, you are agreeing to be bound by
+the terms of this License. If you do not or cannot agree to the terms
+of this License, please do not download or use the software.
+
+1. General; Definitions. This License applies to any program or other
+work which Apple Computer, Inc. ("Apple") makes publicly available and
+which contains a notice placed by Apple identifying such program or
+work as "Original Code" and stating that it is subject to the terms of
+this Apple Public Source License version 2.0 ("License"). As used in
+this License:
+
+1.1 "Applicable Patent Rights" mean: (a) in the case where Apple is
the grantor of rights, (i) claims of patents that are now or hereafter
acquired, owned by or assigned to Apple and (ii) that cover subject
matter contained in the Original Code, but only to the extent
owned by or assigned to You and (ii) that cover subject matter in Your
Modifications, taken alone or in combination with Original Code.
+1.2 "Contributor" means any person or entity that creates or
+contributes to the creation of Modifications.
+
1.3 "Covered Code" means the Original Code, Modifications, the
combination of Original Code and any Modifications, and/or any
respective portions thereof.
-1.4 "Deploy" means to use, sublicense or distribute Covered Code other
-than for Your internal research and development (R&D), and includes
-without limitation, any and all internal use or distribution of
-Covered Code within Your business or organization except for R&D use,
-as well as direct or indirect sublicensing or distribution of Covered
-Code by You to any third party in any form or manner.
+1.4 "Externally Deploy" means: (a) to sublicense, distribute or
+otherwise make Covered Code available, directly or indirectly, to
+anyone other than You; and/or (b) to use Covered Code, alone or as
+part of a Larger Work, in any way to provide a service, including but
+not limited to delivery of content, through electronic communication
+with a client other than You.
1.5 "Larger Work" means a work which combines Covered Code or portions
thereof with code not governed by the terms of this License.
1.6 "Modifications" mean any addition to, deletion from, and/or change
-to, the substance and/or structure of Covered Code. When code is
+to, the substance and/or structure of the Original Code, any previous
+Modifications, the combination of Original Code and any previous
+Modifications, and/or any respective portions thereof. When code is
released as a series of files, a Modification is: (a) any addition to
or deletion from the contents of a file containing Covered Code;
and/or (b) any new file or other representation of computer program
(object code).
1.9 "You" or "Your" means an individual or a legal entity exercising
-rights under this License. For legal entities, "You" or "Your"
+rights under this License. For legal entities, "You" or "Your"
includes any entity which controls, is controlled by, or is under
common control with, You, where "control" means (a) the power, direct
or indirect, to cause the direction or management of such entity,
(50%) or more of the outstanding shares or beneficial ownership of
such entity.
-2. Permitted Uses; Conditions & Restrictions. Subject to the terms
+2. Permitted Uses; Conditions & Restrictions. Subject to the terms
and conditions of this License, Apple hereby grants You, effective on
the date You accept this License and download the Original Code, a
-world-wide, royalty-free, non- exclusive license, to the extent of
+world-wide, royalty-free, non-exclusive license, to the extent of
Apple's Applicable Patent Rights and copyrights covering the Original
Code, to do the following:
-2.1 You may use, copy, modify and distribute Original Code, with or
-without Modifications, solely for Your internal research and
-development, provided that You must in each instance:
-
-(a) retain and reproduce in all copies of Original Code the copyright
-and other proprietary notices and disclaimers of Apple as they appear
-in the Original Code, and keep intact all notices in the Original Code
-that refer to this License;
-
-(b) include a copy of this License with every copy of Source Code of
-Covered Code and documentation You distribute, and You may not offer
-or impose any terms on such Source Code that alter or restrict this
-License or the recipients' rights hereunder, except as permitted under
-Section 6; and
-
-(c) completely and accurately document all Modifications that you have
-made and the date of each such Modification, designate the version of
-the Original Code you used, prominently include a file carrying such
-information with the Modifications, and duplicate the notice in
-Exhibit A in each file of the Source Code of all such Modifications.
-
-2.2 You may Deploy Covered Code, provided that You must in each
- instance:
-
-(a) satisfy all the conditions of Section 2.1 with respect to the
-Source Code of the Covered Code;
-
-(b) make all Your Deployed Modifications publicly available in Source
-Code form via electronic distribution (e.g. download from a web site)
-under the terms of this License and subject to the license grants set
-forth in Section 3 below, and any additional terms You may choose to
-offer under Section 6. You must continue to make the Source Code of
-Your Deployed Modifications available for as long as you Deploy the
-Covered Code or twelve (12) months from the date of initial
-Deployment, whichever is longer;
-
-(c) if You Deploy Covered Code containing Modifications made by You,
-inform others of how to obtain those Modifications by filling out and
-submitting the information found at
-http://www.apple.com/publicsource/modifications.html, if available;
-and
-
-(d) if You Deploy Covered Code in object code, executable form only,
-include a prominent notice, in the code itself as well as in related
-documentation, stating that Source Code of the Covered Code is
-available under the terms of this License with information on how and
-where to obtain such Source Code.
-
-3. Your Grants. In consideration of, and as a condition to, the
-licenses granted to You under this License:
-
-(a) You hereby grant to Apple and all third parties a non-exclusive,
-royalty-free license, under Your Applicable Patent Rights and other
-intellectual property rights owned or controlled by You, to use,
-reproduce, modify, distribute and Deploy Your Modifications of the
-same scope and extent as Apple's licenses under Sections 2.1 and 2.2;
-and
-
-(b) You hereby grant to Apple and its subsidiaries a non-exclusive,
-worldwide, royalty-free, perpetual and irrevocable license, under Your
-Applicable Patent Rights and other intellectual property rights owned
-or controlled by You, to use, reproduce, execute, compile, display,
-perform, modify or have modified (for Apple and/or its subsidiaries),
-sublicense and distribute Your Modifications, in any form, through
-multiple tiers of distribution.
-
-4. Larger Works. You may create a Larger Work by combining Covered
+2.1 Unmodified Code. You may use, reproduce, display, perform,
+internally distribute within Your organization, and Externally Deploy
+verbatim, unmodified copies of the Original Code, for commercial or
+non-commercial purposes, provided that in each instance:
+
+(a) You must retain and reproduce in all copies of Original Code the
+copyright and other proprietary notices and disclaimers of Apple as
+they appear in the Original Code, and keep intact all notices in the
+Original Code that refer to this License; and
+
+(b) You must include a copy of this License with every copy of Source
+Code of Covered Code and documentation You distribute or Externally
+Deploy, and You may not offer or impose any terms on such Source Code
+that alter or restrict this License or the recipients' rights
+hereunder, except as permitted under Section 6.
+
+2.2 Modified Code. You may modify Covered Code and use, reproduce,
+display, perform, internally distribute within Your organization, and
+Externally Deploy Your Modifications and Covered Code, for commercial
+or non-commercial purposes, provided that in each instance You also
+meet all of these conditions:
+
+(a) You must satisfy all the conditions of Section 2.1 with respect to
+the Source Code of the Covered Code;
+
+(b) You must duplicate, to the extent it does not already exist, the
+notice in Exhibit A in each file of the Source Code of all Your
+Modifications, and cause the modified files to carry prominent notices
+stating that You changed the files and the date of any change; and
+
+(c) If You Externally Deploy Your Modifications, You must make
+Source Code of all Your Externally Deployed Modifications either
+available to those to whom You have Externally Deployed Your
+Modifications, or publicly available. Source Code of Your Externally
+Deployed Modifications must be released under the terms set forth in
+this License, including the license grants set forth in Section 3
+below, for as long as you Externally Deploy the Covered Code or twelve
+(12) months from the date of initial External Deployment, whichever is
+longer. You should preferably distribute the Source Code of Your
+Externally Deployed Modifications electronically (e.g. download from a
+web site).
+
+2.3 Distribution of Executable Versions. In addition, if You
+Externally Deploy Covered Code (Original Code and/or Modifications) in
+object code, executable form only, You must include a prominent
+notice, in the code itself as well as in related documentation,
+stating that Source Code of the Covered Code is available under the
+terms of this License with information on how and where to obtain such
+Source Code.
+
+2.4 Third Party Rights. You expressly acknowledge and agree that
+although Apple and each Contributor grants the licenses to their
+respective portions of the Covered Code set forth herein, no
+assurances are provided by Apple or any Contributor that the Covered
+Code does not infringe the patent or other intellectual property
+rights of any other entity. Apple and each Contributor disclaim any
+liability to You for claims brought by any other entity based on
+infringement of intellectual property rights or otherwise. As a
+condition to exercising the rights and licenses granted hereunder, You
+hereby assume sole responsibility to secure any other intellectual
+property rights needed, if any. For example, if a third party patent
+license is required to allow You to distribute the Covered Code, it is
+Your responsibility to acquire that license before distributing the
+Covered Code.
+
+3. Your Grants. In consideration of, and as a condition to, the
+licenses granted to You under this License, You hereby grant to any
+person or entity receiving or distributing Covered Code under this
+License a non-exclusive, royalty-free, perpetual, irrevocable license,
+under Your Applicable Patent Rights and other intellectual property
+rights (other than patent) owned or controlled by You, to use,
+reproduce, display, perform, modify, sublicense, distribute and
+Externally Deploy Your Modifications of the same scope and extent as
+Apple's licenses under Sections 2.1 and 2.2 above.
+
+4. Larger Works. You may create a Larger Work by combining Covered
Code with other code not governed by the terms of this License and
-distribute the Larger Work as a single product. In each such
-instance, You must make sure the requirements of this License are
-fulfilled for the Covered Code or any portion thereof.
+distribute the Larger Work as a single product. In each such instance,
+You must make sure the requirements of this License are fulfilled for
+the Covered Code or any portion thereof.
-5. Limitations on Patent License. Except as expressly stated in
+5. Limitations on Patent License. Except as expressly stated in
Section 2, no other patent rights, express or implied, are granted by
-Apple herein. Modifications and/or Larger Works may require
-additional patent licenses from Apple which Apple may grant in its
-sole discretion.
-
-6. Additional Terms. You may choose to offer, and to charge a fee
-for, warranty, support, indemnity or liability obligations and/or
-other rights consistent with the scope of the license granted herein
-("Additional Terms") to one or more recipients of Covered
-Code. However, You may do so only on Your own behalf and as Your sole
-responsibility, and not on behalf of Apple. You must obtain the
-recipient's agreement that any such Additional Terms are offered by
-You alone, and You hereby agree to indemnify, defend and hold Apple
-harmless for any liability incurred by or claims asserted against
-Apple by reason of any such Additional Terms.
-
-7. Versions of the License. Apple may publish revised and/or new
-versions of this License from time to time. Each version will be
-given a distinguishing version number. Once Original Code has been
-published under a particular version of this License, You may continue
-to use it under the terms of that version. You may also choose to use
-such Original Code under the terms of any subsequent version of this
-License published by Apple. No one other than Apple has the right to
+Apple herein. Modifications and/or Larger Works may require additional
+patent licenses from Apple which Apple may grant in its sole
+discretion.
+
+6. Additional Terms. You may choose to offer, and to charge a fee for,
+warranty, support, indemnity or liability obligations and/or other
+rights consistent with the scope of the license granted herein
+("Additional Terms") to one or more recipients of Covered Code.
+However, You may do so only on Your own behalf and as Your sole
+responsibility, and not on behalf of Apple or any Contributor. You
+must obtain the recipient's agreement that any such Additional Terms
+are offered by You alone, and You hereby agree to indemnify, defend
+and hold Apple and every Contributor harmless for any liability
+incurred by or claims asserted against Apple or such Contributor by
+reason of any such Additional Terms.
+
+7. Versions of the License. Apple may publish revised and/or new
+versions of this License from time to time. Each version will be given
+a distinguishing version number. Once Original Code has been published
+under a particular version of this License, You may continue to use it
+under the terms of that version. You may also choose to use such
+Original Code under the terms of any subsequent version of this
+License published by Apple. No one other than Apple has the right to
modify the terms applicable to Covered Code created under this
License.
-8. NO WARRANTY OR SUPPORT. The Original Code may contain in whole or
-in part pre-release, untested, or not fully tested works. The
-Original Code may contain errors that could cause failures or loss of
-data, and may be incomplete or contain inaccuracies. You expressly
-acknowledge and agree that use of the Original Code, or any portion
-thereof, is at Your sole and entire risk. THE ORIGINAL CODE IS
-PROVIDED "AS IS" AND WITHOUT WARRANTY, UPGRADES OR SUPPORT OF ANY KIND
-AND APPLE AND APPLE'S LICENSOR(S) (FOR THE PURPOSES OF SECTIONS 8 AND
-9, APPLE AND APPLE'S LICENSOR(S) ARE COLLECTIVELY REFERRED TO AS
-"APPLE") EXPRESSLY DISCLAIM ALL WARRANTIES AND/OR CONDITIONS, EXPRESS
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-AND/OR CONDITIONS OF MERCHANTABILITY OR SATISFACTORY QUALITY AND
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY
-RIGHTS. APPLE DOES NOT WARRANT THAT THE FUNCTIONS CONTAINED IN THE
-ORIGINAL CODE WILL MEET YOUR REQUIREMENTS, OR THAT THE OPERATION OF
-THE ORIGINAL CODE WILL BE UNINTERRUPTED OR ERROR- FREE, OR THAT
-DEFECTS IN THE ORIGINAL CODE WILL BE CORRECTED. NO ORAL OR WRITTEN
-INFORMATION OR ADVICE GIVEN BY APPLE OR AN APPLE AUTHORIZED
-REPRESENTATIVE SHALL CREATE A WARRANTY OR IN ANY WAY INCREASE THE
-SCOPE OF THIS WARRANTY. You acknowledge that the Original Code is not
-intended for use in the operation of nuclear facilities, aircraft
-navigation, communication systems, or air traffic control machines in
-which case the failure of the Original Code could lead to death,
-personal injury, or severe physical or environmental damage.
-
-9. Liability.
-
-9.1 Infringement. If any portion of, or functionality implemented by,
-the Original Code becomes the subject of a claim of infringement,
-Apple may, at its option: (a) attempt to procure the rights necessary
-for Apple and You to continue using the Affected Original Code; (b)
-modify the Affected Original Code so that it is no longer infringing;
-or (c) suspend Your rights to use, reproduce, modify, sublicense and
-distribute the Affected Original Code until a final determination of
-the claim is made by a court or governmental administrative agency of
-competent jurisdiction and Apple lifts the suspension as set forth
-below. Such suspension of rights will be effective immediately upon
-Apple's posting of a notice to such effect on the Apple web site that
-is used for implementation of this License. Upon such final
-determination being made, if Apple is legally able, without the
-payment of a fee or royalty, to resume use, reproduction,
-modification, sublicensing and distribution of the Affected Original
-Code, Apple will lift the suspension of rights to the Affected
-Original Code by posting a notice to such effect on the Apple web site
-that is used for implementation of this License. If Apple suspends
-Your rights to Affected Original Code, nothing in this License shall
-be construed to restrict You, at Your option and subject to applicable
-law, from replacing the Affected Original Code with non-infringing
-code or independently negotiating for necessary rights from such third
-party.
-
-9.2 LIMITATION OF LIABILITY. UNDER NO CIRCUMSTANCES SHALL APPLE BE
-LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES
-ARISING OUT OF OR RELATING TO THIS LICENSE OR YOUR USE OR INABILITY TO
-USE THE ORIGINAL CODE, OR ANY PORTION THEREOF, WHETHER UNDER A THEORY
-OF CONTRACT, WARRANTY, TORT (INCLUDING NEGLIGENCE), PRODUCTS LIABILITY
-OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGES AND NOTWITHSTANDING THE FAILURE OF ESSENTIAL PURPOSE OF
-ANY REMEDY. In no event shall Apple's total liability to You for all
-damages under this License exceed the amount of fifty dollars
-($50.00).
-
-10. Trademarks. This License does not grant any rights to use the
-trademarks or trade names "Apple", "Apple Computer", "Mac OS X", "Mac
-OS X Server" or any other trademarks or trade names belonging to Apple
-(collectively "Apple Marks") and no Apple Marks may be used to endorse
-or promote products derived from the Original Code other than as
-permitted by and in strict compliance at all times with Apple's third
-party trademark usage guidelines which are posted at
-http://www.apple.com/legal/guidelinesfor3rdparties.html.
-
-11. Ownership. Apple retains all rights, title and interest in and to
-the Original Code and any Modifications made by or on behalf of Apple
-("Apple Modifications"), and such Apple Modifications will not be
-automatically subject to this License. Apple may, at its sole
-discretion, choose to license such Apple Modifications under this
-License, or on different terms from those contained in this License or
-may choose not to license them at all. Apple's development, use,
-reproduction, modification, sublicensing and distribution of Covered
-Code will not be subject to this License.
+8. NO WARRANTY OR SUPPORT. The Covered Code may contain in whole or in
+part pre-release, untested, or not fully tested works. The Covered
+Code may contain errors that could cause failures or loss of data, and
+may be incomplete or contain inaccuracies. You expressly acknowledge
+and agree that use of the Covered Code, or any portion thereof, is at
+Your sole and entire risk. THE COVERED CODE IS PROVIDED "AS IS" AND
+WITHOUT WARRANTY, UPGRADES OR SUPPORT OF ANY KIND AND APPLE AND
+APPLE'S LICENSOR(S) (COLLECTIVELY REFERRED TO AS "APPLE" FOR THE
+PURPOSES OF SECTIONS 8 AND 9) AND ALL CONTRIBUTORS EXPRESSLY DISCLAIM
+ALL WARRANTIES AND/OR CONDITIONS, EXPRESS OR IMPLIED, INCLUDING, BUT
+NOT LIMITED TO, THE IMPLIED WARRANTIES AND/OR CONDITIONS OF
+MERCHANTABILITY, OF SATISFACTORY QUALITY, OF FITNESS FOR A PARTICULAR
+PURPOSE, OF ACCURACY, OF QUIET ENJOYMENT, AND NONINFRINGEMENT OF THIRD
+PARTY RIGHTS. APPLE AND EACH CONTRIBUTOR DOES NOT WARRANT AGAINST
+INTERFERENCE WITH YOUR ENJOYMENT OF THE COVERED CODE, THAT THE
+FUNCTIONS CONTAINED IN THE COVERED CODE WILL MEET YOUR REQUIREMENTS,
+THAT THE OPERATION OF THE COVERED CODE WILL BE UNINTERRUPTED OR
+ERROR-FREE, OR THAT DEFECTS IN THE COVERED CODE WILL BE CORRECTED. NO
+ORAL OR WRITTEN INFORMATION OR ADVICE GIVEN BY APPLE, AN APPLE
+AUTHORIZED REPRESENTATIVE OR ANY CONTRIBUTOR SHALL CREATE A WARRANTY.
+You acknowledge that the Covered Code is not intended for use in the
+operation of nuclear facilities, aircraft navigation, communication
+systems, or air traffic control machines in which case the failure of
+the Covered Code could lead to death, personal injury, or severe
+physical or environmental damage.
+
+9. LIMITATION OF LIABILITY. TO THE EXTENT NOT PROHIBITED BY LAW, IN NO
+EVENT SHALL APPLE OR ANY CONTRIBUTOR BE LIABLE FOR ANY INCIDENTAL,
+SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR RELATING
+TO THIS LICENSE OR YOUR USE OR INABILITY TO USE THE COVERED CODE, OR
+ANY PORTION THEREOF, WHETHER UNDER A THEORY OF CONTRACT, WARRANTY,
+TORT (INCLUDING NEGLIGENCE), PRODUCTS LIABILITY OR OTHERWISE, EVEN IF
+APPLE OR SUCH CONTRIBUTOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES AND NOTWITHSTANDING THE FAILURE OF ESSENTIAL PURPOSE OF ANY
+REMEDY. SOME JURISDICTIONS DO NOT ALLOW THE LIMITATION OF LIABILITY OF
+INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS LIMITATION MAY NOT APPLY
+TO YOU. In no event shall Apple's total liability to You for all
+damages (other than as may be required by applicable law) under this
+License exceed the amount of fifty dollars ($50.00).
+
+10. Trademarks. This License does not grant any rights to use the
+trademarks or trade names "Apple", "Apple Computer", "Mac", "Mac OS",
+"QuickTime", "QuickTime Streaming Server" or any other trademarks,
+service marks, logos or trade names belonging to Apple (collectively
+"Apple Marks") or to any trademark, service mark, logo or trade name
+belonging to any Contributor. You agree not to use any Apple Marks in
+or as part of the name of products derived from the Original Code or
+to endorse or promote products derived from the Original Code other
+than as expressly permitted by and in strict compliance at all times
+with Apple's third party trademark usage guidelines which are posted
+at http://www.apple.com/legal/guidelinesfor3rdparties.html.
+
+11. Ownership. Subject to the licenses granted under this License,
+each Contributor retains all rights, title and interest in and to any
+Modifications made by such Contributor. Apple retains all rights,
+title and interest in and to the Original Code and any Modifications
+made by or on behalf of Apple ("Apple Modifications"), and such Apple
+Modifications will not be automatically subject to this License. Apple
+may, at its sole discretion, choose to license such Apple
+Modifications under this License, or on different terms from those
+contained in this License or may choose not to license them at all.
12. Termination.
-12.1 Termination. This License and the rights granted hereunder will
- terminate:
+12.1 Termination. This License and the rights granted hereunder will
+terminate:
(a) automatically without notice from Apple if You fail to comply with
any term(s) of this License and fail to cure such breach within 30
-days of becoming aware of such breach; (b) immediately in the event of
-the circumstances described in Section 13.5(b); or (c) automatically
-without notice from Apple if You, at any time during the term of this
-License, commence an action for patent infringement against Apple.
-
-12.2 Effect of Termination. Upon termination, You agree to
-immediately stop any further use, reproduction, modification,
-sublicensing and distribution of the Covered Code and to destroy all
-copies of the Covered Code that are in your possession or control.
-All sublicenses to the Covered Code which have been properly granted
-prior to termination shall survive any termination of this License.
-Provisions which, by their nature, should remain in effect beyond the
-termination of this License shall survive, including but not limited
-to Sections 3, 5, 8, 9, 10, 11, 12.2 and 13. Neither party will be
-liable to the other for compensation, indemnity or damages of any sort
-solely as a result of terminating this License in accordance with its
-terms, and termination of this License will be without prejudice to
-any other right or remedy of either party.
-
-13. Miscellaneous.
-
-13.1 Government End Users. The Covered Code is a "commercial item" as
-defined in FAR 2.101. Government software and technical data rights
-in the Covered Code include only those rights customarily provided to
-the public as defined in this License. This customary commercial
-license in technical data and software is provided in accordance with
-FAR 12.211 (Technical Data) and 12.212 (Computer Software) and, for
+days of becoming aware of such breach;
+
+(b) immediately in the event of the circumstances described in Section
+13.5(b); or
+
+(c) automatically without notice from Apple if You, at any time during
+the term of this License, commence an action for patent infringement
+against Apple; provided that Apple did not first commence
+an action for patent infringement against You in that instance.
+
+12.2 Effect of Termination. Upon termination, You agree to immediately
+stop any further use, reproduction, modification, sublicensing and
+distribution of the Covered Code. All sublicenses to the Covered Code
+which have been properly granted prior to termination shall survive
+any termination of this License. Provisions which, by their nature,
+should remain in effect beyond the termination of this License shall
+survive, including but not limited to Sections 3, 5, 8, 9, 10, 11,
+12.2 and 13. No party will be liable to any other for compensation,
+indemnity or damages of any sort solely as a result of terminating
+this License in accordance with its terms, and termination of this
+License will be without prejudice to any other right or remedy of
+any party.
+
+13. Miscellaneous.
+
+13.1 Government End Users. The Covered Code is a "commercial item" as
+defined in FAR 2.101. Government software and technical data rights in
+the Covered Code include only those rights customarily provided to the
+public as defined in this License. This customary commercial license
+in technical data and software is provided in accordance with FAR
+12.211 (Technical Data) and 12.212 (Computer Software) and, for
Department of Defense purchases, DFAR 252.227-7015 (Technical Data --
Commercial Items) and 227.7202-3 (Rights in Commercial Computer
-Software or Computer Software Documentation). Accordingly, all U.S.
+Software or Computer Software Documentation). Accordingly, all U.S.
Government End Users acquire Covered Code with only those rights set
forth herein.
-13.2 Relationship of Parties. This License will not be construed as
+13.2 Relationship of Parties. This License will not be construed as
creating an agency, partnership, joint venture or any other form of
-legal association between You and Apple, and You will not represent to
-the contrary, whether expressly, by implication, appearance or
-otherwise.
+legal association between or among You, Apple or any Contributor, and
+You will not represent to the contrary, whether expressly, by
+implication, appearance or otherwise.
-13.3 Independent Development. Nothing in this License will impair
+13.3 Independent Development. Nothing in this License will impair
Apple's right to acquire, license, develop, have others develop for
it, market and/or distribute technology or products that perform the
same or similar functions as, or otherwise compete with,
Modifications, Larger Works, technology or products that You may
develop, produce, market or distribute.
-13.4 Waiver; Construction. Failure by Apple to enforce any provision
-of this License will not be deemed a waiver of future enforcement of
-that or any other provision. Any law or regulation which provides
-that the language of a contract shall be construed against the drafter
-will not apply to this License.
+13.4 Waiver; Construction. Failure by Apple or any Contributor to
+enforce any provision of this License will not be deemed a waiver of
+future enforcement of that or any other provision. Any law or
+regulation which provides that the language of a contract shall be
+construed against the drafter will not apply to this License.
-13.5 Severability. (a) If for any reason a court of competent
+13.5 Severability. (a) If for any reason a court of competent
jurisdiction finds any provision of this License, or portion thereof,
to be unenforceable, that provision of the License will be enforced to
the maximum extent permissible so as to effect the economic benefits
and intent of the parties, and the remainder of this License will
-continue in full force and effect. (b) Notwithstanding the foregoing,
+continue in full force and effect. (b) Notwithstanding the foregoing,
if applicable law prohibits or restricts You from fully and/or
specifically complying with Sections 2 and/or 3 or prevents the
enforceability of either of those Sections, this License will
the Covered Code and destroy all copies of it that are in your
possession or control.
-13.6 Dispute Resolution. Any litigation or other dispute resolution
+13.6 Dispute Resolution. Any litigation or other dispute resolution
between You and Apple relating to this License shall take place in the
Northern District of California, and You and Apple hereby consent to
the personal jurisdiction of, and venue in, the state and federal
application of the United Nations Convention on Contracts for the
International Sale of Goods is expressly excluded.
-13.7 Entire Agreement; Governing Law. This License constitutes the
+13.7 Entire Agreement; Governing Law. This License constitutes the
entire agreement between the parties with respect to the subject
-matter hereof. This License shall be governed by the laws of the
+matter hereof. This License shall be governed by the laws of the
United States and the State of California, except that body of
California law concerning conflicts of law.
EXHIBIT A.
-"Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
-Reserved. This file contains Original Code and/or Modifications of
-Original Code as defined in and that are subject to the Apple Public
-Source License Version 1.1 (the "License"). You may not use this file
-except in compliance with the License. Please obtain a copy of the
-License at http://www.apple.com/publicsource and read it before using
-this file.
+"Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights
+Reserved.
+
+This file contains Original Code and/or Modifications of Original Code
+as defined in and that are subject to the Apple Public Source License
+Version 2.0 (the 'License'). You may not use this file except in
+compliance with the License. Please obtain a copy of the License at
+http://www.opensource.apple.com/apsl/ and read it before using this
+file.
The Original Code and all software distributed under the License are
-distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
-License for the specific language governing rights and limitations
-under the License."
+FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+Please see the License for the specific language governing rights and
+limitations under the License."
"RC_KANJI=$(RC_KANJI)" \
"JAPANESE=$(JAPANESE)" \
"RC_CFLAGS=$$XCFLAGS" $@ \
- ) || exit $?; \
+ ) || exit $$?; \
else \
echo "========= nothing to build for $$i ========="; \
fi; \
"RC_KANJI=$(RC_KANJI)" \
"JAPANESE=$(JAPANESE)" \
"RC_CFLAGS=$(RC_CFLAGS)" $@ \
- ) || exit $?; \
+ ) || exit $$?; \
done
installsrc:
#import <sys/types.h>
#import <sys/param.h>
-#import <sys/vnode.h>
#import <ufs/fsdir.h>
#include <libkern/OSByteOrder.h>
#import "ufs_byteorder.h"
* Created.
*/
#import <sys/disktab.h>
-#import <sys/vnode.h>
#import <sys/buf.h>
#import <sys/disk.h>
#import <ufs/fs.h>
-MD -dependency-file $(OBJROOT)/$*.d
md -u $(OBJROOT)/Makedep -f -d $(OBJROOT)/$*.d
+$(OBJROOT)/%.o: %.c
+ $(CC) $(CFLAGS) $(DEFINES) -c $(INC) $< -o $(OBJROOT)/$*.o \
+ -MD -dependency-file $(OBJROOT)/$*.d
+ md -u $(OBJROOT)/Makedep -f -d $(OBJROOT)/$*.d
+
+$(OBJROOT)/%.o: %.m
+ $(CC) $(CFLAGS) $(DEFINES) -c $(INC) $< -o $(OBJROOT)/$*.o \
+ -MD -dependency-file $(OBJROOT)/$*.d
+ md -u $(OBJROOT)/Makedep -f -d $(OBJROOT)/$*.d
+
#.s.o:
# cc $(INC) -E $< > $(OBJROOT)/$*.o2
# $(AS) -o $(OBJROOT)/$@ $(OBJROOT)/$*.o2
.s.o:
cc -c $(INC) -arch i386 -o $(OBJROOT)/$(@F) $<
+$(OBJROOT)/%.o: %.s
+ cc -c $(INC) -arch i386 -o $(OBJROOT)/$(@F) $<
+
$(DIRS_NEEDED) $(INSTALLDIR) $(SRCROOT):
$(MKDIRS) $@
endif
AS = as
LD = ld
-# LIBS= -lc_static
#
# these paths are only valid in subdirectories of this directory
VPATH = $(OBJROOT):$(SYMROOT)
# The order of building is important.
-SUBDIRS = rcz util libsa libsaio nasm boot2 boot1 boot1u boot0 cdboot strings
+SUBDIRS = util libsa libsaio nasm boot2 boot1 boot1u boot0 cdboot strings
all tags clean debug install installhdrs:
@for i in ${SUBDIRS}; \
"RC_KANJI=$(RC_KANJI)" \
"JAPANESE=$(JAPANESE)" \
"RC_CFLAGS=$(RC_CFLAGS)" $@ \
- ) || exit $?; \
+ ) || exit $$?; \
done
installsrc:
INSTALLDIR = $(DSTROOT)/usr/standalone/i386
DIRS_NEEDED = $(SYMROOT)
-all: $(DIRS_NEEDED) boot0
+all: $(DIRS_NEEDED) boot0 chain0
boot0: boot0.s Makefile $(NASM)
$(NASM) boot0.s -o $(SYMROOT)/$@
+chain0: chain0.s Makefile $(NASM)
+ $(NASM) chain0.s -o $(SYMROOT)/$@
+
install_i386:: all $(INSTALLDIR)
- cp $(SYMROOT)/boot0 $(INSTALLDIR)
+ cp $(SYMROOT)/boot0 $(SYMROOT)/chain0 $(INSTALLDIR)
cd $(INSTALLDIR); chmod u+w boot0
+clean::
+ rm -f $(SYMROOT)/boot0 $(SYMROOT)/chain0
+
include ../MakeInc.dir
#dependencies
-; Copyright (c) 1999-2002 Apple Computer, Inc. All rights reserved.
+; Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved.
;
; @APPLE_LICENSE_HEADER_START@
;
-; Portions Copyright (c) 1999-2002 Apple Computer, Inc. All Rights
+; Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights
; Reserved. This file contains Original Code and/or Modifications of
; Original Code as defined in and that are subject to the Apple Public
-; Source License Version 1.2 (the "License"). You may not use this file
+; Source License Version 2.0 (the "License"). You may not use this file
; except in compliance with the License. Please obtain a copy of the
; License at http://www.apple.com/publicsource and read it before using
; this file.
;
EXT_PART_SUPPORT EQU 1
+CHS_SUPPORT EQU 1
+
;
; Various constants.
;
DebugChar('>')
- mov dl, kDriveNumber ; starting BIOS drive number
-
.loop:
%if DEBUG
; Clear various flags in memory.
;
xor eax, eax
- mov [ebios_lba], eax ; clear EBIOS LBA offset
- mov [ebios_present], al ; clear EBIOS support flag
+ mov [first_part], eax ; clear EBIOS LBA offset
+ mov [this_part], eax
+%if CHS_SUPPORT
+ mov [ebios_present], al ; clear EBIOS support flag
+
;
; Check if EBIOS is supported for this hard drive.
;
mov ah, 0x41 ; Function 0x41
mov bx, 0x55AA ; check signature
-; mov dl, kDriveNumber ; Drive number
int 0x13
;
setnz [ebios_present] ; EBIOS supported, set flag
DebugChar('E') ; EBIOS supported
.ebios_check_done:
+%else
+ inc al
+ mov [ebios_present], al
+%endif
;
; Since this code may not always reside in the MBR, always start by
mov es, bx ; MBR load segment = 0
mov bx, kMBRBuffer ; MBR load address
mov si, bx ; pointer to fake partition entry
+%if CHS_SUPPORT
mov WORD [si], 0x0000 ; CHS DX: head = 0
mov WORD [si + 2], 0x0001 ; CHS CX: cylinder = 0, sector = 1
+%endif
+ mov DWORD [si + part.lba], 0x00000000 ; LBA sector 0
call load
jc .next_drive ; MBR load error
; which is at offset kMBRPartTable.
;
mov di, kMBRPartTable ; pointer to partition table
- mov ah, 0 ; initial nesting level is 0
call find_boot ; will not return on success
.next_drive:
test dl, 0x4 ; went through all 4 drives?
jz .loop ; not yet, loop again
+error:
mov si, boot_error_str
call print_string
hang:
+ hlt
jmp SHORT hang
;--------------------------------------------------------------------------
; Find the active (boot) partition and load the booter from the partition.
;
; Arguments:
-; AH = recursion nesting level
; DL = drive number (0x80 + unit number)
; DI = pointer to fdisk partition table.
;
; Clobber list:
-; AX, BX, EBP
+; EAX, BX, EBP
;
find_boot:
push cx ; preserve CX and SI
; entries.
;
cmp WORD [di + part_size * kPartCount], kBootSignature
- jne .exit ; boot signature not found
+ jne NEAR .exit ; boot signature not found
mov si, di ; make SI a pointer to partition table
mov cx, kPartCount ; number of partition entries per table
; buffering scheme used to store extended partition tables.
;
%if DEBUG
- mov al, ah ; indent based on nesting level
- call print_spaces
mov al, [si + part.type] ; print partition type
call print_hex
%endif
+ cmp BYTE [si + part.type], 0
+ je .continue
cmp BYTE [si + part.bootid], kPartActive
jne .continue
DebugChar('*')
+ ; fix offset for load
+ mov eax, [this_part]
+ mov [first_part], eax
+
;
; Found boot partition, read boot sector to memory.
;
mov es, bx
mov bx, kBoot0LoadAddr
call load ; will not return on success
- jc .continue ; load error, keep looking?
+ jc error ; load error, keep looking?
;
; Fix up absolute block location in partition record.
;
mov eax, [si + part.lba]
- add eax, [ebios_lba]
+ add eax, [this_part]
mov [si + part.lba], eax
-
+
+ DebugChar('J')
;
; Jump to partition booter. The drive number is already in register DL.
; SI is pointing to the modified partition entry.
jmp .exit ; boot partition not found
.ext_load:
+ DebugChar('L')
+
+ ; Save current partition offset, since for extended
+ ; partitions we will overwrite it when loading the new
+ ; table.
+ ;
+ mov ebp, [si + part.lba]
+
;
; Setup the arguments for the load function call to bring the
; extended partition table into memory.
; the extended partition at the head of the chain. Thus it is
; necessary to save the LBA address of the first extended partition.
;
- or ah, ah
+
+ DebugChar('+')
+
+ add ebp, [first_part]
+ mov [this_part], ebp
+
+ mov eax,[first_part]
+ or eax, eax
jnz .ext_find_boot
- mov ebp, [si + part.lba]
- mov [ebios_lba], ebp
+ mov [first_part], ebp
+
+%if DEBUG
+ DebugChar('=')
+ mov eax, ebp
+ call print_hex
+%endif
.ext_find_boot:
+
;
; Call find_boot recursively to scan through the extended partition
; table. Load DI with a pointer to the extended table in memory.
;
- inc ah ; increment recursion level
mov di, kExtPartTable ; partition table pointer
call find_boot ; recursion...
- ;dec ah
;
; Since there is an "unwritten" rule that limits each partition table
;
load:
push cx
+%if CHS_SUPPORT
test BYTE [ebios_present], 1
jz .chs
+%endif
.ebios:
mov cx, 5 ; load retry count
jnc .exit
loop .ebios_loop
+%if CHS_SUPPORT
.chs:
mov cx, 5 ; load retry count
.chs_loop:
call read_chs ; use INT13/F2
jnc .exit
loop .chs_loop
+%endif
.exit
pop cx
ret
+%if CHS_SUPPORT
;--------------------------------------------------------------------------
; read_chs - Read sectors from a partition using CHS addressing.
;
; carry = 0 success
; 1 error
;
-; mov dl, kDriveNumber
mov ah, 0x02 ; Func 2
int 0x13 ; INT 13
jnc .exit
.exit:
popa
ret
+%endif
;--------------------------------------------------------------------------
; read_lba - Read sectors from a partition using LBA addressing.
push ds ; For sake of saving memory,
push ds ; push DS register, which is 0.
- mov ecx, [ebios_lba] ; offset 8, lower 32-bit LBA
+ mov ecx, [first_part] ; offset 8, lower 32-bit LBA
add ecx, [si + part.lba]
push ecx
push WORD 16 ; offset 0-1, packet size
+ DebugChar('<')
+%if DEBUG
+ mov eax, ecx
+ call print_hex
+%endif
+
;
; INT13 Func 42 - Extended Read Sectors
;
; Packet offset 2 indicates the number of sectors read
; successfully.
;
-; mov dl, kDriveNumber
mov si, sp
mov ah, 0x42
int 0x13
ret
-%if DEBUG
-
;--------------------------------------------------------------------------
; Write a ASCII character to the console.
;
popa
ret
+%if DEBUG
+
;--------------------------------------------------------------------------
-; Write a variable number of spaces to the console.
-;
-; Arguments:
-; AL = number to spaces.
-;
-print_spaces:
- pusha
- xor cx, cx
- mov cl, al ; use CX as the loop counter
- mov al, ' ' ; character to print
-.loop:
- jcxz .exit
- call print_char
- loop .loop
-.exit:
- popa
- ret
-
-;--------------------------------------------------------------------------
-; Write the byte value to the console in hex.
+; Write the 4-byte value to the console in hex.
;
; Arguments:
-; AL = Value to be displayed in hex.
+; EAX = Value to be displayed in hex.
;
print_hex:
+ pushad
+ mov cx, WORD 4
+ bswap eax
+.loop
push ax
ror al, 4
call print_nibble ; display upper nibble
pop ax
call print_nibble ; display lower nibble
+ ror eax, 8
+ loop .loop
mov al, 10 ; carriage return
call print_char
mov al, 13
call print_char
+ popad
ret
-
+
print_nibble:
and al, 0x0f
add al, '0'
int 0x16
popa
ret
+%endif ;DEBUG
-%endif ; DEBUG
;--------------------------------------------------------------------------
; NULL terminated strings.
;
-boot_error_str db 10, 13, 'Error', 0
+boot_error_str db 10, 13, 'b0 error', 0
;--------------------------------------------------------------------------
; Pad the rest of the 512 byte sized booter with zeroes. The last
; If the booter code becomes too large, then nasm will complain
; that the 'times' argument is negative.
-;
-; In memory variables.
-;
-ebios_lba dd 0 ; starting LBA of the intial extended partition.
-ebios_present db 0 ; 1 if EBIOS is supported, 0 otherwise.
-
pad_boot
times 446-($-$$) db 0
pad_table_and_sig
times 510-($-$$) db 0
dw kBootSignature
+
+
+ ABSOLUTE 0xE400
+;
+; In memory variables.
+;
+first_part resd 1 ; starting LBA of the intial extended partition.
+this_part resd 1 ; starting LBA of the current extended partition.
+ebios_present resb 1 ; 1 if EBIOS is supported, 0 otherwise.
+
END
--- /dev/null
+; Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved.
+;
+; @APPLE_LICENSE_HEADER_START@
+;
+; Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights
+; Reserved. This file contains Original Code and/or Modifications of
+; Original Code as defined in and that are subject to the Apple Public
+; Source License Version 2.0 (the "License"). You may not use this file
+; except in compliance with the License. Please obtain a copy of the
+; License at http://www.apple.com/publicsource and read it before using
+; this file.
+;
+; The Original Code and all software distributed under the License are
+; distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+; EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+; INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+; FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
+; License for the specific language governing rights and limitations
+; under the License.
+;
+; @APPLE_LICENSE_HEADER_END@
+;
+; Boot Loader: boot0
+;
+; A small boot sector program written in x86 assembly whose only
+; responsibility is to locate the active partition, load the
+; partition booter into memory, and jump to the booter's entry point.
+; It leaves the boot drive in DL and a pointer to the partition entry in SI.
+;
+; This boot loader must be placed in the Master Boot Record.
+;
+; In order to coexist with a fdisk partition table (64 bytes), and
+; leave room for a two byte signature (0xAA55) in the end, boot0 is
+; restricted to 446 bytes (512 - 64 - 2). If boot0 did not have to
+; live in the MBR, then we would have 510 bytes to work with.
+;
+; boot0 is always loaded by the BIOS or another booter to 0:7C00h.
+;
+; This code is written for the NASM assembler.
+; nasm boot0.s -o boot0
+
+
+;
+; Set to 1 to enable obscure debug messages.
+;
+DEBUG EQU 0
+
+;
+; Set to 1 to support loading the partition booter (boot1) from a
+; logical partition.
+;
+EXT_PART_SUPPORT EQU 1
+
+;
+; Various constants.
+;
+kBoot0Segment EQU 0x0000
+kBoot0Stack EQU 0xFFF0 ; boot0 stack pointer
+kBoot0LoadAddr EQU 0x7C00 ; boot0 load address
+kBoot0RelocAddr EQU 0xE000 ; boot0 relocated address
+
+kMBRBuffer EQU 0x1000 ; MBR buffer address
+kExtBuffer EQU 0x1200 ; EXT boot block buffer address
+
+kPartTableOffset EQU 0x1be
+kMBRPartTable EQU kMBRBuffer + kPartTableOffset
+kExtPartTable EQU kExtBuffer + kPartTableOffset
+
+kSectorBytes EQU 512 ; sector size in bytes
+kBootSignature EQU 0xAA55 ; boot sector signature
+
+kPartCount EQU 4 ; number of paritions per table
+kPartTypeBoot EQU 0xab ; boot2 partition type
+kPartTypeUFS EQU 0xa8 ; UFS partition type
+kPartTypeHFS EQU 0xaf ; HFS partition type
+kPartTypeExtDOS EQU 0x05 ; DOS extended partition type
+kPartTypeExtWin EQU 0x0f ; Windows extended partition type
+kPartTypeExtLinux EQU 0x85 ; Linux extended partition type
+
+kPartActive EQU 0x80
+
+;
+; Format of fdisk partition entry.
+;
+; The symbol 'part_size' is automatically defined as an `EQU'
+; giving the size of the structure.
+;
+ struc part
+.bootid: resb 1 ; bootable or not
+.head: resb 1 ; starting head, sector, cylinder
+.sect: resb 1 ;
+.cyl: resb 1 ;
+.type: resb 1 ; partition type
+.endhead resb 1 ; ending head, sector, cylinder
+.endsect: resb 1 ;
+.endcyl: resb 1 ;
+.lba: resd 1 ; starting lba
+.sectors resd 1 ; size in sectors
+ endstruc
+
+;
+; Macros.
+;
+%macro DebugCharMacro 1
+ mov al, %1
+ call print_char
+%endmacro
+
+%if DEBUG
+%define DebugChar(x) DebugCharMacro x
+%else
+%define DebugChar(x)
+%endif
+
+;--------------------------------------------------------------------------
+; Start of text segment.
+
+ SEGMENT .text
+
+ ORG 0xE000 ; must match kBoot0RelocAddr
+
+;--------------------------------------------------------------------------
+; Boot code is loaded at 0:7C00h.
+;
+start
+ ;
+ ; Set up the stack to grow down from kBoot0Segment:kBoot0Stack.
+ ; Interrupts should be off while the stack is being manipulated.
+ ;
+ cli ; interrupts off
+ xor ax, ax ; zero ax
+ mov ss, ax ; ss <- 0
+ mov sp, kBoot0Stack ; sp <- top of stack
+ sti ; reenable interrupts
+
+ mov es, ax ; es <- 0
+ mov ds, ax ; ds <- 0
+
+ ;
+ ; Relocate boot0 code.
+ ;
+ mov si, kBoot0LoadAddr ; si <- source
+ mov di, kBoot0RelocAddr ; di <- destination
+ ;
+ cld ; auto-increment SI and/or DI registers
+ mov cx, kSectorBytes/2 ; copy 256 words
+ repnz movsw ; repeat string move (word) operation
+
+ ; Code relocated, jump to start_reloc in relocated location.
+ ;
+ jmp 0:start_reloc
+
+;--------------------------------------------------------------------------
+; Start execution from the relocated location.
+;
+start_reloc:
+
+ DebugChar('>')
+
+.loop:
+
+%if DEBUG
+ mov al, dl
+ call print_hex
+%endif
+
+ ;
+ ; Clear various flags in memory.
+ ;
+ xor eax, eax
+ mov [ebios_lba], eax ; clear EBIOS LBA offset
+ mov [ebios_present], al ; clear EBIOS support flag
+
+ ;
+ ; Check if EBIOS is supported for this hard drive.
+ ;
+ mov ah, 0x41 ; Function 0x41
+ mov bx, 0x55AA ; check signature
+ int 0x13
+
+ ;
+ ; If successful, the return values are as follows:
+ ;
+ ; carry = 0
+ ; ah = major version of EBIOS extensions (0x21 = version 1.1)
+ ; al = altered
+ ; bx = 0xAA55
+ ; cx = support bits. bit 0 must be set for function 0x42.
+ ;
+ jc .ebios_check_done
+ cmp bx, 0xAA55 ; check BX = 0xAA55
+ jnz .ebios_check_done
+ test cl, 0x01 ; check enhanced drive read support
+ setnz [ebios_present] ; EBIOS supported, set flag
+ DebugChar('E') ; EBIOS supported
+.ebios_check_done:
+
+ ;
+ ; Since this code may not always reside in the MBR, always start by
+ ; loading the MBR to kMBRBuffer.
+ ;
+ mov al, 1 ; load one sector
+ xor bx, bx
+ mov es, bx ; MBR load segment = 0
+ mov bx, kMBRBuffer ; MBR load address
+ mov si, bx ; pointer to fake partition entry
+ mov WORD [si], 0x0000 ; CHS DX: head = 0
+ mov WORD [si + 2], 0x0001 ; CHS CX: cylinder = 0, sector = 1
+ mov DWORD [si + part.lba], 0x00000000 ; LBA sector 0
+
+ call load
+ jc .next_drive ; MBR load error
+
+ ;
+ ; Look for the booter partition in the MBR partition table,
+ ; which is at offset kMBRPartTable.
+ ;
+ mov di, kMBRPartTable ; pointer to partition table
+ mov ah, 0 ; initial nesting level is 0
+ call find_boot ; will not return on success
+
+.next_drive:
+ inc dl ; next drive number
+ test dl, 0x4 ; went through all 4 drives?
+ jz .loop ; not yet, loop again
+
+ mov si, boot_error_str
+ call print_string
+
+hang:
+ jmp SHORT hang
+
+;--------------------------------------------------------------------------
+; Find the active (boot) partition and load the booter from the partition.
+;
+; Arguments:
+; AH = recursion nesting level
+; DL = drive number (0x80 + unit number)
+; DI = pointer to fdisk partition table.
+;
+; Clobber list:
+; AX, BX, EBP
+;
+find_boot:
+ push cx ; preserve CX and SI
+ push si
+
+ ;
+ ; Check for boot block signature 0xAA55 following the 4 partition
+ ; entries.
+ ;
+ cmp WORD [di + part_size * kPartCount], kBootSignature
+ jne NEAR .exit ; boot signature not found
+
+ mov si, di ; make SI a pointer to partition table
+ mov cx, kPartCount ; number of partition entries per table
+
+.loop:
+ ;
+ ; First scan through the partition table looking for the active
+ ; partition. Postpone walking the extended partition chain for
+ ; the second pass. Do not merge the two without changing the
+ ; buffering scheme used to store extended partition tables.
+ ;
+%if DEBUG
+ mov al, ah ; indent based on nesting level
+ call print_spaces
+ mov al, [si + part.type] ; print partition type
+ call print_hex
+%endif
+
+ cmp BYTE [si + part.type], kPartTypeBoot
+ je .found
+ cmp BYTE [si + part.type], kPartTypeUFS
+ je .found
+ cmp BYTE [si + part.type], kPartTypeHFS
+ je .found
+
+ jmp .continue
+
+.found
+ DebugChar('*')
+
+ ;
+ ; Found boot partition, read boot sector to memory.
+ ;
+ mov al, 1
+ mov bx, kBoot0Segment
+ mov es, bx
+ mov bx, kBoot0LoadAddr
+ call load
+ jc .continue ; load error, keep looking?
+
+ ;
+ ; Check signature
+ ;
+ cmp WORD [bx + 510], kBootSignature
+ jne NEAR .exit ; boot signature not found
+
+ DebugChar('&')
+
+ ;
+ ; Fix up absolute block location in partition record.
+ ;
+ mov eax, [si + part.lba]
+ add eax, [ebios_lba]
+ mov [si + part.lba], eax
+
+ DebugChar('%')
+
+ ;
+ ; Jump to partition booter. The drive number is already in register DL.
+ ; SI is pointing to the modified partition entry.
+ ;
+ jmp kBoot0Segment:kBoot0LoadAddr
+
+.continue:
+ add si, part_size ; advance SI to next partition entry
+ loop .loop ; loop through all partition entries
+
+%if EXT_PART_SUPPORT
+ ;
+ ; No primary (or logical) boot partition found in the current
+ ; partition table. Restart and look for extended partitions.
+ ;
+ mov si, di ; make SI a pointer to partition table
+ mov cx, kPartCount ; number of partition entries per table
+
+.ext_loop:
+
+ mov al, [si + part.type] ; AL <- partition type
+
+ cmp al, kPartTypeExtDOS ; Extended DOS
+ je .ext_load
+
+ cmp al, kPartTypeExtWin ; Extended Windows(95)
+ je .ext_load
+
+ cmp al, kPartTypeExtLinux ; Extended Linux
+ je .ext_load
+
+.ext_continue:
+ ;
+ ; Advance si to the next partition entry in the extended
+ ; partition table.
+ ;
+ add si, part_size ; advance SI to next partition entry
+ loop .ext_loop ; loop through all partition entries
+ jmp .exit ; boot partition not found
+
+.ext_load:
+ ;
+ ; Setup the arguments for the load function call to bring the
+ ; extended partition table into memory.
+ ; Remember that SI points to the extended partition entry.
+ ;
+ mov al, 1 ; read 1 sector
+ xor bx, bx
+ mov es, bx ; es = 0
+ mov bx, kExtBuffer ; load extended boot sector
+ call load
+ jc .ext_continue ; load error
+
+ ;
+ ; The LBA address of all extended partitions is relative based
+ ; on the LBA address of the extended partition in the MBR, or
+ ; the extended partition at the head of the chain. Thus it is
+ ; necessary to save the LBA address of the first extended partition.
+ ;
+ or ah, ah
+ jnz .ext_find_boot
+ mov ebp, [si + part.lba]
+ mov [ebios_lba], ebp
+
+.ext_find_boot:
+ ;
+ ; Call find_boot recursively to scan through the extended partition
+ ; table. Load DI with a pointer to the extended table in memory.
+ ;
+ inc ah ; increment recursion level
+ mov di, kExtPartTable ; partition table pointer
+ call find_boot ; recursion...
+ ;dec ah
+
+ ;
+ ; Since there is an "unwritten" rule that limits each partition table
+ ; to have 0 or 1 extended partitions, there is no point in looking for
+ ; any additional extended partition entries at this point. There is no
+ ; boot partition linked beyond the extended partition that was loaded
+ ; above.
+ ;
+
+%endif ; EXT_PART_SUPPORT
+
+.exit:
+ ;
+ ; Boot partition not found. Giving up.
+ ;
+ DebugChar('X')
+ pop si
+ pop cx
+ ret
+
+;--------------------------------------------------------------------------
+; load - Load one or more sectors from a partition.
+;
+; Arguments:
+; AL = number of 512-byte sectors to read.
+; ES:BX = pointer to where the sectors should be stored.
+; DL = drive number (0x80 + unit number)
+; SI = pointer to the partition entry.
+;
+; Returns:
+; CF = 0 success
+; 1 error
+;
+load:
+ push cx
+ test BYTE [ebios_present], 1
+ jz .chs
+
+.ebios:
+ mov cx, 5 ; load retry count
+.ebios_loop:
+ call read_lba ; use INT13/F42
+ jnc .exit
+ loop .ebios_loop
+.chs:
+ mov cx, 5 ; load retry count
+.chs_loop:
+ call read_chs ; use INT13/F2
+ jnc .exit
+ loop .chs_loop
+
+.exit
+ DebugChar('R')
+ pop cx
+ ret
+
+;--------------------------------------------------------------------------
+; read_chs - Read sectors from a partition using CHS addressing.
+;
+; Arguments:
+; AL = number of 512-byte sectors to read.
+; ES:BX = pointer to where the sectors should be stored.
+; DL = drive number (0x80 + unit number)
+; SI = pointer to the partition entry.
+;
+; Returns:
+; CF = 0 success
+; 1 error
+;
+read_chs:
+ pusha ; save all registers
+
+ ;
+ ; Read the CHS start values from the partition entry.
+ ;
+ mov dh, [ si + part.head ] ; drive head
+ mov cx, [ si + part.sect ] ; drive sector + cylinder
+
+ ;
+ ; INT13 Func 2 - Read Disk Sectors
+ ;
+ ; Arguments:
+ ; AH = 2
+ ; AL = number of sectors to read
+ ; CH = lowest 8 bits of the 10-bit cylinder number
+ ; CL = bits 6 & 7: cylinder number bits 8 and 9
+ ; bits 0 - 5: starting sector number (1-63)
+ ; DH = starting head number (0 to 255)
+ ; DL = drive number (80h + drive unit)
+ ; es:bx = pointer where to place sectors read from disk
+ ;
+ ; Returns:
+ ; AH = return status (sucess is 0)
+ ; AL = burst error length if ah=0x11 (ECC corrected)
+ ; carry = 0 success
+ ; 1 error
+ ;
+ mov ah, 0x02 ; Func 2
+ int 0x13 ; INT 13
+ jnc .exit
+
+ DebugChar('r') ; indicate INT13/F2 error
+
+ ;
+ ; Issue a disk reset on error.
+ ; Should this be changed to Func 0xD to skip the diskette controller
+ ; reset?
+ ;
+ xor ax, ax ; Func 0
+ int 0x13 ; INT 13
+ stc ; set carry to indicate error
+
+.exit:
+ popa
+ ret
+
+;--------------------------------------------------------------------------
+; read_lba - Read sectors from a partition using LBA addressing.
+;
+; Arguments:
+; AL = number of 512-byte sectors to read (valid from 1-127).
+; ES:BX = pointer to where the sectors should be stored.
+; DL = drive number (0x80 + unit number)
+; SI = pointer to the partition entry.
+;
+; Returns:
+; CF = 0 success
+; 1 error
+;
+read_lba:
+ pusha ; save all registers
+ mov bp, sp ; save current SP
+
+ ;
+ ; Create the Disk Address Packet structure for the
+ ; INT13/F42 (Extended Read Sectors) on the stack.
+ ;
+
+ ; push DWORD 0 ; offset 12, upper 32-bit LBA
+ push ds ; For sake of saving memory,
+ push ds ; push DS register, which is 0.
+
+ mov ecx, [ebios_lba] ; offset 8, lower 32-bit LBA
+ add ecx, [si + part.lba]
+ push ecx
+
+ push es ; offset 6, memory segment
+
+ push bx ; offset 4, memory offset
+
+ xor ah, ah ; offset 3, must be 0
+ push ax ; offset 2, number of sectors
+
+ push WORD 16 ; offset 0-1, packet size
+
+ ;
+ ; INT13 Func 42 - Extended Read Sectors
+ ;
+ ; Arguments:
+ ; AH = 0x42
+ ; DL = drive number (80h + drive unit)
+ ; DS:SI = pointer to Disk Address Packet
+ ;
+ ; Returns:
+ ; AH = return status (sucess is 0)
+ ; carry = 0 success
+ ; 1 error
+ ;
+ ; Packet offset 2 indicates the number of sectors read
+ ; successfully.
+ ;
+ mov si, sp
+ mov ah, 0x42
+ int 0x13
+
+ jnc .exit
+
+ DebugChar('R') ; indicate INT13/F42 error
+
+ ;
+ ; Issue a disk reset on error.
+ ; Should this be changed to Func 0xD to skip the diskette controller
+ ; reset?
+ ;
+ xor ax, ax ; Func 0
+ int 0x13 ; INT 13
+ stc ; set carry to indicate error
+
+.exit:
+ mov sp, bp ; restore SP
+ popa
+ ret
+
+;--------------------------------------------------------------------------
+; Write a string to the console.
+;
+; Arguments:
+; DS:SI pointer to a NULL terminated string.
+;
+; Clobber list:
+; AX, BX, SI
+;
+print_string
+ mov bx, 1 ; BH=0, BL=1 (blue)
+ cld ; increment SI after each lodsb call
+.loop
+ lodsb ; load a byte from DS:SI into AL
+ cmp al, 0 ; Is it a NULL?
+ je .exit ; yes, all done
+ mov ah, 0xE ; INT10 Func 0xE
+ int 0x10 ; display byte in tty mode
+ jmp short .loop
+.exit
+ ret
+
+
+%if DEBUG
+
+;--------------------------------------------------------------------------
+; Write a ASCII character to the console.
+;
+; Arguments:
+; AL = ASCII character.
+;
+print_char
+ pusha
+ mov bx, 1 ; BH=0, BL=1 (blue)
+ mov ah, 0x0e ; bios INT 10, Function 0xE
+ int 0x10 ; display byte in tty mode
+ popa
+ ret
+
+%if DEBUG
+;--------------------------------------------------------------------------
+; Write a variable number of spaces to the console.
+;
+; Arguments:
+; AL = number to spaces.
+;
+print_spaces:
+ pusha
+ xor cx, cx
+ mov cl, al ; use CX as the loop counter
+ mov al, ' ' ; character to print
+.loop:
+ jcxz .exit
+ call print_char
+ loop .loop
+.exit:
+ popa
+ ret
+%endif
+
+;--------------------------------------------------------------------------
+; Write the byte value to the console in hex.
+;
+; Arguments:
+; AL = Value to be displayed in hex.
+;
+print_hex:
+ push ax
+ ror al, 4
+ call print_nibble ; display upper nibble
+ pop ax
+ call print_nibble ; display lower nibble
+
+ mov al, 10 ; carriage return
+ call print_char
+ mov al, 13
+ call print_char
+ ret
+
+print_nibble:
+ and al, 0x0f
+ add al, '0'
+ cmp al, '9'
+ jna .print_ascii
+ add al, 'A' - '9' - 1
+.print_ascii:
+ call print_char
+ ret
+
+getc:
+ pusha
+ mov ah, 0
+ int 0x16
+ popa
+ ret
+
+%endif ; DEBUG
+
+;--------------------------------------------------------------------------
+; NULL terminated strings.
+;
+boot_error_str db 10, 13, 'Chain booting error', 0
+
+;--------------------------------------------------------------------------
+; Pad the rest of the 512 byte sized booter with zeroes. The last
+; two bytes is the mandatory boot sector signature.
+;
+; If the booter code becomes too large, then nasm will complain
+; that the 'times' argument is negative.
+
+;
+; In memory variables.
+;
+ebios_lba dd 0 ; starting LBA of the intial extended partition.
+ebios_present db 0 ; 1 if EBIOS is supported, 0 otherwise.
+
+pad_boot
+ times 446-($-$$) db 0
+
+pad_table_and_sig
+ times 510-($-$$) db 0
+ dw kBootSignature
+
+ END
NASM = $(SYMROOT)/nasm
-VERSIONED_FILES = boot1h boot1f
+VERSIONED_FILES = boot1h
VERS = `vers_string -f 5.0 | tr - .`
NEW_VERS = Darwin boot1h v$(VERS)
boot1h: boot1.s Makefile
$(NASM) -dBOOTDEV=HDISK -dVERS="'$(NEW_VERS)'" boot1.s -o $(SYMROOT)/$@
-
-boot1f: boot1.s Makefile
- $(NASM) -dBOOTDEV=FLOPPY -dVERS="'$(NEW_VERS)'" boot1.s -o $(SYMROOT)/$@
install_i386:: all $(INSTALLDIR)
cp $(SYMROOT)/boot1h $(INSTALLDIR)/
- cp $(SYMROOT)/boot1f $(INSTALLDIR)/
cd $(INSTALLDIR); chmod u+w $(VERSIONED_FILES)
+clean::
+ rm -f $(SYMROOT)/boot1h
+
include ../MakeInc.dir
-; Copyright (c) 1999-2002 Apple Computer, Inc. All rights reserved.
+; Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved.
;
; @APPLE_LICENSE_HEADER_START@
;
-; Portions Copyright (c) 1999-2002 Apple Computer, Inc. All Rights
+; Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights
; Reserved. This file contains Original Code and/or Modifications of
; Original Code as defined in and that are subject to the Apple Public
-; Source License Version 1.2 (the "License"). You may not use this file
+; Source License Version 2.0 (the "License"). You may not use this file
; except in compliance with the License. Please obtain a copy of the
; License at http://www.apple.com/publicsource and read it before using
; this file.
;
DEBUG EQU 0
-;
-; Set to 1 to support loading the booter (boot2) from a
-; logical partition.
-;
-EXT_PART_SUPPORT EQU 0
-
;
; Various constants.
;
kBoot0LoadAddr EQU 0x7C00 ; boot0 load address
kBoot0RelocAddr EQU 0xE000 ; boot0 relocated address
-ebios_lba EQU 0xEF00 ; storage for variables
-
kMBRBuffer EQU 0x1000 ; MBR buffer address
kExtBuffer EQU 0x1200 ; EXT boot block buffer address
kMBRPartTable EQU kMBRBuffer + kPartTableOffset
kExtPartTable EQU kExtBuffer + kPartTableOffset
-kBoot2Sectors EQU 112 ; sectors to load for boot2
+kBoot2Sectors EQU 126 ; sectors to load for boot2
kBoot2Address EQU 0x0000 ; boot2 load address
kBoot2Segment EQU 0x2000 ; boot2 load segment
;; HFS+ constants
;;
kHFSPlusSig EQU 0x2B48 ; HFS+ volume signature
+kHFSXSig EQU 0x5848 ; HFSX volume signature
kBlockSizeOffset EQU 0x28
kExtentOffset EQU 0x1c0
kHFSPlusExtent EQU kHFSBuffer + kExtentOffset
-%ifdef FLOPPY
-kDriveNumber EQU 0x00
-%else
kDriveNumber EQU 0x80
-%endif
;
; Format of fdisk partition entry.
call getc
%endmacro
+%macro PrintString 1
+ mov si, %1
+ call print_string
+%endmacro
+
%if DEBUG
%define DebugChar(x) DebugCharMacro x
%else
SEGMENT .text
- ORG 0xE000 ; must match kBoot0RelocAddr
+ ORG 0x7C00 ; must match kBoot0RelocAddr
;--------------------------------------------------------------------------
; Boot code is loaded at 0:7C00h.
cmp BYTE [si + part.type], kPartTypeHFS
jne .part_err
- cmp BYTE [si + part.bootid], kPartActive
- jne .part_err
jmp find_startup
.part_err:
- DebugChar('P')
+ PrintString(part_error_str)
jmp hang
;;; ---------------------------------------
DebugChar('}')
mov ax, [kHFSPlusSigAddr]
cmp ax, kHFSPlusSig
+ je .hfs_plus2
+ cmp ax, kHFSXSig
jne startup_err
;;; Now the HFS+ volume header is in our buffer.
+.hfs_plus2
DebugChar('*')
mov eax, [kHFSPlusBlockSize]
bswap eax
dec eax
dec eax
-; add [ebios_lba], eax ; offset to startup file
-; mov ecx, [ebios_lba]
add ecx, eax
DebugChar('!')
startup_err:
+ PrintString(boot2_error_str)
DebugChar('X')
hang:
hlt
jmp SHORT hang
-;--------------------------------------------------------------------------
-; load - Load one or more sectors from a partition.
-;
-; Arguments:
-; AL = number of 512-byte sectors to read.
-; ES:BX = pointer to where the sectors should be stored.
-; ECX = sector offset in partition
-; DL = drive number (0x80 + unit number)
-; SI = pointer to the partition entry.
-;
-; Returns:
-; CF = 0 success
-; 1 error
-;
-; load:
-; ; push cx
-
-; .ebios:
-; ; mov cx, 5 ; load retry count
-; .ebios_loop:
-; call read_lba ; use INT13/F42
-; jnc .exit
-; ; loop .ebios_loop
-
-; .exit
-; pop cx
-; ret
-
;--------------------------------------------------------------------------
; read_lba - Read sectors from a partition using LBA addressing.
pushad ; save all registers
mov bp, sp ; save current SP
-;
+ ;
; Create the Disk Address Packet structure for the
; INT13/F42 (Extended Read Sectors) on the stack.
;
push WORD 16 ; offset 0-1, packet size
-;
+ ;
; INT13 Func 42 - Extended Read Sectors
-;
+ ;
; Arguments:
; AH = 0x42
; DL = drive number (80h + drive unit)
; DS:SI = pointer to Disk Address Packet
-;
+ ;
; Returns:
; AH = return status (sucess is 0)
; carry = 0 success
; 1 error
-;
+ ;
; Packet offset 2 indicates the number of sectors read
; successfully.
;
-; mov dl, kDriveNumber
+ ; mov dl, kDriveNumber
mov si, sp
mov ah, 0x42
int 0x13
popad
ret
-%if 0
;-------------------------------------------------------------------------
; Write a string to the console.
;
jmp short .loop
.exit
ret
-%endif
%if DEBUG
; NULL terminated strings.
;
; boot_error_str db 10, 13, 'Error', 0
+part_error_str db 10, 13, 'HFS+ partition error', 0
+boot2_error_str db 10, 13, 'Error loading booter', 0
;--------------------------------------------------------------------------
; Pad the rest of the 512 byte sized booter with zeroes. The last
; If the booter code becomes too large, then nasm will complain
; that the 'times' argument is negative.
-pad_boot
- times 510-($-$$) db 0
-
-%ifdef FLOPPY
-;--------------------------------------------------------------------------
-; Put fake partition entries for the bootable floppy image
-;
-part1bootid db 0x80 ; first partition active
-part1head db 0x00 ; head #
-part1sect db 0x02 ; sector # (low 6 bits)
-part1cyl db 0x00 ; cylinder # (+ high 2 bits of above)
-part1systid db 0xab ; Apple boot partition
-times 3 db 0x00 ; ignore head/cyl/sect #'s
-part1relsect dd 0x00000001 ; start at sector 1
-part1numsect dd 0x00000080 ; 64K for booter
-part2bootid db 0x00 ; not active
-times 3 db 0x00 ; ignore head/cyl/sect #'s
-part2systid db 0xa8 ; Apple UFS partition
-times 3 db 0x00 ; ignore head/cyl/sect #'s
-part2relsect dd 0x00000082 ; start after booter
-; part2numsect dd 0x00000abe ; 1.44MB - 65K
-part2numsect dd 0x000015fe ; 2.88MB - 65K
-%endif
-
pad_table_and_sig
times 510-($-$$) db 0
dw kBootSignature
+
+ ABSOLUTE 0xE400
+
+;
+; Variable storage area
+;
+ebios_lba resd 1
+
END
+
DIR = boot1u
include ../MakePaths.dir
-#
-# these paths are only valid in subdirectories of this directory
-#
-OBJROOT=../../obj/i386/boot1u
-SYMROOT=../../sym/i386
-DSTROOT=../../dst/i386
-SRCROOT=/tmp
-
OPTIM = -Os
CFLAGS = $(RC_CFLAGS) $(OPTIM) $(MORECPP) -arch i386 -g -Wmost -Werror \
- -fno-builtin -DSAIO_INTERNAL_USER -static \
+ -fno-builtin -DSAIO_INTERNAL_USER -DBOOT1 -static \
-fomit-frame-pointer -mpreferred-stack-boundary=2 \
-fno-align-functions
DEFINES=
endif
AS = as
LD = ld
-LIBS= -L$(SYMDIR) -lsaio -lsa
+LIBS= -L$(SYMDIR) -lsa
#LIBS= -L$(SYMDIR)
OTHER_FILES =
INSTALLDIR = $(DSTROOT)/usr/standalone/i386
-VPATH = $(OBJROOT):$(SYMROOT)
+VPATH = $(SYMROOT):$(OBJROOT)
+vpath %.c ../libsaio
+vpath % $(SYMROOT)
+vpath %.h ../libsaio
+vpath % $(SYMROOT)
# The ordering is important;
# boot1u.o must be first.
-#OBJS = $(OBJROOT)/boot1u.o $(OBJROOT)/asm.o $(OBJROOT)/bios.o $(OBJROOT)/boot.o $(OBJROOT)/string.o $(OBJROOT)/malloc.o $(OBJROOT)/disk.o $(OBJROOT)/put.o
-OBJS = boot1u.o asm.o bios.o boot.o string.o malloc.o disk.o put.o
-
-# OBJS += $(OBJROOT)/../libsaio/ufs.o \
-# $(OBJROOT)/../libsaio/cache.o \
-# $(OBJROOT)/../libsaio/ufs_byteorder.o \
-# $(OBJROOT)/../libsaio/table.o \
-# $(OBJROOT)/../libsaio/misc.o
+OBJS = boot1u.o asm.o bios.o boot.o string.o malloc.o disk.o put.o \
+ ufs.o cache.o misc.o ufs_byteorder.o table.o
# OBJS += $(OBJROOT)/../libsa/prf.o $(OBJROOT)/../libsa/printf.o
-# We get the following object files out of libsaio:
+# We build the following source files from the libsaio directory:
# ufs.o cache.o ufs_byteorder.o table.o
-# and these from libsa:
+# and get these object files from libsa:
# prf.o printf.o
# If they increase in size, or if other accidental dependencies
-# are created with other .o files in libsaio.a, then boot1u can get too large.
-# Use care in changing the library.
+# are created with other .o files in libsa.a, then boot1u can get too large.
+# Use care in changing libsaio and libsa.
UTILDIR = ../util
SFILES = boot1u.s bios.s asm.s
-CFILES = boot.c disk.c string.c put.c malloc.c
+CFILES = boot.c disk.c malloc.c put.c string.c \
+ ufs.c cache.c misc.c ufs_byteorder.c table.c
HFILES =
OTHERFILES = Makefile
ALLSRC = $(FOREIGNSRC) $(FOREIGNBIN) $(SFILES) $(CFILES) \
$(HFILES) $(OTHERFILES)
DIRS_NEEDED = $(OBJROOT) $(SYMROOT)
BOOT1UADDR = 10200
-MAXBOOTSIZE = 7680
+
+# Max boot1u code size is 7k (to leave room for the disk label)
+# minus 512 bytes for the partition booter,
+# for a total of 6.5k.
+MAXBOOTSIZE = 6656
+
NASM = $(SYMROOT)/nasm
all: $(DIRS_NEEDED) boot1u0 boot1u
boot1u0: boot1u0.s Makefile $(NASM)
$(NASM) boot1u0.s -o $(SYMROOT)/$@
-boot1u: $(SYMROOT)/machOconv $(OBJS) boot1u0
+boot1u: $(SYMROOT)/machOconv boot1u0 $(OBJS)
$(LD) -static -preload -segaddr __TEXT $(BOOT1UADDR) -segalign 20 \
- -o $(SYMROOT)/boot1u.sys $(OBJS) $(LIBS) -lcc_kext
- size $(SYMROOT)/boot1u.sys
- $(SYMROOT)/machOconv $(SYMROOT)/boot1u.sys $(SYMROOT)/boot1u.post
- ls -l $(SYMROOT)/boot1u.post
- @( size=`ls -l $(SYMROOT)/boot1u.post | awk '{ print $$5}'` ; \
+ -o $(SYMROOT)/$(@F).sys $(filter %.o,$^) $(LIBS) -lcc_kext
+ size $(SYMROOT)/$(@F).sys
+ $(SYMROOT)/machOconv $(SYMROOT)/$(@F).sys $(SYMROOT)/$(@F).post
+ ls -l $(SYMROOT)/$(@F).post
+ @( size=`ls -l $(SYMROOT)/$(@F).post | awk '{ print $$5}'` ; \
if expr "$$size" ">" "$(MAXBOOTSIZE)" > /dev/null ;\
then \
echo "Booter executable larger than $(MAXBOOTSIZE) bytes" ;\
exit 1;\
fi)
- cat $(SYMROOT)/boot1u0 $(SYMROOT)/boot1u.post | dd obs=8k conv=osync of=$(SYMROOT)/boot1u
- rm $(SYMROOT)/boot1u.post
+ cat $(SYMROOT)/boot1u0 $(SYMROOT)/$(@F).post | dd obs=7k conv=osync of=$(SYMROOT)/$(@F)
+ rm $(SYMROOT)/$(@F).post
install_i386:: all $(INSTALLDIR)
cd $(INSTALLDIR); chmod u+w boot1u $(OTHER_FILES)
clean::
- rm -f $(SYMROOT)/boot1u.sys $(SYMROOT)/boot1u
+ rm -f $(SYMROOT)/boot1u.sys $(SYMROOT)/boot1u $(SYMROOT)/boot1u0
include ../MakeInc.dir
/*
- * Copyright (c) 1999-2002 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
- * Portions Copyright (c) 1999-2002 Apple Computer, Inc. All Rights
+ * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights
* Reserved. This file contains Original Code and/or Modifications of
* Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.2 (the "License"). You may not use this file
+ * Source License Version 2.0 (the "License"). You may not use this file
* except in compliance with the License. Please obtain a copy of the
* License at http://www.apple.com/publicsource and read it before using
* this file.
/*
* HISTORY
* $Log: asm.s,v $
+ * Revision 1.3 2003/11/05 20:50:59 curtisg
+ * Integrated 3069695,3331770,3370488,3371823
+ *
+ * Revision 1.2.14.1 2003/10/27 23:57:55 curtisg
+ * Added printing of volume names, better handling of extended
+ * partitions, and updated Apple license strings.
+ * New chain booter should work better with foreign operating
+ * systems.
+ *
* Revision 1.2 2003/04/08 20:28:27 curtisg
* Merged PR-3073653, PR-3172003.
*
/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
- * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
+ * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights
* Reserved. This file contains Original Code and/or Modifications of
* Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.1 (the "License"). You may not use this file
+ * Source License Version 2.0 (the "License"). You may not use this file
* except in compliance with the License. Please obtain a copy of the
* License at http://www.apple.com/publicsource and read it before using
* this file.
/*
- * Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
- * Portions Copyright (c) 2002 Apple Computer, Inc. All Rights
+ * Portions Copyright (c) 2002-2003 Apple Computer, Inc. All Rights
* Reserved. This file contains Original Code and/or Modifications of
* Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.2 (the "License"). You may not use this file
+ * Source License Version 2.0 (the "License"). You may not use this file
* except in compliance with the License. Please obtain a copy of the
* License at http://www.apple.com/publicsource and read it before using
* this file.
zeroBSS();
- // printf("Hello, world.\n");
-
// Enable A20 gate before accessing memory above 1Mb.
enableA20();
gFSLoadAddress = (void *)BOOT2_ADDR;
cc = UFSLoadFile(&bv, BOOT_FILE);
if (cc < 0) {
- printf("Could not load" BOOT_FILE "\n");
+ printf("Could not load %s\n", BOOT_FILE);
halt();
}
// Return to execute booter
/*
- * Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
- * Portions Copyright (c) 2002 Apple Computer, Inc. All Rights
+ * Portions Copyright (c) 2002-2003 Apple Computer, Inc. All Rights
* Reserved. This file contains Original Code and/or Modifications of
* Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.2 (the "License"). You may not use this file
+ * Source License Version 2.0 (the "License"). You may not use this file
* except in compliance with the License. Please obtain a copy of the
* License at http://www.apple.com/publicsource and read it before using
* this file.
/*
- * Copyright (c) 1999-2002 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
- * Portions Copyright (c) 1999-2002 Apple Computer, Inc. All Rights
+ * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights
* Reserved. This file contains Original Code and/or Modifications of
* Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.2 (the "License"). You may not use this file
+ * Source License Version 2.0 (the "License"). You may not use this file
* except in compliance with the License. Please obtain a copy of the
* License at http://www.apple.com/publicsource and read it before using
* this file.
-; Copyright (c) 1999-2002 Apple Computer, Inc. All rights reserved.
+; Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved.
;
; @APPLE_LICENSE_HEADER_START@
;
-; Portions Copyright (c) 1999-2002 Apple Computer, Inc. All Rights
+; Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights
; Reserved. This file contains Original Code and/or Modifications of
; Original Code as defined in and that are subject to the Apple Public
-; Source License Version 1.2 (the "License"). You may not use this file
+; Source License Version 2.0 (the "License"). You may not use this file
; except in compliance with the License. Please obtain a copy of the
; License at http://www.apple.com/publicsource and read it before using
; this file.
; Boot Loader: boot0
;
; A small boot sector program written in x86 assembly whose only
-; responsibility is to locate the booter partition, load the
-; booter into memory, and jump to the booter's entry point.
+; responsibility is to load the booter into memory
+; and jump to the booter's entry point.
; The booter partition can be a primary or a logical partition.
;
; This boot loader can be placed at any of the following places:
-; 1. Master Boot Record (MBR)
-; 2. Boot sector of an extended partition
-; 3. Boot sector of a primary partition
-; 4. Boot sector of a logical partition
+; 1. Boot sector of an extended partition
+; 2. Boot sector of a primary partition
+; 3. Boot sector of a logical partition
+;
+; It expects that the MBR has left the drive number in DL
+; and a pointer to the partition entry in SI.
;
; In order to coexist with a fdisk partition table (64 bytes), and
; leave room for a two byte signature (0xAA55) in the end, boot0 is
kDriveNumber EQU 0x80
%endif
-;
-; In memory variables.
-;
-ebios_lba dd 0 ; starting LBA of the intial extended partition.
-ebios_present db 0 ; 1 if EBIOS is supported, 0 otherwise.
-
;
; Format of fdisk partition entry.
;
SEGMENT .text
- ORG 0xE000 ; must match kBoot0RelocAddr
+ ORG 0x7C00
;--------------------------------------------------------------------------
; Boot code is loaded at 0:7C00h.
;
start
+ DebugChar('!')
+%if DEBUG
+ mov al, dl
+ call print_hex
+%endif
;
; Set up the stack to grow down from kBoot0Segment:kBoot0Stack.
; Interrupts should be off while the stack is being manipulated.
mov es, ax ; es <- 0
mov ds, ax ; ds <- 0
+%if 0
+ ;
+ ; Save SI register.
+ ;
+ mov bx, si
+
;
- ; Relocate boot0 code.
+ ; Relocate ourselves.
;
mov si, kBoot0LoadAddr ; si <- source
mov di, kBoot0RelocAddr ; di <- destination
; Start execution from the relocated location.
;
start_reloc:
-
+%endif
+
DebugChar('*')
- mov dl, kDriveNumber ; starting BIOS drive number
-
.loop:
%if DEBUG
mov [ebios_lba], eax ; clear EBIOS LBA offset
mov [ebios_present], al ; clear EBIOS support flag
- ;
- ; Since this code may not always reside in the MBR, always start by
- ; loading the MBR to kMBRBuffer.
- ;
- mov al, 1 ; load one sector
- xor bx, bx
- mov es, bx ; MBR load segment = 0
- mov bx, kMBRBuffer ; MBR load address
- mov si, bx ; pointer to fake partition entry
- mov WORD [si], 0x0000 ; CHS DX: head = 0
- mov WORD [si + 2], 0x0001 ; CHS CX: cylinder = 0, sector = 1
-
- call load
- jc .next_drive ; MBR load error
-
;
; Check if EBIOS is supported for this hard drive.
;
DebugChar('E') ; EBIOS supported
.ebios_check_done:
- ;
- ; Look for the booter partition in the MBR partition table,
- ; which is at offset kMBRPartTable.
- ;
- mov di, kMBRPartTable ; pointer to partition table
- mov ah, 0 ; initial nesting level is 0
- call find_boot ; will not return on success
+ DebugChar('L')
-.next_drive:
-;; inc dl ; next drive number
-;; test dl, 0x84 ; went through all 4 drives?
-;; jz .loop ; not yet, loop again
+%if DEBUG
+ mov al, BYTE [si + part.type]
+ call print_hex
+%endif
+
+ ; Check to make sure our partition is the correct type.
+ cmp BYTE [si + part.type], kPartTypeUFS
+ je load_boot
- mov si, boot_error_str
+part_error:
+ ; Drat, the partition entry was the wrong type.
+ ; Print an error and hang.
+ mov si, part_error_str
call print_string
hang:
hlt
jmp SHORT hang
-;--------------------------------------------------------------------------
-; Find the boot partition and load the booter from the partition.
-;
-; Arguments:
-; AH = recursion nesting level
-; DL = drive number (0x80 + unit number)
-; DI = pointer to fdisk partition table.
-;
-; Clobber list:
-; AX, BX, EBP
-;
-find_boot:
- push cx ; preserve CX and SI
- push si
+ ;--------------------------------------------------------------------------
+ ; Load the booter from the partition.
- ;
- ; Check for boot block signature 0xAA55 following the 4 partition
- ; entries.
- ;
- cmp WORD [di + part_size * kPartCount], kBootSignature
- jne .exit ; boot signature not found
-
- mov si, di ; make SI a pointer to partition table
- mov cx, kPartCount ; number of partition entries per table
-
-.loop:
- ;
- ; First scan through the partition table looking for the boot
- ; partition. Postpone walking the extended partition chain for
- ; the second pass. Do not merge the two without changing the
- ; buffering scheme used to store extended partition tables.
- ;
-%if DEBUG
- mov al, ah ; indent based on nesting level
- call print_spaces
- mov al, [si + part.type] ; print partition type
- call print_hex
-%endif
-
- cmp BYTE [si + part.type], kPartTypeUFS
- jne .continue
- cmp BYTE [si + part.bootid], kPartActive
- jne .continue
+load_boot:
;
; Found boot partition, read boot1u image to memory.
mov es, bx
mov bx, kBoot1uAddress
call load ;
- jc .continue ; load error, keep looking?
+ jc part_error ; load error, keep looking?
+
+ DebugChar('^')
-DebugChar('^')
;
; Jump to boot1u. The drive number is already in register DL.
;
;
jmp kBoot1uSegment:kBoot1uAddress + kSectorBytes
-.continue:
- add si, part_size ; advance SI to next partition entry
- loop .loop ; loop through all partition entries
-
-%if EXT_PART_SUPPORT
- ;
- ; No primary (or logical) boot partition found in the current
- ; partition table. Restart and look for extended partitions.
- ;
- mov si, di ; make SI a pointer to partition table
- mov cx, kPartCount ; number of partition entries per table
-
-.ext_loop:
-
- mov al, [si + part.type] ; AL <- partition type
-
- cmp al, kPartTypeExtDOS ; Extended DOS
- je .ext_load
-
- cmp al, kPartTypeExtWin ; Extended Windows(95)
- je .ext_load
-
- cmp al, kPartTypeExtLinux ; Extended Linux
- je .ext_load
-
-.ext_continue:
- ;
- ; Advance si to the next partition entry in the extended
- ; partition table.
- ;
- add si, part_size ; advance SI to next partition entry
- loop .ext_loop ; loop through all partition entries
- jmp .exit ; boot partition not found
-
-.ext_load:
- ;
- ; Setup the arguments for the load function call to bring the
- ; extended partition table into memory.
- ; Remember that SI points to the extended partition entry.
- ;
- mov al, 1 ; read 1 sector
- xor bx, bx
- mov es, bx ; es = 0
- mov bx, kExtBuffer ; load extended boot sector
- call load
- jc .ext_continue ; load error
-
- ;
- ; The LBA address of all extended partitions is relative based
- ; on the LBA address of the extended partition in the MBR, or
- ; the extended partition at the head of the chain. Thus it is
- ; necessary to save the LBA address of the first extended partition.
- ;
- or ah, ah
- jnz .ext_find_boot
- mov ebp, [si + part.lba]
- mov [ebios_lba], ebp
-
-.ext_find_boot:
- ;
- ; Call find_boot recursively to scan through the extended partition
- ; table. Load DI with a pointer to the extended table in memory.
- ;
- inc ah ; increment recursion level
- mov di, kExtPartTable ; partition table pointer
- call find_boot ; recursion...
- ;dec ah
-
- ;
- ; Since there is an "unwritten" rule that limits each partition table
- ; to have 0 or 1 extended partitions, there is no point in looking for
- ; any additional extended partition entries at this point. There is no
- ; boot partition linked beyond the extended partition that was loaded
- ; above.
- ;
-
-%endif ; EXT_PART_SUPPORT
-
.exit:
;
; Boot partition not found. Giving up.
popa
ret
-;--------------------------------------------------------------------------
-; Write a variable number of spaces to the console.
-;
-; Arguments:
-; AL = number to spaces.
-;
-print_spaces:
- pusha
- xor cx, cx
- mov cl, al ; use CX as the loop counter
- mov al, ' ' ; character to print
-.loop:
- jcxz .exit
- call print_char
- loop .loop
-.exit:
- popa
- ret
-
;--------------------------------------------------------------------------
; Write the byte value to the console in hex.
;
;--------------------------------------------------------------------------
; NULL terminated strings.
;
-boot_error_str db 10, 13, 'Error', 0
+part_error_str db 10, 13, 'Error loading UFS partition', 0
;--------------------------------------------------------------------------
; Pad the rest of the 512 byte sized booter with zeroes. The last
times 510-($-$$) db 0
dw kBootSignature
+ ABSOLUTE 0xE400
+
+;
+; In memory variables.
+;
+ebios_lba resd 1 ; starting LBA of the intial extended partition.
+ebios_present resb 1 ; 1 if EBIOS is supported, 0 otherwise.
+
END
/*
- * Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
- * Portions Copyright (c) 2002 Apple Computer, Inc. All Rights
+ * Portions Copyright (c) 2002-2003 Apple Computer, Inc. All Rights
* Reserved. This file contains Original Code and/or Modifications of
* Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.2 (the "License"). You may not use this file
+ * Source License Version 2.0 (the "License"). You may not use this file
* except in compliance with the License. Please obtain a copy of the
* License at http://www.apple.com/publicsource and read it before using
* this file.
#define ECC_CORRECTED_ERR 0x11
-//#undef DEBUG_DISK
-//#define DEBUG_DISK(x) printf x
-
extern void bios(biosBuf_t *bb);
static biosBuf_t bb;
+
int ebiosread(int dev, long sec, int count)
{
int i;
(void *) addr );
}
+
int
findUFSPartition(int dev, struct fdisk_part *_fp)
{
struct fdisk_part *fp;
int i, cc;
unsigned long offset = 0;
+ unsigned long firstoff = 0;
+ int ext_index = -1;
db = (struct disk_blk0 *)biosbuf;
- for (i=0; i<FDISK_NPART; i++) {
- DEBUG_DISK(("i=%d, %ld\n", i, offset));
- if (i==0) {
- DEBUG_DISK(("reading\n"));
+ do {
+ DEBUG_DISK(("reading at offset %d\n", offset));
cc = Biosread(dev, offset);
if (cc < 0) {
- return cc;
+ return cc;
}
- }
- fp = (struct fdisk_part *)&db->parts[i];
- DEBUG_DISK(("systid %x\n", fp->systid));
- if (fp->systid == 0xA8) {
- bcopy(fp, _fp, sizeof(struct fdisk_part));
- _fp->relsect += offset;
- DEBUG_DISK(("found %d\n", i));
- return 0;
- } else if (fp->systid == 0x05 ||
- fp->systid == 0x0F ||
- fp->systid == 0x85) {
- offset += fp->relsect;
- i = -1;
- continue;
- }
- }
+ for (i=0; i<FDISK_NPART; i++) {
+ DEBUG_DISK(("i=%d, offset %ld\n", i, offset));
+ fp = (struct fdisk_part *)&db->parts[i];
+ DEBUG_DISK(("systid %x\n", fp->systid));
+ if (fp->systid == FDISK_UFS) {
+ bcopy(fp, _fp, sizeof(struct fdisk_part));
+ _fp->relsect += offset;
+ DEBUG_DISK(("** found UFS at partition %d\n", i));
+ return 0;
+ } else if (fp->systid == FDISK_DOSEXT ||
+ fp->systid == 0x0F ||
+ fp->systid == 0x85) {
+ ext_index = i;
+ }
+ }
+ if (ext_index != -1) {
+ DEBUG_DISK(("Found ext part at %d\n", ext_index));
+ fp = (struct fdisk_part *)&db->parts[ext_index];
+ ext_index = -1;
+ offset = firstoff + fp->relsect;
+ if (firstoff == 0) {
+ firstoff = fp->relsect;
+ }
+ continue;
+ }
+ break;
+ } while (1);
return -1;
}
void
initUFSBVRef( BVRef bvr, int biosdev, const struct fdisk_part * part)
{
- bvr->biosdev = biosdev;
- bvr->part_no = 0;
- bvr->part_boff = part->relsect + UFS_FRONT_PORCH/BPS,
+ bvr->biosdev = biosdev;
+ bvr->part_no = 0;
+ bvr->part_boff = part->relsect + UFS_FRONT_PORCH/BPS,
bvr->part_type = part->systid;
- bvr->fs_loadfile = UFSLoadFile;
- bvr->fs_getdirentry = UFSGetDirEntry;
- bvr->description = 0;
+ bvr->fs_loadfile = UFSLoadFile;
+ //bvr->fs_getdirentry = UFSGetDirEntry;
+ bvr->description = 0;
}
void putc(int ch)
/*
- * Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
- * Portions Copyright (c) 2002 Apple Computer, Inc. All Rights
+ * Portions Copyright (c) 2002-2003 Apple Computer, Inc. All Rights
* Reserved. This file contains Original Code and/or Modifications of
* Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.2 (the "License"). You may not use this file
+ * Source License Version 2.0 (the "License"). You may not use this file
* except in compliance with the License. Please obtain a copy of the
* License at http://www.apple.com/publicsource and read it before using
* this file.
/*
- * Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
- * Portions Copyright (c) 2002 Apple Computer, Inc. All Rights
+ * Portions Copyright (c) 2002-2003 Apple Computer, Inc. All Rights
* Reserved. This file contains Original Code and/or Modifications of
* Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.2 (the "License"). You may not use this file
+ * Source License Version 2.0 (the "License"). You may not use this file
* except in compliance with the License. Please obtain a copy of the
* License at http://www.apple.com/publicsource and read it before using
* this file.
/*
- * Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
- * Portions Copyright (c) 2002 Apple Computer, Inc. All Rights
+ * Portions Copyright (c) 2002-2003 Apple Computer, Inc. All Rights
* Reserved. This file contains Original Code and/or Modifications of
* Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.2 (the "License"). You may not use this file
+ * Source License Version 2.0 (the "License"). You may not use this file
* except in compliance with the License. Please obtain a copy of the
* License at http://www.apple.com/publicsource and read it before using
* this file.
int verbose(const char * fmt, ...)
{
-#if 1
+#if DEBUG
va_list ap;
va_start(ap, fmt);
/*
- * Copyright (c) 1999-2002 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
- * Portions Copyright (c) 1999-2002 Apple Computer, Inc. All Rights
+ * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights
* Reserved. This file contains Original Code and/or Modifications of
* Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.2 (the "License"). You may not use this file
+ * Source License Version 2.0 (the "License"). You may not use this file
* except in compliance with the License. Please obtain a copy of the
* License at http://www.apple.com/publicsource and read it before using
* this file.
void bcopy(const void * src, void * dst, size_t len)
{
- memcpy(dst, src, len);
+ memcpy(dst, src, len);
}
void bzero(void * dst, size_t len)
AS = as
LD = ld
# LIBS= -lc_static
-LIBS= -L$(SYMDIR) -lsaio -lsa -lrcz
-LIBDEP= $(SYMDIR)/libsaio.a $(SYMDIR)/libsa.a $(SYMDIR)/librcz.a
+LIBS= -L$(SYMDIR) -lsaio -lsa
+LIBDEP= $(SYMDIR)/libsaio.a $(SYMDIR)/libsa.a
OTHER_FILES =
boot: machOconv $(OBJS) $(LIBDEP)
$(LD) -static -preload -segaddr __TEXT $(BOOT2ADDR) -segalign 20 \
- -o $(SYMROOT)/boot.sys $(OBJS) $(LIBS) -lcc_kext
+ -o $(SYMROOT)/boot.sys $(filter %.o,$^) $(LIBS) -lcc_kext
machOconv $(SYMROOT)/boot.sys $(SYMROOT)/boot
size $(SYMROOT)/boot.sys
ls -l $(SYMROOT)/boot
cd $(INSTALLDIR); chmod u+w boot $(OTHER_FILES)
clean::
- rm -f $(SYMROOT)/boot.sys $(SYMROOT)/boot
+ rm -f $(SYMROOT)/boot.sys $(SYMROOT)/boot $(SYMROOT)/vers.h
include ../MakeInc.dir
/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
- * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
+ * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights
* Reserved. This file contains Original Code and/or Modifications of
* Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.1 (the "License"). You may not use this file
+ * Source License Version 2.0 (the "License"). You may not use this file
* except in compliance with the License. Please obtain a copy of the
* License at http://www.apple.com/publicsource and read it before using
* this file.
/*
- * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2003 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
- * The contents of this file constitute Original Code as defined in and
- * are subject to the Apple Public Source License Version 1.1 (the
- * "License"). You may not use this file except in compliance with the
- * License. Please obtain a copy of the License at
- * http://www.apple.com/publicsource and read it before using this file.
+ * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights
+ * Reserved. This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 2.0 (the "License"). You may not use this file
+ * except in compliance with the License. Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
*
- * This Original Code and all software distributed under the License are
+ * The Original Code and all software distributed under the License are
* distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
- * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
+ * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights
* Reserved. This file contains Original Code and/or Modifications of
* Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.1 (the "License"). You may not use this file
+ * Source License Version 2.0 (the "License"). You may not use this file
* except in compliance with the License. Please obtain a copy of the
* License at http://www.apple.com/publicsource and read it before using
* this file.
* Reworked again by Curtis Galloway (galloway@NeXT.com)
*/
+
#include "boot.h"
#include "bootstruct.h"
#include "sl.h"
+#include "libsa.h"
-/*
- * The user asked for boot graphics.
- */
-BOOL gBootGraphics = NO;
-long gBootMode = kBootModeNormal;
+
+long gBootMode; /* defaults to 0 == kBootModeNormal */
+BOOL gOverrideKernel;
static char gBootKernelCacheFile[512];
+static char gCacheNameAdler[64 + 256];
+char *gPlatformName = gCacheNameAdler;
+char gMKextName[512];
+BVRef gBootVolume;
+
+static
+unsigned long Adler32(unsigned char *buffer, long length);
+
static BOOL gUnloadPXEOnExit = 0;
{
entry_t kernelEntry;
int ret;
+#ifdef APM_SUPPORT
+ BOOL apm;
+#endif /* APM_SUPPORT */
+ BOOL bootGraphics;
bootArgs->kaddr = bootArgs->ksize = 0;
turnOffFloppy();
+#ifdef APM_SUPPORT
// Connect to APM BIOS.
- if ( getBoolForKey("APM") )
+ if ( getBoolForKey("APM", &apm) && apm == YES )
{
if ( APMPresent() ) APMConnect32();
}
+#endif /* APM_SUPPORT */
// Cleanup the PXE base code.
}
}
- // Switch to desired video mode just before starting the kernel.
+ // Unless Boot Graphics = No, Always switch to graphics mode
+ // just before starting the kernel.
- setVideoMode( gBootGraphics ? GRAPHICS_MODE : TEXT_MODE );
+ if (!getBoolForKey(kBootGraphicsKey, &bootGraphics)) {
+ bootGraphics = YES;
+ }
+
+ if (bootGraphics) {
+ if (bootArgs->graphicsMode == TEXT_MODE) {
+ // If we were in text mode, switch to graphics mode.
+ // This will draw the boot graphics.
+ setVideoMode( GRAPHICS_MODE );
+ } else {
+ // If we were already in graphics mode, clear the screen.
+ drawBootGraphics();
+ }
+ } else {
+ if (bootArgs->graphicsMode == GRAPHICS_MODE) {
+ setVideoMode( TEXT_MODE );
+ }
+ }
// Jump to kernel's entry point. There's no going back now.
// booting was unsuccessful. This allows the PXE firmware to try the
// next boot device on its list.
+#define DLOG(x) outb(0x80, (x))
+
void boot(int biosdev)
{
int status;
char *bootFile;
+ unsigned long adler32;
+ BOOL quiet;
+ BOOL firstRun = YES;
+ BVRef bvChain;
zeroBSS();
// Not sure if it is safe to call setVideoMode() before the
// config table has been loaded. Call video_mode() instead.
- video_mode( 2 ); // 80x25 mono text mode.
+ video_mode( 2 ); // 80x25 mono text mode.
// Scan hardware configuration.
scanHardware();
- // Display banner and show hardware info.
+ // First get info for boot volume.
+ bvChain = scanBootVolumes(gBIOSDev, 0);
- setCursorPosition( 0, 0, 0 );
- printf( bootBanner, bootArgs->convmem, bootArgs->extmem );
- printVBEInfo();
+ // Record default boot device.
+ gBootVolume = selectBootVolume(bvChain);
+ bootArgs->kernDev = MAKEKERNDEV(gBIOSDev,
+ BIOS_DEV_UNIT(gBootVolume),
+ gBootVolume->part_no );
+
+ // Load default config file from boot device.
+ status = loadSystemConfig(0, 0);
+
+ if ( getBoolForKey( kQuietBootKey, &quiet ) && quiet ) {
+ gBootMode |= kBootModeQuiet;
+ }
// Parse args, load and start kernel.
while (1)
{
const char *val;
- int len, trycache;
- long flags, cachetime, time;
+ int len;
+ int trycache;
+ long flags, cachetime, kerneltime, exttime;
int ret = -1;
// Initialize globals.
sysConfigValid = 0;
gErrors = 0;
- // Reset config space.
- bootArgs->configEnd = bootArgs->config;
+ status = getBootOptions(firstRun);
+ firstRun = NO;
+ if (status == -1) continue;
- getBootOptions();
status = processBootOptions();
if ( status == 1 ) break;
if ( status == -1 ) continue;
// Found and loaded a config file. Proceed with boot.
- // Check for cache file.
- if (getValueForKey(kKernelCacheKey, &val, &len)) {
- strncpy(gBootKernelCacheFile, val, len);
- gBootKernelCacheFile[len] = '\0';
+ // Reset cache name.
+ bzero(gCacheNameAdler, sizeof(gCacheNameAdler));
+
+ if ( getValueForKey( kRootDeviceKey, &val, &len ) == YES ) {
+ if (*val == '*') {
+ val++;
+ len--;
+ }
+ strncpy( gCacheNameAdler + 64, val, len );
+ sprintf(gCacheNameAdler + 64 + len, ",%s", bootArgs->bootFile);
} else {
- strcpy(gBootKernelCacheFile, kDefaultCachePath);
+ strcpy(gCacheNameAdler + 64, bootArgs->bootFile);
}
+ adler32 = Adler32(gCacheNameAdler, sizeof(gCacheNameAdler));
+
+ if (getValueForKey(kKernelCacheKey, &val, &len) == YES) {
+ strlcpy(gBootKernelCacheFile, val, len+1);
+ } else {
+ sprintf(gBootKernelCacheFile, "%s.%08lX", kDefaultCachePath, adler32);
+ }
+
+ // Check for cache file.
+
trycache = (((gBootMode & kBootModeSafe) == 0) &&
+ (gOverrideKernel == NO) &&
(gBootFileType == kBlockDeviceType) &&
+ (gMKextName[0] == '\0') &&
(gBootKernelCacheFile[0] != '\0'));
printf("Loading Darwin/x86\n");
if (trycache) do {
// if we haven't found the kernel yet, don't use the cache
- ret = GetFileInfo(NULL, bootArgs->bootFile, &flags, &time);
+ ret = GetFileInfo(NULL, bootArgs->bootFile, &flags, &kerneltime);
if ((ret != 0) || ((flags & kFileTypeMask) != kFileTypeFlat)) {
trycache = 0;
break;
}
ret = GetFileInfo(NULL, gBootKernelCacheFile, &flags, &cachetime);
if ((ret != 0) || ((flags & kFileTypeMask) != kFileTypeFlat)
- || (cachetime < time)) {
+ || (cachetime < kerneltime)) {
trycache = 0;
break;
}
- ret = GetFileInfo("/System/Library/", "Extensions", &flags, &time);
+ ret = GetFileInfo("/System/Library/", "Extensions", &flags, &exttime);
if ((ret == 0) && ((flags & kFileTypeMask) == kFileTypeDirectory)
- && (cachetime < time)) {
+ && (cachetime < exttime)) {
+ trycache = 0;
+ break;
+ }
+ if (kerneltime > exttime) {
+ exttime = kerneltime;
+ }
+ if (cachetime != (exttime + 1)) {
trycache = 0;
break;
}
} while (0);
clearActivityIndicator();
+#if DEBUG
+ printf("Pausing...");
+ sleep(8);
+#endif
if (ret < 0) {
error("Can't find %s\n", bootFile);
// floppy in drive, but failed to load kernel.
gBIOSDev = kBIOSDevTypeHardDrive;
initKernBootStruct( gBIOSDev );
- printf("Attempt to load from hard drive.");
+ printf("Attempting to load from hard drive...");
}
else if ( gBootFileType == kNetworkDeviceType )
{
nbpUnloadBaseCode();
}
}
+
+#define BASE 65521L /* largest prime smaller than 65536 */
+#define NMAX 5000
+// NMAX (was 5521) the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1
+
+#define DO1(buf,i) {s1 += buf[i]; s2 += s1;}
+#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
+#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
+#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
+#define DO16(buf) DO8(buf,0); DO8(buf,8);
+
+unsigned long Adler32(unsigned char *buf, long len)
+{
+ unsigned long s1 = 1; // adler & 0xffff;
+ unsigned long s2 = 0; // (adler >> 16) & 0xffff;
+ unsigned long result;
+ int k;
+
+ while (len > 0) {
+ k = len < NMAX ? len : NMAX;
+ len -= k;
+ while (k >= 16) {
+ DO16(buf);
+ buf += 16;
+ k -= 16;
+ }
+ if (k != 0) do {
+ s1 += *buf++;
+ s2 += s1;
+ } while (--k);
+ s1 %= BASE;
+ s2 %= BASE;
+ }
+ result = (s2 << 16) | s1;
+ return OSSwapHostToBigInt32(result);
+}
+
/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
- * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
+ * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights
* Reserved. This file contains Original Code and/or Modifications of
* Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.1 (the "License"). You may not use this file
+ * Source License Version 2.0 (the "License"). You may not use this file
* except in compliance with the License. Please obtain a copy of the
* License at http://www.apple.com/publicsource and read it before using
* this file.
#include "libsaio.h"
/*
- * Keys used in system Default.table / Instance0.table
+ * Keys used in system Boot.plist
*/
#define kGraphicsModeKey "Graphics Mode"
#define kTextModeKey "Text Mode"
#define kBootGraphicsKey "Boot Graphics"
#define kQuietBootKey "Quiet Boot"
#define kKernelFlagsKey "Kernel Flags"
+#define kMKextCacheKey "MKext Cache"
#define kKernelNameKey "Kernel"
#define kKernelCacheKey "Kernel Cache"
+#define kBootDeviceKey "Boot Device"
+#define kTimeoutKey "Timeout"
+#define kRootDeviceKey "rd"
+#define kPlatformKey "platform"
+#define kACPIKey "acpi"
+#define kDefaultKernel "mach_kernel"
+
+/*
+ * Flags to the booter or kernel
+ *
+ */
+#define kVerboseModeFlag "-v"
+#define kSafeModeFlag "-f"
+#define kIgnoreBootFileFlag "-F"
+#define kSingleUserModeFlag "-s"
+
+/*
+ * Booter behavior control
+ */
+#define kBootTimeout 8
/*
* A global set by boot() to record the device that the booter
* was loaded from.
*/
extern int gBIOSDev;
-extern BOOL gBootGraphics;
extern long gBootMode;
extern BOOL sysConfigValid;
extern char bootBanner[];
extern char bootPrompt[];
+extern BOOL gOverrideKernel;
+extern char *gPlatformName;
+extern char gMKextName[];
+extern BVRef gBootVolume;
// Boot Modes
enum {
kBootModeNormal = 0,
- kBootModeSafe,
- kBootModeSecure
+ kBootModeSafe = 1,
+ kBootModeSecure = 2,
+ kBootModeQuiet = 4
};
/*
* graphics.c
*/
extern void printVBEInfo();
+extern void printVBEModeInfo();
extern void setVideoMode(int mode);
extern int getVideoMode();
extern void spinActivityIndicator();
extern void clearActivityIndicator();
+extern void drawColorRectangle( unsigned short x,
+ unsigned short y,
+ unsigned short width,
+ unsigned short height,
+ unsigned char colorIndex );
+extern void drawDataRectangle( unsigned short x,
+ unsigned short y,
+ unsigned short width,
+ unsigned short height,
+ unsigned char * data );
+extern int
+convertImage( unsigned short width,
+ unsigned short height,
+ const unsigned char *imageData,
+ unsigned char **newImageData );
+extern char * decodeRLE( const void * rleData, int rleBlocks, int outBytes );
+extern void drawBootGraphics(void);
/*
* drivers.c
/*
* options.c
*/
-extern void getBootOptions();
+extern int getBootOptions(BOOL firstRun);
extern int processBootOptions();
/*
/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
- * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
+ * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights
* Reserved. This file contains Original Code and/or Modifications of
* Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.0 (the 'License'). You may not use this file
+ * Source License Version 2.0 (the 'License'). You may not use this file
* except in compliance with the License. Please obtain a copy of the
* License at http://www.apple.com/publicsource and read it before using
* this file.
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
* License for the specific language governing rights and limitations
- * under the License."
+ * under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
}
else if ( gBootFileType == kBlockDeviceType )
{
- strcpy(gExtensionsSpec, dirSpec);
- strcat(gExtensionsSpec, "System/Library/");
- FileLoadDrivers(gExtensionsSpec, 0);
+ if (gMKextName[0] != '\0')
+ {
+ verbose("LoadDrivers: Loading from [%s]\n", gMKextName);
+ if ( LoadDriverMKext(gMKextName) != 0 )
+ {
+ error("Could not load %s\n", gMKextName);
+ return -1;
+ }
+ }
+ else
+ {
+ strcpy(gExtensionsSpec, dirSpec);
+ strcat(gExtensionsSpec, "System/Library/");
+ FileLoadDrivers(gExtensionsSpec, 0);
+ }
}
else
{
{
ret = GetFileInfo(dirSpec, "Extensions", &flags, &time2);
if ((ret != 0) || ((flags & kFileTypeMask) != kFileTypeDirectory) ||
- (((gBootMode & kBootModeSafe) == 0) && (time > time2)))
+ (((gBootMode & kBootModeSafe) == 0) && (time == (time2 + 1))))
{
sprintf(gDriverSpec, "%sExtensions.mkext", dirSpec);
verbose("LoadDrivers: Loading from [%s]\n", gDriverSpec);
/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
- * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
+ * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights
* Reserved. This file contains Original Code and/or Modifications of
* Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.1 (the "License"). You may not use this file
+ * Source License Version 2.0 (the "License"). You may not use this file
* except in compliance with the License. Please obtain a copy of the
* License at http://www.apple.com/publicsource and read it before using
* this file.
static unsigned long lookUpCLUTIndex( unsigned char index,
unsigned char depth );
-static void drawColorRectangle( unsigned short x,
+void drawColorRectangle( unsigned short x,
unsigned short y,
unsigned short width,
unsigned short height,
unsigned char colorIndex );
-static void drawDataRectangle( unsigned short x,
+void drawDataRectangle( unsigned short x,
unsigned short y,
unsigned short width,
unsigned short height,
- unsigned char * data );
+ unsigned char * data );
+
+
+int
+convertImage( unsigned short width,
+ unsigned short height,
+ const unsigned char *imageData,
+ unsigned char **newImageData );
#define VIDEO(x) (bootArgs->video.v_ ## x)
+#define MIN(x, y) ((x) < (y) ? (x) : (y))
//==========================================================================
// printVBEInfo
{
VBEInfoBlock vbeInfo;
int err;
+ int small;
// Fetch VBE Controller Info.
// Announce controller properties.
- printf("VESA v%d.%d %dMB (%s)\n",
+ small = (vbeInfo.TotalMemory < 16);
+
+ printf("VESA v%d.%d %d%s (%s)\n",
vbeInfo.VESAVersion >> 8,
vbeInfo.VESAVersion & 0xf,
- vbeInfo.TotalMemory / 16,
+ small ? (vbeInfo.TotalMemory * 64) : (vbeInfo.TotalMemory / 16),
+ small ? "KB" : "MB",
VBEDecodeFP(const char *, vbeInfo.OEMStringPtr) );
}
+//==========================================================================
+//
+
+void
+printVBEModeInfo()
+{
+ VBEInfoBlock vbeInfo;
+ unsigned short * modePtr;
+ VBEModeInfoBlock modeInfo;
+ int err;
+ int line;
+
+ err = getVBEInfo( &vbeInfo );
+ if ( err != errSuccess )
+ return;
+
+ line = 0;
+
+ // Activate and clear page 1
+ setActiveDisplayPage(1);
+ clearScreenRows(0, 24);
+ setCursorPosition( 0, 0, 1 );
+
+ printVBEInfo();
+ printf("Video modes supported:\n", VBEDecodeFP(const char *, vbeInfo.OEMStringPtr));
+
+ // Loop through the mode list, and find the matching mode.
+
+ for ( modePtr = VBEDecodeFP( unsigned short *, vbeInfo.VideoModePtr );
+ *modePtr != modeEndOfList; modePtr++ )
+ {
+ // Get mode information.
+
+ bzero( &modeInfo, sizeof(modeInfo) );
+ err = getVBEModeInfo( *modePtr, &modeInfo );
+ if ( err != errSuccess )
+ {
+ continue;
+ }
+
+ printf("Mode %x: %dx%dx%d mm:%d attr:%x\n",
+ *modePtr, modeInfo.XResolution, modeInfo.YResolution,
+ modeInfo.BitsPerPixel, modeInfo.MemoryModel,
+ modeInfo.ModeAttributes);
+
+ if (line++ >= 20) {
+ printf("(Press a key to continue...)");
+ getc();
+ line = 0;
+ clearScreenRows(0, 24);
+ setCursorPosition( 0, 0, 1 );
+ }
+ }
+ if (line != 0) {
+ printf("(Press a key to continue...)");
+ getc();
+ }
+ setActiveDisplayPage(0);
+}
+
+
//==========================================================================
// getVESAModeWithProperties
//
continue;
}
-#if 0 // debug
+#if DEBUG
printf("Mode %x: %dx%dx%d mm:%d attr:%x\n",
*modePtr, modeInfo.XResolution, modeInfo.YResolution,
modeInfo.BitsPerPixel, modeInfo.MemoryModel,
}
if ( modeInfo.XResolution < outModeInfo->XResolution ||
modeInfo.YResolution < outModeInfo->YResolution ||
- modeBitsPerPixel < 16 )
+ modeBitsPerPixel < outModeInfo->BitsPerPixel )
{
continue; // Saved mode has more resolution.
}
//==========================================================================
// Simple decompressor for boot images encoded in RLE format.
-static char * decodeRLE( const void * rleData, int rleBlocks, int outBytes )
+char * decodeRLE( const void * rleData, int rleBlocks, int outBytes )
{
char *out, *cp;
bootArgs->video.v_depth = minfo.BitsPerPixel;
bootArgs->video.v_rowBytes = minfo.BytesPerScanline;
bootArgs->video.v_baseAddr = VBEMakeUInt32(minfo.PhysBasePtr);
+
}
while ( 0 );
return err;
}
+int
+convertImage( unsigned short width,
+ unsigned short height,
+ const unsigned char *imageData,
+ unsigned char **newImageData )
+{
+ int cnt;
+ unsigned char *img = 0;
+ unsigned short *img16;
+ unsigned long *img32;
+
+ switch ( VIDEO(depth) ) {
+ case 16 :
+ img16 = malloc(width * height * 2);
+ if ( !img16 ) break;
+ for (cnt = 0; cnt < (width * height); cnt++)
+ img16[cnt] = lookUpCLUTIndex(imageData[cnt], 16);
+ img = (unsigned char *)img16;
+ break;
+
+ case 32 :
+ img32 = malloc(width * height * 4);
+ if ( !img32 ) break;
+ for (cnt = 0; cnt < (width * height); cnt++)
+ img32[cnt] = lookUpCLUTIndex(imageData[cnt], 32);
+ img = (unsigned char *)img32;
+ break;
+
+ default :
+ img = malloc(width * height);
+ bcopy(imageData, img, width * height);
+ break;
+ }
+ *newImageData = img;
+ return 0;
+}
+
//==========================================================================
// drawBootGraphics
-static int
-drawBootGraphics( unsigned short width,
- unsigned short height,
- unsigned char bitsPerPixel,
- unsigned short refreshRate )
+void
+drawBootGraphics( void )
{
- VBEModeInfoBlock minfo;
- unsigned short mode;
- unsigned short vesaVersion;
- int err = errFuncNotSupported;
-
- char * appleBoot = 0;
- short * appleBoot16;
- long * appleBoot32;
- long cnt, x, y;
+ unsigned char * imageData = 0;
+ long x, y;
char * appleBootPict;
do {
- mode = getVESAModeWithProperties( width, height, bitsPerPixel,
- maColorModeBit |
- maModeIsSupportedBit |
- maGraphicsModeBit |
- maLinearFrameBufferAvailBit,
- 0,
- &minfo, &vesaVersion );
- if ( mode == modeEndOfList )
- {
- break;
- }
-
// Fill the background to 75% grey (same as BootX).
- drawColorRectangle( 0, 0, minfo.XResolution, minfo.YResolution,
+ drawColorRectangle( 0, 0, VIDEO(width), VIDEO(height),
0x01 /* color index */ );
appleBootPict = decodeRLE( gAppleBootPictRLE, kAppleBootRLEBlocks,
if ( appleBootPict )
{
- switch ( VIDEO(depth) )
- {
- case 16 :
- appleBoot16 = malloc(kAppleBootWidth * kAppleBootHeight * 2);
- if ( !appleBoot16 ) break;
- for (cnt = 0; cnt < (kAppleBootWidth * kAppleBootHeight); cnt++)
- appleBoot16[cnt] = lookUpCLUTIndex(appleBootPict[cnt], 16);
- appleBoot = (char *) appleBoot16;
- break;
-
- case 32 :
- appleBoot32 = malloc(kAppleBootWidth * kAppleBootHeight * 4);
- if ( !appleBoot32 ) break;
- for (cnt = 0; cnt < (kAppleBootWidth * kAppleBootHeight); cnt++)
- appleBoot32[cnt] = lookUpCLUTIndex(appleBootPict[cnt], 32);
- appleBoot = (char *) appleBoot32;
- break;
-
- default :
- appleBoot = (char *) appleBootPict;
- break;
- }
+ convertImage(kAppleBootWidth, kAppleBootHeight,
+ appleBootPict, &imageData);
x = ( VIDEO(width) - kAppleBootWidth ) / 2;
y = ( VIDEO(height) - kAppleBootHeight ) / 2 + kAppleBootOffset;
// Draw the happy mac in the center of the display.
- if ( appleBoot )
+ if ( imageData )
{
drawDataRectangle( x, y, kAppleBootWidth, kAppleBootHeight,
- appleBoot );
+ imageData );
+ free( imageData );
}
-
free( appleBootPict );
}
- } while (0);
- return err;
+ } while (0);
}
//==========================================================================
return dst;
}
-static void drawColorRectangle( unsigned short x,
+void drawColorRectangle( unsigned short x,
unsigned short y,
unsigned short width,
unsigned short height,
vram = (char *) VIDEO(baseAddr) +
VIDEO(rowBytes) * y + pixelBytes * x;
+ width = MIN(width, VIDEO(width) - x);
+ height = MIN(height, VIDEO(height) - y);
+
while ( height-- )
{
int rem = ( pixelBytes * width ) % 4;
//==========================================================================
// drawDataRectangle
-static void drawDataRectangle( unsigned short x,
- unsigned short y,
- unsigned short width,
- unsigned short height,
- unsigned char * data )
+void drawDataRectangle( unsigned short x,
+ unsigned short y,
+ unsigned short width,
+ unsigned short height,
+ unsigned char * data )
{
+ unsigned short drawWidth;
long pixelBytes = VIDEO(depth) / 8;
- char * vram = (char *) VIDEO(baseAddr) +
- VIDEO(rowBytes) * y + pixelBytes * x;
+ unsigned char * vram = (unsigned char *) VIDEO(baseAddr) +
+ VIDEO(rowBytes) * y + pixelBytes * x;
- while ( height-- )
- {
- bcopy( data, vram, width * pixelBytes );
+ drawWidth = MIN(width, VIDEO(width) - x);
+ height = MIN(height, VIDEO(height) - y);
+ while ( height-- ) {
+ bcopy( data, vram, drawWidth * pixelBytes );
vram += VIDEO(rowBytes);
data += width * pixelBytes;
}
count = getNumberArrayFromProperty( kGraphicsModeKey, params, 4 );
if ( count < 3 )
{
- params[0] = 1024; // Default graphics mode is 1024x768x16.
+ params[0] = 1024; // Default graphics mode is 1024x768x32.
params[1] = 768;
- params[2] = 16;
+ params[2] = 32;
}
// Map from pixel format to bits per pixel.
bootArgs->video.v_display = !gVerboseMode;
if (!gVerboseMode) {
- drawBootGraphics( params[0], params[1], params[2], params[3] );
+ drawBootGraphics();
}
}
}
// Display and clear the activity indicator.
static char indicator[] = {'-', '\\', '|', '/', '-', '\\', '|', '/', '\0'};
+#define kNumIndicators (sizeof(indicator) - 1)
// To prevent a ridiculously fast-spinning indicator,
// ensure a minimum of 1/9 sec between animation frames.
if ( getVideoMode() == TEXT_MODE )
{
- string[0] = indicator[currentIndicator];
+ if (currentIndicator >= kNumIndicators) currentIndicator = 0;
+ string[0] = indicator[currentIndicator++];
printf(string);
- if (indicator[++currentIndicator] == 0)
- currentIndicator = 0;
}
}
printf(" \b");
}
}
+
*
* @APPLE_LICENSE_HEADER_START@
*
- * The contents of this file constitute Original Code as defined in and
- * are subject to the Apple Public Source License Version 1.2 (the
- * "License"). You may not use this file except in compliance with the
- * License. Please obtain a copy of the License at
- * http://www.apple.com/publicsource and read it before using this file.
+ * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights
+ * Reserved. This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 2.0 (the "License"). You may not use this file
+ * except in compliance with the License. Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
*
- * This Original Code and all software distributed under the License are
+ * The Original Code and all software distributed under the License are
* distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
* License for the specific language governing rights and limitations
* under the License.
*
/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2004 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
- * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
+ * Portions Copyright (c) 1999-2004 Apple Computer, Inc. All Rights
* Reserved. This file contains Original Code and/or Modifications of
* Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.1 (the "License"). You may not use this file
+ * Source License Version 2.0 (the "License"). You may not use this file
* except in compliance with the License. Please obtain a copy of the
* License at http://www.apple.com/publicsource and read it before using
* this file.
kScreenLastRow = 24
};
-static BVRef gBootVolume = 0;
-
static void showHelp();
//==========================================================================
//==========================================================================
-static void flushKeyboardBuffer()
+/* Flush keyboard buffer; returns TRUE if any of the flushed
+ * characters was F8.
+ */
+
+static BOOL flushKeyboardBuffer()
{
- while ( readKeyboardStatus() ) getc();
+ BOOL status = FALSE;
+
+ while ( readKeyboardStatus() ) {
+ if (bgetc() == 0x4200) status = TRUE;
+ }
+ return status;
}
//==========================================================================
if (ch = readKeyboardStatus())
break;
+ // Count can be interrupted by holding down shift,
+ // control or alt key
+ if ( ( readKeyboardShiftFlags() & 0x0F ) != 0 ) {
+ ch = 1;
+ break;
+ }
+
if ( time18() >= time )
{
time += 18;
}
else
{
- printf("Press Return to start up the foreign OS. ");
+ printf("Press Enter to start up the foreign OS. ");
}
}
//==========================================================================
-void getBootOptions()
+static void
+printMemoryInfo(void)
+{
+ int line;
+ int i;
+ MemoryRange *mp = bootArgs->memoryMap;
+
+ // Activate and clear page 1
+ setActiveDisplayPage(1);
+ clearScreenRows(0, 24);
+ setCursorPosition( 0, 0, 1 );
+
+ printf("BIOS reported memory ranges:\n");
+ line = 1;
+ for (i=0; i<bootArgs->memoryMapCount; i++) {
+ printf("Base 0x%08x%08x, ",
+ (unsigned long)(mp->base >> 32),
+ (unsigned long)(mp->base));
+ printf("length 0x%08x%08x, type %d\n",
+ (unsigned long)(mp->length >> 32),
+ (unsigned long)(mp->length),
+ mp->type);
+ if (line++ > 20) {
+ printf("(Press a key to continue...)");
+ getc();
+ line = 0;
+ }
+ mp++;
+ }
+ if (line > 0) {
+ printf("(Press a key to continue...)");
+ getc();
+ }
+
+ setActiveDisplayPage(0);
+}
+
+//==========================================================================
+
+int
+getBootOptions(BOOL firstRun)
{
int i;
int key;
int selectIndex = 0;
int bvCount;
int nextRow;
+ int timeout;
BVRef bvr;
BVRef bvChain;
BVRef menuBVR;
BOOL showPrompt, newShowPrompt;
MenuItem * menuItems = NULL;
- static BOOL firstRun = YES;
+
+ // Allow user to override default timeout.
+
+ if ( getIntForKey(kTimeoutKey, &timeout) == NO )
+ {
+ timeout = kBootTimeout;
+ }
+
+ // If the user is holding down a shift key,
+ // abort quiet mode.
+ if ( ( readKeyboardShiftFlags() & 0x0F ) != 0 ) {
+ gBootMode &= ~kBootModeQuiet;
+ }
+
+ // If user typed F8, abort quiet mode,
+ // and display the menu.
+ if (flushKeyboardBuffer()) {
+ gBootMode &= ~kBootModeQuiet;
+ timeout = 0;
+ }
clearBootArgs();
- clearScreenRows( kMenuTopRow, kScreenLastRow );
+
+ setCursorPosition( 0, 0, 0 );
+ clearScreenRows( 0, kScreenLastRow );
+ if ( ! ( gBootMode & kBootModeQuiet ) ) {
+ // Display banner and show hardware info.
+ printf( bootBanner, (bootArgs->convmem + bootArgs->extmem) / 1024 );
+ printVBEInfo();
+ }
+
changeCursor( 0, kMenuTopRow, kCursorTypeUnderline, 0 );
+
verbose("Scanning device %x...", gBIOSDev);
// Get a list of bootable volumes on the device.
}
#endif
- // Allow user to override default setting.
+ if ( gBootMode & kBootModeQuiet )
+ {
+ // No input allowed from user.
+ goto done;
+ }
- if ( firstRun &&
- countdown("Press any key to enter startup options.",
- kMenuTopRow, 3) == 0 )
+ if ( firstRun && ( timeout > 0 ) &&
+ ( countdown("Press any key to enter startup options.",
+ kMenuTopRow, timeout) == 0 ) )
{
goto done;
}
for ( bvr = bvChain, i = bvCount - 1, selectIndex = 0;
bvr; bvr = bvr->next, i-- )
{
- getBootVolumeDescription( bvr, menuItems[i].name, 80 );
+ getBootVolumeDescription( bvr, menuItems[i].name, 80, YES );
menuItems[i].param = (void *) bvr;
if ( bvr == menuBVR ) selectIndex = i;
}
case kReturnKey:
if ( *gBootArgs == '?' )
{
- showHelp(); key = 0;
+ if ( strcmp( gBootArgs, "?video" ) == 0 ) {
+ printVBEModeInfo();
+ } else if ( strcmp( gBootArgs, "?memory" ) == 0 ) {
+ printMemoryInfo();
+ } else {
+ showHelp();
+ }
+ key = 0;
showBootPrompt( nextRow, showPrompt );
break;
}
changeCursor( 0, kMenuTopRow, kCursorTypeUnderline, 0 );
if ( menuItems ) free(menuItems);
+
+ return 0;
}
//==========================================================================
int cnt;
int userCnt;
int cntRemaining;
+ char * argP;
skipblanks( &cp );
if ( !sysConfigValid ) return -1;
// Use the kernel name specified by the user, or fetch the name
- // in the config table.
-
- if (( kernel = extractKernelName((char **)&cp) ))
- {
+ // in the config table, or use the default if not specified.
+ // Specifying a kernel name on the command line, or specifying
+ // a non-default kernel name in the config file counts as
+ // overriding the kernel, which causes the kernelcache not
+ // to be used.
+
+ gOverrideKernel = NO;
+ if (( kernel = extractKernelName((char **)&cp) )) {
strcpy( bootArgs->bootFile, kernel );
- }
- else
- {
- if ( getValueForKey( kKernelNameKey, &val, &cnt ) )
+ gOverrideKernel = YES;
+ } else {
+ if ( getValueForKey( kKernelNameKey, &val, &cnt ) ) {
strlcpy( bootArgs->bootFile, val, cnt+1 );
+ if (strcmp( bootArgs->bootFile, kDefaultKernel ) != 0) {
+ gOverrideKernel = YES;
+ }
+ } else {
+ strcpy( bootArgs->bootFile, kDefaultKernel );
+ }
+ }
+
+ cntRemaining = BOOT_STRING_LEN - 2; // save 1 for NULL, 1 for space
+
+ // Check to see if we need to specify root device.
+ // If user types "rd=.." on the boot line, it overrides
+ // the boot device key in the boot arguments file.
+ //
+ argP = bootArgs->bootString;
+ if ( getValueForBootKey( cp, kRootDeviceKey, &val, &cnt ) == FALSE &&
+ getValueForKey( kRootDeviceKey, &val, &cnt ) == FALSE ) {
+ if ( getValueForKey( kBootDeviceKey, &val, &cnt ) ) {
+ strcpy( argP, "rd=*" );
+ argP += 4;
+ strlcpy( argP, val, cnt+1);
+ cntRemaining -= cnt;
+ argP += cnt;
+ *argP++ = ' ';
+ }
}
// Check to see if we should ignore saved kernel flags.
- if (getValueForBootKey(cp, "-F", &val, &cnt) == FALSE) {
+ if (getValueForBootKey(cp, kIgnoreBootFileFlag, &val, &cnt) == FALSE) {
if (getValueForKey( kKernelFlagsKey, &val, &cnt ) == FALSE) {
val = 0;
cnt = 0;
// Store the merged kernel flags and boot args.
- cntRemaining = BOOT_STRING_LEN - 2; // save 1 for NULL, 1 for space
if (cnt > cntRemaining) {
error("Warning: boot arguments too long, truncated\n");
cnt = cntRemaining;
}
if (cnt) {
- strncpy(bootArgs->bootString, val, cnt);
- bootArgs->bootString[cnt++] = ' ';
+ strncpy(argP, val, cnt);
+ argP[cnt++] = ' ';
}
cntRemaining = cntRemaining - cnt;
userCnt = strlen(cp);
error("Warning: boot arguments too long, truncated\n");
userCnt = cntRemaining;
}
- strncpy(&bootArgs->bootString[cnt], cp, userCnt);
- bootArgs->bootString[cnt+userCnt] = '\0';
+ strncpy(&argP[cnt], cp, userCnt);
+ argP[cnt+userCnt] = '\0';
- gVerboseMode = getValueForKey( "-v", &val, &cnt ) ||
- getValueForKey( "-s", &val, &cnt );
+ gVerboseMode = getValueForKey( kVerboseModeFlag, &val, &cnt ) ||
+ getValueForKey( kSingleUserModeFlag, &val, &cnt );
- gBootGraphics = getBoolForKey( kBootGraphicsKey );
+ gBootMode = ( getValueForKey( kSafeModeFlag, &val, &cnt ) ) ?
+ kBootModeSafe : kBootModeNormal;
- gBootGraphics = YES;
- if ( getValueForKey(kBootGraphicsKey, &val, &cnt) && cnt &&
- (val[0] == 'N' || val[0] == 'n') )
- gBootGraphics = NO;
+ if ( getValueForKey( kPlatformKey, &val, &cnt ) ) {
+ strlcpy(gPlatformName, val, cnt + 1);
+ } else {
+ strcpy(gPlatformName, "ACPI");
+ }
- gBootMode = ( getValueForKey( "-f", &val, &cnt ) ) ?
- kBootModeSafe : kBootModeNormal;
+ if ( getValueForKey( kMKextCacheKey, &val, &cnt ) ) {
+ strlcpy(gMKextName, val, cnt + 1);
+ }
return 0;
}
#define BOOT_HELP_PATH "/usr/standalone/i386/BootHelp.txt"
int fd;
+ int size;
+ int line;
+ int line_offset;
+ int c;
if ( (fd = open(BOOT_HELP_PATH, 0)) >= 0 )
{
char * buffer;
+ char * bp;
+
+ size = file_size(fd);
+ buffer = malloc( size + 1 );
+ read(fd, buffer, size);
+ close(fd);
- // Activate and clear page 1
- // Perhaps this should be loaded only once?
+ bp = buffer;
+ while (size > 0) {
+ while (*bp != '\n') {
+ bp++;
+ size--;
+ }
+ *bp++ = '\0';
+ size--;
+ }
+ *bp = '\1';
+ line_offset = 0;
setActiveDisplayPage(1);
- clearScreenRows(0, 24);
- setCursorPosition( 0, 0, 1 );
-
- buffer = malloc( file_size(fd) );
- read(fd, buffer, file_size(fd) - 1);
- close(fd);
- printf("%s", buffer);
- free(buffer);
-
- // Wait for a keystroke and return to page 0.
- getc();
+ while (1) {
+ clearScreenRows(0, 24);
+ setCursorPosition(0, 0, 1);
+ bp = buffer;
+ for (line = 0; *bp != '\1' && line < line_offset; line++) {
+ while (*bp != '\0') bp++;
+ bp++;
+ }
+ for (line = 0; *bp != '\1' && line < 23; line++) {
+ setCursorPosition(0, line, 1);
+ printf("%s\n", bp);
+ while (*bp != '\0') bp++;
+ bp++;
+ }
+
+ setCursorPosition(0, 23, 1);
+ if (*bp == '\1') {
+ printf("[Type %sq or space to quit help]",
+ (line_offset > 0) ? "p for previous page, " : "");
+ } else {
+ printf("[Type %s%sq to quit help]",
+ (line_offset > 0) ? "p for previous page, " : "",
+ (*bp != '\1') ? "space for next page, " : "");
+ }
+
+ c = getc();
+ if (c == 'q' || c == 'Q') {
+ break;
+ }
+ if ((c == 'p' || c == 'P') && line_offset > 0) {
+ line_offset -= 23;
+ }
+ if (c == ' ') {
+ if (*bp == '\1') {
+ break;
+ } else {
+ line_offset += 23;
+ }
+ }
+ }
+
+ free(buffer);
setActiveDisplayPage(0);
}
}
/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
- * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
+ * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights
* Reserved. This file contains Original Code and/or Modifications of
* Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.1 (the "License"). You may not use this file
+ * Source License Version 2.0 (the "License"). You may not use this file
* except in compliance with the License. Please obtain a copy of the
* License at http://www.apple.com/publicsource and read it before using
* this file.
#include "vers.h"
char bootBanner[] = "\nDarwin/x86 boot v" I386BOOT_VERSION "\n"
- "%dK conventional / %dK extended memory\n";
+ "%dMB memory\n";
char bootPrompt[] =
- "Press Return to start up Darwin/x86 with no options, or you can:\n"
- " Type -v and press Return to start up with diagnostic messages\n"
- " Type ? and press Return to learn about advanced startup options\n\n"
+ "Press Enter to start up Darwin/x86 with no options, or you can:\n"
+ " Type -v and press Enter to start up with diagnostic messages\n"
+ " Type ? and press Enter to learn about advanced startup options\n\n"
"boot: ";
cp $(SYMROOT)/cdboot $(INSTALLDIR)
cd $(INSTALLDIR); chmod u+w cdboot
+clean::
+ rm -f $(SYMROOT)/cdboot
+
include ../MakeInc.dir
#dependencies
-; Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
+; Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
;
; @APPLE_LICENSE_HEADER_START@
;
-; Portions Copyright (c) 2002 Apple Computer, Inc. All Rights
+; Portions Copyright (c) 2002-2003 Apple Computer, Inc. All Rights
; Reserved. This file contains Original Code and/or Modifications of
; Original Code as defined in and that are subject to the Apple Public
-; Source License Version 1.2 (the "License"). You may not use this file
+; Source License Version 2.0 (the "License"). You may not use this file
; except in compliance with the License. Please obtain a copy of the
; License at http://www.apple.com/publicsource and read it before using
; this file.
; Portions Copyright (c) 2003 Apple Computer, Inc. All Rights
; Reserved. This file contains Original Code and/or Modifications of
; Original Code as defined in and that are subject to the Apple Public
-; Source License Version 1.2 (the "License"). You may not use this file
+; Source License Version 2.0 (the "License"). You may not use this file
; except in compliance with the License. Please obtain a copy of the
; License at http://www.apple.com/publicsource and read it before using
; this file.
-Limits on various things
-
-Sarld can only be 128k long (when loaded).
-Drivers relocatable files can't be bigger than 320K.
-Kernel symbols can't be bigger than 512k.
-Sarld can't use more than 1024k of malloc memory.
-Kernel symbols can't be more than 512k bytes long.
-Kernel + drivers can't be more than 5.5Mb.
-
The memory map and sizes of various things are in libsa/memory.h.
all: $(DIRS_NEEDED) $(LIBS)
libsa.a: $(SA_OBJS)
- rm -f $(SYMROOT)/libsa.a
- ar q $(SYMROOT)/libsa.a $(SA_OBJS)
- ranlib $(SYMROOT)/libsa.a
+ rm -f $(SYMROOT)/$(@F)
+ ar q $(SYMROOT)/$(@F) $^
+ ranlib $(SYMROOT)/$(@F)
clean::
rm -rf $(SYMROOT)/libsa.a $(SYMROOT)/libsaio.a
/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
- * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
+ * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights
* Reserved. This file contains Original Code and/or Modifications of
* Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.1 (the "License"). You may not use this file
+ * Source License Version 2.0 (the "License"). You may not use this file
* except in compliance with the License. Please obtain a copy of the
* License at http://www.apple.com/publicsource and read it before using
* this file.
/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
- * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
+ * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights
* Reserved. This file contains Original Code and/or Modifications of
* Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.1 (the "License"). You may not use this file
+ * Source License Version 2.0 (the "License"). You may not use this file
* except in compliance with the License. Please obtain a copy of the
* License at http://www.apple.com/publicsource and read it before using
* this file.
*/
extern long strtol(const char * nptr, char ** endptr, int base);
extern unsigned long strtoul(const char * nptr, char ** endptr, int base);
+extern unsigned long long strtouq(const char *nptr, char ** endptr, int base);
/*
* prf.c
/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
- * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
+ * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights
* Reserved. This file contains Original Code and/or Modifications of
* Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.1 (the "License"). You may not use this file
+ * Source License Version 2.0 (the "License"). You may not use this file
* except in compliance with the License. Please obtain a copy of the
* License at http://www.apple.com/publicsource and read it before using
* this file.
/* Memory addresses used by booter and friends */
#define BASE_SEG 0x2000
-#define STACK_SEG 0x3000
+#define STACK_SEG 0x5000
#define STACK_OFS 0xFFF0 // stack pointer
#define BOOT1U_SEG 0x1000
#define BOOT2_SEG BASE_SEG
#define BOOT2_OFS 0x0200 // 512 byte disk sector offset
-#define BIOS_ADDR 0x0C00 // BIOS disk I/O buffer
-#define BIOS_LEN 0x2000 // 8K - divisible by 512 and 2048
+#define BIOS_ADDR 0x8000 // BIOS disk I/O buffer
+#define BIOS_LEN 0x8000 // 32K - divisible by 512 and 2048
+
+#define BOOT0_ADDR 0x7E00 // boot0 gets loaded here
+
/* These are all "virtual" addresses...
* which are physical addresses plus MEMBASE.
#define MEMBASE 0x0
-#define BOOTSTRUCT_ADDR 0x011000 // it's slightly smaller
-#define BOOTSTRUCT_LEN 0x00F000
+#define BOOTSTRUCT_ADDR 0x00011000 // it's slightly smaller
+#define BOOTSTRUCT_LEN 0x0000F000
#define BASE_ADDR ADDR32(BASE_SEG, 0)
#define BASE1U_ADDR ADDR32(BOOT1U_SEG, 0)
#define BOOT1U_ADDR ADDR32(BOOT1U_SEG, BOOT1U_OFS)
#define BOOT2_ADDR ADDR32(BOOT2_SEG, BOOT2_OFS)
-#define VIDEO_ADDR 0x0A0000 // unusable space
-#define VIDEO_LEN 0x060000
+#define HIB_ADDR 0x00040000 // special hibernation area
+#define HIB_LEN 0x00060000
+
+#define VIDEO_ADDR 0x000A0000 // unusable space
+#define VIDEO_LEN 0x00060000
-#define KERNEL_ADDR 0x0100000 // 64M kernel + drivers
-#define KERNEL_LEN 0x4000000
+#define KERNEL_ADDR 0x00100000 // 64M kernel + drivers
+#define KERNEL_LEN 0x04000000
-#define ZALLOC_ADDR 0x4100000 // 47M zalloc area
-#define ZALLOC_LEN 0x2F00000
+#define ZALLOC_ADDR 0x04100000 // 47M zalloc area
+#define ZALLOC_LEN 0x02F00000
-#define LOAD_ADDR 0x7000000 // 16M File load buffer
-#define LOAD_LEN 0x1000000
+#define LOAD_ADDR 0x07000000 // 16M File load buffer
+#define LOAD_LEN 0x01000000
#define TFTP_ADDR LOAD_ADDR // tftp download buffer
#define TFTP_LEN LOAD_LEN
/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
- * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
+ * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights
* Reserved. This file contains Original Code and/or Modifications of
* Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.1 (the "License"). You may not use this file
+ * Source License Version 2.0 (the "License"). You may not use this file
* except in compliance with the License. Please obtain a copy of the
* License at http://www.apple.com/publicsource and read it before using
* this file.
#define SPACE 1
#define ZERO 2
+#define UCASE 16
/*
* Scaled down version of C Library printf.
}
cp = prbuf;
do {
- *cp++ = "0123456789abcdef"[n%b];
+ *cp++ = "0123456789abcdef0123456789ABCDEF"[(flag & UCASE) + n%b];
n /= b;
width++;
} while (n);
{
int b, c;
char *s;
- int flag = 0, minwidth = 0, width = 0;
+ int flag = 0, width = 0;
+ int minwidth;
loop:
while ((c = *fmt++) != '%') {
return;
(*putfn_p)(c, putfn_arg);
}
+ minwidth = 0;
again:
c = *fmt++;
switch (c) {
minwidth *= 10;
minwidth += c - '0';
goto again;
- case 'x': case 'X':
+ case 'X':
+ flag |= UCASE;
+ /* fall through */
+ case 'x':
b = 16;
goto number;
case 'd':
/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
- * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
+ * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights
* Reserved. This file contains Original Code and/or Modifications of
* Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.1 (the "License"). You may not use this file
+ * Source License Version 2.0 (the "License"). You may not use this file
* except in compliance with the License. Please obtain a copy of the
* License at http://www.apple.com/publicsource and read it before using
* this file.
*pi.str = '\0';
return (pi.str - str);
}
-
/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
- * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
+ * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights
* Reserved. This file contains Original Code and/or Modifications of
* Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.1 (the "License"). You may not use this file
+ * Source License Version 2.0 (the "License"). You may not use this file
* except in compliance with the License. Please obtain a copy of the
* License at http://www.apple.com/publicsource and read it before using
* this file.
/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
- * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
+ * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights
* Reserved. This file contains Original Code and/or Modifications of
* Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.1 (the "License"). You may not use this file
+ * Source License Version 2.0 (the "License"). You may not use this file
* except in compliance with the License. Please obtain a copy of the
* License at http://www.apple.com/publicsource and read it before using
* this file.
return dst;
}
+#if 0
void * memcpy(void * dst, const void * src, size_t len)
{
asm( "rep; movsb"
memset(dst, 0, len);
}
+#else
+void * memcpy(void * dst, const void * src, size_t len)
+{
+ asm( "cld \n\t"
+ "movl %%ecx, %%edx \n\t"
+ "shrl $2, %%ecx \n\t"
+ "rep; movsl \n\t"
+ "movl %%edx, %%ecx \n\t"
+ "andl $3, %%ecx \n\t"
+ "rep; movsb \n\t"
+ : "=D" (dst)
+ : "c" (len), "D" (dst), "S" (src)
+ : "memory", "%edx" );
+
+ return dst;
+}
+
+void bcopy(const void * src, void * dst, size_t len)
+{
+ asm( "cld \n\t"
+ "movl %%ecx, %%edx \n\t"
+ "shrl $2, %%ecx \n\t"
+ "rep; movsl \n\t"
+ "movl %%edx, %%ecx \n\t"
+ "andl $3, %%ecx \n\t"
+ "rep; movsb \n\t"
+ :
+ : "c" (len), "D" (dst), "S" (src)
+ : "memory", "%edx" );
+}
+
+void bzero(void * dst, size_t len)
+{
+ asm( "xorl %%eax, %%eax \n\t"
+ "cld \n\t"
+ "movl %%ecx, %%edx \n\t"
+ "shrl $2, %%ecx \n\t"
+ "rep; stosl \n\t"
+ "movl %%edx, %%ecx \n\t"
+ "andl $3, %%ecx \n\t"
+ "rep; stosb \n\t"
+ :
+ : "c" (len), "D" (dst)
+ : "memory", "%eax" );
+}
+#endif
+
/* #if DONT_USE_GCC_BUILT_IN_STRLEN */
#define tolower(c) ((int)((c) & ~0x20))
/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
- * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
+ * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights
* Reserved. This file contains Original Code and/or Modifications of
* Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.1 (the "License"). You may not use this file
+ * Source License Version 2.0 (the "License"). You may not use this file
* except in compliance with the License. Please obtain a copy of the
* License at http://www.apple.com/publicsource and read it before using
* this file.
*endptr = (char *)(any ? s - 1 : nptr);
return (acc);
}
+
+/*
+ * Convert a string to an unsigned quad integer.
+ *
+ * Ignores `locale' stuff. Assumes that the upper and lower case
+ * alphabets and digits are each contiguous.
+ */
+unsigned long long
+strtouq(nptr, endptr, base)
+ const char *nptr;
+ char **endptr;
+ register int base;
+{
+ register const char *s = nptr;
+ register unsigned long long acc;
+ register int c;
+ register unsigned long long qbase, cutoff;
+ register int neg, any, cutlim;
+
+ /*
+ * See strtoq for comments as to the logic used.
+ */
+ s = nptr;
+ do {
+ c = *s++;
+ } while (isspace(c));
+ if (c == '-') {
+ neg = 1;
+ c = *s++;
+ } else {
+ neg = 0;
+ if (c == '+')
+ c = *s++;
+ }
+ if ((base == 0 || base == 16) &&
+ c == '0' && (*s == 'x' || *s == 'X')) {
+ c = s[1];
+ s += 2;
+ base = 16;
+ }
+ if (base == 0)
+ base = c == '0' ? 8 : 10;
+ qbase = (unsigned)base;
+ cutoff = (unsigned long long)UQUAD_MAX / qbase;
+ cutlim = (unsigned long long)UQUAD_MAX % qbase;
+ for (acc = 0, any = 0;; c = *s++) {
+ if (isdigit(c))
+ c -= '0';
+ else if (isalpha(c))
+ c -= isupper(c) ? 'A' - 10 : 'a' - 10;
+ else
+ break;
+ if (c >= base)
+ break;
+ if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim)
+ any = -1;
+ else {
+ any = 1;
+ acc *= qbase;
+ acc += c;
+ }
+ }
+ if (any < 0) {
+ acc = UQUAD_MAX;
+// errno = ERANGE;
+ } else if (neg)
+ acc = -acc;
+ if (endptr != 0)
+ *endptr = (char *)(any ? s - 1 : nptr);
+ return (acc);
+}
/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
- * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
+ * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights
* Reserved. This file contains Original Code and/or Modifications of
* Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.1 (the "License"). You may not use this file
+ * Source License Version 2.0 (the "License"). You may not use this file
* except in compliance with the License. Please obtain a copy of the
* License at http://www.apple.com/publicsource and read it before using
* this file.
zalloc_base = start ? start : (char *)ZALLOC_ADDR;
totalNodes = nodes ? nodes : ZALLOC_NODES;
zalloced = (zmem *) zalloc_base;
- zavailable = (zmem *) zalloc_base + sizeof(zmem) * totalNodes;;
+ zavailable = (zmem *) zalloc_base + sizeof(zmem) * totalNodes;
zavailable[0].start = (char *)zavailable + sizeof(zmem) * totalNodes;
if (size == 0) size = ZALLOC_LEN;
zavailable[0].size = size - (zavailable[0].start - zalloc_base);
UTILDIR = ../util
LIBSADIR = ../libsa
INSTALLDIR = $(DSTROOT)/System/Library/Frameworks/System.framework/Versions/B/PrivateHeaders/standalone
-SYMROOT=
+#SYMROOT=
OPTIM = -Os
CFLAGS = $(RC_CFLAGS) $(OPTIM) $(MORECPP) -arch i386 -g -Wmost -Werror \
ufs.o ufs_byteorder.o \
stringTable.o load.o memory.o misc.o \
vbe.o nbp.o hfs.o hfs_compare.o \
- xml.o
+ xml.o ntfs.o msdos.o
SAIO_EXTERN_OBJS = console.o
libsaio.a: $(SAIO_EXTERN_OBJS) $(SAIO_OBJS)
rm -f $(SYMROOT)/$(@F)
- ar q $(SYMROOT)/$(@F) $(SAIO_EXTERN_OBJS) $(SAIO_OBJS)
+ ar q $(SYMROOT)/$(@F) $^
ranlib $(SYMROOT)/$(@F)
#saio_internal.h: saio_external.h
/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
- * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
+ * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights
* Reserved. This file contains Original Code and/or Modifications of
* Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.1 (the "License"). You may not use this file
+ * Source License Version 2.0 (the "License"). You may not use this file
* except in compliance with the License. Please obtain a copy of the
* License at http://www.apple.com/publicsource and read it before using
* this file.
/*
* HISTORY
* $Log: asm.s,v $
+ * Revision 1.7 2004/05/13 17:58:38 curtisg
+ * Integrating:
+ * <rdar://problem/3094680>: (Silent boot)
+ * <rdar://problem/3363893>: (5 sec boot timeout is too short)
+ * <rdar://problem/3533781>: (Boot option to display graphics modes)
+ * <rdar://problem/3545539>: (Default graphics mode should be 32-bit)
+ * <rdar://problem/3643065>: (Booter should always find a video mode)
+ * <rdar://problem/3643815>: (Booter displays "0MB" VRAM)
+ *
+ * Revision 1.6 2003/11/05 20:51:02 curtisg
+ * Integrated 3069695,3331770,3370488,3371823
+ *
+ * Revision 1.5.26.1 2003/10/27 23:57:59 curtisg
+ * Added printing of volume names, better handling of extended
+ * partitions, and updated Apple license strings.
+ * New chain booter should work better with foreign operating
+ * systems.
+ *
* Revision 1.5 2002/11/05 20:34:26 jliu
* Integrating:
* 3051234 boot shouldnt require Graphics = Yes
leave
ret
-#if 0
+#if UNUSED
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// pcpy(src, dst, cnt)
// where src is a virtual address and dst is a physical address
/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
- * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
+ * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights
* Reserved. This file contains Original Code and/or Modifications of
* Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.1 (the "License"). You may not use this file
+ * Source License Version 2.0 (the "License"). You may not use this file
* except in compliance with the License. Please obtain a copy of the
* License at http://www.apple.com/publicsource and read it before using
* this file.
/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
- * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
+ * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights
* Reserved. This file contains Original Code and/or Modifications of
* Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.1 (the "License"). You may not use this file
+ * Source License Version 2.0 (the "License"). You may not use this file
* except in compliance with the License. Please obtain a copy of the
* License at http://www.apple.com/publicsource and read it before using
* this file.
/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
- * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
+ * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights
* Reserved. This file contains Original Code and/or Modifications of
* Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.1 (the "License"). You may not use this file
+ * Source License Version 2.0 (the "License"). You may not use this file
* except in compliance with the License. Please obtain a copy of the
* License at http://www.apple.com/publicsource and read it before using
* this file.
MemoryRange * range = rangeArray;
unsigned long count = 0;
unsigned long long conMemSize = 0;
- unsigned long long extMemTop = 0;
+ unsigned long long extMemSize = 0;
// The memory pointed by the rangeArray must reside within the
// first megabyte.
range->type == kMemoryRangeNVS )
{
// Tally the conventional memory ranges.
- if ( range->base + range->length <= 0xa0000 )
+ if ( range->base + range->length <= 0xa0000 ) {
conMemSize += range->length;
+ }
// Record the top of extended memory.
- if ( range->base >= EXTENDED_ADDR &&
- range->base >= extMemTop )
- extMemTop = range->base + range->length;
+ if ( range->base >= EXTENDED_ADDR ) {
+ extMemSize += range->length;
+ }
}
range++;
if ( bb.ebx.rx == 0 ) break;
}
-
- if (extMemTop) extMemTop -= EXTENDED_ADDR; // convert to size
*conMemSizePtr = conMemSize / 1024; // size in KB
- *extMemSizePtr = extMemTop / 1024; // size in KB
+ *extMemSizePtr = extMemSize / 1024; // size in KB
+
+#if DEBUG
+ {
+ for (range = rangeArray; range->length != 0; range++) {
+ printf("range: type %d, base 0x%x, length 0x%x\n",
+ range->type, (unsigned int)range->base, (unsigned int)range->length); getc();
+
+ }
+ }
+#endif
return count;
}
unsigned short bufferOffset;
unsigned short bufferSegment;
unsigned long long startblock;
- } addrpacket = {0};
+ } addrpacket __attribute__((aligned(16))) = {0};
addrpacket.size = sizeof(addrpacket);
for (i=0;;) {
return bb.eax.r.h;
}
+int ebioswrite(int dev, long sec, int count)
+{
+ int i;
+ static struct {
+ unsigned char size;
+ unsigned char reserved;
+ unsigned char numblocks;
+ unsigned char reserved2;
+ unsigned short bufferOffset;
+ unsigned short bufferSegment;
+ unsigned long long startblock;
+ } addrpacket __attribute__((aligned(16))) = {0};
+ addrpacket.size = sizeof(addrpacket);
+
+ for (i=0;;) {
+ bb.intno = 0x13;
+ bb.eax.r.l = 0; /* Don't verify */
+ bb.eax.r.h = 0x43;
+ bb.edx.r.l = dev;
+ bb.esi.rr = OFFSET((unsigned)&addrpacket);
+ bb.ds = SEGMENT((unsigned)&addrpacket);
+ addrpacket.reserved = addrpacket.reserved2 = 0;
+ addrpacket.numblocks = count;
+ addrpacket.bufferOffset = OFFSET(ptov(BIOS_ADDR));
+ addrpacket.bufferSegment = SEGMENT(ptov(BIOS_ADDR));
+ addrpacket.startblock = sec;
+ bios(&bb);
+ if ((bb.eax.r.h == 0x00) || (i++ >= 5))
+ break;
+
+ /* reset disk subsystem and try again */
+ bb.eax.r.h = 0x00;
+ bios(&bb);
+ }
+ return bb.eax.r.h;
+}
+
void putc(int ch)
{
bb.intno = 0x10;
unsigned char sec_count;
unsigned char head_count;
unsigned char reseved;
- };
+ } __attribute__((packed));
static struct packet pkt;
bzero(&pkt, sizeof(pkt));
boot_drive_info_t *di = &dp->di;
int ret = 0;
-#if 0
+#if UNUSED
if (maxhd == 0) {
bb.intno = 0x13;
bb.eax.r.h = 0x08;
}
#endif
+#ifdef APM_SUPPORT
+
#define APM_INTNO 0x15
#define APM_INTCODE 0x53
return 0;
}
+#endif /* APM_SUPPORT */
+
#ifdef EISA_SUPPORT
BOOL
eisa_present(
bb.edx.rr = ms & 0xFFFF;
bios(&bb);
}
+
/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
- * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
+ * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights
* Reserved. This file contains Original Code and/or Modifications of
* Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.1 (the "License"). You may not use this file
+ * Source License Version 2.0 (the "License"). You may not use this file
* except in compliance with the License. Please obtain a copy of the
* License at http://www.apple.com/publicsource and read it before using
* this file.
/*
- * Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
- * Portions Copyright (c) 2002 Apple Computer, Inc. All Rights
+ * Portions Copyright (c) 2002-2003 Apple Computer, Inc. All Rights
* Reserved. This file contains Original Code and/or Modifications of
* Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.1 (the "License"). You may not use this file
+ * Source License Version 2.0 (the "License"). You may not use this file
* except in compliance with the License. Please obtain a copy of the
* License at http://www.apple.com/publicsource and read it before using
* this file.
/*
- * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2003 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* The contents of this file constitute Original Code as defined in and
- * are subject to the Apple Public Source License Version 1.1 (the
+ * are subject to the Apple Public Source License Version 2.0 (the
* "License"). You may not use this file except in compliance with the
* License. Please obtain a copy of the License at
* http://www.apple.com/publicsource and read it before using this file.
/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
- * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
+ * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights
* Reserved. This file contains Original Code and/or Modifications of
* Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.1 (the "License"). You may not use this file
+ * Source License Version 2.0 (the "License"). You may not use this file
* except in compliance with the License. Please obtain a copy of the
* License at http://www.apple.com/publicsource and read it before using
* this file.
*/
#include "libsaio.h"
+#include "bootstruct.h"
BOOL gVerboseMode;
BOOL gErrors;
int printf(const char * fmt, ...)
{
va_list ap;
+ if (bootArgs->graphicsMode != TEXT_MODE) return -1;
va_start(ap, fmt);
prf(fmt, ap, putchar, 0);
va_end(ap);
/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
- * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
+ * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights
* Reserved. This file contains Original Code and/or Modifications of
* Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.1 (the "License"). You may not use this file
+ * Source License Version 2.0 (the "License"). You may not use this file
* except in compliance with the License. Please obtain a copy of the
* License at http://www.apple.com/publicsource and read it before using
* this file.
#include "fdisk.h"
#include "ufs.h"
#include "hfs.h"
+#include "ntfs.h"
+#include "msdos.h"
#include <limits.h>
#include <IOKit/storage/IOApplePartitionScheme.h>
* biosbuf points to a sector within the track cache, and is
* updated by Biosread().
*/
-static const char * const trackbuf = (char *) ptov(BIOS_ADDR);
-static const char * biosbuf;
+static char * const trackbuf = (char *) ptov(BIOS_ADDR);
+static char * biosbuf;
/*
* Map a disk drive to bootable volumes contained within.
// Return:
// 0 on success, or an error code from INT13/F2 or INT13/F42 BIOS call.
+static BOOL cache_valid = FALSE;
+
static int Biosread( int biosdev, unsigned int secno )
{
static int xbiosdev, xcyl, xhead;
static unsigned int xsec, xnsecs;
- static BOOL cache_valid = FALSE;
struct driveInfo di;
int rc = -1;
bps = 2048;
} else {
bps = di.di.params.phys_nbps;
+ if (bps == 0) {
+ return -1;
+ }
}
divisor = bps / BPS;
{
static int sBiosdev = -1;
static int sNextPartNo;
+ static unsigned int sFirstBase;
static unsigned int sExtBase;
static unsigned int sExtDepth;
static struct fdisk_part * sExtPart;
sBiosdev = biosdev;
sNextPartNo = 0;
+ sFirstBase = 0;
sExtBase = 0;
sExtDepth = 0;
sExtPart = NULL;
}
else if ( sExtPart )
{
- unsigned int blkno = sExtPart->relsect + sExtBase;
+ unsigned int blkno = sExtPart->relsect + sFirstBase;
// Save the block offset of the first extended partition.
- if ( sExtDepth == 0 ) sExtBase = sExtPart->relsect;
+ if (sExtDepth == 0) {
+ sFirstBase = blkno;
+ }
+ sExtBase = blkno;
// Load extended partition table.
sExtPart = NULL;
continue;
}
+ // Fall through to part == NULL
}
if ( part == NULL ) break; // Reached end of partition chain.
sNextPartNo++;
- // Assume at most one extended partition per table.
-
if ( isExtendedFDiskPartition(part) )
{
sExtPart = part;
}
// Change relative offset to an absolute offset.
-
part->relsect += sExtBase;
*outPart = part;
- *partno = sExtDepth ? (int)(sExtDepth + 4) : sNextPartNo;
+ *partno = sExtDepth ? (int)(sExtDepth + FDISK_NPART) : sNextPartNo;
break;
}
static BVRef newFDiskBVRef( int biosdev, int partno, unsigned int blkoff,
const struct fdisk_part * part,
FSInit initFunc, FSLoadFile loadFunc,
- FSGetDirEntry getdirFunc, int probe, int type )
+ FSReadFile readFunc,
+ FSGetDirEntry getdirFunc,
+ FSGetFileBlock getBlockFunc,
+ BVGetDescription getDescriptionFunc,
+ int probe, int type )
{
BVRef bvr = (BVRef) malloc( sizeof(*bvr) );
if ( bvr )
bvr->part_boff = blkoff;
bvr->part_type = part->systid;
bvr->fs_loadfile = loadFunc;
+ bvr->fs_readfile = readFunc;
bvr->fs_getdirentry = getdirFunc;
- bvr->description = getVolumeDescription;
+ bvr->fs_getfileblock= getBlockFunc;
+ bvr->description = getDescriptionFunc ?
+ getDescriptionFunc : getVolumeDescription;
bvr->type = type;
if ( part->bootid & FDISK_ACTIVE )
BVRef newAPMBVRef( int biosdev, int partno, unsigned int blkoff,
const DPME * part,
FSInit initFunc, FSLoadFile loadFunc,
- FSGetDirEntry getdirFunc, int probe, int type )
+ FSReadFile readFunc,
+ FSGetDirEntry getdirFunc,
+ FSGetFileBlock getBlockFunc,
+ BVGetDescription getDescriptionFunc,
+ int probe, int type )
{
BVRef bvr = (BVRef) malloc( sizeof(*bvr) );
if ( bvr )
bvr->part_no = partno;
bvr->part_boff = blkoff;
bvr->fs_loadfile = loadFunc;
+ bvr->fs_readfile = readFunc;
bvr->fs_getdirentry = getdirFunc;
- bvr->description = getVolumeDescription;
+ bvr->fs_getfileblock= getBlockFunc;
+ bvr->description = getDescriptionFunc ?
+ getDescriptionFunc : getVolumeDescription;
bvr->type = type;
strlcpy(bvr->name, part->dpme_name, DPISTRLEN);
strlcpy(bvr->type_name, part->dpme_type, DPISTRLEN);
//==========================================================================
+/* A note on partition numbers:
+ * IOKit makes the primary partitions numbers 1-4, and then
+ * extended partitions are numbered consecutively 5 and up.
+ * So, for example, if you have two primary partitions and
+ * one extended partition they will be numbered 1, 2, 5.
+ */
+
static BVRef diskScanFDiskBootVolumes( int biosdev, int * countPtr )
{
const struct fdisk_part * part;
part,
UFSInitPartition,
UFSLoadFile,
+ UFSReadFile,
UFSGetDirEntry,
+ UFSGetFileBlock,
+ UFSGetDescription,
0,
kBIOSDevTypeHardDrive);
break;
part,
HFSInitPartition,
HFSLoadFile,
+ HFSReadFile,
HFSGetDirEntry,
+ HFSGetFileBlock,
+ HFSGetDescription,
0,
kBIOSDevTypeHardDrive);
break;
part,
UFSInitPartition,
UFSLoadFile,
+ UFSReadFile,
UFSGetDirEntry,
+ UFSGetFileBlock,
+ UFSGetDescription,
0,
kBIOSDevTypeHardDrive);
break;
+ case FDISK_NTFS:
+ bvr = newFDiskBVRef(
+ biosdev, partno,
+ part->relsect,
+ part,
+ 0, 0, 0, 0, 0,
+ NTFSGetDescription,
+ 0,
+ kBIOSDevTypeHardDrive);
+ break;
+
default:
bvr = newFDiskBVRef(
biosdev, partno,
part->relsect,
part,
- 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,
kBIOSDevTypeHardDrive);
break;
}
* If no FDisk partition, then we will check for
* an Apple partition map elsewhere.
*/
-#if 0
+#if UNUSED
if (map->bvrcnt == 0) {
static struct fdisk_part cdpart;
cdpart.systid = 0xCD;
&cdpart,
HFSInitPartition,
HFSLoadFile,
+ HFSReadFile,
HFSGetDirEntry,
+ HFSGetFileBlock,
0,
kBIOSDevTypeHardDrive);
bvr->next = map->bvr;
return NULL;
}
block0_p = buffer;
- if (NXSwapBigShortToHost(block0_p->sbSig) == BLOCK0_SIGNATURE) {
- blksize = NXSwapBigShortToHost(block0_p->sbBlkSize);
+ if (OSSwapBigToHostInt16(block0_p->sbSig) == BLOCK0_SIGNATURE) {
+ blksize = OSSwapBigToHostInt16(block0_p->sbBlkSize);
if (blksize != BPS) {
free(buffer);
buffer = malloc(blksize);
for (i=0; i<npart; i++) {
error = readBytes( biosdev, (kAPMSector + i) * factor, blksize, buffer );
- if (error || NXSwapBigShortToHost(dpme_p->dpme_signature) != DPME_SIGNATURE) {
+ if (error || OSSwapBigToHostInt16(dpme_p->dpme_signature) != DPME_SIGNATURE) {
break;
}
if (i==0) {
- npart = NXSwapBigLongToHost(dpme_p->dpme_map_entries);
+ npart = OSSwapBigToHostInt32(dpme_p->dpme_map_entries);
}
/*
printf("name = %s, %s%s %d -> %d [%d -> %d] {%d}\n",
if (strcmp(dpme_p->dpme_type, "Apple_HFS") == 0) {
bvr = newAPMBVRef(biosdev,
i,
- NXSwapBigLongToHost(dpme_p->dpme_pblock_start) * factor,
+ OSSwapBigToHostInt32(dpme_p->dpme_pblock_start) * factor,
dpme_p,
HFSInitPartition,
HFSLoadFile,
+ HFSReadFile,
HFSGetDirEntry,
+ HFSGetFileBlock,
+ HFSGetDescription,
0,
kBIOSDevTypeHardDrive);
bvr->next = map->bvr;
static const struct NamedValue fdiskTypes[] =
{
- { 0x07, "Windows NTFS" },
- { 0x0c, "Windows FAT32" },
+ { FDISK_NTFS, "Windows NTFS" },
+ { FDISK_FAT32, "Windows FAT32" },
{ 0x83, "Linux" },
{ FDISK_UFS, "Apple UFS" },
{ FDISK_HFS, "Apple HFS" },
{ 0x00, 0 } /* must be last */
};
-static void getVolumeDescription( BVRef bvr, char * str, long strMaxLen )
+//==========================================================================
+
+void getBootVolumeDescription( BVRef bvr, char * str, long strMaxLen, BOOL verbose )
{
unsigned char type = (unsigned char) bvr->part_type;
const char * name = getNameForValue( fdiskTypes, type );
+ char *p;
+
+ if (name == NULL)
+ name = bvr->type_name;
+
+ p = str;
+ if ( name && verbose ) {
+ sprintf( str, "hd(%d,%d) ",
+ BIOS_DEV_UNIT(bvr), bvr->part_no);
+ for (; strMaxLen > 0 && *p != '\0'; p++, strMaxLen--);
+ } else {
+ *p = '\0';
+ }
+ bvr->description(bvr, p, strMaxLen);
+ if (*p == '\0') {
+ const char * name = getNameForValue( fdiskTypes, type );
+ if (name == NULL) {
+ name = bvr->type_name;
+ }
+ if (name == NULL) {
+ sprintf(p, "TYPE %02x", type);
+ } else {
+ strncpy(p, name, strMaxLen);
+ }
+ }
+}
+
+#if UNUSED
+//==========================================================================
+
+static int
+getFAT32VolumeDescription( BVRef bvr, char *str, long strMaxLen)
+{
+ struct fat32_header {
+ unsigned char code[3];
+ unsigned char oem_id[8];
+ unsigned char data[56];
+ unsigned long serial;
+ unsigned char label[11];
+ unsigned char fsid[8];
+ unsigned char reserved[420];
+ unsigned short signature;
+ } __attribute__((packed));
+
+ char *buf, *name;
+ struct fat32_header *fat32_p;
+ int label_len = sizeof(fat32_p->label);
+ int error;
+
+ buf = (char *)malloc(BPS);
+ name = (char *)malloc(label_len + 1);
+ fat32_p = (struct fat32_header *)buf;
+
+ diskSeek(bvr, 0ULL);
+ error = diskRead(bvr, (long)buf, BPS);
+ if ( error ) return 0;
+
+ if (fat32_p->signature != 0xaa55) return 0;
+
+ if (strMaxLen < label_len) label_len = strMaxLen;
+ strncpy(str, fat32_p->label, label_len);
+ str[label_len] = '\0';
+ return 1;
+}
+#endif
+
+//==========================================================================
+
+static void getVolumeDescription( BVRef bvr, char * str, long strMaxLen )
+{
+ unsigned char type = (unsigned char) bvr->part_type;
+ const char * name = NULL;
+
+ /* First try a few types that we can figure out the
+ * volume description.
+ */
+ switch(type) {
+ case FDISK_FAT32:
+ str[0] = '\0';
+ MSDOSGetDescription(bvr, str, strMaxLen);
+ if (str[0] != '\0')
+ return;
+ break;
+
+ default: // Not one of our known types
+ break;
+ }
+
+ if (name == NULL)
+ name = getNameForValue( fdiskTypes, type );
if (name == NULL)
name = bvr->type_name;
if ( name )
- sprintf( str, "hd(%d,%d) %s",
- BIOS_DEV_UNIT(bvr), bvr->part_no, name );
+ strncpy( str, name, strMaxLen);
else
- sprintf( str, "hd(%d,%d) TYPE %02x",
- BIOS_DEV_UNIT(bvr), bvr->part_no, type );
+ sprintf( str, "TYPE %02x", type);
}
(void *) addr );
}
+int rawDiskRead( BVRef bvr, unsigned int secno, void *buffer, unsigned int len )
+{
+ int secs;
+ unsigned char *cbuf = (unsigned char *)buffer;
+ unsigned int copy_len;
+ int rc;
+
+ if ((len & (BPS-1)) != 0) {
+ error("raw disk read not sector aligned");
+ return -1;
+ }
+ secno += bvr->part_boff;
+
+ cache_valid = FALSE;
+
+ while (len > 0) {
+ secs = len / BPS;
+ if (secs > N_CACHE_SECS) secs = N_CACHE_SECS;
+ copy_len = secs * BPS;
+
+ //printf("rdr: ebiosread(%d, %d, %d)\n", bvr->biosdev, secno, secs);
+ if ((rc = ebiosread(bvr->biosdev, secno, secs)) != 0) {
+ /* Ignore corrected ECC errors */
+ if (rc != ECC_CORRECTED_ERR) {
+ error(" EBIOS read error: %s\n", bios_error(rc), rc);
+ error(" Block %d Sectors %d\n", secno, secs);
+ return rc;
+ }
+ }
+ bcopy( trackbuf, cbuf, copy_len );
+ len -= copy_len;
+ cbuf += copy_len;
+ secno += secs;
+ spinActivityIndicator();
+ }
+
+ return 0;
+}
+
+int rawDiskWrite( BVRef bvr, unsigned int secno, void *buffer, unsigned int len )
+{
+ int secs;
+ unsigned char *cbuf = (unsigned char *)buffer;
+ unsigned int copy_len;
+ int rc;
+
+ if ((len & (BPS-1)) != 0) {
+ error("raw disk write not sector aligned");
+ return -1;
+ }
+ secno += bvr->part_boff;
+
+ cache_valid = FALSE;
+
+ while (len > 0) {
+ secs = len / BPS;
+ if (secs > N_CACHE_SECS) secs = N_CACHE_SECS;
+ copy_len = secs * BPS;
+
+ bcopy( cbuf, trackbuf, copy_len );
+ //printf("rdr: ebioswrite(%d, %d, %d)\n", bvr->biosdev, secno, secs);
+ if ((rc = ebioswrite(bvr->biosdev, secno, secs)) != 0) {
+ error(" EBIOS write error: %s\n", bios_error(rc), rc);
+ error(" Block %d Sectors %d\n", secno, secs);
+ return rc;
+ }
+ len -= copy_len;
+ cbuf += copy_len;
+ secno += secs;
+ spinActivityIndicator();
+ }
+
+ return 0;
+}
+
void turnOffFloppy(void)
{
/*
/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
- * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
+ * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights
* Reserved. This file contains Original Code and/or Modifications of
* Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.1 (the "License"). You may not use this file
+ * Source License Version 2.0 (the "License"). You may not use this file
* except in compliance with the License. Please obtain a copy of the
* License at http://www.apple.com/publicsource and read it before using
* this file.
#define FDISK_DOS16S 0x04 /* 16-bit fat < 32MB dos partition */
#define FDISK_DOSEXT 0x05 /* extended dos partition */
#define FDISK_DOS16B 0x06 /* 16-bit fat >= 32MB dos partition */
+#define FDISK_NTFS 0x07 /* NTFS partition */
+#define FDISK_FAT32 0x0c /* FAT32 partition */
#define FDISK_UFS 0xa8 /* Apple UFS partition */
#define FDISK_HFS 0xaf /* Apple HFS partition */
#define FDISK_BOOTER 0xab /* Apple booter partition */
/*
- * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2003 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* The contents of this file constitute Original Code as defined in and
- * are subject to the Apple Public Source License Version 1.1 (the
+ * are subject to the Apple Public Source License Version 2.0 (the
* "License"). You may not use this file except in compliance with the
* License. Please obtain a copy of the License at
* http://www.apple.com/publicsource and read it before using this file.
static CICell gCurrentIH;
static long long gAllocationOffset;
static long gIsHFSPlus;
+static long gCaseSensitive;
static long gBlockSize;
static long gCacheBlockSize;
static char *gBTreeHeaderBuffer;
static long long gAllocationOffset;
static long gIsHFSPlus;
static long gBlockSize;
+static long gCaseSensitive;
static long gCacheBlockSize;
static char gBTreeHeaderBuffer[512];
static BTHeaderRec *gBTHeaders[2];
#endif /* !__i386__ */
-static long ReadFile(void *file, long *length);
-static long GetCatalogEntryInfo(void *entry, long *flags, long *time);
+static long ReadFile(void *file, long *length, void *base, long offset);
+static long GetCatalogEntryInfo(void *entry, long *flags, long *time,
+ FinderInfo *finderInfo, long *infoValid);
static long ResolvePathToCatalogEntry(char *filePath, long *flags,
void *entry, long dirID, long *dirIndex);
static long GetCatalogEntry(long *dirIndex, char **name,
- long *flags, long *time);
+ long *flags, long *time,
+ FinderInfo *finderInfo, long *infoValid);
static long ReadCatalogEntry(char *fileName, long dirID, void *entry,
long *dirIndex);
static long ReadExtentsEntry(long fileID, long startBlock, void *entry);
extern long FastRelString(char *str1, char *str2);
extern long FastUnicodeCompare(u_int16_t *uniStr1, u_int32_t len1,
u_int16_t *uniStr2, u_int32_t len2);
-extern void utf_encodestr(const u_int16_t *ucsp, int ucslen,
- u_int8_t *utf8p, u_int32_t bufsize);
-extern void utf_decodestr(const u_int8_t *utf8p, u_int16_t *ucsp,
- u_int16_t *ucslen, u_int32_t bufsize);
+extern long BinaryUnicodeCompare(u_int16_t *uniStr1, u_int32_t len1,
+ u_int16_t *uniStr2, u_int32_t len2);
+static void
+SwapFinderInfo(FndrFileInfo *dst, FndrFileInfo *src)
+{
+ dst->fdType = SWAP_BE32(src->fdType);
+ dst->fdCreator = SWAP_BE32(src->fdCreator);
+ dst->fdFlags = SWAP_BE16(src->fdFlags);
+ // Don't bother with location
+}
+
long HFSInitPartition(CICell ih)
{
long extentSize, extentFile, nodeSize;
gAllocationOffset = 0;
gIsHFSPlus = 0;
+ gCaseSensitive = 0;
gBTHeaders[0] = 0;
gBTHeaders[1] = 0;
Seek(ih, gAllocationOffset + kMDBBaseOffset);
Read(ih, (long)gHFSPlusHeader, kBlockSize);
- // Not a HFS[+] volume.
- if (SWAP_BE16(gHFSPlus->signature) != kHFSPlusSigWord) {
+ // Not a HFS+ or HFSX volume.
+ if (SWAP_BE16(gHFSPlus->signature) != kHFSPlusSigWord &&
+ SWAP_BE16(gHFSPlus->signature) != kHFSXSigWord) {
verbose("HFS signature was not present.\n");
+ gCurrentIH = 0;
return -1;
}
}
long HFSLoadFile(CICell ih, char * filePath)
+{
+ return HFSReadFile(ih, filePath, (void *)gFSLoadAddress, 0, 0);
+}
+
+long HFSReadFile(CICell ih, char * filePath, void *base, unsigned long offset, unsigned long length)
{
char entry[512];
- long dirID, result, length, flags;
+ long dirID, result, flags;
verbose("Loading HFS%s file: [%s] from %x.\n",
(gIsHFSPlus ? "+" : ""), filePath, ih);
return -1;
}
-#if 0 // Not yet for Intel. System.config/Default.table will fail this check.
+#if UNUSED
+ // Not yet for Intel. System.config/Default.table will fail this check.
// Check file owner and permissions.
if (flags & (kOwnerNotRoot | kPermGroupWrite | kPermOtherWrite)) return -1;
#endif
- result = ReadFile(entry, &length);
+ result = ReadFile(entry, &length, base, offset);
if (result == -1) {
return -1;
}
}
long HFSGetDirEntry(CICell ih, char * dirPath, long * dirIndex, char ** name,
- long * flags, long * time)
+ long * flags, long * time,
+ FinderInfo * finderInfo, long * infoValid)
{
char entry[512];
long dirID, dirFlags;
if ((dirFlags & kFileTypeMask) != kFileTypeUnknown) return -1;
}
- GetCatalogEntry(dirIndex, name, flags, time);
+ GetCatalogEntry(dirIndex, name, flags, time, finderInfo, infoValid);
if (*dirIndex == 0) *dirIndex = -1;
if ((*flags & kFileTypeMask) == kFileTypeUnknown) return -1;
return 0;
}
+void
+HFSGetDescription(CICell ih, char *str, long strMaxLen)
+{
+
+ UInt16 nodeSize;
+ UInt32 firstLeafNode;
+ long dirIndex;
+ char *name;
+ long flags, time;
+
+ if (HFSInitPartition(ih) == -1) { return; }
+
+ /* Fill some crucial data structures by side effect. */
+ dirIndex = 0;
+ HFSGetDirEntry(ih, "/", &dirIndex, &name, &flags, &time, 0, 0);
+
+ /* Now we can loook up the volume name node. */
+ nodeSize = SWAP_BE16(gBTHeaders[kBTreeCatalog]->nodeSize);
+ firstLeafNode = SWAP_BE32(gBTHeaders[kBTreeCatalog]->firstLeafNode);
+
+ dirIndex = firstLeafNode * nodeSize;
+
+ GetCatalogEntry(&dirIndex, &name, &flags, &time, 0, 0);
+
+ strncpy(str, name, strMaxLen);
+ str[strMaxLen] = '\0';
+}
+
+
+long
+HFSGetFileBlock(CICell ih, char *filePath, unsigned long long *firstBlock)
+{
+ char entry[512];
+ long dirID, result, flags;
+ void *extents;
+ HFSCatalogFile *hfsFile = (void *)entry;
+ HFSPlusCatalogFile *hfsPlusFile = (void *)entry;
+
+ if (HFSInitPartition(ih) == -1) return -1;
+
+ dirID = kHFSRootFolderID;
+ // Skip a lead '\'. Start in the system folder if there are two.
+ if (filePath[0] == '/') {
+ if (filePath[1] == '/') {
+ if (gIsHFSPlus) dirID = SWAP_BE32(((long *)gHFSPlus->finderInfo)[5]);
+ else dirID = SWAP_BE32(gHFSMDB->drFndrInfo[5]);
+ if (dirID == 0) {
+ return -1;
+ }
+ filePath++;
+ }
+ filePath++;
+ }
+
+ result = ResolvePathToCatalogEntry(filePath, &flags, entry, dirID, 0);
+ if ((result == -1) || ((flags & kFileTypeMask) != kFileTypeFlat)) {
+ printf("HFS: Resolve path %s failed\n", filePath);
+ return -1;
+ }
+
+ if (gIsHFSPlus) {
+ extents = &hfsPlusFile->dataFork.extents;
+ } else {
+ extents = &hfsFile->dataExtents;
+ }
+
+#if DEBUG
+ printf("extent start 0x%x\n", (unsigned long)GetExtentStart(extents, 0));
+ printf("block size 0x%x\n", (unsigned long)gBlockSize);
+ printf("Allocation offset 0x%x\n", (unsigned long)gAllocationOffset);
+#endif
+ *firstBlock = ((unsigned long long)GetExtentStart(extents, 0) * (unsigned long long) gBlockSize + gAllocationOffset) / 512ULL;
+ return 0;
+}
+
+
// Private Functions
-static long ReadFile(void * file, long * length)
+static long ReadFile(void * file, long * length, void * base, long offset)
{
void *extents;
long fileID;
+ long fileLength;
HFSCatalogFile *hfsFile = file;
HFSPlusCatalogFile *hfsPlusFile = file;
if (gIsHFSPlus) {
fileID = SWAP_BE32(hfsPlusFile->fileID);
- *length = SWAP_BE64(hfsPlusFile->dataFork.logicalSize);
+ fileLength = SWAP_BE64(hfsPlusFile->dataFork.logicalSize);
extents = &hfsPlusFile->dataFork.extents;
} else {
fileID = SWAP_BE32(hfsFile->fileID);
- *length = SWAP_BE32(hfsFile->dataLogicalSize);
+ fileLength = SWAP_BE32(hfsFile->dataLogicalSize);
extents = &hfsFile->dataExtents;
}
+ if (offset > fileLength) {
+ printf("Offset is too large.\n");
+ return -1;
+ }
+
+ if (*length == 0 || (offset + *length) > fileLength) {
+ *length = fileLength - offset;
+ }
+
+ // XXX
+#if 0
if (*length > kLoadSize) {
printf("File is too large.\n");
return -1;
}
-
-#ifdef __i386__
- *length = ReadExtent((char *)extents, *length, fileID,
- 0, *length, (char *)gFSLoadAddress, 0);
-#else
- *length = ReadExtent((char *)extents, *length, fileID,
- 0, *length, (char *)kLoadAddr, 0);
#endif
+ *length = ReadExtent((char *)extents, fileLength, fileID,
+ offset, *length, (char *)base, 0);
+
return 0;
}
-static long GetCatalogEntryInfo(void * entry, long * flags, long * time)
+static long GetCatalogEntryInfo(void * entry, long * flags, long * time,
+ FinderInfo * finderInfo, long * infoValid)
{
long tmpTime = 0;
+ long valid = 0;
// Get information about the file.
case kHFSFileRecord :
*flags = kFileTypeFlat;
tmpTime = SWAP_BE32(((HFSCatalogFile *)entry)->modifyDate);
+ if (finderInfo) {
+ SwapFinderInfo((FndrFileInfo *)finderInfo, &((HFSCatalogFile *)entry)->userInfo);
+ valid = 1;
+ }
break;
case kHFSPlusFileRecord :
if (SWAP_BE32(((HFSPlusCatalogFile *)entry)->bsdInfo.ownerID) != 0)
*flags |= kOwnerNotRoot;
tmpTime = SWAP_BE32(((HFSPlusCatalogFile *)entry)->contentModDate);
+ if (finderInfo) {
+ SwapFinderInfo((FndrFileInfo *)finderInfo, &((HFSPlusCatalogFile *)entry)->userInfo);
+ valid = 1;
+ }
break;
case kHFSFileThreadRecord :
// Convert base time from 1904 to 1970.
*time = tmpTime - 2082844800;
}
+ if (infoValid) *infoValid = valid;
return 0;
}
return -1;
}
- GetCatalogEntryInfo(entry, flags, 0);
+ GetCatalogEntryInfo(entry, flags, 0, 0, 0);
if ((*flags & kFileTypeMask) == kFileTypeDirectory) {
if (gIsHFSPlus)
}
static long GetCatalogEntry(long * dirIndex, char ** name,
- long * flags, long * time)
+ long * flags, long * time,
+ FinderInfo * finderInfo, long * infoValid)
{
long extentSize, nodeSize, curNode, index;
void *extent;
curNode * nodeSize, nodeSize, nodeBuf, 1);
GetBTreeRecord(index, nodeBuf, nodeSize, &testKey, &entry);
- GetCatalogEntryInfo(entry, flags, time);
+ GetCatalogEntryInfo(entry, flags, time, finderInfo, infoValid);
// Get the file name.
if (gIsHFSPlus) {
utf_encodestr(((HFSPlusCatalogKey *)testKey)->nodeName.unicode,
SWAP_BE16(((HFSPlusCatalogKey *)testKey)->nodeName.length),
- gTempStr, 256);
+ gTempStr, 256, OSBigEndian);
} else {
strncpy(gTempStr,
&((HFSCatalogKey *)testKey)->nodeName[1],
length = strlen(fileName);
if (length > 255) length = 255;
utf_decodestr(fileName, hfsPlusKey->nodeName.unicode,
- &(hfsPlusKey->nodeName.length), 512);
+ &(hfsPlusKey->nodeName.length), 512, OSBigEndian);
} else {
hfsKey->parentID = SWAP_BE32(dirID);
length = strlen(fileName);
gBTreeHeaderBuffer + btree * 256, 0);
gBTHeaders[btree] = (BTHeaderRec *)(gBTreeHeaderBuffer + btree * 256 +
sizeof(BTNodeDescriptor));
+ if ((gIsHFSPlus && btree == kBTreeCatalog) &&
+ (gBTHeaders[btree]->keyCompareType == kHFSBinaryCompare)) {
+ gCaseSensitive = 1;
+ }
}
curNode = SWAP_BE32(gBTHeaders[btree]->rootNode);
if ((searchKey->nodeName.length == 0) || (trialKey->nodeName.length == 0))
result = searchKey->nodeName.length - trialKey->nodeName.length;
else
+ if (gCaseSensitive) {
+ result = BinaryUnicodeCompare(&searchKey->nodeName.unicode[0],
+ SWAP_BE16(searchKey->nodeName.length),
+ &trialKey->nodeName.unicode[0],
+ SWAP_BE16(trialKey->nodeName.length));
+ } else {
result = FastUnicodeCompare(&searchKey->nodeName.unicode[0],
SWAP_BE16(searchKey->nodeName.length),
&trialKey->nodeName.unicode[0],
SWAP_BE16(trialKey->nodeName.length));
+ }
}
return result;
return result;
}
+
* @APPLE_LICENSE_HEADER_START@
*
* The contents of this file constitute Original Code as defined in and
- * are subject to the Apple Public Source License Version 1.2 (the
+ * are subject to the Apple Public Source License Version 2.0 (the
* "License"). You may not use this file except in compliance with the
* License. Please obtain a copy of the License at
* http://www.apple.com/publicsource and read it before using this file.
extern long HFSInitPartition(CICell ih);
extern long HFSLoadFile(CICell ih, char * filePath);
+extern long HFSReadFile(CICell ih, char * filePath, void *base, unsigned long offset, unsigned long length);
extern long HFSGetDirEntry(CICell ih, char * dirPath, long * dirIndex,
- char ** name, long * flags, long * time);
-
+ char ** name, long * flags, long * time,
+ FinderInfo * finderInfo, long * infoValid);
+extern void HFSGetDescription(CICell ih, char *str, long strMaxLen);
+extern long HFSGetFileBlock(CICell ih, char *str, unsigned long long *firstBlock);
/*
- * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2003 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* The contents of this file constitute Original Code as defined in and
- * are subject to the Apple Public Source License Version 1.1 (the
+ * are subject to the Apple Public Source License Version 2.0 (the
* "License"). You may not use this file except in compliance with the
* License. Please obtain a copy of the License at
* http://www.apple.com/publicsource and read it before using this file.
ignored characters in that block. Ignored characters are mapped to zero.
*/
+#if UNCOMPRESSED
u_int16_t gLowerCaseTable[] = {
// High-byte indices ( == 0 iff no case mapping and no ignorables )
/* F */ 0xFFF0, 0xFFF1, 0xFFF2, 0xFFF3, 0xFFF4, 0xFFF5, 0xFFF6, 0xFFF7, 0xFFF8, 0xFFF9, 0xFFFA, 0xFFFB, 0xFFFC, 0xFFFD, 0xFFFE, 0xFFFF,
};
-
/* RelString case folding table */
unsigned short gCompareTable[] = {
/* F */ 0xF000, 0xF100, 0xF200, 0xF300, 0xF400, 0xF500, 0xF600, 0xF700, 0xF800, 0xF900, 0xFA00, 0xFB00, 0xFC00, 0xFD00, 0xFE00, 0xFF00,
};
+#else /* ! UNCOMPRESSED */
+
+enum {
+ kTypeLiteral = 0,
+ kTypeAscending = 1,
+ kTypeAscending256 = 2
+};
+
+struct compressed_block {
+ unsigned char type;
+ unsigned char count;
+ unsigned short data;
+};
+
+unsigned short *gLowerCaseTable;
+
+struct compressed_block gLowerCaseTableCompressed[] = {
+ {0x0, 0x1, 0x100},
+ {0x0, 0x1, 0x200},
+ {0x0, 0x1, 0x0},
+ {0x0, 0x1, 0x300},
+ {0x0, 0x1, 0x400},
+ {0x0, 0x1, 0x500},
+ {0x0, 0xa, 0x0},
+ {0x0, 0x1, 0x600},
+ {0x0, 0xf, 0x0},
+ {0x0, 0x1, 0x700},
+ {0x0, 0x1, 0x800},
+ {0x0, 0xdc, 0x0},
+ {0x0, 0x1, 0x900},
+ {0x0, 0x1, 0xa00},
+ {0x0, 0x1, 0xffff},
+ {0x1, 0x40, 0x1},
+ {0x1, 0x1a, 0x61},
+ {0x1, 0x6b, 0x5b},
+ {0x0, 0x1, 0xe6},
+ {0x1, 0x9, 0xc7},
+ {0x0, 0x1, 0xf0},
+ {0x1, 0x7, 0xd1},
+ {0x0, 0x1, 0xf8},
+ {0x1, 0x5, 0xd9},
+ {0x0, 0x1, 0xfe},
+ {0x1, 0x31, 0xdf},
+ {0x0, 0x2, 0x111},
+ {0x1, 0x14, 0x112},
+ {0x0, 0x2, 0x127},
+ {0x1, 0xa, 0x128},
+ {0x0, 0x2, 0x133},
+ {0x1, 0xb, 0x134},
+ {0x0, 0x2, 0x140},
+ {0x0, 0x2, 0x142},
+ {0x1, 0x7, 0x143},
+ {0x0, 0x2, 0x14b},
+ {0x1, 0x6, 0x14c},
+ {0x0, 0x2, 0x153},
+ {0x1, 0x12, 0x154},
+ {0x0, 0x2, 0x167},
+ {0x1, 0x19, 0x168},
+ {0x0, 0x1, 0x253},
+ {0x0, 0x2, 0x183},
+ {0x0, 0x2, 0x185},
+ {0x0, 0x1, 0x254},
+ {0x0, 0x2, 0x188},
+ {0x1, 0x2, 0x256},
+ {0x0, 0x2, 0x18c},
+ {0x0, 0x1, 0x18d},
+ {0x0, 0x1, 0x1dd},
+ {0x0, 0x1, 0x259},
+ {0x0, 0x1, 0x25b},
+ {0x0, 0x2, 0x192},
+ {0x0, 0x1, 0x260},
+ {0x0, 0x1, 0x263},
+ {0x0, 0x1, 0x195},
+ {0x0, 0x1, 0x269},
+ {0x0, 0x1, 0x268},
+ {0x0, 0x2, 0x199},
+ {0x1, 0x2, 0x19a},
+ {0x0, 0x1, 0x26f},
+ {0x0, 0x1, 0x272},
+ {0x0, 0x1, 0x19e},
+ {0x0, 0x1, 0x275},
+ {0x1, 0x2, 0x1a0},
+ {0x0, 0x2, 0x1a3},
+ {0x0, 0x2, 0x1a5},
+ {0x0, 0x1, 0x1a6},
+ {0x0, 0x2, 0x1a8},
+ {0x0, 0x1, 0x283},
+ {0x1, 0x2, 0x1aa},
+ {0x0, 0x2, 0x1ad},
+ {0x0, 0x1, 0x288},
+ {0x1, 0x2, 0x1af},
+ {0x1, 0x2, 0x28a},
+ {0x0, 0x2, 0x1b4},
+ {0x0, 0x2, 0x1b6},
+ {0x0, 0x1, 0x292},
+ {0x0, 0x2, 0x1b9},
+ {0x1, 0x2, 0x1ba},
+ {0x0, 0x2, 0x1bd},
+ {0x1, 0x6, 0x1be},
+ {0x0, 0x3, 0x1c6},
+ {0x0, 0x3, 0x1c9},
+ {0x0, 0x3, 0x1cc},
+ {0x1, 0x17, 0x1cd},
+ {0x0, 0x2, 0x1e5},
+ {0x1, 0xb, 0x1e6},
+ {0x0, 0x3, 0x1f3},
+ {0x1, 0xc, 0x1f4},
+ {0x1, 0x91, 0x300},
+ {0x1, 0x11, 0x3b1},
+ {0x0, 0x1, 0x3a2},
+ {0x1, 0x7, 0x3c3},
+ {0x1, 0x38, 0x3aa},
+ {0x0, 0x2, 0x3e3},
+ {0x0, 0x2, 0x3e5},
+ {0x0, 0x2, 0x3e7},
+ {0x0, 0x2, 0x3e9},
+ {0x0, 0x2, 0x3eb},
+ {0x0, 0x2, 0x3ed},
+ {0x0, 0x2, 0x3ef},
+ {0x1, 0x12, 0x3f0},
+ {0x0, 0x1, 0x452},
+ {0x0, 0x1, 0x403},
+ {0x1, 0x3, 0x454},
+ {0x0, 0x1, 0x407},
+ {0x1, 0x4, 0x458},
+ {0x1, 0x3, 0x40c},
+ {0x0, 0x1, 0x45f},
+ {0x1, 0x9, 0x430},
+ {0x0, 0x1, 0x419},
+ {0x1, 0x16, 0x43a},
+ {0x1, 0x30, 0x430},
+ {0x0, 0x2, 0x461},
+ {0x0, 0x2, 0x463},
+ {0x0, 0x2, 0x465},
+ {0x0, 0x2, 0x467},
+ {0x0, 0x2, 0x469},
+ {0x0, 0x2, 0x46b},
+ {0x0, 0x2, 0x46d},
+ {0x0, 0x2, 0x46f},
+ {0x0, 0x2, 0x471},
+ {0x0, 0x2, 0x473},
+ {0x0, 0x2, 0x475},
+ {0x1, 0x2, 0x476},
+ {0x0, 0x2, 0x479},
+ {0x0, 0x2, 0x47b},
+ {0x0, 0x2, 0x47d},
+ {0x0, 0x2, 0x47f},
+ {0x0, 0x2, 0x481},
+ {0x1, 0xe, 0x482},
+ {0x0, 0x2, 0x491},
+ {0x0, 0x2, 0x493},
+ {0x0, 0x2, 0x495},
+ {0x0, 0x2, 0x497},
+ {0x0, 0x2, 0x499},
+ {0x0, 0x2, 0x49b},
+ {0x0, 0x2, 0x49d},
+ {0x0, 0x2, 0x49f},
+ {0x0, 0x2, 0x4a1},
+ {0x0, 0x2, 0x4a3},
+ {0x0, 0x2, 0x4a5},
+ {0x0, 0x2, 0x4a7},
+ {0x0, 0x2, 0x4a9},
+ {0x0, 0x2, 0x4ab},
+ {0x0, 0x2, 0x4ad},
+ {0x0, 0x2, 0x4af},
+ {0x0, 0x2, 0x4b1},
+ {0x0, 0x2, 0x4b3},
+ {0x0, 0x2, 0x4b5},
+ {0x0, 0x2, 0x4b7},
+ {0x0, 0x2, 0x4b9},
+ {0x0, 0x2, 0x4bb},
+ {0x0, 0x2, 0x4bd},
+ {0x0, 0x2, 0x4bf},
+ {0x1, 0x3, 0x4c0},
+ {0x0, 0x2, 0x4c4},
+ {0x1, 0x2, 0x4c5},
+ {0x0, 0x2, 0x4c8},
+ {0x1, 0x2, 0x4c9},
+ {0x0, 0x2, 0x4cc},
+ {0x1, 0x64, 0x4cd},
+ {0x1, 0x26, 0x561},
+ {0x1, 0xa9, 0x557},
+ {0x1, 0xa0, 0x1000},
+ {0x1, 0x26, 0x10d0},
+ {0x1, 0x3a, 0x10c6},
+ {0x1, 0xc, 0x2000},
+ {0x0, 0x4, 0x0},
+ {0x1, 0x1a, 0x2010},
+ {0x0, 0x5, 0x0},
+ {0x1, 0x3b, 0x202f},
+ {0x0, 0x6, 0x0},
+ {0x1, 0xf0, 0x2070},
+ {0x1, 0x10, 0x2170},
+ {0x1, 0x90, 0x2170},
+ {0x1, 0xff, 0xfe00},
+ {0x0, 0x1, 0x0},
+ {0x1, 0x21, 0xff00},
+ {0x1, 0x1a, 0xff41},
+ {0x1, 0xc5, 0xff3b},
+};
+#define kLowerCaseTableNBlocks 182
+#define kLowerCaseTableDataSize 5632 /* size of uncompressed structure in bytes */
+
+unsigned short *gCompareTable;
+
+struct compressed_block gCompareTableCompressed[] = {
+ {0x2, 0x60, 0x0},
+ {0x0, 0x1, 0x4180},
+ {0x2, 0x1a, 0x4100},
+ {0x2, 0x5, 0x7b00},
+ {0x0, 0x1, 0x4108},
+ {0x0, 0x1, 0x410c},
+ {0x0, 0x1, 0x4310},
+ {0x0, 0x1, 0x4502},
+ {0x0, 0x1, 0x4e0a},
+ {0x0, 0x1, 0x4f08},
+ {0x0, 0x1, 0x5508},
+ {0x0, 0x1, 0x4182},
+ {0x0, 0x1, 0x4104},
+ {0x0, 0x1, 0x4186},
+ {0x0, 0x1, 0x4108},
+ {0x0, 0x1, 0x410a},
+ {0x0, 0x1, 0x410c},
+ {0x0, 0x1, 0x4310},
+ {0x0, 0x1, 0x4502},
+ {0x0, 0x1, 0x4584},
+ {0x0, 0x1, 0x4586},
+ {0x0, 0x1, 0x4588},
+ {0x0, 0x1, 0x4982},
+ {0x0, 0x1, 0x4984},
+ {0x0, 0x1, 0x4986},
+ {0x0, 0x1, 0x4988},
+ {0x0, 0x1, 0x4e0a},
+ {0x0, 0x1, 0x4f82},
+ {0x0, 0x1, 0x4f84},
+ {0x0, 0x1, 0x4f86},
+ {0x0, 0x1, 0x4f08},
+ {0x0, 0x1, 0x4f0a},
+ {0x0, 0x1, 0x5582},
+ {0x0, 0x1, 0x5584},
+ {0x0, 0x1, 0x5586},
+ {0x0, 0x1, 0x5508},
+ {0x2, 0x7, 0xa000},
+ {0x0, 0x1, 0x5382},
+ {0x2, 0x6, 0xa800},
+ {0x0, 0x1, 0x4114},
+ {0x0, 0x1, 0x4f0e},
+ {0x2, 0xb, 0xb000},
+ {0x0, 0x1, 0x4192},
+ {0x0, 0x1, 0x4f92},
+ {0x0, 0x1, 0xbd00},
+ {0x0, 0x1, 0x4114},
+ {0x0, 0x1, 0x4f0e},
+ {0x2, 0x7, 0xc000},
+ {0x0, 0x1, 0x2206},
+ {0x0, 0x1, 0x2208},
+ {0x0, 0x1, 0xc900},
+ {0x0, 0x1, 0x2000},
+ {0x0, 0x1, 0x4104},
+ {0x0, 0x1, 0x410a},
+ {0x0, 0x1, 0x4f0a},
+ {0x0, 0x2, 0x4f14},
+ {0x2, 0x2, 0xd000},
+ {0x0, 0x1, 0x2202},
+ {0x0, 0x1, 0x2204},
+ {0x0, 0x1, 0x2702},
+ {0x0, 0x1, 0x2704},
+ {0x2, 0x2, 0xd600},
+ {0x0, 0x1, 0x5988},
+ {0x2, 0x27, 0xd900},
+};
+#define kCompareTableNBlocks 255
+#define kCompareTableDataSize 512 /* size of uncompressed structure in bytes */
+
+#endif /* UNCOMPRESSED */
/*
- * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2003 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* The contents of this file constitute Original Code as defined in and
- * are subject to the Apple Public Source License Version 1.1 (the
+ * are subject to the Apple Public Source License Version 2.0 (the
* "License"). You may not use this file except in compliance with the
* License. Please obtain a copy of the License at
* http://www.apple.com/publicsource and read it before using this file.
#include <sl.h>
#include "hfs_CaseTables.h"
+#if ! UNCOMPRESSED
+
+static unsigned short *
+UncompressStructure(struct compressed_block *bp, int count, int size)
+{
+ unsigned short *out = malloc(size);
+ unsigned short *op = out;
+ unsigned short data;
+ int i, j;
+
+ for (i=0; i<count; i++, bp++) {
+ data = bp->data;
+ for (j=0; j<bp->count; j++) {
+ *op++ = data;
+ if (bp->type == kTypeAscending) data++;
+ else if (bp->type == kTypeAscending256) data += 256;
+ }
+ }
+ return out;
+}
+
+static void
+InitCompareTables(void)
+{
+ if (gCompareTable == 0) {
+ gCompareTable = UncompressStructure(gCompareTableCompressed,
+ kCompareTableNBlocks, kCompareTableDataSize);
+ gLowerCaseTable = UncompressStructure(gLowerCaseTableCompressed,
+ kLowerCaseTableNBlocks, kLowerCaseTableDataSize);
+ }
+}
+
+#endif /* ! UNCOMPRESSED */
+
//_______________________________________________________________________
//
// Routine: FastRelString
int32_t bestGuess;
u_int8_t length, length2;
+#if ! UNCOMPRESED
+ InitCompareTables();
+#endif
+
length = *(str1++);
length2 = *(str2++);
register u_int16_t c1,c2;
register u_int16_t temp;
+#if ! UNCOMPRESSED
+ InitCompareTables();
+#endif
+
while (1) {
/* Set default values for c1, c2 in case there are no more valid chars */
c1 = 0;
}
+//
+// BinaryUnicodeCompare - Compare two Unicode strings; produce a relative ordering
+// Compared using a 16-bit binary comparison (no case folding)
+//
+int32_t BinaryUnicodeCompare (u_int16_t * str1, u_int32_t length1,
+ u_int16_t * str2, u_int32_t length2)
+{
+ register u_int16_t c1, c2;
+ int32_t bestGuess;
+ u_int32_t length;
+
+ bestGuess = 0;
+
+ if (length1 < length2) {
+ length = length1;
+ --bestGuess;
+ } else if (length1 > length2) {
+ length = length2;
+ ++bestGuess;
+ } else {
+ length = length1;
+ }
+
+ while (length--) {
+ c1 = *(str1++);
+ c2 = *(str2++);
+
+ if (c1 > c2)
+ return (1);
+ if (c1 < c2)
+ return (-1);
+ }
+
+ return (bestGuess);
+}
+
+
/*
* UTF-8 (UCS Transformation Format)
*
*/
void
utf_encodestr( const u_int16_t * ucsp, int ucslen,
- u_int8_t * utf8p, u_int32_t bufsize )
+ u_int8_t * utf8p, u_int32_t bufsize, int byte_order )
{
u_int8_t *bufend;
u_int16_t ucs_ch;
bufend = utf8p + bufsize;
while (ucslen-- > 0) {
- ucs_ch = SWAP_BE16(*ucsp++);
+ if (byte_order == OSBigEndian)
+ ucs_ch = SWAP_BE16(*ucsp++);
+ else
+ ucs_ch = SWAP_LE16(*ucsp++);
if (ucs_ch < 0x0080) {
if (utf8p >= bufend)
* ucslen is the number of UCS-2 output characters (not bytes)
* bufsize is the size of the output buffer in bytes
*/
-void utf_decodestr(const u_int8_t * utf8p, u_int16_t * ucsp, u_int16_t * ucslen, u_int32_t bufsize)
+void utf_decodestr(const u_int8_t * utf8p, u_int16_t * ucsp, u_int16_t * ucslen, u_int32_t bufsize, int byte_order)
{
u_int16_t *bufstart;
u_int16_t *bufend;
if (byte < 0x80) {
ucs_ch = byte;
- *ucsp++ = SWAP_BE16(ucs_ch);
+ if (byte_order == OSBigEndian)
+ *ucsp++ = SWAP_BE16(ucs_ch);
+ else
+ *ucsp++ = SWAP_LE16(ucs_ch);
+
continue;
}
goto stop;
ucs_ch += (byte & 0x3F);
- *ucsp++ = SWAP_BE16(ucs_ch);
+ if (byte_order == OSBigEndian)
+ *ucsp++ = SWAP_BE16(ucs_ch);
+ else
+ *ucsp++ = SWAP_LE16(ucs_ch);
}
stop:
- *ucslen = SWAP_BE16(ucsp - bufstart);
+ if (byte_order == OSBigEndian)
+ *ucslen = SWAP_BE16(ucsp - bufstart);
+ else
+ *ucslen = SWAP_LE16(ucsp - bufstart);
}
/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
- * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
+ * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights
* Reserved. This file contains Original Code and/or Modifications of
* Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.1 (the "License"). You may not use this file
+ * Source License Version 2.0 (the "License"). You may not use this file
* except in compliance with the License. Please obtain a copy of the
* License at http://www.apple.com/publicsource and read it before using
* this file.
/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
- * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
+ * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights
* Reserved. This file contains Original Code and/or Modifications of
* Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.1 (the "License"). You may not use this file
+ * Source License Version 2.0 (the "License"). You may not use this file
* except in compliance with the License. Please obtain a copy of the
* License at http://www.apple.com/publicsource and read it before using
* this file.
* @APPLE_LICENSE_HEADER_START@
*
* The contents of this file constitute Original Code as defined in and
- * are subject to the Apple Public Source License Version 1.2 (the
+ * are subject to the Apple Public Source License Version 2.0 (the
* "License"). You may not use this file except in compliance with the
* License. Please obtain a copy of the License at
* http://www.apple.com/publicsource and read it before using this file.
nfat = fhp->nfat_arch;
swapped = 0;
} else if (fhp->magic == FAT_CIGAM) {
- nfat = NXSwapInt(fhp->nfat_arch);
+ nfat = OSSwapInt32(fhp->nfat_arch);
swapped = 1;
} else {
return -1;
for (; nfat > 0; nfat--, fap++) {
if (swapped) {
- fap->cputype = NXSwapInt(fap->cputype);
- fap->offset = NXSwapInt(fap->offset);
- fap->size = NXSwapInt(fap->size);
+ fap->cputype = OSSwapInt32(fap->cputype);
+ fap->offset = OSSwapInt32(fap->offset);
+ fap->size = OSSwapInt32(fap->size);
}
if (fap->cputype == CPU_TYPE_I386) {
return -1;
}
-#if NOTDEF
+#if DEBUG
printf("magic: %x\n", (unsigned)mH->magic);
printf("cputype: %x\n", (unsigned)mH->cputype);
printf("cpusubtype: %x\n", (unsigned)mH->cpusubtype);
case LC_SEGMENT:
ret = DecodeSegment(cmdBase, &load_addr, &load_size);
- if (ret == 0 && load_size != 0) {
+ if (ret == 0 && load_size != 0 && load_addr >= KERNEL_ADDR) {
vmaddr = min(vmaddr, load_addr);
vmend = max(vmend, load_addr + load_size);
}
return 0;
}
-#if NOTDEF
+#if DEBUG
printf("segname: %s, vmaddr: %x, vmsize: %x, fileoff: %x, filesize: %x, nsects: %d, flags: %x.\n",
segCmd->segname, (unsigned)vmaddr, (unsigned)vmsize, (unsigned)fileaddr, (unsigned)filesize,
(unsigned) segCmd->nsects, (unsigned)segCmd->flags);
getc();
#endif
- if (vmaddr < KERNEL_ADDR ||
- (vmaddr + vmsize) > (KERNEL_ADDR + KERNEL_LEN)) {
+ if (! ((vmaddr >= KERNEL_ADDR &&
+ (vmaddr + vmsize) <= (KERNEL_ADDR + KERNEL_LEN)) ||
+ (vmaddr >= HIB_ADDR &&
+ (vmaddr + vmsize) <= (HIB_ADDR + HIB_LEN)))) {
stop("Kernel overflows available space");
}
* Portions Copyright (c) 2003 Apple Computer, Inc. All Rights
* Reserved. This file contains Original Code and/or Modifications of
* Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.2 (the "License"). You may not use this file
+ * Source License Version 2.0 (the "License"). You may not use this file
* except in compliance with the License. Please obtain a copy of the
* License at http://www.apple.com/publicsource and read it before using
* this file.
/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
- * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
+ * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights
* Reserved. This file contains Original Code and/or Modifications of
* Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.1 (the "License"). You may not use this file
+ * Source License Version 2.0 (the "License"). You may not use this file
* except in compliance with the License. Please obtain a copy of the
* License at http://www.apple.com/publicsource and read it before using
* this file.
while (inb(PORT_B) & KB_INFULL); /* wait until done */
}
+
--- /dev/null
+/*
+ * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * The contents of this file constitute Original Code as defined in and
+ * are subject to the Apple Public Source License Version 2.0 (the
+ * "License"). You may not use this file except in compliance with the
+ * License. Please obtain a copy of the License at
+ * http://www.apple.com/publicsource and read it before using this file.
+ *
+ * This Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1998 Robert Nordier
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "libsaio.h"
+#include "sl.h"
+
+#include "msdos_private.h"
+#include "msdos.h"
+
+#define LABEL_LENGTH 11
+#define MAX_DOS_BLOCKSIZE 2048
+
+#define CLUST_FIRST 2 /* first legal cluster number */
+#define CLUST_RSRVD 0xfffffff6 /* reserved cluster range */
+
+
+#define false 0
+#define true 1
+
+#if DEBUG
+#define DLOG(x) { outb(0x80, (x)); getc(); }
+#else
+#define DLOG(x)
+#endif
+
+#if UNUSED
+/*
+ * Check a volume label.
+ */
+static int
+oklabel(const char *src)
+{
+ int c, i;
+
+ for (i = 0, c = 0; i <= 11; i++) {
+ c = (u_char)*src++;
+ if (c < ' ' + !i || strchr("\"*+,./:;<=>?[\\]|", c))
+ break;
+ }
+ return i && !c;
+}
+#endif /* UNUSED */
+
+/* Fix up volume label. */
+static void
+fixLabel(char *label, char *str, long strMaxLen)
+{
+ int i;
+ //unsigned char labelUTF8[LABEL_LENGTH*3];
+
+ /* Convert leading 0x05 to 0xE5 for multibyte languages like Japanese */
+ if (label[0] == 0x05)
+ label[0] = 0xE5;
+
+#if UNUSED
+ /* Check for illegal characters */
+ if (!oklabel(label))
+ label[0] = 0;
+#endif /* UNUSED */
+
+ /* Remove any trailing spaces */
+ for (i=LABEL_LENGTH-1; i>=0; --i) {
+ if (label[i] == ' ')
+ label[i] = 0;
+ else
+ break;
+ }
+
+ /* TODO: Convert it to UTF-8 from DOSLatin1 encoding */
+ strncpy(str, label, strMaxLen);
+}
+
+
+void
+MSDOSGetDescription(CICell ih, char *str, long strMaxLen)
+{
+ struct direntry *dirp;
+ union bootsector *bsp;
+ struct bpb33 *b33;
+ struct bpb50 *b50;
+ struct bpb710 *b710;
+ u_int16_t bps;
+ int8_t spc;
+ int rootDirSectors;
+ int i, finished;
+ char *buf;
+ unsigned char label[LABEL_LENGTH+1];
+
+ DLOG(0);
+ buf = (char *)malloc(MAX_DOS_BLOCKSIZE);
+ if (buf == 0) goto error;
+
+ DLOG(1);
+ /*
+ * Read the boot sector of the filesystem, and then check the
+ * boot signature. If not a dos boot sector then error out.
+ *
+ * NOTE: 2048 is a maximum sector size in current...
+ */
+ Seek(ih, 0);
+ Read(ih, (long)buf, MAX_DOS_BLOCKSIZE);
+
+ DLOG(2);
+ bsp = (union bootsector *)buf;
+ b33 = (struct bpb33 *)bsp->bs33.bsBPB;
+ b50 = (struct bpb50 *)bsp->bs50.bsBPB;
+ b710 = (struct bpb710 *)bsp->bs710.bsBPB;
+
+ DLOG(3);
+ /* [2699033]
+ *
+ * The first three bytes are an Intel x86 jump instruction. It should be one
+ * of the following forms:
+ * 0xE9 0x?? 0x??
+ * 0xEC 0x?? 0x90
+ * where 0x?? means any byte value is OK.
+ */
+ if (bsp->bs50.bsJump[0] != 0xE9
+ && (bsp->bs50.bsJump[0] != 0xEB || bsp->bs50.bsJump[2] != 0x90)) {
+ goto error;
+ }
+
+ DLOG(4);
+ /* It is possible that the above check could match a partition table, or some */
+ /* non-FAT disk meant to boot a PC. Check some more fields for sensible values. */
+
+ /* We only work with 512, 1024, and 2048 byte sectors */
+ bps = OSSwapLittleToHostInt16(b33->bpbBytesPerSec);
+ if ((bps < 0x200) || (bps & (bps - 1)) || (bps > 0x800)) {
+ goto error;
+ }
+
+ DLOG(5);
+ /* Check to make sure valid sectors per cluster */
+ spc = b33->bpbSecPerClust;
+ if ((spc == 0 ) || (spc & (spc - 1))) {
+ goto error;
+ }
+
+ DLOG(6);
+ /* we know this disk, find the volume label */
+ /* First, find the root directory */
+ label[0] = '\0';
+ finished = false;
+ rootDirSectors = ((OSSwapLittleToHostInt16(b50->bpbRootDirEnts) * sizeof(struct direntry)) +
+ (bps-1)) / bps;
+
+ DLOG(7);
+
+ if (rootDirSectors) { /* FAT12 or FAT16 */
+ int firstRootDirSecNum;
+ u_int8_t *rootDirBuffer;
+ int j;
+
+ rootDirBuffer = (char *)malloc(MAX_DOS_BLOCKSIZE);
+
+ DLOG(8);
+ firstRootDirSecNum = OSSwapLittleToHostInt16(b33->bpbResSectors) +
+ (b33->bpbFATs * OSSwapLittleToHostInt16(b33->bpbFATsecs));
+ for (i=0; i< rootDirSectors; i++) {
+ Seek(ih, (firstRootDirSecNum+i)*bps);
+ Read(ih, (long)rootDirBuffer, bps);
+ dirp = (struct direntry *)rootDirBuffer;
+ for (j=0; j<bps; j+=sizeof(struct direntry), dirp++) {
+ if (dirp->deName[0] == SLOT_EMPTY) {
+ finished = true;
+ break;
+ }
+ else if (dirp->deName[0] == SLOT_DELETED)
+ continue;
+ else if (dirp->deAttributes == ATTR_WIN95)
+ continue;
+ else if (dirp->deAttributes & ATTR_VOLUME) {
+ strncpy(label, dirp->deName, LABEL_LENGTH);
+ finished = true;
+ break;
+ }
+ } /* j */
+ if (finished == true) {
+ break;
+ }
+ } /* i */
+
+ free(rootDirBuffer);
+
+ } else { /* FAT32 */
+ u_int32_t cluster;
+ u_int32_t bytesPerCluster;
+ u_int8_t *rootDirBuffer;
+ off_t readOffset;
+
+ DLOG(9);
+ bytesPerCluster = bps * spc;
+ rootDirBuffer = malloc(bytesPerCluster);
+ cluster = OSSwapLittleToHostInt32(b710->bpbRootClust);
+
+ DLOG(0x20);
+ finished = false;
+ while (!finished && cluster >= CLUST_FIRST && cluster < CLUST_RSRVD) {
+
+ DLOG(0x21);
+ /* Find sector where clusters start */
+ readOffset = OSSwapLittleToHostInt16(b710->bpbResSectors) +
+ (b710->bpbFATs * OSSwapLittleToHostInt16(b710->bpbBigFATsecs));
+ /* Find sector where "cluster" starts */
+ readOffset += ((off_t) cluster - CLUST_FIRST) * (off_t) spc;
+ /* Convert to byte offset */
+ readOffset *= (off_t) bps;
+
+ DLOG(0x22);
+ /* Read in "cluster" */
+ Seek(ih, readOffset);
+ Read(ih, (long)rootDirBuffer, bytesPerCluster);
+ dirp = (struct direntry *) rootDirBuffer;
+
+ DLOG(0x23);
+ /* Examine each directory entry in this cluster */
+ for (i=0; i < bytesPerCluster; i += sizeof(struct direntry), dirp++) {
+
+ DLOG(0x24);
+ if (dirp->deName[0] == SLOT_EMPTY) {
+ finished = true; // Reached end of directory (never used entry)
+ break;
+ }
+ else if (dirp->deName[0] == SLOT_DELETED)
+ continue;
+ else if (dirp->deAttributes == ATTR_WIN95)
+ continue;
+ else if (dirp->deAttributes & ATTR_VOLUME) {
+ DLOG(0x31);
+ strncpy(label, dirp->deName, LABEL_LENGTH);
+ finished = true;
+ break;
+ }
+ DLOG(0x25);
+ }
+ if (finished)
+ break;
+
+ DLOG(0x26);
+ /* Find next cluster in the chain by reading the FAT */
+
+ /* Find first sector of FAT */
+ readOffset = OSSwapLittleToHostInt16(b710->bpbResSectors);
+ /* Find sector containing "cluster" entry in FAT */
+ readOffset += (cluster * 4) / bps;
+ /* Convert to byte offset */
+ readOffset *= bps;
+
+ DLOG(0x27);
+ /* Read one sector of the FAT */
+ Seek(ih, readOffset);
+ Read(ih, (long)rootDirBuffer, bps);
+
+ DLOG(0x28);
+ cluster = OSReadLittleInt32(rootDirBuffer + ((cluster * 4) % bps), 0);
+ cluster &= 0x0FFFFFFF; // ignore reserved upper bits
+ }
+
+ free(rootDirBuffer);
+
+ } /* rootDirSectors */
+
+ DLOG(10);
+ /* else look in the boot blocks */
+ if (str[0] == '\0') {
+ if (OSSwapLittleToHostInt16(b50->bpbRootDirEnts) == 0) { /* It's FAT32 */
+ strncpy(label, ((struct extboot *)bsp->bs710.bsExt)->exVolumeLabel, LABEL_LENGTH);
+ }
+ else if (((struct extboot *)bsp->bs50.bsExt)->exBootSignature == EXBOOTSIG) {
+ strncpy(label, ((struct extboot *)bsp->bs50.bsExt)->exVolumeLabel, LABEL_LENGTH);
+ }
+ }
+
+ fixLabel(label, str, strMaxLen);
+
+ free(buf);
+ return;
+
+ error:
+ DLOG(0xee);
+ if (buf) free(buf);
+ return;
+}
--- /dev/null
+/*
+ * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * The contents of this file constitute Original Code as defined in and
+ * are subject to the Apple Public Source License Version 2.0 (the
+ * "License"). You may not use this file except in compliance with the
+ * License. Please obtain a copy of the License at
+ * http://www.apple.com/publicsource and read it before using this file.
+ *
+ * This Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+extern void MSDOSGetDescription(CICell ih, char *str, long strMaxLen);
--- /dev/null
+/*
+ * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * The contents of this file constitute Original Code as defined in and
+ * are subject to the Apple Public Source License Version 2.0 (the
+ * "License"). You may not use this file except in compliance with the
+ * License. Please obtain a copy of the License at
+ * http://www.apple.com/publicsource and read it before using this file.
+ *
+ * This Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Written by Paul Popelka (paulp@uts.amdahl.com)
+ *
+ * You can do anything you want with this software, just don't say you wrote
+ * it, and don't remove this notice.
+ *
+ * This software is provided "as is".
+ *
+ * The author supplies this software to be publicly redistributed on the
+ * understanding that the author is not responsible for the correct
+ * functioning of this software in any circumstances and is not liable for
+ * any damages caused by this software.
+ *
+ * October 1992
+ */
+
+/*
+ * Format of a boot sector. This is the first sector on a DOS floppy disk
+ * or the fist sector of a partition on a hard disk. But, it is not the
+ * first sector of a partitioned hard disk.
+ */
+struct bootsector33 {
+ u_int8_t bsJump[3]; /* jump inst E9xxxx or EBxx90 */
+ int8_t bsOemName[8]; /* OEM name and version */
+ int8_t bsBPB[19]; /* BIOS parameter block */
+ int8_t bsDriveNumber; /* drive number (0x80) */
+ int8_t bsBootCode[479]; /* pad so struct is 512b */
+ u_int8_t bsBootSectSig0;
+ u_int8_t bsBootSectSig1;
+#define BOOTSIG0 0x55
+#define BOOTSIG1 0xaa
+};
+
+struct extboot {
+ int8_t exDriveNumber; /* drive number (0x80) */
+ int8_t exReserved1; /* reserved */
+ int8_t exBootSignature; /* ext. boot signature (0x29) */
+#define EXBOOTSIG 0x29
+ int8_t exVolumeID[4]; /* volume ID number */
+ int8_t exVolumeLabel[11]; /* volume label */
+ int8_t exFileSysType[8]; /* fs type (FAT12 or FAT16) */
+};
+
+struct bootsector50 {
+ u_int8_t bsJump[3]; /* jump inst E9xxxx or EBxx90 */
+ int8_t bsOemName[8]; /* OEM name and version */
+ int8_t bsBPB[25]; /* BIOS parameter block */
+ int8_t bsExt[26]; /* Bootsector Extension */
+ int8_t bsBootCode[448]; /* pad so structure is 512b */
+ u_int8_t bsBootSectSig0;
+ u_int8_t bsBootSectSig1;
+#define BOOTSIG0 0x55
+#define BOOTSIG1 0xaa
+};
+
+struct bootsector710 {
+ u_int8_t bsJump[3]; /* jump inst E9xxxx or EBxx90 */
+ int8_t bsOEMName[8]; /* OEM name and version */
+ int8_t bsBPB[53]; /* BIOS parameter block */
+ int8_t bsExt[26]; /* Bootsector Extension */
+ int8_t bsBootCode[420]; /* pad so structure is 512b */
+ u_int8_t bsBootSectSig0;
+ u_int8_t bsBootSectSig1;
+#define BOOTSIG0 0x55
+#define BOOTSIG1 0xaa
+};
+
+union bootsector {
+ struct bootsector33 bs33;
+ struct bootsector50 bs50;
+ struct bootsector710 bs710;
+};
+
+
+/* BPB */
+
+/*
+ * BIOS Parameter Block (BPB) for DOS 3.3
+ */
+struct bpb33 {
+ u_int16_t bpbBytesPerSec; /* bytes per sector */
+ u_int8_t bpbSecPerClust; /* sectors per cluster */
+ u_int16_t bpbResSectors; /* number of reserved sectors */
+ u_int8_t bpbFATs; /* number of FATs */
+ u_int16_t bpbRootDirEnts; /* number of root directory entries */
+ u_int16_t bpbSectors; /* total number of sectors */
+ u_int8_t bpbMedia; /* media descriptor */
+ u_int16_t bpbFATsecs; /* number of sectors per FAT */
+ u_int16_t bpbSecPerTrack; /* sectors per track */
+ u_int16_t bpbHeads; /* number of heads */
+ u_int16_t bpbHiddenSecs; /* number of hidden sectors */
+} __attribute__((packed));
+
+/*
+ * BPB for DOS 5.0 The difference is bpbHiddenSecs is a short for DOS 3.3,
+ * and bpbHugeSectors is not in the 3.3 bpb.
+ */
+struct bpb50 {
+ u_int16_t bpbBytesPerSec; /* bytes per sector */
+ u_int8_t bpbSecPerClust; /* sectors per cluster */
+ u_int16_t bpbResSectors; /* number of reserved sectors */
+ u_int8_t bpbFATs; /* number of FATs */
+ u_int16_t bpbRootDirEnts; /* number of root directory entries */
+ u_int16_t bpbSectors; /* total number of sectors */
+ u_int8_t bpbMedia; /* media descriptor */
+ u_int16_t bpbFATsecs; /* number of sectors per FAT */
+ u_int16_t bpbSecPerTrack; /* sectors per track */
+ u_int16_t bpbHeads; /* number of heads */
+ u_int32_t bpbHiddenSecs; /* # of hidden sectors */
+ u_int32_t bpbHugeSectors; /* # of sectors if bpbSectors == 0 */
+} __attribute__((packed));
+
+/*
+ * BPB for DOS 7.10 (FAT32). This one has a few extensions to bpb50.
+ */
+struct bpb710 {
+ u_int16_t bpbBytesPerSec; /* bytes per sector */
+ u_int8_t bpbSecPerClust; /* sectors per cluster */
+ u_int16_t bpbResSectors; /* number of reserved sectors */
+ u_int8_t bpbFATs; /* number of FATs */
+ u_int16_t bpbRootDirEnts; /* number of root directory entries */
+ u_int16_t bpbSectors; /* total number of sectors */
+ u_int8_t bpbMedia; /* media descriptor */
+ u_int16_t bpbFATsecs; /* number of sectors per FAT */
+ u_int16_t bpbSecPerTrack; /* sectors per track */
+ u_int16_t bpbHeads; /* number of heads */
+ u_int32_t bpbHiddenSecs; /* # of hidden sectors */
+ u_int32_t bpbHugeSectors; /* # of sectors if bpbSectors == 0 */
+ u_int32_t bpbBigFATsecs; /* like bpbFATsecs for FAT32 */
+ u_int16_t bpbExtFlags; /* extended flags: */
+#define FATNUM 0xf /* mask for numbering active FAT */
+#define FATMIRROR 0x80 /* FAT is mirrored (like it always was) */
+ u_int16_t bpbFSVers; /* filesystem version */
+#define FSVERS 0 /* currently only 0 is understood */
+ u_int32_t bpbRootClust; /* start cluster for root directory */
+ u_int16_t bpbFSInfo; /* filesystem info structure sector */
+ u_int16_t bpbBackup; /* backup boot sector */
+ /* There is a 12 byte filler here, but we ignore it */
+} __attribute__((packed));
+
+#if 0
+/*
+ * BIOS Parameter Block (BPB) for DOS 3.3
+ */
+struct byte_bpb33 {
+ int8_t bpbBytesPerSec[2]; /* bytes per sector */
+ int8_t bpbSecPerClust; /* sectors per cluster */
+ int8_t bpbResSectors[2]; /* number of reserved sectors */
+ int8_t bpbFATs; /* number of FATs */
+ int8_t bpbRootDirEnts[2]; /* number of root directory entries */
+ int8_t bpbSectors[2]; /* total number of sectors */
+ int8_t bpbMedia; /* media descriptor */
+ int8_t bpbFATsecs[2]; /* number of sectors per FAT */
+ int8_t bpbSecPerTrack[2]; /* sectors per track */
+ int8_t bpbHeads[2]; /* number of heads */
+ int8_t bpbHiddenSecs[2]; /* number of hidden sectors */
+};
+
+/*
+ * BPB for DOS 5.0 The difference is bpbHiddenSecs is a short for DOS 3.3,
+ * and bpbHugeSectors is not in the 3.3 bpb.
+ */
+struct byte_bpb50 {
+ int8_t bpbBytesPerSec[2]; /* bytes per sector */
+ int8_t bpbSecPerClust; /* sectors per cluster */
+ int8_t bpbResSectors[2]; /* number of reserved sectors */
+ int8_t bpbFATs; /* number of FATs */
+ int8_t bpbRootDirEnts[2]; /* number of root directory entries */
+ int8_t bpbSectors[2]; /* total number of sectors */
+ int8_t bpbMedia; /* media descriptor */
+ int8_t bpbFATsecs[2]; /* number of sectors per FAT */
+ int8_t bpbSecPerTrack[2]; /* sectors per track */
+ int8_t bpbHeads[2]; /* number of heads */
+ int8_t bpbHiddenSecs[4]; /* number of hidden sectors */
+ int8_t bpbHugeSectors[4]; /* # of sectors if bpbSectors == 0 */
+};
+
+/*
+ * BPB for DOS 7.10 (FAT32). This one has a few extensions to bpb50.
+ */
+struct byte_bpb710 {
+ u_int8_t bpbBytesPerSec[2]; /* bytes per sector */
+ u_int8_t bpbSecPerClust; /* sectors per cluster */
+ u_int8_t bpbResSectors[2]; /* number of reserved sectors */
+ u_int8_t bpbFATs; /* number of FATs */
+ u_int8_t bpbRootDirEnts[2]; /* number of root directory entries */
+ u_int8_t bpbSectors[2]; /* total number of sectors */
+ u_int8_t bpbMedia; /* media descriptor */
+ u_int8_t bpbFATsecs[2]; /* number of sectors per FAT */
+ u_int8_t bpbSecPerTrack[2]; /* sectors per track */
+ u_int8_t bpbHeads[2]; /* number of heads */
+ u_int8_t bpbHiddenSecs[4]; /* # of hidden sectors */
+ u_int8_t bpbHugeSectors[4]; /* # of sectors if bpbSectors == 0 */
+ u_int8_t bpbBigFATsecs[4]; /* like bpbFATsecs for FAT32 */
+ u_int8_t bpbExtFlags[2]; /* extended flags: */
+ u_int8_t bpbFSVers[2]; /* filesystem version */
+ u_int8_t bpbRootClust[4]; /* start cluster for root directory */
+ u_int8_t bpbFSInfo[2]; /* filesystem info structure sector */
+ u_int8_t bpbBackup[2]; /* backup boot sector */
+ /* There is a 12 byte filler here, but we ignore it */
+};
+#endif
+
+/*
+ * FAT32 FSInfo block.
+ */
+struct fsinfo {
+ u_int8_t fsisig1[4];
+ u_int8_t fsifill1[480];
+ u_int8_t fsisig2[4];
+ u_int8_t fsinfree[4];
+ u_int8_t fsinxtfree[4];
+ u_int8_t fsifill2[12];
+ u_int8_t fsisig3[4];
+};
+
+
+/* direntry */
+
+/*-
+ * Copyright (C) 1994, 1995, 1997 Wolfgang Solfrank.
+ * Copyright (C) 1994, 1995, 1997 TooLs GmbH.
+ * All rights reserved.
+ * Original code by Paul Popelka (paulp@uts.amdahl.com) (see above).
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Structure of a dos directory entry.
+ */
+struct direntry {
+ u_int8_t deName[8]; /* filename, blank filled */
+#define SLOT_EMPTY 0x00 /* slot has never been used */
+#define SLOT_E5 0x05 /* the real value is 0xe5 */
+#define SLOT_DELETED 0xe5 /* file in this slot deleted */
+ u_int8_t deExtension[3]; /* extension, blank filled */
+ u_int8_t deAttributes; /* file attributes */
+#define ATTR_NORMAL 0x00 /* normal file */
+#define ATTR_READONLY 0x01 /* file is read-only (immutable) */
+#define ATTR_HIDDEN 0x02 /* file is hidden */
+#define ATTR_SYSTEM 0x04 /* file is a system file */
+#define ATTR_VOLUME 0x08 /* entry is a volume label */
+#define ATTR_DIRECTORY 0x10 /* entry is a directory name */
+#define ATTR_ARCHIVE 0x20 /* file is new or modified */
+ u_int8_t deLowerCase; /* NT VFAT lower case flags */
+#define LCASE_BASE 0x08 /* filename base in lower case */
+#define LCASE_EXT 0x10 /* filename extension in lower case */
+ u_int8_t deCHundredth; /* hundredth of seconds in CTime */
+ u_int8_t deCTime[2]; /* create time */
+ u_int8_t deCDate[2]; /* create date */
+ u_int8_t deADate[2]; /* access date */
+ u_int8_t deHighClust[2]; /* high bytes of cluster number */
+ u_int8_t deMTime[2]; /* last update time */
+ u_int8_t deMDate[2]; /* last update date */
+ u_int8_t deStartCluster[2]; /* starting cluster of file */
+ u_int8_t deFileSize[4]; /* size of file in bytes */
+};
+
+/*
+ * Structure of a Win95 long name directory entry
+ */
+struct winentry {
+ u_int8_t weCnt;
+#define WIN_LAST 0x40
+#define WIN_CNT 0x3f
+ u_int8_t wePart1[10];
+ u_int8_t weAttributes;
+#define ATTR_WIN95 0x0f
+ u_int8_t weReserved1;
+ u_int8_t weChksum;
+ u_int8_t wePart2[12];
+ u_int16_t weReserved2;
+ u_int8_t wePart3[4];
+};
+#define WIN_CHARS 13 /* Number of chars per winentry */
+
+/*
+ * Maximum filename length in Win95
+ * Note: Must be < sizeof(dirent.d_name)
+ */
+#define WIN_MAXLEN 255
+
+/*
+ * This is the format of the contents of the deTime field in the direntry
+ * structure.
+ * We don't use bitfields because we don't know how compilers for
+ * arbitrary machines will lay them out.
+ */
+#define DT_2SECONDS_MASK 0x1F /* seconds divided by 2 */
+#define DT_2SECONDS_SHIFT 0
+#define DT_MINUTES_MASK 0x7E0 /* minutes */
+#define DT_MINUTES_SHIFT 5
+#define DT_HOURS_MASK 0xF800 /* hours */
+#define DT_HOURS_SHIFT 11
+
+/*
+ * This is the format of the contents of the deDate field in the direntry
+ * structure.
+ */
+#define DD_DAY_MASK 0x1F /* day of month */
+#define DD_DAY_SHIFT 0
+#define DD_MONTH_MASK 0x1E0 /* month */
+#define DD_MONTH_SHIFT 5
+#define DD_YEAR_MASK 0xFE00 /* year - 1980 */
+#define DD_YEAR_SHIFT 9
+
/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
- * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
+ * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights
* Reserved. This file contains Original Code and/or Modifications of
* Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.1 (the "License"). You may not use this file
+ * Source License Version 2.0 (the "License"). You may not use this file
* except in compliance with the License. Please obtain a copy of the
* License at http://www.apple.com/publicsource and read it before using
* this file.
* GetDirEntry is not supported.
*/
static long NBPGetDirEntry(CICell ih, char * dirPath, long * dirIndex,
- char ** name, long * flags, long * time)
+ char ** name, long * flags, long * time,
+ FinderInfo * finderInfo, long * infoValid)
{
return -1;
}
/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
- * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
+ * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights
* Reserved. This file contains Original Code and/or Modifications of
* Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.1 (the "License"). You may not use this file
+ * Source License Version 2.0 (the "License"). You may not use this file
* except in compliance with the License. Please obtain a copy of the
* License at http://www.apple.com/publicsource and read it before using
* this file.
--- /dev/null
+/*
+ * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Copyright (c) 1999-2004 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+#include "libsaio.h"
+#include "sl.h"
+
+#define BYTE_ORDER_MARK 0xFEFF
+
+#include "ntfs_private.h"
+
+#define FS_TYPE "ntfs"
+#define FS_NAME_FILE "NTFS"
+
+#define MAX_BLOCK_SIZE 2048
+#define MAX_CLUSTER_SIZE 32768
+
+#define LABEL_LENGTH 1024
+#define UNKNOWN_LABEL "Untitled NTFS"
+
+#define FSUR_IO_FAIL -1
+#define FSUR_UNRECOGNIZED -1
+#define FSUR_RECOGNIZED 0
+
+#define ERROR -1
+
+/*
+ * Process per-sector "fixups" that NTFS uses to detect corruption of
+ * multi-sector data structures, like MFT records.
+ */
+static int
+ntfs_fixup(
+ char *buf,
+ size_t len,
+ u_int32_t magic,
+ u_int32_t bytesPerSector)
+{
+ struct fixuphdr *fhp = (struct fixuphdr *) buf;
+ int i;
+ u_int16_t fixup;
+ u_int16_t *fxp;
+ u_int16_t *cfxp;
+ u_int32_t fixup_magic;
+ u_int16_t fixup_count;
+ u_int16_t fixup_offset;
+
+ fixup_magic = OSReadLittleInt32(&fhp->fh_magic,0);
+ if (fixup_magic != magic) {
+ error("ntfs_fixup: magic doesn't match: %08x != %08x\n",
+ fixup_magic, magic);
+ return (ERROR);
+ }
+ fixup_count = OSReadLittleInt16(&fhp->fh_fnum,0);
+ if ((fixup_count - 1) * bytesPerSector != len) {
+ error("ntfs_fixup: " \
+ "bad fixups number: %d for %ld bytes block\n",
+ fixup_count, (long)len); /* XXX printf kludge */
+ return (ERROR);
+ }
+ fixup_offset = OSReadLittleInt16(&fhp->fh_foff,0);
+ if (fixup_offset >= len) {
+ error("ntfs_fixup: invalid offset: %x", fixup_offset);
+ return (ERROR);
+ }
+ fxp = (u_int16_t *) (buf + fixup_offset);
+ cfxp = (u_int16_t *) (buf + bytesPerSector - 2);
+ fixup = *fxp++;
+ for (i = 1; i < fixup_count; i++, fxp++) {
+ if (*cfxp != fixup) {
+ error("ntfs_fixup: fixup %d doesn't match\n", i);
+ return (ERROR);
+ }
+ *cfxp = *fxp;
+ ((caddr_t) cfxp) += bytesPerSector;
+ }
+ return (0);
+}
+
+/*
+ * Find a resident attribute of a given type. Returns a pointer to the
+ * attribute data, and its size in bytes.
+ */
+static int
+ntfs_find_attr(
+ char *buf,
+ u_int32_t attrType,
+ void **attrData,
+ size_t *attrSize)
+{
+ struct filerec *filerec;
+ struct attr *attr;
+ u_int16_t offset;
+
+ filerec = (struct filerec *) buf;
+ offset = OSReadLittleInt16(&filerec->fr_attroff,0);
+ attr = (struct attr *) (buf + offset);
+
+ /*¥¥ Should we also check offset < buffer size? */
+ while (attr->a_hdr.a_type != 0xFFFFFFFF) /* same for big/little endian */
+ {
+ if (OSReadLittleInt32(&attr->a_hdr.a_type,0) == attrType)
+ {
+ if (attr->a_hdr.a_flag != 0)
+ {
+ //verbose("NTFS: attriubte 0x%X is non-resident\n", attrType);
+ return 1;
+ }
+
+ *attrSize = OSReadLittleInt16(&attr->a_r.a_datalen,0);
+ *attrData = buf + offset + OSReadLittleInt16(&attr->a_r.a_dataoff,0);
+ return 0; /* found it! */
+ }
+
+ /* Skip to the next attribute */
+ offset += OSReadLittleInt32(&attr->a_hdr.reclen,0);
+ attr = (struct attr *) (buf + offset);
+ }
+
+ return 1; /* No matching attrType found */
+}
+
+static int
+memcmp(char *p1, char *p2, int len)
+{
+ while (len--) {
+ if (*p1++ != *p2++)
+ return -1;
+ }
+ return 0;
+}
+
+/*
+ * Examine a volume to see if we recognize it as a mountable.
+ */
+void
+NTFSGetDescription(CICell ih, char *str, long strMaxLen)
+{
+ struct bootfile *boot;
+ unsigned bytesPerSector;
+ unsigned sectorsPerCluster;
+ int mftRecordSize;
+ u_int64_t totalClusters;
+ u_int64_t cluster, mftCluster;
+ size_t mftOffset;
+ void *nameAttr;
+ size_t nameSize;
+ char *buf;
+
+ buf = (char *)malloc(MAX_CLUSTER_SIZE);
+ if (buf == 0) {
+ goto error;
+ }
+
+ /*
+ * Read the boot sector, check signatures, and do some minimal
+ * sanity checking. NOTE: the size of the read below is intended
+ * to be a multiple of all supported block sizes, so we don't
+ * have to determine or change the device's block size.
+ */
+ Seek(ih, 0);
+ Read(ih, (long)buf, MAX_BLOCK_SIZE);
+
+ boot = (struct bootfile *) buf;
+
+ /*
+ * The first three bytes are an Intel x86 jump instruction. I assume it
+ * can be the same forms as DOS FAT:
+ * 0xE9 0x?? 0x??
+ * 0xEC 0x?? 0x90
+ * where 0x?? means any byte value is OK.
+ */
+ if (boot->reserved1[0] != 0xE9
+ && (boot->reserved1[0] != 0xEB || boot->reserved1[2] != 0x90))
+ {
+ goto error;
+ }
+
+ /*
+ * Check the "NTFS " signature.
+ */
+ if (memcmp(boot->bf_sysid, "NTFS ", 8) != 0)
+ {
+ goto error;
+ }
+
+ /*
+ * Make sure the bytes per sector and sectors per cluster are
+ * powers of two, and within reasonable ranges.
+ */
+ bytesPerSector = OSReadLittleInt16(&boot->bf_bps,0);
+ if ((bytesPerSector & (bytesPerSector-1)) || bytesPerSector < 512 || bytesPerSector > 32768)
+ {
+ //verbose("NTFS: invalid bytes per sector (%d)\n", bytesPerSector);
+ goto error;
+ }
+
+ sectorsPerCluster = boot->bf_spc; /* Just one byte; no swapping needed */
+ if ((sectorsPerCluster & (sectorsPerCluster-1)) || sectorsPerCluster > 128)
+ {
+ //verbose("NTFS: invalid sectors per cluster (%d)\n", bytesPerSector);
+ goto error;
+ }
+
+ /*
+ * Calculate the number of clusters from the number of sectors.
+ * Then bounds check the $MFT and $MFTMirr clusters.
+ */
+ totalClusters = OSReadLittleInt64(&boot->bf_spv,0) / sectorsPerCluster;
+ mftCluster = OSReadLittleInt64(&boot->bf_mftcn,0);
+ if (mftCluster > totalClusters)
+ {
+ ////verbose("NTFS: invalid $MFT cluster (%lld)\n", mftCluster);
+ goto error;
+ }
+ cluster = OSReadLittleInt64(&boot->bf_mftmirrcn,0);
+ if (cluster > totalClusters)
+ {
+ //verbose("NTFS: invalid $MFTMirr cluster (%lld)\n", cluster);
+ goto error;
+ }
+
+ /*
+ * Determine the size of an MFT record.
+ */
+ mftRecordSize = (int8_t) boot->bf_mftrecsz;
+ if (mftRecordSize < 0)
+ mftRecordSize = 1 << -mftRecordSize;
+ else
+ mftRecordSize *= bytesPerSector * sectorsPerCluster;
+ //verbose("NTFS: MFT record size = %d\n", mftRecordSize);
+
+ /*
+ * Read the MFT record for $Volume. This assumes the first four
+ * file records in the MFT are contiguous; if they aren't, we
+ * would have to map the $MFT itself.
+ *
+ * This will fail if the device sector size is larger than the
+ * MFT record size, since the $Volume record won't be aligned
+ * on a sector boundary.
+ */
+ mftOffset = mftCluster * sectorsPerCluster * bytesPerSector;
+ mftOffset += mftRecordSize * NTFS_VOLUMEINO;
+
+ Seek(ih, mftOffset);
+ Read(ih, (long)buf, mftRecordSize);
+#if UNUSED
+ if (lseek(fd, mftOffset, SEEK_SET) == -1)
+ {
+ //verbose("NTFS: lseek to $Volume failed: %s\n", strerror(errno));
+ goto error;
+ }
+ if (read(fd, buf, mftRecordSize) != mftRecordSize)
+ {
+ //verbose("NTFS: error reading MFT $Volume record: %s\n",
+ strerror(errno));
+ goto error;
+ }
+#endif
+
+ if (ntfs_fixup(buf, mftRecordSize, NTFS_FILEMAGIC, bytesPerSector) != 0)
+ {
+ //verbose("NTFS: block fixup failed\n");
+ goto error;
+ }
+
+ /*
+ * Loop over the attributes, looking for $VOLUME_NAME (0x60).
+ */
+ if(ntfs_find_attr(buf, NTFS_A_VOLUMENAME, &nameAttr, &nameSize) != 0)
+ {
+ //verbose("NTFS: $VOLUME_NAME attribute not found\n");
+ goto error;
+ }
+
+ str[0] = '\0';
+
+ utf_encodestr( nameAttr, nameSize / 2, str, strMaxLen, OSLittleEndian );
+
+ free(buf);
+ return;
+
+ error:
+ if (buf) free(buf);
+ return;
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * The contents of this file constitute Original Code as defined in and
+ * are subject to the Apple Public Source License Version 2.0 (the
+ * "License"). You may not use this file except in compliance with the
+ * License. Please obtain a copy of the License at
+ * http://www.apple.com/publicsource and read it before using this file.
+ *
+ * This Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+extern void NTFSGetDescription(CICell ih, char *str, long strMaxLen);
+extern void NTFSGetDescriptionX(CICell ih, char *str, long strMaxLen);
+
--- /dev/null
+/*
+ * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/* $NetBSD: ntfs.h,v 1.9 1999/10/31 19:45:26 jdolecek Exp $ */
+
+/*-
+ * Copyright (c) 1998, 1999 Semen Ustimenko
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD: src/sys/fs/ntfs/ntfs.h,v 1.14 2001/11/27 00:18:33 jhb Exp $
+ */
+
+/*#define NTFS_DEBUG 1*/
+
+#ifdef APPLE
+/* We're using FreeBSD style byte order macros in the source. */
+#include <libkern/OSByteOrder.h>
+#define le16toh(x) OSSwapLittleToHostInt16(x)
+#define le32toh(x) OSSwapLittleToHostInt32(x)
+#define le64toh(x) OSSwapLittleToHostInt64(x)
+
+/* FreeBSD mutexes correspond to Darwin's simple locks */
+#define mtx_lock(lock) simple_lock(lock)
+#define mtx_unlock(lock) simple_unlock(lock)
+#define mtx_destroy(lock) /* Nothing. */
+
+#define lockdestroy(lock) /* Nothing. */
+
+#endif
+
+typedef u_int64_t cn_t;
+typedef u_int16_t wchar;
+
+#pragma pack(1)
+#define BBSIZE 1024
+#define BBOFF ((off_t)(0))
+#define BBLOCK ((daddr_t)(0))
+#define NTFS_MFTINO 0
+#define NTFS_VOLUMEINO 3
+#define NTFS_ATTRDEFINO 4
+#define NTFS_ROOTINO 5
+#define NTFS_BITMAPINO 6
+#define NTFS_BOOTINO 7
+#define NTFS_BADCLUSINO 8
+#define NTFS_UPCASEINO 10
+#define NTFS_MAXFILENAME 255
+
+struct fixuphdr {
+ u_int32_t fh_magic;
+ u_int16_t fh_foff;
+ u_int16_t fh_fnum;
+};
+
+#define NTFS_AF_INRUN 0x00000001
+struct attrhdr {
+ u_int32_t a_type;
+ u_int32_t reclen;
+ u_int8_t a_flag;
+ u_int8_t a_namelen;
+ u_int8_t a_nameoff;
+ u_int8_t reserved1;
+ u_int8_t a_compression;
+ u_int8_t reserved2;
+ u_int16_t a_index;
+};
+#define NTFS_A_STD 0x10
+#define NTFS_A_ATTRLIST 0x20
+#define NTFS_A_NAME 0x30
+#define NTFS_A_VOLUMENAME 0x60
+#define NTFS_A_DATA 0x80
+#define NTFS_A_INDXROOT 0x90
+#define NTFS_A_INDX 0xA0
+#define NTFS_A_INDXBITMAP 0xB0
+
+#define NTFS_MAXATTRNAME 255
+struct attr {
+ struct attrhdr a_hdr;
+ union {
+ struct {
+ u_int16_t a_datalen;
+ u_int16_t reserved1;
+ u_int16_t a_dataoff;
+ u_int16_t a_indexed;
+ } a_S_r;
+ struct {
+ cn_t a_vcnstart;
+ cn_t a_vcnend;
+ u_int16_t a_dataoff;
+ u_int16_t a_compressalg;
+ u_int32_t reserved1;
+ u_int64_t a_allocated;
+ u_int64_t a_datalen;
+ u_int64_t a_initialized;
+ } a_S_nr;
+ } a_S;
+};
+#define a_r a_S.a_S_r
+#define a_nr a_S.a_S_nr
+
+typedef struct {
+ u_int64_t t_create;
+ u_int64_t t_write;
+ u_int64_t t_mftwrite;
+ u_int64_t t_access;
+} ntfs_times_t;
+
+#define NTFS_FFLAG_RDONLY 0x01LL
+#define NTFS_FFLAG_HIDDEN 0x02LL
+#define NTFS_FFLAG_SYSTEM 0x04LL
+#define NTFS_FFLAG_ARCHIVE 0x20LL
+#define NTFS_FFLAG_COMPRESSED 0x0800LL
+#define NTFS_FFLAG_DIR 0x10000000LL
+
+struct attr_name {
+ u_int32_t n_pnumber; /* Parent ntnode */
+ u_int32_t reserved;
+ ntfs_times_t n_times;
+ u_int64_t n_size;
+ u_int64_t n_attrsz;
+ u_int64_t n_flag;
+ u_int8_t n_namelen;
+ u_int8_t n_nametype;
+ u_int16_t n_name[1];
+};
+
+#define NTFS_IRFLAG_INDXALLOC 0x00000001
+struct attr_indexroot {
+ u_int32_t ir_unkn1; /* attribute type (0x30 for $FILE_NAME) */
+ u_int32_t ir_unkn2; /* collation rule (0x01 for file names) */
+ u_int32_t ir_size; /* size of index allocation entry */
+ u_int32_t ir_unkn3; /* clusters per index record, and 3 bytes padding */
+ u_int32_t ir_unkn4; /* (offset to first index entry?) always 0x10 */
+ u_int32_t ir_datalen; /* (total size of index enties?) sizeof something */
+ u_int32_t ir_allocated; /* (allocated size of index entries?) */
+ u_int8_t ir_flag; /* 1=index allocation needed (large index) */
+ u_int8_t ir_pad1; /* padding */
+ u_int16_t ir_pad2; /* padding */
+};
+
+struct attr_attrlist {
+ u_int32_t al_type; /* Attribute type */
+ u_int16_t reclen; /* length of this entry */
+ u_int8_t al_namelen; /* Attribute name len */
+ u_int8_t al_nameoff; /* Name offset from entry start */
+ u_int64_t al_vcnstart; /* VCN number */
+ u_int32_t al_inumber; /* Parent ntnode */
+ u_int32_t reserved;
+ u_int16_t al_index; /* Attribute index in MFT record */
+ u_int16_t al_name[1]; /* Name */
+};
+
+#define NTFS_INDXMAGIC (u_int32_t)(0x58444E49)
+struct attr_indexalloc {
+ struct fixuphdr ia_fixup;
+ u_int64_t unknown1;
+ cn_t ia_bufcn;
+ u_int16_t ia_hdrsize;
+ u_int16_t unknown2;
+ u_int32_t ia_inuse;
+ u_int32_t ia_allocated;
+};
+
+#define NTFS_IEFLAG_SUBNODE 0x00000001
+#define NTFS_IEFLAG_LAST 0x00000002
+
+struct attr_indexentry {
+ u_int32_t ie_number;
+ u_int32_t unknown1;
+ u_int16_t reclen;
+ u_int16_t ie_size;
+ u_int32_t ie_flag;/* 1 - has subnodes, 2 - last */
+ u_int32_t ie_fpnumber;
+ u_int32_t unknown2;
+ ntfs_times_t ie_ftimes;
+ u_int64_t ie_fallocated;
+ u_int64_t ie_fsize;
+ u_int32_t ie_fflag;
+ u_int32_t unknown3; /* used by reparse points and external attributes? */
+ u_int8_t ie_fnamelen;
+ u_int8_t ie_fnametype;
+ wchar ie_fname[NTFS_MAXFILENAME];
+ /* cn_t ie_bufcn; buffer with subnodes */
+};
+
+#define NTFS_FILEMAGIC (u_int32_t)(0x454C4946)
+#define NTFS_FRFLAG_DIR 0x0002
+struct filerec {
+ struct fixuphdr fr_fixup;
+ u_int8_t reserved[8];
+ u_int16_t fr_seqnum; /* Sequence number */
+ u_int16_t fr_nlink;
+ u_int16_t fr_attroff; /* offset to attributes */
+ u_int16_t fr_flags; /* 1-nonresident attr, 2-directory */
+ u_int32_t fr_size;/* hdr + attributes */
+ u_int32_t fr_allocated; /* allocated length of record */
+ u_int64_t fr_mainrec; /* main record */
+ u_int16_t fr_attrnum; /* maximum attr number + 1 ??? */
+};
+
+#define NTFS_ATTRNAME_MAXLEN 0x40
+#define NTFS_ADFLAG_NONRES 0x0080 /* Attrib can be non resident */
+#define NTFS_ADFLAG_INDEX 0x0002 /* Attrib can be indexed */
+struct attrdef {
+ wchar ad_name[NTFS_ATTRNAME_MAXLEN];
+ u_int32_t ad_type;
+ u_int32_t reserved1[2];
+ u_int32_t ad_flag;
+ u_int64_t ad_minlen;
+ u_int64_t ad_maxlen; /* -1 for nonlimited */
+};
+
+struct ntvattrdef {
+ char ad_name[0x40];
+ int ad_namelen;
+ u_int32_t ad_type;
+};
+
+#define NTFS_BBID "NTFS "
+#define NTFS_BBIDLEN 8
+struct bootfile {
+ u_int8_t reserved1[3]; /* asm jmp near ... */
+ u_int8_t bf_sysid[8]; /* 'NTFS ' */
+ u_int16_t bf_bps; /* bytes per sector */
+ u_int8_t bf_spc; /* sectors per cluster */
+ u_int8_t reserved2[7]; /* unused (zeroed) */
+ u_int8_t bf_media; /* media desc. (0xF8) */
+ u_int8_t reserved3[2];
+ u_int16_t bf_spt; /* sectors per track */
+ u_int16_t bf_heads; /* number of heads */
+ u_int8_t reserver4[12];
+ u_int64_t bf_spv; /* sectors per volume */
+ cn_t bf_mftcn; /* $MFT cluster number */
+ cn_t bf_mftmirrcn; /* $MFTMirr cn */
+ u_int8_t bf_mftrecsz; /* MFT record size (clust) */
+ /* 0xF6 inducates 1/4 */
+ u_int32_t bf_ibsz; /* index buffer size */
+ u_int32_t bf_volsn; /* volume ser. num. */
+};
+
+/*
+ * Darwin's ntfs.util needs to include this file to get definitions
+ * for the on-disk structures. It doesn't need the ntfsmount structure.
+ * In fact, since it doesn't #define KERNEL, the struct netexport below
+ * won't be defined.
+ *
+ * So, I'm using #ifdef KERNEL around the things that are only relevant
+ * to the in-kernel implementation.
+ *
+ *¥¥ I don't know if FreeBSD defines KERNEL, or if I need to use or
+ * invent a different conditional here.
+ */
+#ifdef KERNEL
+
+#define NTFS_SYSNODESNUM 0x0B
+struct ntfsmount {
+ struct mount *ntm_mountp; /* filesystem vfs structure */
+ struct bootfile ntm_bootfile;
+ dev_t ntm_dev; /* device mounted */
+ struct vnode *ntm_devvp; /* block device mounted vnode */
+ struct vnode *ntm_sysvn[NTFS_SYSNODESNUM];
+ u_int32_t ntm_bpmftrec;
+ uid_t ntm_uid;
+ gid_t ntm_gid;
+ mode_t ntm_mode;
+ u_long ntm_flag;
+ cn_t ntm_cfree;
+ struct ntvattrdef *ntm_ad; /* attribute names are stored in native byte order */
+ int ntm_adnum;
+ wchar * ntm_82u; /* 8bit to Unicode */
+ char ** ntm_u28; /* Unicode to 8 bit */
+#ifdef APPLE
+ struct netexport ntm_export; /* NFS export information */
+#endif
+};
+
+#define ntm_mftcn ntm_bootfile.bf_mftcn
+#define ntm_mftmirrcn ntm_bootfile.bf_mftmirrcn
+#define ntm_mftrecsz ntm_bootfile.bf_mftrecsz
+#define ntm_spc ntm_bootfile.bf_spc
+#define ntm_bps ntm_bootfile.bf_bps
+
+#pragma pack()
+
+#define NTFS_NEXTREC(s, type) ((type)(((caddr_t) s) + le16toh((s)->reclen)))
+
+/* Convert mount ptr to ntfsmount ptr. */
+#define VFSTONTFS(mp) ((struct ntfsmount *)((mp)->mnt_data))
+#define VTONT(v) FTONT(VTOF(v))
+#define VTOF(v) ((struct fnode *)((v)->v_data))
+#define FTOV(f) ((f)->f_vp)
+#define FTONT(f) ((f)->f_ip)
+#define ntfs_cntobn(cn) ((daddr_t)(cn) * (ntmp->ntm_spc))
+#define ntfs_cntob(cn) ((off_t)(cn) * (ntmp)->ntm_spc * (ntmp)->ntm_bps)
+#define ntfs_btocn(off) (cn_t)((off) / ((ntmp)->ntm_spc * (ntmp)->ntm_bps))
+#define ntfs_btocl(off) (cn_t)((off + ntfs_cntob(1) - 1) / ((ntmp)->ntm_spc * (ntmp)->ntm_bps))
+#define ntfs_btocnoff(off) (off_t)((off) % ((ntmp)->ntm_spc * (ntmp)->ntm_bps))
+#define ntfs_bntob(bn) (daddr_t)((bn) * (ntmp)->ntm_bps)
+
+#define ntfs_bpbl (daddr_t)((ntmp)->ntm_bps)
+
+#ifdef MALLOC_DECLARE
+MALLOC_DECLARE(M_NTFSMNT);
+MALLOC_DECLARE(M_NTFSNTNODE);
+MALLOC_DECLARE(M_NTFSFNODE);
+MALLOC_DECLARE(M_NTFSDIR);
+MALLOC_DECLARE(M_NTFSNTHASH);
+#endif
+
+#ifndef M_NTFSMNT
+#define M_NTFSMNT M_TEMP
+#endif
+#ifndef M_NTFSNTNODE
+#define M_NTFSNTNODE M_TEMP
+#endif
+#ifndef M_NTFSFNODE
+#define M_NTFSFNODE M_TEMP
+#endif
+#ifndef M_NTFSDIR
+#define M_NTFSDIR M_TEMP
+#endif
+#ifndef M_NTFSNTHASH
+#define M_NTFSNTHASH M_TEMP
+#endif
+#ifndef M_NTFSRUN
+#define M_NTFSRUN M_TEMP
+#endif
+#ifndef M_NTFSRDATA
+#define M_NTFSRDATA M_TEMP
+#endif
+#ifndef M_NTFSNTVATTR
+#define M_NTFSNTVATTR M_TEMP
+#endif
+#ifndef M_NTFSDECOMP
+#define M_NTFSDECOMP M_TEMP
+#endif
+#define VT_NTFS VT_OTHER
+
+#if defined(NTFS_DEBUG)
+#define dprintf(a) printf a
+#if NTFS_DEBUG > 1
+#define ddprintf(a) printf a
+#else
+#define ddprintf(a)
+#endif
+#else
+#define dprintf(a)
+#define ddprintf(a)
+#endif
+
+#ifdef APPLE
+typedef int vop_t(void *);
+#else
+#endif
+extern vop_t **ntfs_vnodeop_p;
+#endif /* KERNEL */
/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
- * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
+ * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights
* Reserved. This file contains Original Code and/or Modifications of
* Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.1 (the "License"). You may not use this file
+ * Source License Version 2.0 (the "License"). You may not use this file
* except in compliance with the License. Please obtain a copy of the
* License at http://www.apple.com/publicsource and read it before using
* this file.
/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
- * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
+ * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights
* Reserved. This file contains Original Code and/or Modifications of
* Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.1 (the "License"). You may not use this file
+ * Source License Version 2.0 (the "License"). You may not use this file
* except in compliance with the License. Please obtain a copy of the
* License at http://www.apple.com/publicsource and read it before using
* this file.
/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
- * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
+ * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights
* Reserved. This file contains Original Code and/or Modifications of
* Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.1 (the "License"). You may not use this file
+ * Source License Version 2.0 (the "License"). You may not use this file
* except in compliance with the License. Please obtain a copy of the
* License at http://www.apple.com/publicsource and read it before using
* this file.
extern int bgetc(void);
extern int biosread(int dev, int cyl, int head, int sec, int num);
extern int ebiosread(int dev, long sec, int count);
+extern int ebioswrite(int dev, long sec, int count);
extern int get_drive_info(int drive, struct driveInfo *dp);
extern void putc(int ch);
extern void putca(int ch, int attr, int repeat);
extern int getc(void);
extern int readKeyboardStatus(void);
+extern int readKeyboardShiftFlags(void);
extern unsigned int time18(void);
extern void delay(int ms);
extern unsigned int get_diskinfo(int dev);
+#if APM_SUPPORT
extern int APMPresent(void);
extern int APMConnect32(void);
+#endif
extern int memsize(int i);
extern void video_mode(int mode);
extern void setCursorPosition(int x, int y, int page);
extern BVRef diskScanBootVolumes(int biosdev, int *count);
extern void diskSeek(BVRef bvr, long long position);
extern int diskRead(BVRef bvr, long addr, long length);
+extern int rawDiskRead(BVRef bvr, unsigned int secno, void *buffer, unsigned int len);
+extern int rawDiskWrite(BVRef bvr, unsigned int secno, void *buffer, unsigned int len);
extern int readBootSector(int biosdev, unsigned int secno, void *buffer);
extern void turnOffFloppy(void);
+/* hfs_compare.c */
+extern void utf_encodestr( const u_int16_t * ucsp, int ucslen,
+ u_int8_t * utf8p, u_int32_t bufsize, int byte_order );
+extern void utf_decodestr(const u_int8_t *utf8p, u_int16_t *ucsp,
+ u_int16_t *ucslen, u_int32_t bufsize, int byte_order );
+
/* load.c */
extern char gHaveKernelCache;
extern long ThinFatFile(void **binary, unsigned long *length);
extern char * newStringForKey(char *key);
extern BOOL getValueForBootKey(const char *line, const char *match, const char **matchval, int *len);
extern BOOL getValueForKey(const char *key, const char **val, int *size);
-extern BOOL getBoolForKey(const char *key);
+extern BOOL getBoolForKey(const char *key, BOOL *val);
extern BOOL getIntForKey(const char *key, int *val);
-extern int loadConfigFile(const char *configFile, const char **table, BOOL allocTable);
-extern int loadConfigDir(const char *bundleName, BOOL useDefault, const char **table,
- BOOL allocTable);
+extern int loadConfigFile(const char *configFile);
extern int loadSystemConfig(const char *which, int size);
-extern void addConfig(const char *config);
extern char * newString(const char *oldString);
/* sys.c */
+extern BVRef getBootVolumeRef( const char * path, const char ** outPath );
+extern long LoadVolumeFile(BVRef bvr, const char *fileSpec);
extern long LoadFile(const char *fileSpec);
+extern long ReadFileAtOffset(const char * fileSpec, void *buffer, unsigned long offset, unsigned long length);
+extern long LoadThinFatFile(const char *fileSpec, void **binary);
extern long GetDirEntry(const char *dirSpec, long *dirIndex, const char **name,
long *flags, long *time);
extern long GetFileInfo(const char *dirSpec, const char *name,
long *flags, long *time);
+extern long GetFileBlock(const char *fileSpec, unsigned long long *firstBlock);
extern int openmem(char *buf, int len);
extern int open(const char *str, int how);
extern int close(int fdesc);
extern const char * usrDevices(void);
extern const char * systemConfigDir(void);
extern struct dirstuff * opendir(const char *path);
+extern struct dirstuff * vol_opendir(BVRef bvr, const char *path);
extern int closedir(struct dirstuff *dirp);
extern int readdir(struct dirstuff *dirp, const char **name, long *flags, long *time);
+extern int readdir_ext(struct dirstuff * dirp, const char ** name, long * flags,
+ long * time, FinderInfo *finderInfo, long *infoValid);
extern void flushdev(void);
extern int currentdev(void);
extern int switchdev(int dev);
extern BVRef scanBootVolumes(int biosdev, int *count);
extern BVRef selectBootVolume(BVRef chain);
-extern void getBootVolumeDescription(BVRef bvr, char *str, long strMaxLen);
+extern void getBootVolumeDescription(BVRef bvr, char *str, long strMaxLen, BOOL verbose);
extern int gBIOSDev;
extern int gBootFileType;
/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
- * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
+ * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights
* Reserved. This file contains Original Code and/or Modifications of
* Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.1 (the "License"). You may not use this file
+ * Source License Version 2.0 (the "License"). You may not use this file
* except in compliance with the License. Please obtain a copy of the
* License at http://www.apple.com/publicsource and read it before using
* this file.
int valid;
};
+typedef struct FinderInfo {
+ unsigned char data[16];
+} FinderInfo;
struct BootVolume;
typedef struct BootVolume * BVRef;
typedef long (*FSInit)(CICell ih);
typedef long (*FSLoadFile)(CICell ih, char * filePath);
+typedef long (*FSReadFile)(CICell ih, char *filePath, void *base, unsigned long offset, unsigned long length);
+typedef long (*FSGetFileBlock)(CICell ih, char *filePath, unsigned long long *firstBlock);
typedef long (*FSGetDirEntry)(CICell ih, char * dirPath, long * dirIndex,
- char ** name, long * flags, long * time);
+ char ** name, long * flags, long * time,
+ FinderInfo * finderInfo, long * infoValid);
typedef void (*BVGetDescription)(CICell ih, char * str, long strMaxLen);
struct iob {
unsigned int part_type; /* partition type */
unsigned int fs_boff; /* 1st block # of next read */
FSLoadFile fs_loadfile; /* FSLoadFile function */
+ FSReadFile fs_readfile; /* FSReadFile function */
FSGetDirEntry fs_getdirentry; /* FSGetDirEntry function */
+ FSGetFileBlock fs_getfileblock; /* FSGetFileBlock function */
unsigned int bps; /* bytes per sector for this device */
char name[BVSTRLEN]; /* (name of partition) */
char type_name[BVSTRLEN]; /* (type of partition, eg. Apple_HFS) */
/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
- * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
+ * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights
* Reserved. This file contains Original Code and/or Modifications of
* Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.1 (the "License"). You may not use this file
+ * Source License Version 2.0 (the "License"). You may not use this file
* except in compliance with the License. Please obtain a copy of the
* License at http://www.apple.com/publicsource and read it before using
* this file.
#include <sys/vnode.h>
#include "libsaio.h"
-#define SWAP_BE16(x) NXSwapBigShortToHost(x)
-#define SWAP_BE32(x) NXSwapBigLongToHost(x)
-#define SWAP_BE64(x) NXSwapBigLongLongToHost(x)
+#define SWAP_BE16(x) OSSwapBigToHostInt16(x)
+#define SWAP_LE16(x) OSSwapLittleToHostInt16(x)
+#define SWAP_BE32(x) OSSwapBigToHostInt32(x)
+#define SWAP_LE32(x) OSSwapLittleToHostInt32(x)
+#define SWAP_BE64(x) OSSwapBigToHostInt64(x)
+#define SWAP_LE64(x) OSSwapLittleToHostInt64(x)
// File Permissions and Types
enum {
/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
- * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
+ * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights
* Reserved. This file contains Original Code and/or Modifications of
* Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.1 (the "License"). You may not use this file
+ * Source License Version 2.0 (the "License"). You may not use this file
* except in compliance with the License. Please obtain a copy of the
* License at http://www.apple.com/publicsource and read it before using
* this file.
/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
- * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
+ * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights
* Reserved. This file contains Original Code and/or Modifications of
* Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.1 (the "License"). You may not use this file
+ * Source License Version 2.0 (the "License"). You may not use this file
* except in compliance with the License. Please obtain a copy of the
* License at http://www.apple.com/publicsource and read it before using
* this file.
*table_p = table;
}
+#if UNUSED
+
/* Remove key and its associated value from the table. */
BOOL
return newstr;
}
+#endif
+
/*
* compress == compress escaped characters to one character
*/
return NO;
}
+#if UNUSED
+
/*
* Returns a new malloc'ed string if one is found
* in the string table matching 'key'. Also translates
}
}
+#endif
+
char *
newStringForKey(char *key)
{
{
const char *key, *value;
int key_len, value_len;
+ BOOL retval = NO;
while (*line) {
/* look for keyword or argument */
&& strncmp(match, key, key_len) == 0) {
*matchval = value;
*len = value_len;
- return YES;
+ retval = YES;
+ /* Continue to look for this key; last one wins. */
}
}
- return NO;
+ return retval;
}
+/* Returns TRUE if a value was found, FALSE otherwise.
+ * The boolean value of the key is stored in 'val'.
+ */
BOOL getBoolForKey(
- const char *key
+ const char *key,
+ BOOL *result_val
)
{
- const char *val;
+ const char *key_val;
int size;
- if (getValueForKey(key, &val, &size) && (size >= 1) &&
- val[0] == 'Y' || val[0] == 'y')
- return YES;
+ if (getValueForKey(key, &key_val, &size)) {
+ if ( (size >= 1) && (key_val[0] == 'Y' || key_val[0] == 'y') ) {
+ *result_val = YES;
+ } else {
+ *result_val = NO;
+ }
+ return YES;
+ }
return NO;
}
* Allocates an extra number of bytes for table expansion.
*/
int
-loadConfigFile(const char *configFile, const char **table, BOOL allocTable)
+loadConfigFile(const char *configFile)
{
- char *configPtr = bootArgs->configEnd;
+ char *configPtr = bootArgs->config;
int fd, count;
/* Read config file into memory */
if ((fd = open(configFile, 0)) >= 0)
{
- if (allocTable) {
- configPtr = malloc(file_size(fd)+2+TABLE_EXPAND_SIZE);
- } else {
- if ((configPtr - bootArgs->config) > CONFIG_SIZE) {
- error("No room in memory for config files\n");
- close(fd);
- return -1;
- }
- verbose("Reading configuration file '%s'.\n",configFile);
- }
- if (table) *table = configPtr;
+ if ((configPtr - bootArgs->config) > CONFIG_SIZE) {
+ error("No room in memory for config files\n");
+ close(fd);
+ return -1;
+ }
+ verbose("Reading configuration file '%s'.\n",configFile);
+
count = read(fd, configPtr, IO_CONFIG_DATA_SIZE);
close(fd);
configPtr += count;
*configPtr++ = 0;
*configPtr = 0;
- if (!allocTable)
- bootArgs->configEnd = configPtr;
+
+ bootArgs->configEnd = configPtr;
return 0;
} else {
}
}
-/* Returns 0 if requested config files were loaded,
- * 1 if default files were loaded,
- * -1 if no files were loaded.
- * Prints error message if files cannot be loaded.
- */
-
-int
-loadConfigDir(
- const char *bundleName, // bundle directory name (e.g. "System")
- BOOL useDefault, // use Default.table instead of instance tables
- const char **table, // returns pointer to config table
- BOOL allocTable // malloc the table and return in *table
-)
-{
- char *buf;
- int i, max, ret;
- const char *device_dir = usrDevices();
-
- buf = malloc(256);
- ret = 0;
-
- // load up to 99 instance tables
- if (allocTable)
- max = 1;
- else
- max = 99;
- for (i=0; i < max; i++) {
- sprintf(buf, "%s/%s.config/Instance%d.table",
- device_dir,
- bundleName, i);
- if (useDefault || (loadConfigFile(buf, table, allocTable) != 0)) {
- if (i == 0) {
- // couldn't load first instance table;
- // try the default table
- sprintf(buf, "%s/%s.config/%s",
- device_dir,
- bundleName,
- IO_DEFAULT_TABLE_FILENAME);
- if (loadConfigFile(buf, table, allocTable) == 0) {
- ret = 1;
- } else {
- if (!allocTable) {
- error("Config file \"%s\" not found\n", buf);
- sleep(1); // let the message be seen!
- }
- ret = -1;
- }
- }
- // we must be done.
- break;
- }
- }
- free(buf);
- return ret;
-}
-
-
-#define USR_SYSTEM_CONFIG \
- USR_DEVICES "/System.config"
-#define USR_SYSTEM_DEFAULT_FILE \
- USR_SYSTEM_CONFIG "/Default.table"
-#define ARCH_SYSTEM_CONFIG \
- ARCH_DEVICES "/System.config"
-#define ARCH_SYSTEM_DEFAULT_FILE \
- ARCH_SYSTEM_CONFIG "/Default.table"
-#define SYSTEM_CONFIG "System"
#define LP '('
#define RP ')'
#define SYSTEM_CONFIG_DIR "/Library/Preferences/SystemConfiguration"
#define SYSTEM_CONFIG_FILE "/com.apple.Boot.plist"
+#define LRE_CONFIG_FILE "/com.apple.lre.Boot.plist"
#define SYSTEM_CONFIG_PATH SYSTEM_CONFIG_DIR SYSTEM_CONFIG_FILE
#define CONFIG_EXT ".plist"
-#if 1
+#if UNUSED
void
printSystemConfig(void)
{
}
#endif
-static int sysconfig_dev;
-
//==========================================================================
// ParseXMLFile
// Modifies the input buffer.
// Puts the first dictionary it finds in the
// tag pointer and returns 0, or returns -1 if not found
// (and does not modify dict pointer).
+// Prints an error message if there is a parsing error.
//
static long
ParseXMLFile( char * buffer, TagPtr * dict )
}
free(configBuffer);
if (length < 0) {
+ error ("Error parsing plist file");
return -1;
}
*dict = tag;
if (*cp == LP) {
while (len-- && *cp && *cp++ != RP) ;
/* cp now points past device */
- strlcpy(buf,which,cp - which);
+ strlcpy(buf,which,cp - which + 1);
bp += cp - which;
} else {
cp = which;
CONFIG_EXT, strlen(CONFIG_EXT)) != 0)
strcat(bp, CONFIG_EXT);
} else {
- strlcpy(bp, cp, len);
+ strlcpy(bp, cp, len + 1);
}
if ((strcmp(bp, SYSTEM_CONFIG_PATH) == 0)) {
doDefault = 1;
}
- ret = loadConfigFile(bp = buf, 0, 0);
+ bp = buf;
+ ret = loadConfigFile(bp);
} else {
+ /* First try LRE file */
strcpy(bp, systemConfigDir());
- strcat(bp, SYSTEM_CONFIG_FILE);
- ret = loadConfigFile(bp, 0, 0);
+ strcat(bp, LRE_CONFIG_FILE);
+ ret = loadConfigFile(bp);
+
if (ret < 0) {
- ret = loadConfigDir((bp = SYSTEM_CONFIG), 0, 0, 0);
+ /* If not found, try default file */
+ strcpy(bp, systemConfigDir());
+ strcat(bp, SYSTEM_CONFIG_FILE);
+ ret = loadConfigFile(bp);
}
}
- sysconfig_dev = currentdev();
if (ret < 0) {
error("System config file '%s' not found\n", bp);
sleep(1);
/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
- * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
+ * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights
* Reserved. This file contains Original Code and/or Modifications of
* Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.1 (the "License"). You may not use this file
+ * Source License Version 2.0 (the "License"). You may not use this file
* except in compliance with the License. Please obtain a copy of the
* License at http://www.apple.com/publicsource and read it before using
* this file.
void * gFSLoadAddress = 0;
-static BVRef getBootVolumeRef( const char * path, const char ** outPath );
+//static BVRef getBootVolumeRef( const char * path, const char ** outPath );
static BVRef newBootVolumeRef( int biosdev, int partno );
+//==========================================================================
+// LoadVolumeFile - LOW-LEVEL FILESYSTEM FUNCTION.
+// Load the specified file from the specified volume
+// to the load buffer at LOAD_ADDR.
+// If the file is fat, load only the i386 portion.
+
+long LoadVolumeFile(BVRef bvr, const char *filePath)
+{
+ long fileSize;
+
+ // Read file into load buffer. The data in the load buffer will be
+ // overwritten by the next LoadFile() call.
+
+ gFSLoadAddress = (void *) LOAD_ADDR;
+
+ fileSize = bvr->fs_loadfile(bvr, (char *)filePath);
+
+ // Return the size of the file, or -1 if load failed.
+
+ return fileSize;
+}
+
//==========================================================================
// LoadFile - LOW-LEVEL FILESYSTEM FUNCTION.
// Load the specified file to the load buffer at LOAD_ADDR.
long LoadFile(const char * fileSpec)
{
const char * filePath;
- long fileSize;
BVRef bvr;
// Resolve the boot volume from the file spec.
if ((bvr = getBootVolumeRef(fileSpec, &filePath)) == NULL)
return -1;
+ return LoadVolumeFile(bvr, filePath);
+}
+
+long ReadFileAtOffset(const char * fileSpec, void *buffer, unsigned long offset, unsigned long length)
+{
+ const char *filePath;
+ BVRef bvr;
+
+ if ((bvr = getBootVolumeRef(fileSpec, &filePath)) == NULL)
+ return -1;
+
+ if (bvr->fs_readfile == NULL)
+ return -1;
+
+ return bvr->fs_readfile(bvr, (char *)filePath, buffer, offset, length);
+}
+
+long LoadThinFatFile(const char *fileSpec, void **binary)
+{
+ const char *filePath;
+ FSReadFile readFile;
+ BVRef bvr;
+ long length, length2;
+
+ // Resolve the boot volume from the file spec.
+
+ if ((bvr = getBootVolumeRef(fileSpec, &filePath)) == NULL)
+ return -1;
+
+ *binary = (void *)kLoadAddr;
+
// Read file into load buffer. The data in the load buffer will be
// overwritten by the next LoadFile() call.
gFSLoadAddress = (void *) LOAD_ADDR;
- fileSize = bvr->fs_loadfile(bvr, (char *)filePath);
-
- // Return the size of the file, or -1 if load failed.
-
- return fileSize;
+ readFile = bvr->fs_readfile;
+
+ if (readFile != NULL) {
+ // Read the first 4096 bytes (fat header)
+ length = readFile(bvr, (char *)filePath, *binary, 0, 0x1000);
+ if (length > 0) {
+ if (ThinFatFile(binary, &length) == 0) {
+ // We found a fat binary; read only the thin part
+ length = readFile(bvr, (char *)filePath,
+ (void *)kLoadAddr, (unsigned long)(*binary) - kLoadAddr, length);
+ *binary = (void *)kLoadAddr;
+ } else {
+ // Not a fat binary; read the rest of the file
+ length2 = readFile(bvr, (char *)filePath, (void *)(kLoadAddr + length), length, 0);
+ if (length2 == -1) return -1;
+ length += length2;
+ }
+ }
+ } else {
+ length = bvr->fs_loadfile(bvr, (char *)filePath);
+ if (length > 0) {
+ ThinFatFile(binary, &length);
+ }
+ }
+
+ return length;
}
+
//==========================================================================
// GetDirEntry - LOW-LEVEL FILESYSTEM FUNCTION.
// Fetch the next directory entry for the given directory.
return bvr->fs_getdirentry( bvr,
/* dirPath */ (char *)dirPath,
/* dirIndex */ dirIndex,
- /* dirEntry */ (char **)name, flags, time );
+ /* dirEntry */ (char **)name, flags, time, 0, 0 );
}
//==========================================================================
// GetFileInfo - LOW-LEVEL FILESYSTEM FUNCTION.
// Get attributes for the specified file.
-static char gMakeDirSpec[1024];
+static char* gMakeDirSpec;
long GetFileInfo(const char * dirSpec, const char * name,
long * flags, long * time)
long index = 0;
const char * entryName;
+ if (gMakeDirSpec == 0)
+ gMakeDirSpec = (char *)malloc(1024);
+
if (!dirSpec) {
long idx, len;
return -1; // file not found
}
+long GetFileBlock(const char *fileSpec, unsigned long long *firstBlock)
+{
+ const char * filePath;
+ BVRef bvr;
+
+ // Resolve the boot volume from the file spec.
+
+ if ((bvr = getBootVolumeRef(fileSpec, &filePath)) == NULL) {
+ printf("Boot volume for '%s' is bogus\n", fileSpec);
+ return -1;
+ }
+
+ return bvr->fs_getfileblock(bvr, (char *)filePath, firstBlock);
+}
+
//==========================================================================
// iob_from_fdesc()
//
return io;
}
+#if UNUSED
//==========================================================================
// openmem()
return fdesc;
}
+#endif
//==========================================================================
// open() - Open the file specified by 'path' for reading.
//==========================================================================
+struct dirstuff * vol_opendir(BVRef bvr, const char * path)
+{
+ struct dirstuff * dirp = 0;
+
+ dirp = (struct dirstuff *) malloc(sizeof(struct dirstuff));
+ if (dirp == NULL)
+ goto error;
+
+ dirp->dir_path = newString(path);
+ if (dirp->dir_path == NULL)
+ goto error;
+
+ dirp->dir_bvr = bvr;
+
+ return dirp;
+
+error:
+ closedir(dirp);
+ return NULL;
+}
+
+//==========================================================================
+
struct dirstuff * opendir(const char * path)
{
struct dirstuff * dirp = 0;
return dirp->dir_bvr->fs_getdirentry( dirp->dir_bvr,
/* dirPath */ dirp->dir_path,
/* dirIndex */ &dirp->dir_index,
- /* dirEntry */ (char **)name, flags, time );
+ /* dirEntry */ (char **)name, flags, time,
+ 0, 0);
+}
+
+//==========================================================================
+
+int readdir_ext(struct dirstuff * dirp, const char ** name, long * flags,
+ long * time, FinderInfo *finderInfo, long *infoValid)
+{
+ return dirp->dir_bvr->fs_getdirentry( dirp->dir_bvr,
+ /* dirPath */ dirp->dir_path,
+ /* dirIndex */ &dirp->dir_index,
+ /* dirEntry */ (char **)name,
+ flags, time,
+ finderInfo, infoValid);
}
//==========================================================================
//==========================================================================
-void getBootVolumeDescription( BVRef bvr, char * str, long strMaxLen )
-{
- bvr->description( bvr, str, strMaxLen );
-}
-
-//==========================================================================
-
BVRef selectBootVolume( BVRef chain )
{
BVRef bvr, bvr1 = 0, bvr2 = 0;
#define RP ')'
int gBIOSDev;
-static BVRef getBootVolumeRef( const char * path, const char ** outPath )
+BVRef getBootVolumeRef( const char * path, const char ** outPath )
{
const char * cp;
BVRef bvr;
/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
- * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
+ * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights
* Reserved. This file contains Original Code and/or Modifications of
* Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.1 (the "License"). You may not use this file
+ * Source License Version 2.0 (the "License"). You may not use this file
* except in compliance with the License. Please obtain a copy of the
* License at http://www.apple.com/publicsource and read it before using
* this file.
/*
- * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2003 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* The contents of this file constitute Original Code as defined in and
- * are subject to the Apple Public Source License Version 1.1 (the
+ * are subject to the Apple Public Source License Version 2.0 (the
* "License"). You may not use this file except in compliance with the
* License. Please obtain a copy of the License at
* http://www.apple.com/publicsource and read it before using this file.
InodePtr fileInode, InodePtr dirInode);
static char *ReadFileBlock(InodePtr fileInode, long fragNum, long blockOffset,
long length, char *buffer, long cache);
-static long ReadFile(InodePtr fileInode, long *length);
+static long ReadFile(InodePtr fileInode, long *length, void *base, long offset);
#define kDevBlockSize (0x200) // Size of each disk block.
-#define kDiskLableBlock (15) // Block the DL is in.
+#define kDiskLabelBlock (15) // Block the DL is in.
#ifdef __i386__
static CICell gCurrentIH;
static long long gPartitionBase;
-static char *gDLBuf;
+static char *gULBuf;
static char *gFSBuf;
static struct fs *gFS;
static long gBlockSize;
return 0;
}
+#if !BOOT1
verbose("UFSInitPartition: %x\n", ih);
+#endif
gCurrentIH = 0;
#ifdef __i386__
- if (!gDLBuf) gDLBuf = (char *) malloc(8192);
+ if (!gULBuf) gULBuf = (char *) malloc(UFS_LABEL_SIZE);
if (!gFSBuf) gFSBuf = (char *) malloc(SBSIZE);
if (!gTempName) gTempName = (char *) malloc(MAXNAMLEN + 1);
if (!gTempName2) gTempName2 = (char *) malloc(MAXNAMLEN + 1);
if (!gRootInodePtr) gRootInodePtr = (InodePtr) malloc(sizeof(Inode));
if (!gFileInodePtr) gFileInodePtr = (InodePtr) malloc(sizeof(Inode));
- if (!gDLBuf || !gFSBuf || !gTempName || !gTempName2 ||
+ if (!gULBuf || !gFSBuf || !gTempName || !gTempName2 ||
!gRootInodePtr || !gFileInodePtr) return -1;
#endif
byte_swap_superblock(gFS);
if (gFS->fs_magic != FS_MAGIC) {
-#ifdef __i386__
- return -1; // not yet for Intel
-#else /* !__i386__ */
- disk_label_t *dl;
- partition_t *part;
-
- // Did not find it... Look for the Disk Label.
- // Look for the Disk Label
- Seek(ih, 1ULL * kDevBlockSize * kDiskLableBlock);
- Read(ih, (long)gDLBuf, 8192);
-
- dl = (disk_label_t *)gDLBuf;
- byte_swap_disklabel_in(dl);
-
- if (dl->dl_version != DL_VERSION) {
- return -1;
- }
-
- part = &dl->dl_part[0];
- gPartitionBase = (1ULL * (dl->dl_front + part->p_base) * dl->dl_secsize) -
- (1ULL * (dl->dl_label_blkno - kDiskLableBlock) * kDevBlockSize);
-
- // Re-read the Super Block.
- Seek(ih, gPartitionBase + SBOFF);
- Read(ih, (long)gFSBuf, SBSIZE);
-
- gFS = (struct fs *)gFSBuf;
- if (gFS->fs_magic != FS_MAGIC) {
- return -1;
- }
-#endif /* !__i386__ */
+ return -1;
}
// Calculate the block size and set up the block cache.
long UFSLoadFile( CICell ih, char * filePath )
{
- long ret, length, flags;
+ return UFSReadFile(ih, filePath, (void *)gFSLoadAddress, 0, 0);
+}
+
+long UFSReadFile( CICell ih, char * filePath, void * base, unsigned long offset, unsigned long length )
+{
+ long ret, flags;
+#if !BOOT1
verbose("Loading UFS file: [%s] from %x.\n", filePath, (unsigned)ih);
+#endif
if (UFSInitPartition(ih) == -1) return -1;
ret = ResolvePathToInode(filePath, &flags, gFileInodePtr, gRootInodePtr);
if ((ret == -1) || ((flags & kFileTypeMask) != kFileTypeFlat)) return -1;
-#if 0
- // System.config/Default.table will fail this check.
- // Turn this back on when usage of System.config is deprecated.
- if (flags & (kOwnerNotRoot | kPermGroupWrite | kPermOtherWrite)) return -1;
-#endif
-
- ret = ReadFile(gFileInodePtr, &length);
+ ret = ReadFile(gFileInodePtr, &length, base, offset);
if (ret == -1) return -1;
return length;
}
+#ifndef BOOT1
+
long UFSGetDirEntry( CICell ih, char * dirPath, long * dirIndex,
- char ** name, long * flags, long * time )
+ char ** name, long * flags, long * time,
+ FinderInfo * finderInfo, long * infoValid)
{
long ret, fileInodeNum, dirFlags;
Inode tmpInode;
if (UFSInitPartition(ih) == -1) return -1;
+ if (infoValid) *infoValid = 0;
+
// Skip a leading '/' if present
if (*dirPath == '/') dirPath++;
if (*dirPath == '/') dirPath++;
return 0;
}
+void
+UFSGetDescription(CICell ih, char *str, long strMaxLen)
+{
+ if (UFSInitPartition(ih) == -1) { return; }
+
+ struct ufslabel *ul;
+
+ // Look for the Disk Label
+ Seek(ih, 1ULL * UFS_LABEL_OFFSET);
+ Read(ih, (long)gULBuf, UFS_LABEL_SIZE);
+
+ ul = (struct ufslabel *)gULBuf;
+
+ unsigned char magic_bytes[] = UFS_LABEL_MAGIC;
+ int i;
+ unsigned char *p = (unsigned char *)&ul->ul_magic;
+
+ for (i=0; i<sizeof(magic_bytes); i++, p++) {
+ if (*p != magic_bytes[i])
+ return;
+ }
+ strncpy(str, ul->ul_name, strMaxLen);
+}
+
+long
+UFSGetFileBlock(CICell ih, char *filePath, unsigned long long *firstBlock)
+{
+ long ret, flags;
+
+ if (UFSInitPartition(ih) == -1) return -1;
+
+ // Skip one or two leading '/'.
+ if (*filePath == '/') filePath++;
+ if (*filePath == '/') filePath++;
+
+ ret = ResolvePathToInode(filePath, &flags, gFileInodePtr, gRootInodePtr);
+ if ((ret == -1) || ((flags & kFileTypeMask) != kFileTypeFlat)) return -1;
+
+ *firstBlock = (gPartitionBase + 1ULL * gFileInodePtr->di_db[0] * gBlockSize) / 512ULL;
+
+ return 0;
+}
+
+
+#endif /* !BOOT1 */
+
// Private functions
static char * ReadBlock( long fragNum, long blockOffset, long length,
return buffer;
}
-static long ReadFile( InodePtr fileInode, long * length )
+static long ReadFile( InodePtr fileInode, long * length, void * base, long offset )
{
- long bytesLeft, curSize, curFrag = 0;
- char *buffer, *curAddr = (char *)kLoadAddr;
+ long bytesLeft, curSize, curFrag;
+ char *buffer, *curAddr = (char *)base;
-#ifdef __i386__
- curAddr = gFSLoadAddress;
-#endif
+ bytesLeft = fileInode->di_size;
- bytesLeft = *length = fileInode->di_size;
+ if (offset > bytesLeft) {
+ printf("Offset is too large.\n");
+ return -1;
+ }
+
+ if ((*length == 0) || ((offset + *length) > bytesLeft)) {
+ *length = bytesLeft - offset;
+ }
- if (*length > kLoadSize) {
+ if (bytesLeft > kLoadSize) {
printf("File is too large.\n");
return -1;
}
+ bytesLeft = *length;
+ curFrag = (offset / gBlockSize) * gFragsPerBlock;
+ offset %= gBlockSize;
+
while (bytesLeft) {
- if (bytesLeft > gBlockSize) curSize = gBlockSize;
- else curSize = bytesLeft;
+ curSize = gBlockSize;
+ if (curSize > bytesLeft) curSize = bytesLeft;
+ if (offset != 0) curSize -= offset;
- buffer = ReadFileBlock(fileInode, curFrag, 0, curSize, curAddr, 0);
+ buffer = ReadFileBlock(fileInode, curFrag, offset, curSize, curAddr, 0);
if (buffer == 0) break;
+ if (offset != 0) offset = 0;
+
curFrag += gFragsPerBlock;
curAddr += curSize;
bytesLeft -= curSize;
* @APPLE_LICENSE_HEADER_START@
*
* The contents of this file constitute Original Code as defined in and
- * are subject to the Apple Public Source License Version 1.2 (the
+ * are subject to the Apple Public Source License Version 2.0 (the
* "License"). You may not use this file except in compliance with the
* License. Please obtain a copy of the License at
* http://www.apple.com/publicsource and read it before using this file.
extern long UFSInitPartition(CICell ih);
extern long UFSLoadFile(CICell ih, char * filePath);
+extern long UFSReadFile( CICell ih, char * filePath, void * base, unsigned long offset, unsigned long length );
extern long UFSGetDirEntry(CICell ih, char * dirPath, long * dirIndex,
- char ** name, long * flags, long * time);
+ char ** name, long * flags, long * time,
+ FinderInfo * finderInfo, long * infoValid);
+extern void UFSGetDescription(CICell ih, char *str, long strMaxLen);
+extern long UFSGetFileBlock(CICell ih, char *str, unsigned long long *firstBlock);
/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
- * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
+ * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights
* Reserved. This file contains Original Code and/or Modifications of
* Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.1 (the "License"). You may not use this file
+ * Source License Version 2.0 (the "License"). You may not use this file
* except in compliance with the License. Please obtain a copy of the
* License at http://www.apple.com/publicsource and read it before using
* this file.
#define byte_swap_int(thing) ((thing) = OSSwapBigToHostInt32(thing))
#define byte_swap_short(thing) ((thing) = OSSwapBigToHostInt16(thing))
+#if UNUSED
void
byte_swap_longlongs(unsigned long long *array, int count)
{
for (i = 0; i < (unsigned long long)count; i++)
byte_swap_longlong(array[i]);
}
+#endif
void
byte_swap_ints(int *array, int count)
byte_swap_short(array[i]);
}
-void
+#if UNUSED
+static void
swapBigIntsToHost(int *array, int count)
{
register int i;
swapBigLongToHost(array[i]);
}
-
-void
+static void
swapBigShortToHosts(short *array, int count)
{
register int i;
for (i = 0; i < count; i++)
swapBigShortToHost(array[i]);
}
+#endif
void
byte_swap_superblock(struct fs *sb)
byte_swap_shorts((int16_t *)sb->fs_opostbl, 16 * 8);
byte_swap_ints((int32_t *)sb->fs_sparecon, 50);
byte_swap_ints((int32_t *)&sb->fs_contigsumsize, 3);
+#if UNUSED
byte_swap_longlongs((u_int64_t *)&sb->fs_maxfilesize,3);
+#endif
byte_swap_ints((int32_t *)&sb->fs_state, 6);
/* Got these magic numbers from mkfs.c in newfs */
}
}
-static inline void
-byte_swap_disklabel_common(disk_label_t *dl)
-{
- swapBigLongToHost(dl->dl_version); /* ditto */
- swapBigLongToHost(dl->dl_label_blkno);
- swapBigLongToHost(dl->dl_size);
- swapBigLongToHost(dl->dl_flags);
- swapBigLongToHost(dl->dl_tag);
-// swapBigShortToHost(dl->dl_checksum);
-// if (dl->dl_version >= DL_V3)
-// swapBigShortToHost(dl->dl_un.DL_v3_checksum);
-// else
-// swapBigIntsToHost(dl->dl_un.DL_bad, NBAD);
-}
-
-void
-byte_swap_disklabel_in(disk_label_t *dl)
-{
- byte_swap_disklabel_common(dl);
- byte_swap_disktab_in(&dl->dl_dt);
-}
-
-static inline void
-byte_swap_disktab_common(struct disktab *dt)
-{
- register unsigned int i;
-
- swapBigLongToHost(dt->d_secsize);
- swapBigLongToHost(dt->d_ntracks);
- swapBigLongToHost(dt->d_nsectors);
- swapBigLongToHost(dt->d_ncylinders);
-// swapBigLongToHost(dt->d_rpm);
- swapBigShortToHost(dt->d_front);
- swapBigShortToHost(dt->d_back);
-// swapBigShortToHost(dt->d_ngroups);
-// swapBigShortToHost(dt->d_ag_size);
-// swapBigShortToHost(dt->d_ag_alts);
-// swapBigShortToHost(dt->d_ag_off);
-// swapBigIntsToHost(dt->d_boot0_blkno, NBOOTS);
-
- for (i=0; i < NPART; i++)
- byte_swap_partition(&dt->d_partitions[i]);
-}
-
-/*
- * This is particularly grody. The beginning of the partition array is two
- * bytes low on the 68 wrt natural alignment rules. Furthermore, each
- * element of the partition table is two bytes smaller on 68k due to padding
- * at the end of the struct.
- */
-void
-byte_swap_disktab_in(struct disktab *dt)
-{
- struct partition * pp;
- int i;
-
- /*
- * Shift each struct partition up in memory by 2 + 2 * offset bytes.
- * Do it backwards so we don't overwrite anything.
- */
- for (i=NPART - 1; i >=0; i--) {
- struct partition temp;
- pp = &dt->d_partitions[i];
- /* beware: compiler doesn't do overlapping struct assignment */
- temp = *(struct partition *)(((char *) pp) - 2 * (i + 1));
- *pp = temp;
- }
-
- byte_swap_disktab_common(dt);
-}
-
-void
-byte_swap_partition(struct partition *part)
-{
- swapBigLongToHost(part->p_base);
- swapBigLongToHost(part->p_size);
- swapBigShortToHost(part->p_bsize);
- swapBigShortToHost(part->p_fsize);
- swapBigShortToHost(part->p_cpg);
- swapBigShortToHost(part->p_density);
-}
/* This value should correspond to the value set in the ffs_mounts */
{
int i;
- di->di_mode = NXSwapShort(di->di_mode);
- di->di_nlink = NXSwapShort(di->di_nlink);
+ di->di_mode = OSSwapInt16(di->di_mode);
+ di->di_nlink = OSSwapInt16(di->di_nlink);
#ifdef LFS
- di->di_u.inumber = NXSwapLong(di->di_u.inumber);
+ di->di_u.inumber = OSSwapInt32(di->di_u.inumber);
#else
- di->di_u.oldids[0] = NXSwapShort(di->di_u.oldids[0]);
- di->di_u.oldids[1] = NXSwapShort(di->di_u.oldids[1]);
+ di->di_u.oldids[0] = OSSwapInt16(di->di_u.oldids[0]);
+ di->di_u.oldids[1] = OSSwapInt16(di->di_u.oldids[1]);
#endif
- di->di_size = NXSwapLongLong(di->di_size);
- di->di_atime = NXSwapLong(di->di_atime);
- di->di_atimensec = NXSwapLong(di->di_atimensec);
- di->di_mtime = NXSwapLong(di->di_mtime);
- di->di_mtimensec = NXSwapLong(di->di_mtimensec);
- di->di_ctime = NXSwapLong(di->di_ctime);
- di->di_ctimensec = NXSwapLong(di->di_ctimensec);
+ di->di_size = OSSwapInt64(di->di_size);
+ di->di_atime = OSSwapInt32(di->di_atime);
+ di->di_atimensec = OSSwapInt32(di->di_atimensec);
+ di->di_mtime = OSSwapInt32(di->di_mtime);
+ di->di_mtimensec = OSSwapInt32(di->di_mtimensec);
+ di->di_ctime = OSSwapInt32(di->di_ctime);
+ di->di_ctimensec = OSSwapInt32(di->di_ctimensec);
if (((di->di_mode & IFMT) != IFLNK ) || (di->di_size > RESYMLNKLEN)) {
for (i=0; i < NDADDR; i++) /* direct blocks */
- di->di_db[i] = NXSwapLong(di->di_db[i]);
+ di->di_db[i] = OSSwapInt32(di->di_db[i]);
for (i=0; i < NIADDR; i++) /* indirect blocks */
- di->di_ib[i] = NXSwapLong(di->di_ib[i]);
+ di->di_ib[i] = OSSwapInt32(di->di_ib[i]);
}
- di->di_flags = NXSwapLong(di->di_flags);
- di->di_blocks = NXSwapLong(di->di_blocks);
- di->di_gen = NXSwapLong(di->di_gen);
- di->di_uid = NXSwapLong(di->di_uid);
- di->di_gid = NXSwapLong(di->di_gid);
- di->di_spare[0] = NXSwapLong(di->di_spare[0]);
- di->di_spare[1] = NXSwapLong(di->di_spare[1]);
+ di->di_flags = OSSwapInt32(di->di_flags);
+ di->di_blocks = OSSwapInt32(di->di_blocks);
+ di->di_gen = OSSwapInt32(di->di_gen);
+ di->di_uid = OSSwapInt32(di->di_uid);
+ di->di_gid = OSSwapInt32(di->di_gid);
+ di->di_spare[0] = OSSwapInt32(di->di_spare[0]);
+ di->di_spare[1] = OSSwapInt32(di->di_spare[1]);
}
void
/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
- * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
+ * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights
* Reserved. This file contains Original Code and/or Modifications of
* Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.1 (the "License"). You may not use this file
+ * Source License Version 2.0 (the "License"). You may not use this file
* except in compliance with the License. Please obtain a copy of the
* License at http://www.apple.com/publicsource and read it before using
* this file.
#ifndef __LIBSAIO_UFS_BYTEORDER_H
#define __LIBSAIO_UFS_BYTEORDER_H
-#include <sys/disktab.h>
#include <sys/vnode.h>
#include <sys/buf.h>
#include <sys/disk.h>
#include <ufs/ufs/dir.h>
#include <ufs/ffs/fs.h>
-#include <IOKit/storage/IONeXTPartitionScheme.h>
-
void byte_swap_ints(int *array, int count);
void byte_swap_shorts(short *array, int count);
void byte_swap_longlongs(unsigned long long *array, int count);
void byte_swap_superblock(struct fs *sb);
-void byte_swap_disklabel_in(disk_label_t *dl);
-void byte_swap_disktab_in(struct disktab *dt);
void byte_swap_partition(struct partition *part);
void byte_swap_dinode_in(struct dinode *di);
void byte_swap_dir_block_in(char *addr, int count);
/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
- * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
+ * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights
* Reserved. This file contains Original Code and/or Modifications of
* Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.1 (the "License"). You may not use this file
+ * Source License Version 2.0 (the "License"). You may not use this file
* except in compliance with the License. Please obtain a copy of the
* License at http://www.apple.com/publicsource and read it before using
* this file.
/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
- * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
+ * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights
* Reserved. This file contains Original Code and/or Modifications of
* Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.1 (the "License"). You may not use this file
+ * Source License Version 2.0 (the "License"). You may not use this file
* except in compliance with the License. Please obtain a copy of the
* License at http://www.apple.com/publicsource and read it before using
* this file.
* Portions Copyright (c) 2003 Apple Computer, Inc. All Rights
* Reserved.
* The contents of this file constitute Original Code as defined in and
- * are subject to the Apple Public Source License Version 1.2 (the
+ * are subject to the Apple Public Source License Version 2.0 (the
* "License"). You may not use this file except in compliance with the
* License. Please obtain a copy of the License at
* http://www.apple.com/publicsource and read it before using this file.
}
+#if UNUSED
//==========================================================================
// XMLParseFile
// Expects to see one dictionary in the XML file.
*dict = tag;
return 0;
}
+#endif /* UNUSED */
//==========================================================================
// ParseNextTag
* Portions Copyright (c) 2003 Apple Computer, Inc. All Rights
* Reserved. This file contains Original Code and/or Modifications of
* Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.2 (the "License"). You may not use this file
+ * Source License Version 2.0 (the "License"). You may not use this file
* except in compliance with the License. Please obtain a copy of the
* License at http://www.apple.com/publicsource and read it before using
* this file.
//
long XMLParseFile( char * buffer, TagPtr * dict );
-#if 0
-// BootX shim functions
-
-extern long AllocateBootXMemory( long inSize );
-extern long InitBootXMemorySupport(void);
-#endif
-
#endif /* __LIBSAIO_XML_H */
perl macros.pl standard.mac
clean::
- rm -rf $(SYMROOT)/nasm $(SYMROOT)/ndisasm
+ rm -rf $(SYMROOT)/nasm $(SYMROOT)/ndisasm\
+ $(SYMROOT)/nasm.1 $(SYMROOT)/ndisasm.1
$(INSTALLDIR) $(MANINSTALLDIR):
$(MKDIRS) $@
-
-The boot: prompt waits ten seconds for you to type advanced startup options.
+The boot: prompt waits for you to type advanced startup options.
If you don't type anything, the computer continues starting up normally. It
uses the kernel and configuration files on the startup device, which it also
-uses as the root device. Advanced startup options use the following syntax:
-
- <<device>kernel> <arguments>
+uses as the root device. Advanced startup options use the following syntax:
+ [device]<kernel> [arguments]
+Example arguments include
+ device: rd=<BSD device name> (e.g. rd=disk0s2)
+ rd=*<IODeviceTree path> (e.g. rd=*/PCI0@0/CHN0@0/@0:1)
+ kernel: kernel name (e.g. "mach_kernel" - must be in "/" )
+ flags: -v (verbose) -s (single user),
+ -f (safe) -F (ignore boot file)
+ "Graphics Mode"="WIDTHxHEIGHTxDEPTH" (e.g. "1024x768x32")
+ For VESA 3.0 graphics, you may append a refresh rate
+ after an "@" character (e.g. "1280x1024x32@75")
+ kernel flags (e.g. debug=0x144)
+ io=0xffffffff (defined in IOKit/IOKitDebug.h)
-For example, to start up from:
- the first SCSI device, type: sd()mach_kernel
- the b partition of the second IDE disk, type: hd(1,b)mach_kernel
- the floppy disk but use the SCSI disk as the root device, type:
- fd()mach_kernel rootdev=sd0a
+Example: mach_kernel rd=disk0s1 -v "Graphics Mode"="4096x4096x32@85"
If the computer won't start up properly, you may be able to start it up using
-safe mode. Type: -f
+safe mode. Type -f to start up in safe mode, which ignores all cached
+driver files.
+
+Special booter commands:
+ ?memory Displays information about the computer's memory.
+ ?video Displays VESA video modes supported by the computer's BIOS.
-To continue starting up using standard options, press Return.
+Additional useful command-line options:
+ config=<file> Use an alternate Boot.plist file.
+ platform=ACPI|X86PC Use either ACPI or non-ACPI platform support.
+Options useful in the com.apple.Boot.plist file:
+ "Boot Graphics"=Yes|No Use graphics mode or text mode when starting.
+ "Quiet Boot"=Yes|No Use quiet boot mode (no messages or prompt).
+ Timeout=8 Number of seconds to pause at the boot: prompt.
CHOWN = chown
-FILES = Language.table \
- BootHelp.txt \
- English.lproj/Localizable.strings \
- English.lproj/NetInstall.strings \
- French.lproj/Localizable.strings \
- French.lproj/NetInstall.strings \
- German.lproj/Localizable.strings \
- German.lproj/NetInstall.strings
-
-# Remove Swedish, Italian and Spanish for Rhap 1.0
-# Italian.lproj/Localizable.strings \
-# Italian.lproj/NetInstall.strings \
-# Spanish.lproj/Localizable.strings \
-# Spanish.lproj/NetInstall.strings \
-# Swedish.lproj/Localizable.strings \
-# Swedish.lproj/NetInstall.strings
-
-DIRS = ${INSTALLDIR}/English.lproj \
- ${INSTALLDIR}/French.lproj \
- ${INSTALLDIR}/German.lproj
-
-# Remove Swedish, Italian and Spanish for Rhap 1.0
-# ${INSTALLDIR}/Italian.lproj
-# ${INSTALLDIR}/Spanish.lproj \
-# ${INSTALLDIR}/Swedish.lproj
-
-DIRS_NEEDED = ${DIRS}
+FILES = BootHelp.txt
all:
-install_i386:: $(INSTALLDIR) $(DIRS_NEEDED)
- tar cf - ${FILES} | (cd ${INSTALLDIR}; tar xfBp - )
+install_i386:: $(INSTALLDIR)
+ cp $(FILES) $(INSTALLDIR)
chown -fR root.wheel $(INSTALLDIR)
chmod -R ugo-w $(INSTALLDIR)
-CFLAGS = -g
-TESTS= rldtest satest
-LIBSA= ../sym/libsa.a
+DIR = tests
+include ../MakePaths.dir
-all: $(TESTS)
+CFLAGS = $(RC_CFLAGS) $(OPTIM) $(MORECPP) -arch i386 -g -Wmost -Werror \
+ -fno-builtin -DSAIO_INTERNAL_USER -static \
+ -fomit-frame-pointer -mpreferred-stack-boundary=2 \
+ -fno-align-functions
+TESTS= satest
+LIBSA= $(SYMROOT)/libsa.a
+LIBSADIR = ../libsa
+INC = -I. -I.. -I$(SYMROOT) -I$(LIBSADIR)
+
+OBJROOT=../../obj/i386
+SYMROOT=../../sym/i386
+DSTROOT=../../dst/i386
+SRCROOT=/tmp
+VPATH=$(SYMROOT):$(OBJROOT)
-sizeof: sizeof.c
- cc -I../libsa sizeof.c -o sizeof
+DIRS_NEEDED = $(OBJROOT) $(SYMROOT)
-rldtest: rldtest.o
- cc -o rldtest rldtest.o
+all: $(TESTS)
satest: satest.o $(LIBSA)
- cc -o satest satest.o $(LIBSA) -lsys_s
+ cc $(CFLAGS) -o satest $(filter %.o,$^) -L$(SYMROOT) -lsa -L/usr/local/lib/system -lc_static -lgcc_static
+
+include ../MakeInc.dir
*/
/* test standalone library */
#include <stdarg.h>
+#include "libsa.h"
#define TEST_RESULT "The quick brown #5 fox did fine.\n"
#define TEST_FMT "The quick %s #%d fox did fine.\n"
sa_rld_error_buf_size,
format, ap);
}
+
+int printf(const char * fmt, ...)
+{
+ extern void putchar(int);
+ va_list ap;
+ va_start(ap, fmt);
+ prf(fmt, ap, putchar, 0);
+ va_end(ap);
+ return 0;
+}
+
/*
* Print the error message and set the 'error' indication.
*/
// errors = 1;
}
-main()
+int
+main(int argc, char **argv)
{
char buf[1024];
- int args[4], ret;
+ int ret;
printf("Testing standalone library\n");
printf("The following two lines should be identical:\n");
printf("printf(\"Test: %% 8d\\n\",-9);\n");
printf("Test: -9\n");
printf("Test: % 8d\n",-9);
+
+ return 0;
}
INSTALLDIR = $(DSTROOT)/usr/standalone/i386
LOCALBIN = $(DSTROOT)/usr/local/bin
-LANGDIR = $(INSTALLDIR)/English.lproj
OPTIM = -Os
-CFLAGS = $(RC_CFLAGS) $(OPTIM) -Wmost -Werror -g -I../rcz -nostdinc -nostdlib -I/usr/include \
- -I/System/Library/Frameworks/System.framework/Headers
-LDFLAGS = -L/usr/lib -lcrt1.o -lSystem -lcc_dynamic
-CFILES = machOconv.c mkfont.c tif_packbits.c
-MFILES = dumptiff.m
-HFILES = cursor.h
-EXPORT_HFILES = bitmap.h font.h
+CFLAGS = $(RC_CFLAGS) $(OPTIM) -Wmost -Werror -g
+LDFLAGS =
+CFILES = machOconv.c
ALLSRC = $(CFILES) $(MFILES) $(HFILES) $(EXPORT_HFILES)
-TIFFILES = return.tiff ns_box.tiff ns_text.tiff ns_logo.tiff dot.tiff
-TIFF_HFILES = $(TIFFILES:.tiff=.h)
-TIFF_BFILES = $(TIFFILES:.tiff=_bitmap.h)
-
-CURSOR_HFILES = ns_wait1.h ns_wait1_bitmap.h \
- ns_wait2.h ns_wait2_bitmap.h \
- ns_wait3.h ns_wait3_bitmap.h
-OTHER_HFILES = hdot.h hdot_bitmap.h
-
-FONTFILES = 14.TimesIta
-FONT_HFILES = FontBitmap.h
-
-#PROGRAMS = machOconv mkfont dumptiff sig
PROGRAMS = machOconv
-OUTFILES = $(PROGRAMS) $(TIFF_HFILES) $(TIFF_BFILES) $(CURSOR_HFILES) \
- $(FONT_HFILES) $(OTHER_HFILES)
-DUMPTIFF = $(SYMROOT)/dumptiff
-DUMPTIFF_OBJS = tif_packbits.o dumptiff.o BooterBitmap.o
-SIG = $(SYMROOT)/sig
-SIG_OBJS = sig.o
+OUTFILES = $(PROGRAMS)
DIRS_NEEDED = $(OBJROOT) $(SYMROOT) $(LANGDIR)
-#BITMAPS = Panel.image Wait1.image Wait2.image Wait3.image
-BITMAPS = Panel.image
-FONTS = Default.font
+all: $(DIRS_NEEDED) $(PROGRAMS)
-.SUFFIXES: .tiff
-.tiff.h:
- $(DUMPTIFF) -o $(SYMROOT)/$* $<
-
-#all: $(DIRS_NEEDED) $(PROGRAMS) $(OUTFILES)
-all: $(DIRS_NEEDED) $(PROGRAMS) $(BITMAPS)
-
-#clean::
-# cd $(SYMROOT); rm -f $(OUTFILES)
clean::
-(cd $(SYMROOT); rm -f $(PROGRAMS))
-install_i386:: $(INSTALLDIR) $(LANGDIR)
- cp $(BITMAPS) $(INSTALLDIR)
- cp $(FONTS) $(INSTALLDIR)/English.lproj
-
-$(TIFF_HFILES): $(DUMPTIFF)
-$(TIFF_BFILES): $(TIFF_HFILES)
-$(CURSOR_HFILES): CURSOR_HFILES
-CURSOR_HFILES: $(DUMPTIFF)
- $(DUMPTIFF) -c -o $(SYMROOT)/ns_wait
-$(FONT_HFILES): mkfont $(FONTFILES)
- mkfont $(FONTFILES) -c $(SYMROOT)/$(@F)
-
-hdot.h hdot_bitmap.h: dot.tiff $(DUMPTIFF)
- $(DUMPTIFF) -b 3 -o $(SYMROOT)/hdot dot.tiff
-
-sig: $(SIG_OBJS)
- $(CC) $(CFLAGS) $(LDFLAGS) $(DEFINES) -o $(SYMROOT)/$(@F) $(SIG_OBJS)
-
-dumptiff: $(DUMPTIFF_OBJS)
- $(CC) $(CFLAGS) $(LDFLAGS) $(DEFINES) -o $(SYMROOT)/$(@F) $(DUMPTIFF_OBJS) -lNeXT_s
-
-mkfont: mkfont.o
- $(CC) $(CFLAGS) $(LDFLAGS) $(DEFINES) -o $(SYMROOT)/$(@F) mkfont.o
-
machOconv: machOconv.o
$(CC) $(CFLAGS) $(LDFLAGS) $(DEFINES) -o $(SYMROOT)/$(@F) machOconv.o
/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
- * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
+ * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights
* Reserved. This file contains Original Code and/or Modifications of
* Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.1 (the "License"). You may not use this file
+ * Source License Version 2.0 (the "License"). You may not use this file
* except in compliance with the License. Please obtain a copy of the
* License at http://www.apple.com/publicsource and read it before using
* this file.