From 57c72a9a9f2a263d364c2df1178760bd057c390f Mon Sep 17 00:00:00 2001 From: Apple Date: Mon, 2 May 2005 21:05:38 +0000 Subject: [PATCH] boot-122.tar.gz --- APPLE_LICENSE | 513 ++++++++++++------------ Makefile | 2 +- gen/Makefile | 2 +- gen/libsaio/ufs_byteorder.c | 1 - gen/libsaio/ufs_byteorder.h | 1 - i386/MakeInc.dir | 13 + i386/Makefile | 5 +- i386/boot0/Makefile | 10 +- i386/boot0/boot0.s | 149 ++++--- i386/boot0/chain0.s | 700 +++++++++++++++++++++++++++++++++ i386/boot1/Makefile | 9 +- i386/boot1/boot1.s | 115 ++---- i386/boot1u/Makefile | 64 ++- i386/boot1u/asm.s | 15 +- i386/boot1u/bios.s | 6 +- i386/boot1u/boot.c | 10 +- i386/boot1u/boot1u.h | 6 +- i386/boot1u/boot1u.s | 6 +- i386/boot1u/boot1u0.s | 243 +++--------- i386/boot1u/disk.c | 76 ++-- i386/boot1u/disk.h | 6 +- i386/boot1u/malloc.c | 6 +- i386/boot1u/put.c | 8 +- i386/boot1u/string.c | 8 +- i386/boot2/Makefile | 8 +- i386/boot2/appleClut8.h | 6 +- i386/boot2/appleboot.h | 16 +- i386/boot2/boot.c | 177 +++++++-- i386/boot2/boot.h | 59 ++- i386/boot2/drivers.c | 28 +- i386/boot2/graphics.c | 238 +++++++---- i386/boot2/lzss.c | 16 +- i386/boot2/options.c | 283 ++++++++++--- i386/boot2/prompt.c | 14 +- i386/cdboot/Makefile | 3 + i386/cdboot/biostest.asm | 6 +- i386/cdboot/cdboot.s | 2 +- i386/doc/Limits | 9 - i386/libsa/Makefile | 6 +- i386/libsa/error.c | 6 +- i386/libsa/libsa.h | 7 +- i386/libsa/memory.h | 38 +- i386/libsa/prf.c | 18 +- i386/libsa/printf.c | 7 +- i386/libsa/qsort.c | 6 +- i386/libsa/string.c | 54 ++- i386/libsa/strtol.c | 77 +++- i386/libsa/zalloc.c | 8 +- i386/libsaio/Makefile | 6 +- i386/libsaio/asm.s | 26 +- i386/libsaio/bios.h | 6 +- i386/libsaio/bios.s | 6 +- i386/libsaio/biosfn.c | 79 +++- i386/libsaio/bootstruct.c | 6 +- i386/libsaio/bootstruct.h | 6 +- i386/libsaio/cache.c | 4 +- i386/libsaio/console.c | 8 +- i386/libsaio/disk.c | 280 +++++++++++-- i386/libsaio/fdisk.h | 8 +- i386/libsaio/hfs.c | 193 +++++++-- i386/libsaio/hfs.h | 9 +- i386/libsaio/hfs_CaseTables.h | 281 ++++++++++++- i386/libsaio/hfs_compare.c | 108 ++++- i386/libsaio/io_inline.h | 6 +- i386/libsaio/libsaio.h | 6 +- i386/libsaio/load.c | 22 +- i386/libsaio/memory.c | 2 +- i386/libsaio/misc.c | 7 +- i386/libsaio/msdos.c | 329 ++++++++++++++++ i386/libsaio/msdos.h | 23 ++ i386/libsaio/msdos_private.h | 351 +++++++++++++++++ i386/libsaio/nbp.c | 9 +- i386/libsaio/nbp_cmd.h | 6 +- i386/libsaio/ntfs.c | 307 +++++++++++++++ i386/libsaio/ntfs.h | 25 ++ i386/libsaio/ntfs_private.h | 397 +++++++++++++++++++ i386/libsaio/pci.c | 6 +- i386/libsaio/pci.h | 6 +- i386/libsaio/saio_internal.h | 35 +- i386/libsaio/saio_types.h | 16 +- i386/libsaio/sl.h | 15 +- i386/libsaio/stringConstants.h | 6 +- i386/libsaio/stringTable.c | 157 +++----- i386/libsaio/sys.c | 166 +++++++- i386/libsaio/table.c | 6 +- i386/libsaio/ufs.c | 152 ++++--- i386/libsaio/ufs.h | 8 +- i386/libsaio/ufs_byteorder.c | 140 ++----- i386/libsaio/ufs_byteorder.h | 11 +- i386/libsaio/vbe.c | 6 +- i386/libsaio/vbe.h | 6 +- i386/libsaio/xml.c | 4 +- i386/libsaio/xml.h | 9 +- i386/nasm/Makefile | 3 +- i386/strings/BootHelp.txt | 40 +- i386/strings/Makefile | 32 +- i386/tests/Makefile | 30 +- i386/tests/satest.c | 19 +- i386/util/Makefile | 68 +--- i386/util/machOconv.c | 6 +- 100 files changed, 4951 insertions(+), 1578 deletions(-) create mode 100644 i386/boot0/chain0.s create mode 100644 i386/libsaio/msdos.c create mode 100644 i386/libsaio/msdos.h create mode 100644 i386/libsaio/msdos_private.h create mode 100644 i386/libsaio/ntfs.c create mode 100644 i386/libsaio/ntfs.h create mode 100644 i386/libsaio/ntfs_private.h diff --git a/APPLE_LICENSE b/APPLE_LICENSE index 84687a4..fe81a60 100644 --- a/APPLE_LICENSE +++ b/APPLE_LICENSE @@ -1,26 +1,19 @@ 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 @@ -30,22 +23,27 @@ rights, (i) claims of patents that are now or hereafter acquired, 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 @@ -66,7 +64,7 @@ scripts used to control compilation and installation of an executable (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, @@ -74,258 +72,253 @@ whether by contract or otherwise, or (b) ownership of fifty percent (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 @@ -333,7 +326,7 @@ immediately terminate and You must immediately discontinue any use of 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 @@ -341,9 +334,9 @@ courts within that District with respect to this License. The 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. @@ -355,18 +348,20 @@ connexes soient rediges en anglais. 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." diff --git a/Makefile b/Makefile index 7c6f380..0a95b5a 100644 --- a/Makefile +++ b/Makefile @@ -62,7 +62,7 @@ all tags clean debug install installhdrs: $(SYMROOT) $(OBJROOT) "RC_KANJI=$(RC_KANJI)" \ "JAPANESE=$(JAPANESE)" \ "RC_CFLAGS=$$XCFLAGS" $@ \ - ) || exit $?; \ + ) || exit $$?; \ else \ echo "========= nothing to build for $$i ========="; \ fi; \ diff --git a/gen/Makefile b/gen/Makefile index 2d2f67d..2b80050 100644 --- a/gen/Makefile +++ b/gen/Makefile @@ -42,7 +42,7 @@ all tags clean debug install installhdrs: "RC_KANJI=$(RC_KANJI)" \ "JAPANESE=$(JAPANESE)" \ "RC_CFLAGS=$(RC_CFLAGS)" $@ \ - ) || exit $?; \ + ) || exit $$?; \ done installsrc: diff --git a/gen/libsaio/ufs_byteorder.c b/gen/libsaio/ufs_byteorder.c index 2b81354..078dc6c 100644 --- a/gen/libsaio/ufs_byteorder.c +++ b/gen/libsaio/ufs_byteorder.c @@ -28,7 +28,6 @@ #import #import -#import #import #include #import "ufs_byteorder.h" diff --git a/gen/libsaio/ufs_byteorder.h b/gen/libsaio/ufs_byteorder.h index bf5fa24..850c041 100644 --- a/gen/libsaio/ufs_byteorder.h +++ b/gen/libsaio/ufs_byteorder.h @@ -33,7 +33,6 @@ * Created. */ #import -#import #import #import #import diff --git a/i386/MakeInc.dir b/i386/MakeInc.dir index ae3d2d8..ec0632a 100644 --- a/i386/MakeInc.dir +++ b/i386/MakeInc.dir @@ -39,6 +39,16 @@ clean:: -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 @@ -46,5 +56,8 @@ clean:: .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) $@ diff --git a/i386/Makefile b/i386/Makefile index 245d8de..d324194 100644 --- a/i386/Makefile +++ b/i386/Makefile @@ -14,7 +14,6 @@ else endif AS = as LD = ld -# LIBS= -lc_static # # these paths are only valid in subdirectories of this directory @@ -27,7 +26,7 @@ SRCROOT=/tmp 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}; \ @@ -42,7 +41,7 @@ all tags clean debug install installhdrs: "RC_KANJI=$(RC_KANJI)" \ "JAPANESE=$(JAPANESE)" \ "RC_CFLAGS=$(RC_CFLAGS)" $@ \ - ) || exit $?; \ + ) || exit $$?; \ done installsrc: diff --git a/i386/boot0/Makefile b/i386/boot0/Makefile index 38eff11..828ed38 100644 --- a/i386/boot0/Makefile +++ b/i386/boot0/Makefile @@ -6,15 +6,21 @@ NASM = $(SYMROOT)/nasm 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 diff --git a/i386/boot0/boot0.s b/i386/boot0/boot0.s index af31d8d..dd07e18 100644 --- a/i386/boot0/boot0.s +++ b/i386/boot0/boot0.s @@ -1,11 +1,11 @@ -; 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. @@ -51,6 +51,8 @@ DEBUG EQU 0 ; EXT_PART_SUPPORT EQU 1 +CHS_SUPPORT EQU 1 + ; ; Various constants. ; @@ -161,8 +163,6 @@ start_reloc: DebugChar('>') - mov dl, kDriveNumber ; starting BIOS drive number - .loop: %if DEBUG @@ -174,15 +174,17 @@ start_reloc: ; 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 ; @@ -201,6 +203,10 @@ start_reloc: 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 @@ -211,8 +217,11 @@ start_reloc: 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 @@ -222,7 +231,6 @@ start_reloc: ; 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: @@ -230,22 +238,23 @@ start_reloc: 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 @@ -256,7 +265,7 @@ find_boot: ; 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 @@ -269,17 +278,21 @@ find_boot: ; 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. ; @@ -288,15 +301,16 @@ find_boot: 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. @@ -338,6 +352,14 @@ find_boot: 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. @@ -356,20 +378,31 @@ find_boot: ; 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 @@ -404,8 +437,10 @@ find_boot: ; load: push cx +%if CHS_SUPPORT test BYTE [ebios_present], 1 jz .chs +%endif .ebios: mov cx, 5 ; load retry count @@ -414,17 +449,20 @@ load: 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. ; @@ -466,7 +504,6 @@ read_chs: ; carry = 0 success ; 1 error ; -; mov dl, kDriveNumber mov ah, 0x02 ; Func 2 int 0x13 ; INT 13 jnc .exit @@ -485,6 +522,7 @@ read_chs: .exit: popa ret +%endif ;-------------------------------------------------------------------------- ; read_lba - Read sectors from a partition using LBA addressing. @@ -512,7 +550,7 @@ read_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 + mov ecx, [first_part] ; offset 8, lower 32-bit LBA add ecx, [si + part.lba] push ecx @@ -525,6 +563,12 @@ read_lba: push WORD 16 ; offset 0-1, packet size + DebugChar('<') +%if DEBUG + mov eax, ecx + call print_hex +%endif + ; ; INT13 Func 42 - Extended Read Sectors ; @@ -541,7 +585,6 @@ read_lba: ; Packet offset 2 indicates the number of sectors read ; successfully. ; -; mov dl, kDriveNumber mov si, sp mov ah, 0x42 int 0x13 @@ -587,8 +630,6 @@ print_string ret -%if DEBUG - ;-------------------------------------------------------------------------- ; Write a ASCII character to the console. ; @@ -603,44 +644,34 @@ print_char 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' @@ -657,13 +688,13 @@ getc: 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 @@ -672,12 +703,6 @@ boot_error_str db 10, 13, 'Error', 0 ; 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 @@ -705,5 +730,15 @@ part2numsect dd 0x000015fe ; 2.88MB - 65K 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 diff --git a/i386/boot0/chain0.s b/i386/boot0/chain0.s new file mode 100644 index 0000000..7b9cca9 --- /dev/null +++ b/i386/boot0/chain0.s @@ -0,0 +1,700 @@ +; 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 diff --git a/i386/boot1/Makefile b/i386/boot1/Makefile index 9fd2dd5..cb32e5f 100644 --- a/i386/boot1/Makefile +++ b/i386/boot1/Makefile @@ -7,7 +7,7 @@ DIRS_NEEDED = $(OBJROOT) $(SYMROOT) NASM = $(SYMROOT)/nasm -VERSIONED_FILES = boot1h boot1f +VERSIONED_FILES = boot1h VERS = `vers_string -f 5.0 | tr - .` NEW_VERS = Darwin boot1h v$(VERS) @@ -21,13 +21,12 @@ all: $(DIRS_NEEDED) $(VERSIONED_FILES) 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 diff --git a/i386/boot1/boot1.s b/i386/boot1/boot1.s index 062758d..45ea209 100644 --- a/i386/boot1/boot1.s +++ b/i386/boot1/boot1.s @@ -1,11 +1,11 @@ -; 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. @@ -38,12 +38,6 @@ ; DEBUG EQU 0 -; -; Set to 1 to support loading the booter (boot2) from a -; logical partition. -; -EXT_PART_SUPPORT EQU 0 - ; ; Various constants. ; @@ -52,8 +46,6 @@ kBoot0Stack EQU 0xFFF0 ; boot0 stack pointer 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 @@ -61,7 +53,7 @@ kPartTableOffset EQU 0x1be 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 @@ -89,6 +81,7 @@ kAlBlkSizOffset EQU 0x14 ;; HFS+ constants ;; kHFSPlusSig EQU 0x2B48 ; HFS+ volume signature +kHFSXSig EQU 0x5848 ; HFSX volume signature kBlockSizeOffset EQU 0x28 kExtentOffset EQU 0x1c0 @@ -104,11 +97,7 @@ kHFSPlusBlockSize EQU kHFSBuffer + kBlockSizeOffset kHFSPlusExtent EQU kHFSBuffer + kExtentOffset -%ifdef FLOPPY -kDriveNumber EQU 0x00 -%else kDriveNumber EQU 0x80 -%endif ; ; Format of fdisk partition entry. @@ -138,6 +127,11 @@ kDriveNumber EQU 0x80 call getc %endmacro +%macro PrintString 1 + mov si, %1 + call print_string +%endmacro + %if DEBUG %define DebugChar(x) DebugCharMacro x %else @@ -150,7 +144,7 @@ kDriveNumber EQU 0x80 SEGMENT .text - ORG 0xE000 ; must match kBoot0RelocAddr + ORG 0x7C00 ; must match kBoot0RelocAddr ;-------------------------------------------------------------------------- ; Boot code is loaded at 0:7C00h. @@ -184,13 +178,11 @@ start 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 ;;; --------------------------------------- @@ -254,10 +246,13 @@ find_startup: 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 @@ -271,8 +266,6 @@ find_startup: dec eax dec eax -; add [ebios_lba], eax ; offset to startup file -; mov ecx, [ebios_lba] add ecx, eax DebugChar('!') @@ -292,40 +285,13 @@ find_startup: 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. @@ -346,7 +312,7 @@ load: 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. ; @@ -379,23 +345,23 @@ load: 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 @@ -421,7 +387,6 @@ load: popad ret -%if 0 ;------------------------------------------------------------------------- ; Write a string to the console. ; @@ -443,7 +408,6 @@ print_string jmp short .loop .exit ret -%endif %if DEBUG @@ -527,6 +491,8 @@ getc: ; 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 @@ -535,32 +501,17 @@ getc: ; 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 + diff --git a/i386/boot1u/Makefile b/i386/boot1u/Makefile index 565c3b0..0f479ca 100644 --- a/i386/boot1u/Makefile +++ b/i386/boot1u/Makefile @@ -1,17 +1,9 @@ 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= @@ -28,45 +20,49 @@ else 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 @@ -74,20 +70,20 @@ 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) @@ -95,7 +91,7 @@ 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 diff --git a/i386/boot1u/asm.s b/i386/boot1u/asm.s index 717c46e..3898c5b 100644 --- a/i386/boot1u/asm.s +++ b/i386/boot1u/asm.s @@ -1,12 +1,12 @@ /* - * 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. @@ -31,6 +31,15 @@ /* * 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. * diff --git a/i386/boot1u/bios.s b/i386/boot1u/bios.s index 4f09157..56750fc 100644 --- a/i386/boot1u/bios.s +++ b/i386/boot1u/bios.s @@ -1,12 +1,12 @@ /* - * 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. diff --git a/i386/boot1u/boot.c b/i386/boot1u/boot.c index 8c37fae..49a5b98 100644 --- a/i386/boot1u/boot.c +++ b/i386/boot1u/boot.c @@ -1,12 +1,12 @@ /* - * 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. @@ -67,8 +67,6 @@ void boot(int biosdev, void *partPtr) zeroBSS(); - // printf("Hello, world.\n"); - // Enable A20 gate before accessing memory above 1Mb. enableA20(); @@ -87,7 +85,7 @@ void boot(int biosdev, void *partPtr) 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 diff --git a/i386/boot1u/boot1u.h b/i386/boot1u/boot1u.h index 91b3c48..3fbb021 100644 --- a/i386/boot1u/boot1u.h +++ b/i386/boot1u/boot1u.h @@ -1,12 +1,12 @@ /* - * 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. diff --git a/i386/boot1u/boot1u.s b/i386/boot1u/boot1u.s index df67d95..9bfa87f 100644 --- a/i386/boot1u/boot1u.s +++ b/i386/boot1u/boot1u.s @@ -1,12 +1,12 @@ /* - * 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. diff --git a/i386/boot1u/boot1u0.s b/i386/boot1u/boot1u0.s index 454a546..4b9437f 100644 --- a/i386/boot1u/boot1u0.s +++ b/i386/boot1u/boot1u0.s @@ -1,11 +1,11 @@ -; 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. @@ -23,15 +23,17 @@ ; 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 @@ -91,12 +93,6 @@ kDriveNumber EQU 0x00 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. ; @@ -135,12 +131,17 @@ ebios_present db 0 ; 1 if EBIOS is supported, 0 otherwise. 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. @@ -154,8 +155,14 @@ start 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 @@ -172,11 +179,10 @@ start ; Start execution from the relocated location. ; start_reloc: - +%endif + DebugChar('*') - mov dl, kDriveNumber ; starting BIOS drive number - .loop: %if DEBUG @@ -191,21 +197,6 @@ start_reloc: 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. ; @@ -231,69 +222,31 @@ start_reloc: 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. @@ -303,9 +256,10 @@ find_boot: 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. ; @@ -314,84 +268,6 @@ DebugChar('^') ; 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. @@ -613,25 +489,6 @@ print_char 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. ; @@ -666,7 +523,7 @@ print_nibble: ;-------------------------------------------------------------------------- ; 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 @@ -703,4 +560,12 @@ pad_table_and_sig 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 diff --git a/i386/boot1u/disk.c b/i386/boot1u/disk.c index cd8b4cd..0fc23eb 100644 --- a/i386/boot1u/disk.c +++ b/i386/boot1u/disk.c @@ -1,12 +1,12 @@ /* - * 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. @@ -56,12 +56,10 @@ static const char * biosbuf = (char *) ptov(BIOS_ADDR); #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; @@ -172,6 +170,7 @@ int diskRead( BVRef bvr, long addr, long length ) (void *) addr ); } + int findUFSPartition(int dev, struct fdisk_part *_fp) { @@ -179,32 +178,43 @@ 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; iparts[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; iparts[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; } @@ -212,13 +222,13 @@ findUFSPartition(int dev, struct fdisk_part *_fp) 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) diff --git a/i386/boot1u/disk.h b/i386/boot1u/disk.h index 9cbd450..61f008d 100644 --- a/i386/boot1u/disk.h +++ b/i386/boot1u/disk.h @@ -1,12 +1,12 @@ /* - * 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. diff --git a/i386/boot1u/malloc.c b/i386/boot1u/malloc.c index f897467..bd3893b 100644 --- a/i386/boot1u/malloc.c +++ b/i386/boot1u/malloc.c @@ -1,12 +1,12 @@ /* - * 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. diff --git a/i386/boot1u/put.c b/i386/boot1u/put.c index 022fd64..7a7fdc7 100644 --- a/i386/boot1u/put.c +++ b/i386/boot1u/put.c @@ -1,12 +1,12 @@ /* - * 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. @@ -56,7 +56,7 @@ int printf(const char * fmt, ...) int verbose(const char * fmt, ...) { -#if 1 +#if DEBUG va_list ap; va_start(ap, fmt); diff --git a/i386/boot1u/string.c b/i386/boot1u/string.c index 16c379f..91e1791 100644 --- a/i386/boot1u/string.c +++ b/i386/boot1u/string.c @@ -1,12 +1,12 @@ /* - * 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. @@ -47,7 +47,7 @@ void * memcpy(void * dst, const void * src, size_t len) 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) diff --git a/i386/boot2/Makefile b/i386/boot2/Makefile index 7995505..4aa84de 100644 --- a/i386/boot2/Makefile +++ b/i386/boot2/Makefile @@ -25,8 +25,8 @@ endif 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 = @@ -53,7 +53,7 @@ all: $(DIRS_NEEDED) boot 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 @@ -75,7 +75,7 @@ install_i386:: all $(INSTALLDIR) 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 diff --git a/i386/boot2/appleClut8.h b/i386/boot2/appleClut8.h index 368a28e..50416f7 100644 --- a/i386/boot2/appleClut8.h +++ b/i386/boot2/appleClut8.h @@ -1,12 +1,12 @@ /* - * 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. diff --git a/i386/boot2/appleboot.h b/i386/boot2/appleboot.h index dad3cbd..f14abd1 100644 --- a/i386/boot2/appleboot.h +++ b/i386/boot2/appleboot.h @@ -1,15 +1,17 @@ /* - * 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, diff --git a/i386/boot2/boot.c b/i386/boot2/boot.c index 48145f4..9bd0829 100644 --- a/i386/boot2/boot.c +++ b/i386/boot2/boot.c @@ -1,12 +1,12 @@ /* - * 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. @@ -49,16 +49,24 @@ * 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; @@ -105,6 +113,10 @@ static int ExecKernel(void *binary) { entry_t kernelEntry; int ret; +#ifdef APM_SUPPORT + BOOL apm; +#endif /* APM_SUPPORT */ + BOOL bootGraphics; bootArgs->kaddr = bootArgs->ksize = 0; @@ -137,12 +149,14 @@ static int ExecKernel(void *binary) 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. @@ -154,9 +168,27 @@ static int ExecKernel(void *binary) } } - // 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. @@ -196,10 +228,16 @@ static void scanHardware() // 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(); @@ -228,25 +266,36 @@ void boot(int biosdev) // 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. @@ -254,27 +303,45 @@ void boot(int biosdev) 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"); @@ -282,20 +349,27 @@ void boot(int biosdev) 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; } @@ -316,6 +390,10 @@ void boot(int biosdev) } while (0); clearActivityIndicator(); +#if DEBUG + printf("Pausing..."); + sleep(8); +#endif if (ret < 0) { error("Can't find %s\n", bootFile); @@ -325,7 +403,7 @@ void boot(int biosdev) // 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 ) { @@ -344,3 +422,40 @@ void boot(int biosdev) 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); +} + diff --git a/i386/boot2/boot.h b/i386/boot2/boot.h index 85c003b..dc7d3ab 100644 --- a/i386/boot2/boot.h +++ b/i386/boot2/boot.h @@ -1,12 +1,12 @@ /* - * 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. @@ -32,42 +32,85 @@ #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 @@ -78,7 +121,7 @@ extern long DecodeKernel(void *binary, entry_t *rentry, char **raddr, int *rsize /* * options.c */ -extern void getBootOptions(); +extern int getBootOptions(BOOL firstRun); extern int processBootOptions(); /* diff --git a/i386/boot2/drivers.c b/i386/boot2/drivers.c index 6a2ac55..ab7742a 100644 --- a/i386/boot2/drivers.c +++ b/i386/boot2/drivers.c @@ -1,12 +1,12 @@ /* - * 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. @@ -17,7 +17,7 @@ * 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@ */ @@ -163,9 +163,21 @@ long LoadDrivers( char * dirSpec ) } 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 { @@ -199,7 +211,7 @@ FileLoadDrivers( char * dirSpec, long plugin ) { 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); diff --git a/i386/boot2/graphics.c b/i386/boot2/graphics.c index d5359b9..89c6268 100644 --- a/i386/boot2/graphics.c +++ b/i386/boot2/graphics.c @@ -1,12 +1,12 @@ /* - * 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. @@ -40,20 +40,28 @@ static int currentIndicator = 0; 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 @@ -62,6 +70,7 @@ void printVBEInfo() { VBEInfoBlock vbeInfo; int err; + int small; // Fetch VBE Controller Info. @@ -77,13 +86,77 @@ void printVBEInfo() // 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 // @@ -137,7 +210,7 @@ getVESAModeWithProperties( unsigned short width, 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, @@ -215,7 +288,7 @@ getVESAModeWithProperties( unsigned short width, } if ( modeInfo.XResolution < outModeInfo->XResolution || modeInfo.YResolution < outModeInfo->YResolution || - modeBitsPerPixel < 16 ) + modeBitsPerPixel < outModeInfo->BitsPerPixel ) { continue; // Saved mode has more resolution. } @@ -247,7 +320,7 @@ static void setupPalette( VBEPalette * p, const unsigned char * g ) //========================================================================== // 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; @@ -361,48 +434,64 @@ setVESAGraphicsMode( unsigned short width, 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, @@ -412,45 +501,24 @@ drawBootGraphics( unsigned short width, 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); } //========================================================================== @@ -499,7 +567,7 @@ static void * stosl(void * dst, long val, long len) return dst; } -static void drawColorRectangle( unsigned short x, +void drawColorRectangle( unsigned short x, unsigned short y, unsigned short width, unsigned short height, @@ -513,6 +581,9 @@ static void drawColorRectangle( unsigned short x, 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; @@ -525,19 +596,21 @@ static void drawColorRectangle( unsigned short x, //========================================================================== // 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; } @@ -638,9 +711,9 @@ setVideoMode( int mode ) 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. @@ -659,7 +732,7 @@ setVideoMode( int mode ) bootArgs->video.v_display = !gVerboseMode; if (!gVerboseMode) { - drawBootGraphics( params[0], params[1], params[2], params[3] ); + drawBootGraphics(); } } } @@ -692,6 +765,7 @@ int getVideoMode(void) // 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. @@ -711,10 +785,9 @@ spinActivityIndicator( void ) 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; } } @@ -726,3 +799,4 @@ clearActivityIndicator( void ) printf(" \b"); } } + diff --git a/i386/boot2/lzss.c b/i386/boot2/lzss.c index 9cc50fb..69f08ea 100644 --- a/i386/boot2/lzss.c +++ b/i386/boot2/lzss.c @@ -3,17 +3,19 @@ * * @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. * diff --git a/i386/boot2/options.c b/i386/boot2/options.c index 72d4014..02000fb 100644 --- a/i386/boot2/options.c +++ b/i386/boot2/options.c @@ -1,12 +1,12 @@ /* - * 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. @@ -39,8 +39,6 @@ enum { kScreenLastRow = 24 }; -static BVRef gBootVolume = 0; - static void showHelp(); //========================================================================== @@ -76,9 +74,18 @@ static void restoreCursor( const CursorState * cs ) //========================================================================== -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; } //========================================================================== @@ -99,6 +106,13 @@ static int countdown( const char * msg, int row, int timeout ) 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; @@ -141,7 +155,7 @@ static void showBootPrompt( int row, BOOL visible ) } else { - printf("Press Return to start up the foreign OS. "); + printf("Press Enter to start up the foreign OS. "); } } @@ -376,23 +390,92 @@ static const char * extractKernelName( char ** cpp ) //========================================================================== -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; imemoryMapCount; 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. @@ -427,11 +510,15 @@ void getBootOptions() } #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; } @@ -448,7 +535,7 @@ void getBootOptions() 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; } @@ -495,7 +582,14 @@ void getBootOptions() 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; } @@ -519,6 +613,8 @@ done: changeCursor( 0, kMenuTopRow, kCursorTypeUnderline, 0 ); if ( menuItems ) free(menuItems); + + return 0; } //========================================================================== @@ -534,6 +630,7 @@ int processBootOptions() int cnt; int userCnt; int cntRemaining; + char * argP; skipblanks( &cp ); @@ -575,20 +672,48 @@ int processBootOptions() 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; @@ -597,14 +722,13 @@ int processBootOptions() // 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); @@ -612,21 +736,24 @@ int processBootOptions() 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; } @@ -639,27 +766,77 @@ static void showHelp() #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); } } diff --git a/i386/boot2/prompt.c b/i386/boot2/prompt.c index cf2ea4d..90776bd 100644 --- a/i386/boot2/prompt.c +++ b/i386/boot2/prompt.c @@ -1,12 +1,12 @@ /* - * 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. @@ -29,10 +29,10 @@ #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: "; diff --git a/i386/cdboot/Makefile b/i386/cdboot/Makefile index 7cd53ad..8b311e2 100644 --- a/i386/cdboot/Makefile +++ b/i386/cdboot/Makefile @@ -19,6 +19,9 @@ install_i386:: all $(INSTALLDIR) cp $(SYMROOT)/cdboot $(INSTALLDIR) cd $(INSTALLDIR); chmod u+w cdboot +clean:: + rm -f $(SYMROOT)/cdboot + include ../MakeInc.dir #dependencies diff --git a/i386/cdboot/biostest.asm b/i386/cdboot/biostest.asm index 39dcb7f..ddf9c82 100644 --- a/i386/cdboot/biostest.asm +++ b/i386/cdboot/biostest.asm @@ -1,11 +1,11 @@ -; 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. diff --git a/i386/cdboot/cdboot.s b/i386/cdboot/cdboot.s index ec5fe23..c286b9e 100644 --- a/i386/cdboot/cdboot.s +++ b/i386/cdboot/cdboot.s @@ -5,7 +5,7 @@ ; 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. diff --git a/i386/doc/Limits b/i386/doc/Limits index 71162c0..8f649de 100644 --- a/i386/doc/Limits +++ b/i386/doc/Limits @@ -1,11 +1,2 @@ -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. diff --git a/i386/libsa/Makefile b/i386/libsa/Makefile index 7772a5d..211b28a 100644 --- a/i386/libsa/Makefile +++ b/i386/libsa/Makefile @@ -43,9 +43,9 @@ DIRS_NEEDED = $(OBJROOT) $(SYMROOT) 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 diff --git a/i386/libsa/error.c b/i386/libsa/error.c index d536dd4..d64a521 100644 --- a/i386/libsa/error.c +++ b/i386/libsa/error.c @@ -1,12 +1,12 @@ /* - * 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. diff --git a/i386/libsa/libsa.h b/i386/libsa/libsa.h index d45029c..d20190a 100644 --- a/i386/libsa/libsa.h +++ b/i386/libsa/libsa.h @@ -1,12 +1,12 @@ /* - * 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. @@ -70,6 +70,7 @@ extern char * strerror(int errnum); */ 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 diff --git a/i386/libsa/memory.h b/i386/libsa/memory.h index e298dfc..a5dbece 100644 --- a/i386/libsa/memory.h +++ b/i386/libsa/memory.h @@ -1,12 +1,12 @@ /* - * 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. @@ -28,7 +28,7 @@ /* 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 @@ -37,8 +37,11 @@ #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. @@ -47,25 +50,28 @@ #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 diff --git a/i386/libsa/prf.c b/i386/libsa/prf.c index a9a74e5..6042d59 100644 --- a/i386/libsa/prf.c +++ b/i386/libsa/prf.c @@ -1,12 +1,12 @@ /* - * 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. @@ -42,6 +42,7 @@ #define SPACE 1 #define ZERO 2 +#define UCASE 16 /* * Scaled down version of C Library printf. @@ -72,7 +73,7 @@ printn(n, b, flag, minwidth, putfn_p, putfn_arg) } cp = prbuf; do { - *cp++ = "0123456789abcdef"[n%b]; + *cp++ = "0123456789abcdef0123456789ABCDEF"[(flag & UCASE) + n%b]; n /= b; width++; } while (n); @@ -98,7 +99,8 @@ void prf( { int b, c; char *s; - int flag = 0, minwidth = 0, width = 0; + int flag = 0, width = 0; + int minwidth; loop: while ((c = *fmt++) != '%') { @@ -106,6 +108,7 @@ loop: return; (*putfn_p)(c, putfn_arg); } + minwidth = 0; again: c = *fmt++; switch (c) { @@ -132,7 +135,10 @@ again: 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': diff --git a/i386/libsa/printf.c b/i386/libsa/printf.c index 5013b2a..970c0e5 100644 --- a/i386/libsa/printf.c +++ b/i386/libsa/printf.c @@ -1,12 +1,12 @@ /* - * 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. @@ -69,4 +69,3 @@ int slvprintf(char * str, int len, const char * fmt, va_list ap) *pi.str = '\0'; return (pi.str - str); } - diff --git a/i386/libsa/qsort.c b/i386/libsa/qsort.c index 051fe63..4bceabb 100644 --- a/i386/libsa/qsort.c +++ b/i386/libsa/qsort.c @@ -1,12 +1,12 @@ /* - * 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. diff --git a/i386/libsa/string.c b/i386/libsa/string.c index 4ed67cd..682abfe 100644 --- a/i386/libsa/string.c +++ b/i386/libsa/string.c @@ -1,12 +1,12 @@ /* - * 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. @@ -35,6 +35,7 @@ void * memset(void * dst, int val, size_t len) return dst; } +#if 0 void * memcpy(void * dst, const void * src, size_t len) { asm( "rep; movsb" @@ -55,6 +56,53 @@ void bzero(void * dst, size_t len) 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)) diff --git a/i386/libsa/strtol.c b/i386/libsa/strtol.c index afad201..08e0848 100644 --- a/i386/libsa/strtol.c +++ b/i386/libsa/strtol.c @@ -1,12 +1,12 @@ /* - * 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. @@ -268,3 +268,74 @@ strtoul(nptr, endptr, base) *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); +} diff --git a/i386/libsa/zalloc.c b/i386/libsa/zalloc.c index 98c4719..51162eb 100644 --- a/i386/libsa/zalloc.c +++ b/i386/libsa/zalloc.c @@ -1,12 +1,12 @@ /* - * 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. @@ -74,7 +74,7 @@ void malloc_init(char * start, int size, int nodes, void (*malloc_err_fn)(char * 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); diff --git a/i386/libsaio/Makefile b/i386/libsaio/Makefile index 8ece05e..273cad7 100644 --- a/i386/libsaio/Makefile +++ b/i386/libsaio/Makefile @@ -5,7 +5,7 @@ include ../MakePaths.dir 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 \ @@ -33,7 +33,7 @@ SAIO_OBJS = table.o asm.o bios.o biosfn.o \ 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 @@ -63,7 +63,7 @@ all: $(DIRS_NEEDED) libsaio.h $(LIBS) 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 diff --git a/i386/libsaio/asm.s b/i386/libsaio/asm.s index 382eed0..367a9ea 100644 --- a/i386/libsaio/asm.s +++ b/i386/libsaio/asm.s @@ -1,12 +1,12 @@ /* - * 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. @@ -31,6 +31,24 @@ /* * HISTORY * $Log: asm.s,v $ + * Revision 1.7 2004/05/13 17:58:38 curtisg + * Integrating: + * : (Silent boot) + * : (5 sec boot timeout is too short) + * : (Boot option to display graphics modes) + * : (Default graphics mode should be 32-bit) + * : (Booter should always find a video mode) + * : (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 @@ -396,7 +414,7 @@ LABEL(_loader) leave ret -#if 0 +#if UNUSED // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // pcpy(src, dst, cnt) // where src is a virtual address and dst is a physical address diff --git a/i386/libsaio/bios.h b/i386/libsaio/bios.h index 79ce732..a29708c 100644 --- a/i386/libsaio/bios.h +++ b/i386/libsaio/bios.h @@ -1,12 +1,12 @@ /* - * 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. diff --git a/i386/libsaio/bios.s b/i386/libsaio/bios.s index 936dc26..369ad55 100644 --- a/i386/libsaio/bios.s +++ b/i386/libsaio/bios.s @@ -1,12 +1,12 @@ /* - * 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. diff --git a/i386/libsaio/biosfn.c b/i386/libsaio/biosfn.c index e5dec84..2c9ab4f 100644 --- a/i386/libsaio/biosfn.c +++ b/i386/libsaio/biosfn.c @@ -1,12 +1,12 @@ /* - * 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. @@ -90,7 +90,7 @@ unsigned long getMemoryMap( MemoryRange * rangeArray, 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. @@ -131,13 +131,14 @@ unsigned long getMemoryMap( MemoryRange * rangeArray, 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++; @@ -147,10 +148,18 @@ unsigned long getMemoryMap( MemoryRange * rangeArray, 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; } @@ -261,7 +270,7 @@ int ebiosread(int dev, long sec, int 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;;) { @@ -286,6 +295,43 @@ int ebiosread(int dev, long sec, int count) 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; @@ -324,7 +370,7 @@ int is_no_emulation(int drive) unsigned char sec_count; unsigned char head_count; unsigned char reseved; - }; + } __attribute__((packed)); static struct packet pkt; bzero(&pkt, sizeof(pkt)); @@ -413,7 +459,7 @@ int get_drive_info(int drive, struct driveInfo *dp) 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; @@ -605,6 +651,8 @@ int readDriveParameters(int drive, struct driveParameters *dp) } #endif +#ifdef APM_SUPPORT + #define APM_INTNO 0x15 #define APM_INTCODE 0x53 @@ -656,6 +704,8 @@ APMConnect32(void) return 0; } +#endif /* APM_SUPPORT */ + #ifdef EISA_SUPPORT BOOL eisa_present( @@ -778,3 +828,4 @@ void delay(int ms) bb.edx.rr = ms & 0xFFFF; bios(&bb); } + diff --git a/i386/libsaio/bootstruct.c b/i386/libsaio/bootstruct.c index 14e0999..18c9ccd 100644 --- a/i386/libsaio/bootstruct.c +++ b/i386/libsaio/bootstruct.c @@ -1,12 +1,12 @@ /* - * 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. diff --git a/i386/libsaio/bootstruct.h b/i386/libsaio/bootstruct.h index d65bf62..e67002a 100644 --- a/i386/libsaio/bootstruct.h +++ b/i386/libsaio/bootstruct.h @@ -1,12 +1,12 @@ /* - * 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. diff --git a/i386/libsaio/cache.c b/i386/libsaio/cache.c index f618714..52a32e4 100644 --- a/i386/libsaio/cache.c +++ b/i386/libsaio/cache.c @@ -1,10 +1,10 @@ /* - * 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. diff --git a/i386/libsaio/console.c b/i386/libsaio/console.c index ff2f1ed..3922373 100644 --- a/i386/libsaio/console.c +++ b/i386/libsaio/console.c @@ -1,12 +1,12 @@ /* - * 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. @@ -45,6 +45,7 @@ */ #include "libsaio.h" +#include "bootstruct.h" BOOL gVerboseMode; BOOL gErrors; @@ -95,6 +96,7 @@ int getchar() 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); diff --git a/i386/libsaio/disk.c b/i386/libsaio/disk.c index 84a8a61..aae0501 100644 --- a/i386/libsaio/disk.c +++ b/i386/libsaio/disk.c @@ -1,12 +1,12 @@ /* - * 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. @@ -49,6 +49,8 @@ #include "fdisk.h" #include "ufs.h" #include "hfs.h" +#include "ntfs.h" +#include "msdos.h" #include #include @@ -67,8 +69,8 @@ * 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. @@ -160,11 +162,12 @@ static const char * bios_error(int errnum) // 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; @@ -180,6 +183,9 @@ static int Biosread( int biosdev, unsigned int secno ) bps = 2048; } else { bps = di.di.params.phys_nbps; + if (bps == 0) { + return -1; + } } divisor = bps / BPS; @@ -332,6 +338,7 @@ static int getNextFDiskPartition( int biosdev, int * partno, { static int sBiosdev = -1; static int sNextPartNo; + static unsigned int sFirstBase; static unsigned int sExtBase; static unsigned int sExtDepth; static struct fdisk_part * sExtPart; @@ -344,6 +351,7 @@ static int getNextFDiskPartition( int biosdev, int * partno, sBiosdev = biosdev; sNextPartNo = 0; + sFirstBase = 0; sExtBase = 0; sExtDepth = 0; sExtPart = NULL; @@ -359,11 +367,14 @@ static int getNextFDiskPartition( int biosdev, int * partno, } 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. @@ -374,6 +385,7 @@ static int getNextFDiskPartition( int biosdev, int * partno, sExtPart = NULL; continue; } + // Fall through to part == NULL } if ( part == NULL ) break; // Reached end of partition chain. @@ -382,8 +394,6 @@ static int getNextFDiskPartition( int biosdev, int * partno, sNextPartNo++; - // Assume at most one extended partition per table. - if ( isExtendedFDiskPartition(part) ) { sExtPart = part; @@ -398,11 +408,10 @@ static int getNextFDiskPartition( int biosdev, int * partno, } // 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; } @@ -415,7 +424,11 @@ static int getNextFDiskPartition( int biosdev, int * partno, 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 ) @@ -427,8 +440,11 @@ static BVRef newFDiskBVRef( int biosdev, int partno, unsigned int blkoff, 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 ) @@ -469,7 +485,11 @@ static BVRef newFDiskBVRef( int biosdev, int partno, unsigned int blkoff, 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 ) @@ -480,8 +500,11 @@ BVRef newAPMBVRef( int biosdev, int partno, unsigned int blkoff, 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); @@ -525,6 +548,13 @@ BVRef newAPMBVRef( int biosdev, int partno, unsigned int blkoff, //========================================================================== +/* 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; @@ -576,7 +606,10 @@ static BVRef diskScanFDiskBootVolumes( int biosdev, int * countPtr ) part, UFSInitPartition, UFSLoadFile, + UFSReadFile, UFSGetDirEntry, + UFSGetFileBlock, + UFSGetDescription, 0, kBIOSDevTypeHardDrive); break; @@ -588,7 +621,10 @@ static BVRef diskScanFDiskBootVolumes( int biosdev, int * countPtr ) part, HFSInitPartition, HFSLoadFile, + HFSReadFile, HFSGetDirEntry, + HFSGetFileBlock, + HFSGetDescription, 0, kBIOSDevTypeHardDrive); break; @@ -600,17 +636,31 @@ static BVRef diskScanFDiskBootVolumes( int biosdev, int * countPtr ) 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; } @@ -642,7 +692,7 @@ static BVRef diskScanFDiskBootVolumes( int biosdev, int * countPtr ) * 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; @@ -654,7 +704,9 @@ static BVRef diskScanFDiskBootVolumes( int biosdev, int * countPtr ) &cdpart, HFSInitPartition, HFSLoadFile, + HFSReadFile, HFSGetDirEntry, + HFSGetFileBlock, 0, kBIOSDevTypeHardDrive); bvr->next = map->bvr; @@ -683,8 +735,8 @@ static BVRef diskScanAPMBootVolumes( int biosdev, int * countPtr ) 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); @@ -715,12 +767,12 @@ static BVRef diskScanAPMBootVolumes( int biosdev, int * countPtr ) for (i=0; idpme_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", @@ -733,11 +785,14 @@ static BVRef diskScanAPMBootVolumes( int biosdev, int * countPtr ) 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; @@ -789,8 +844,8 @@ BVRef diskScanBootVolumes( int biosdev, int * countPtr ) 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" }, @@ -799,20 +854,110 @@ static const struct NamedValue fdiskTypes[] = { 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); } @@ -859,6 +1004,81 @@ int diskRead( BVRef bvr, long addr, long length ) (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) { /* diff --git a/i386/libsaio/fdisk.h b/i386/libsaio/fdisk.h index 6805024..4abd7c1 100644 --- a/i386/libsaio/fdisk.h +++ b/i386/libsaio/fdisk.h @@ -1,12 +1,12 @@ /* - * 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. @@ -46,6 +46,8 @@ #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 */ diff --git a/i386/libsaio/hfs.c b/i386/libsaio/hfs.c index 44baaa6..5f1c48f 100644 --- a/i386/libsaio/hfs.c +++ b/i386/libsaio/hfs.c @@ -1,10 +1,10 @@ /* - * 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. @@ -44,6 +44,7 @@ static CICell gCurrentIH; static long long gAllocationOffset; static long gIsHFSPlus; +static long gCaseSensitive; static long gBlockSize; static long gCacheBlockSize; static char *gBTreeHeaderBuffer; @@ -61,6 +62,7 @@ static CICell gCurrentIH; static long long gAllocationOffset; static long gIsHFSPlus; static long gBlockSize; +static long gCaseSensitive; static long gCacheBlockSize; static char gBTreeHeaderBuffer[512]; static BTHeaderRec *gBTHeaders[2]; @@ -72,13 +74,15 @@ static char gLinkTemp[64]; #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); @@ -101,12 +105,19 @@ static long CompareHFSPlusExtentsKeys(void *key, void *testKey); 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; @@ -137,6 +148,7 @@ long HFSInitPartition(CICell ih) gAllocationOffset = 0; gIsHFSPlus = 0; + gCaseSensitive = 0; gBTHeaders[0] = 0; gBTHeaders[1] = 0; @@ -182,9 +194,11 @@ long HFSInitPartition(CICell ih) 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; } @@ -214,9 +228,14 @@ long HFSInitPartition(CICell ih) } 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); @@ -242,12 +261,13 @@ long HFSLoadFile(CICell ih, char * filePath) 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; } @@ -256,7 +276,8 @@ long HFSLoadFile(CICell ih, char * filePath) } 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; @@ -283,51 +304,137 @@ long HFSGetDirEntry(CICell ih, char * dirPath, long * dirIndex, char ** name, 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. @@ -349,6 +456,10 @@ static long GetCatalogEntryInfo(void * entry, long * flags, long * time) case kHFSFileRecord : *flags = kFileTypeFlat; tmpTime = SWAP_BE32(((HFSCatalogFile *)entry)->modifyDate); + if (finderInfo) { + SwapFinderInfo((FndrFileInfo *)finderInfo, &((HFSCatalogFile *)entry)->userInfo); + valid = 1; + } break; case kHFSPlusFileRecord : @@ -357,6 +468,10 @@ static long GetCatalogEntryInfo(void * entry, long * flags, long * time) 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 : @@ -372,6 +487,7 @@ static long GetCatalogEntryInfo(void * entry, long * flags, long * time) // Convert base time from 1904 to 1970. *time = tmpTime - 2082844800; } + if (infoValid) *infoValid = valid; return 0; } @@ -400,7 +516,7 @@ static long ResolvePathToCatalogEntry(char * filePath, long * flags, return -1; } - GetCatalogEntryInfo(entry, flags, 0); + GetCatalogEntryInfo(entry, flags, 0, 0, 0); if ((*flags & kFileTypeMask) == kFileTypeDirectory) { if (gIsHFSPlus) @@ -427,7 +543,8 @@ static long ResolvePathToCatalogEntry(char * filePath, long * flags, } 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; @@ -454,13 +571,13 @@ static long GetCatalogEntry(long * dirIndex, char ** name, 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], @@ -496,7 +613,7 @@ static long ReadCatalogEntry(char * fileName, long dirID, 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); @@ -566,6 +683,10 @@ static long ReadBTreeEntry(long btree, void * key, char * entry, long * dirIndex 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); @@ -813,10 +934,17 @@ static long CompareHFSPlusCatalogKeys(void * key, void * testKey) 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; @@ -893,3 +1021,4 @@ static long CompareHFSPlusExtentsKeys(void * key, void * testKey) return result; } + diff --git a/i386/libsaio/hfs.h b/i386/libsaio/hfs.h index 641eef4..765106e 100644 --- a/i386/libsaio/hfs.h +++ b/i386/libsaio/hfs.h @@ -4,7 +4,7 @@ * @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. @@ -22,6 +22,9 @@ 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); diff --git a/i386/libsaio/hfs_CaseTables.h b/i386/libsaio/hfs_CaseTables.h index d4691b6..34aa6f0 100644 --- a/i386/libsaio/hfs_CaseTables.h +++ b/i386/libsaio/hfs_CaseTables.h @@ -1,10 +1,10 @@ /* - * 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. @@ -30,6 +30,7 @@ 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 ) @@ -242,7 +243,6 @@ u_int16_t gLowerCaseTable[] = { /* F */ 0xFFF0, 0xFFF1, 0xFFF2, 0xFFF3, 0xFFF4, 0xFFF5, 0xFFF6, 0xFFF7, 0xFFF8, 0xFFF9, 0xFFFA, 0xFFFB, 0xFFFC, 0xFFFD, 0xFFFE, 0xFFFF, }; - /* RelString case folding table */ unsigned short gCompareTable[] = { @@ -273,3 +273,278 @@ 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 */ diff --git a/i386/libsaio/hfs_compare.c b/i386/libsaio/hfs_compare.c index 8917c1c..7a365f6 100644 --- a/i386/libsaio/hfs_compare.c +++ b/i386/libsaio/hfs_compare.c @@ -1,10 +1,10 @@ /* - * 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. @@ -30,6 +30,40 @@ #include #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; idata; + for (j=0; jcount; 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 @@ -45,6 +79,10 @@ int32_t FastRelString(char * str1, char * str2) int32_t bestGuess; u_int8_t length, length2; +#if ! UNCOMPRESED + InitCompareTables(); +#endif + length = *(str1++); length2 = *(str2++); @@ -153,6 +191,10 @@ int32_t FastUnicodeCompare( u_int16_t * str1, register u_int32_t length1, 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; @@ -188,6 +230,43 @@ int32_t FastUnicodeCompare( u_int16_t * str1, register u_int32_t length1, } +// +// 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) * @@ -216,7 +295,7 @@ int32_t FastUnicodeCompare( u_int16_t * str1, register u_int32_t length1, */ 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; @@ -224,7 +303,10 @@ utf_encodestr( const u_int16_t * ucsp, int ucslen, 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) @@ -259,7 +341,7 @@ utf_encodestr( const u_int16_t * ucsp, int ucslen, * 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; @@ -277,7 +359,11 @@ void utf_decodestr(const u_int8_t * utf8p, u_int16_t * ucsp, u_int16_t * ucslen, 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; } @@ -309,8 +395,14 @@ void utf_decodestr(const u_int8_t * utf8p, u_int16_t * ucsp, u_int16_t * ucslen, 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); } diff --git a/i386/libsaio/io_inline.h b/i386/libsaio/io_inline.h index 2a813a2..0535c10 100644 --- a/i386/libsaio/io_inline.h +++ b/i386/libsaio/io_inline.h @@ -1,12 +1,12 @@ /* - * 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. diff --git a/i386/libsaio/libsaio.h b/i386/libsaio/libsaio.h index 2d0fb68..6eee4d1 100644 --- a/i386/libsaio/libsaio.h +++ b/i386/libsaio/libsaio.h @@ -1,12 +1,12 @@ /* - * 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. diff --git a/i386/libsaio/load.c b/i386/libsaio/load.c index 2103c14..77f9f8d 100644 --- a/i386/libsaio/load.c +++ b/i386/libsaio/load.c @@ -4,7 +4,7 @@ * @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. @@ -52,7 +52,7 @@ long ThinFatFile(void **binary, unsigned long *length) 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; @@ -60,9 +60,9 @@ long ThinFatFile(void **binary, unsigned long *length) 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) { @@ -99,7 +99,7 @@ long DecodeMachO(void *binary, entry_t *rentry, char **raddr, int *rsize) 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); @@ -122,7 +122,7 @@ long DecodeMachO(void *binary, entry_t *rentry, char **raddr, int *rsize) 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); } @@ -173,15 +173,17 @@ static long DecodeSegment(long cmdBase, unsigned int *load_addr, unsigned int *l 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"); } diff --git a/i386/libsaio/memory.c b/i386/libsaio/memory.c index 375d989..a06026f 100644 --- a/i386/libsaio/memory.c +++ b/i386/libsaio/memory.c @@ -6,7 +6,7 @@ * 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. diff --git a/i386/libsaio/misc.c b/i386/libsaio/misc.c index 96cee06..43d624a 100644 --- a/i386/libsaio/misc.c +++ b/i386/libsaio/misc.c @@ -1,12 +1,12 @@ /* - * 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. @@ -95,3 +95,4 @@ void enableA20() while (inb(PORT_B) & KB_INFULL); /* wait until done */ } + diff --git a/i386/libsaio/msdos.c b/i386/libsaio/msdos.c new file mode 100644 index 0000000..1797d49 --- /dev/null +++ b/i386/libsaio/msdos.c @@ -0,0 +1,329 @@ +/* + * 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; jdeName[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; +} diff --git a/i386/libsaio/msdos.h b/i386/libsaio/msdos.h new file mode 100644 index 0000000..9add6e5 --- /dev/null +++ b/i386/libsaio/msdos.h @@ -0,0 +1,23 @@ +/* + * 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); diff --git a/i386/libsaio/msdos_private.h b/i386/libsaio/msdos_private.h new file mode 100644 index 0000000..5c0f64d --- /dev/null +++ b/i386/libsaio/msdos_private.h @@ -0,0 +1,351 @@ +/* + * 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 + diff --git a/i386/libsaio/nbp.c b/i386/libsaio/nbp.c index 64734f3..a2b176c 100644 --- a/i386/libsaio/nbp.c +++ b/i386/libsaio/nbp.c @@ -1,12 +1,12 @@ /* - * 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. @@ -80,7 +80,8 @@ static long NBPLoadFile(CICell ih, char * filePath) * 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; } diff --git a/i386/libsaio/nbp_cmd.h b/i386/libsaio/nbp_cmd.h index 1bbdd39..1b3585d 100644 --- a/i386/libsaio/nbp_cmd.h +++ b/i386/libsaio/nbp_cmd.h @@ -1,12 +1,12 @@ /* - * 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. diff --git a/i386/libsaio/ntfs.c b/i386/libsaio/ntfs.c new file mode 100644 index 0000000..b3fbbc7 --- /dev/null +++ b/i386/libsaio/ntfs.c @@ -0,0 +1,307 @@ +/* + * 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; +} + diff --git a/i386/libsaio/ntfs.h b/i386/libsaio/ntfs.h new file mode 100644 index 0000000..4b13ccb --- /dev/null +++ b/i386/libsaio/ntfs.h @@ -0,0 +1,25 @@ +/* + * 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); + diff --git a/i386/libsaio/ntfs_private.h b/i386/libsaio/ntfs_private.h new file mode 100644 index 0000000..c9da79c --- /dev/null +++ b/i386/libsaio/ntfs_private.h @@ -0,0 +1,397 @@ +/* + * 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 +#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 */ diff --git a/i386/libsaio/pci.c b/i386/libsaio/pci.c index 1650bb6..1a79d5c 100644 --- a/i386/libsaio/pci.c +++ b/i386/libsaio/pci.c @@ -1,12 +1,12 @@ /* - * 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. diff --git a/i386/libsaio/pci.h b/i386/libsaio/pci.h index d1fde1a..b57ec17 100644 --- a/i386/libsaio/pci.h +++ b/i386/libsaio/pci.h @@ -1,12 +1,12 @@ /* - * 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. diff --git a/i386/libsaio/saio_internal.h b/i386/libsaio/saio_internal.h index c513fca..a0d2d77 100644 --- a/i386/libsaio/saio_internal.h +++ b/i386/libsaio/saio_internal.h @@ -1,12 +1,12 @@ /* - * 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. @@ -44,16 +44,20 @@ extern BOOL eisa_present(void); 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); @@ -92,9 +96,17 @@ extern void stop(const char *message); 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); @@ -120,21 +132,23 @@ extern char * newStringForStringTableKey(char *table, char *key); 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); @@ -145,14 +159,17 @@ extern int tell(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; diff --git a/i386/libsaio/saio_types.h b/i386/libsaio/saio_types.h index 237249f..e7b6338 100644 --- a/i386/libsaio/saio_types.h +++ b/i386/libsaio/saio_types.h @@ -1,12 +1,12 @@ /* - * 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. @@ -65,6 +65,9 @@ struct driveInfo { int valid; }; +typedef struct FinderInfo { + unsigned char data[16]; +} FinderInfo; struct BootVolume; typedef struct BootVolume * BVRef; @@ -72,8 +75,11 @@ typedef struct BootVolume * CICell; 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 { @@ -110,7 +116,9 @@ struct BootVolume { 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) */ diff --git a/i386/libsaio/sl.h b/i386/libsaio/sl.h index baa9e67..2a9a7b6 100644 --- a/i386/libsaio/sl.h +++ b/i386/libsaio/sl.h @@ -1,12 +1,12 @@ /* - * 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. @@ -30,9 +30,12 @@ #include #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 { diff --git a/i386/libsaio/stringConstants.h b/i386/libsaio/stringConstants.h index 5b961cc..f64b480 100644 --- a/i386/libsaio/stringConstants.h +++ b/i386/libsaio/stringConstants.h @@ -1,12 +1,12 @@ /* - * 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. diff --git a/i386/libsaio/stringTable.c b/i386/libsaio/stringTable.c index 1be07b0..65ef09e 100644 --- a/i386/libsaio/stringTable.c +++ b/i386/libsaio/stringTable.c @@ -1,12 +1,12 @@ /* - * 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. @@ -95,6 +95,8 @@ static void eatThru(char val, const char **table_p) *table_p = table; } +#if UNUSED + /* Remove key and its associated value from the table. */ BOOL @@ -171,6 +173,8 @@ newStringFromList( return newstr; } +#endif + /* * compress == compress escaped characters to one character */ @@ -257,6 +261,8 @@ BOOL getValueForConfigTableKey(const char *table, const char *key, const char ** return NO; } +#if UNUSED + /* * Returns a new malloc'ed string if one is found * in the string table matching 'key'. Also translates @@ -299,6 +305,8 @@ char *newStringForStringTableKey( } } +#endif + char * newStringForKey(char *key) { @@ -341,6 +349,7 @@ BOOL getValueForBootKey(const char *line, const char *match, const char **matchv { const char *key, *value; int key_len, value_len; + BOOL retval = NO; while (*line) { /* look for keyword or argument */ @@ -359,22 +368,32 @@ BOOL getValueForBootKey(const char *line, const char *match, const char **matchv && 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; } @@ -422,33 +441,29 @@ int sysConfigValid; * 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 { @@ -456,81 +471,16 @@ loadConfigFile(const char *configFile, const char **table, BOOL allocTable) } } -/* 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) { @@ -549,8 +499,6 @@ printSystemConfig(void) } #endif -static int sysconfig_dev; - //========================================================================== // ParseXMLFile // Modifies the input buffer. @@ -558,6 +506,7 @@ static int sysconfig_dev; // 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 ) @@ -584,6 +533,7 @@ ParseXMLFile( char * buffer, TagPtr * dict ) } free(configBuffer); if (length < 0) { + error ("Error parsing plist file"); return -1; } *dict = tag; @@ -611,7 +561,7 @@ loadSystemConfig( 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; @@ -625,21 +575,26 @@ loadSystemConfig( 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); diff --git a/i386/libsaio/sys.c b/i386/libsaio/sys.c index da63215..01b6f15 100644 --- a/i386/libsaio/sys.c +++ b/i386/libsaio/sys.c @@ -1,12 +1,12 @@ /* - * 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. @@ -82,9 +82,31 @@ static struct iob iob[NFILES]; 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. @@ -93,7 +115,6 @@ static BVRef newBootVolumeRef( int biosdev, int partno ); long LoadFile(const char * fileSpec) { const char * filePath; - long fileSize; BVRef bvr; // Resolve the boot volume from the file spec. @@ -101,18 +122,71 @@ long LoadFile(const char * fileSpec) 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. @@ -133,14 +207,14 @@ long GetDirEntry(const char * dirSpec, long * dirIndex, const char ** name, 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) @@ -148,6 +222,9 @@ long GetFileInfo(const char * dirSpec, const char * name, long index = 0; const char * entryName; + if (gMakeDirSpec == 0) + gMakeDirSpec = (char *)malloc(1024); + if (!dirSpec) { long idx, len; @@ -173,6 +250,21 @@ long GetFileInfo(const char * dirSpec, const char * name, 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() // @@ -190,6 +282,7 @@ static struct iob * iob_from_fdesc(int fdesc) return io; } +#if UNUSED //========================================================================== // openmem() @@ -219,6 +312,7 @@ gotfile: return fdesc; } +#endif //========================================================================== // open() - Open the file specified by 'path' for reading. @@ -360,6 +454,29 @@ int file_size(int fdesc) //========================================================================== +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; @@ -405,7 +522,21 @@ int readdir(struct dirstuff * dirp, const char ** name, long * flags, 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); } //========================================================================== @@ -463,13 +594,6 @@ BVRef scanBootVolumes( int biosdev, int * count ) //========================================================================== -void getBootVolumeDescription( BVRef bvr, char * str, long strMaxLen ) -{ - bvr->description( bvr, str, strMaxLen ); -} - -//========================================================================== - BVRef selectBootVolume( BVRef chain ) { BVRef bvr, bvr1 = 0, bvr2 = 0; @@ -492,7 +616,7 @@ BVRef selectBootVolume( BVRef chain ) #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; diff --git a/i386/libsaio/table.c b/i386/libsaio/table.c index 35d2117..fea3daf 100644 --- a/i386/libsaio/table.c +++ b/i386/libsaio/table.c @@ -1,12 +1,12 @@ /* - * 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. diff --git a/i386/libsaio/ufs.c b/i386/libsaio/ufs.c index 4322ae2..797eb4c 100644 --- a/i386/libsaio/ufs.c +++ b/i386/libsaio/ufs.c @@ -1,10 +1,10 @@ /* - * 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. @@ -47,16 +47,16 @@ static long FindFileInDir(char *fileName, long *flags, 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; @@ -99,18 +99,20 @@ long UFSInitPartition( CICell ih ) 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 @@ -125,37 +127,7 @@ long UFSInitPartition( CICell ih ) 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. @@ -176,9 +148,16 @@ long UFSInitPartition( CICell ih ) 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; @@ -189,26 +168,25 @@ long UFSLoadFile( CICell ih, char * filePath ) 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++; @@ -225,6 +203,52 @@ long UFSGetDirEntry( CICell ih, char * dirPath, long * dirIndex, 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; iul_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, @@ -419,29 +443,41 @@ static char * ReadFileBlock( InodePtr fileInode, long fragNum, long blockOffset, 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; diff --git a/i386/libsaio/ufs.h b/i386/libsaio/ufs.h index 004e895..9d7743d 100644 --- a/i386/libsaio/ufs.h +++ b/i386/libsaio/ufs.h @@ -4,7 +4,7 @@ * @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. @@ -22,6 +22,10 @@ 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); diff --git a/i386/libsaio/ufs_byteorder.c b/i386/libsaio/ufs_byteorder.c index 3b06483..838f107 100644 --- a/i386/libsaio/ufs_byteorder.c +++ b/i386/libsaio/ufs_byteorder.c @@ -1,12 +1,12 @@ /* - * 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. @@ -40,6 +40,7 @@ #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) { @@ -48,6 +49,7 @@ 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) @@ -67,7 +69,8 @@ byte_swap_shorts(short *array, int count) byte_swap_short(array[i]); } -void +#if UNUSED +static void swapBigIntsToHost(int *array, int count) { register int i; @@ -76,8 +79,7 @@ swapBigIntsToHost(int *array, int count) swapBigLongToHost(array[i]); } - -void +static void swapBigShortToHosts(short *array, int count) { register int i; @@ -85,6 +87,7 @@ swapBigShortToHosts(short *array, int count) for (i = 0; i < count; i++) swapBigShortToHost(array[i]); } +#endif void byte_swap_superblock(struct fs *sb) @@ -98,7 +101,9 @@ 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 */ @@ -109,87 +114,6 @@ byte_swap_superblock(struct fs *sb) } } -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 */ @@ -200,34 +124,34 @@ byte_swap_dinode_in(struct dinode *di) { 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 diff --git a/i386/libsaio/ufs_byteorder.h b/i386/libsaio/ufs_byteorder.h index 49be590..dde46e4 100644 --- a/i386/libsaio/ufs_byteorder.h +++ b/i386/libsaio/ufs_byteorder.h @@ -1,12 +1,12 @@ /* - * 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. @@ -36,7 +36,6 @@ #ifndef __LIBSAIO_UFS_BYTEORDER_H #define __LIBSAIO_UFS_BYTEORDER_H -#include #include #include #include @@ -45,15 +44,11 @@ #include #include -#include - 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); diff --git a/i386/libsaio/vbe.c b/i386/libsaio/vbe.c index 8aad90e..d7f2703 100644 --- a/i386/libsaio/vbe.c +++ b/i386/libsaio/vbe.c @@ -1,12 +1,12 @@ /* - * 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. diff --git a/i386/libsaio/vbe.h b/i386/libsaio/vbe.h index 4b77bdb..295b889 100644 --- a/i386/libsaio/vbe.h +++ b/i386/libsaio/vbe.h @@ -1,12 +1,12 @@ /* - * 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. diff --git a/i386/libsaio/xml.c b/i386/libsaio/xml.c index 75f59aa..4a6ff1d 100644 --- a/i386/libsaio/xml.c +++ b/i386/libsaio/xml.c @@ -6,7 +6,7 @@ * 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. @@ -111,6 +111,7 @@ XMLGetProperty( TagPtr dict, const char * key ) } +#if UNUSED //========================================================================== // XMLParseFile // Expects to see one dictionary in the XML file. @@ -142,6 +143,7 @@ XMLParseFile( char * buffer, TagPtr * dict ) *dict = tag; return 0; } +#endif /* UNUSED */ //========================================================================== // ParseNextTag diff --git a/i386/libsaio/xml.h b/i386/libsaio/xml.h index 9931885..79b76f1 100644 --- a/i386/libsaio/xml.h +++ b/i386/libsaio/xml.h @@ -6,7 +6,7 @@ * 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. @@ -79,11 +79,4 @@ void XMLFreeTag(TagPtr tag); // 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 */ diff --git a/i386/nasm/Makefile b/i386/nasm/Makefile index eee23ff..570169f 100644 --- a/i386/nasm/Makefile +++ b/i386/nasm/Makefile @@ -70,7 +70,8 @@ macros.c: standard.mac macros.pl 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) $@ diff --git a/i386/strings/BootHelp.txt b/i386/strings/BootHelp.txt index 869e04d..e76bfda 100644 --- a/i386/strings/BootHelp.txt +++ b/i386/strings/BootHelp.txt @@ -1,19 +1,35 @@ - -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: - - <kernel> +uses as the root device. Advanced startup options use the following syntax: + [device] [arguments] +Example arguments include + device: rd= (e.g. rd=disk0s2) + rd=* (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= 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. diff --git a/i386/strings/Makefile b/i386/strings/Makefile index 0ea9d36..cb04324 100644 --- a/i386/strings/Makefile +++ b/i386/strings/Makefile @@ -7,38 +7,12 @@ VPATH = $(OBJROOT) 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) diff --git a/i386/tests/Makefile b/i386/tests/Makefile index 15d2a8b..f45209f 100644 --- a/i386/tests/Makefile +++ b/i386/tests/Makefile @@ -1,14 +1,26 @@ -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 diff --git a/i386/tests/satest.c b/i386/tests/satest.c index ea5c106..79b20d0 100644 --- a/i386/tests/satest.c +++ b/i386/tests/satest.c @@ -23,6 +23,7 @@ */ /* test standalone library */ #include +#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" @@ -45,6 +46,17 @@ va_list ap) 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. */ @@ -65,10 +77,11 @@ const char *format, // 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"); @@ -107,4 +120,6 @@ main() printf("printf(\"Test: %% 8d\\n\",-9);\n"); printf("Test: -9\n"); printf("Test: % 8d\n",-9); + + return 0; } diff --git a/i386/util/Makefile b/i386/util/Makefile index 8ae84b9..1fd68e5 100644 --- a/i386/util/Makefile +++ b/i386/util/Makefile @@ -11,82 +11,24 @@ VPATH = $(OBJROOT):$(SYMROOT) 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 diff --git a/i386/util/machOconv.c b/i386/util/machOconv.c index 66e8bd4..f11469e 100644 --- a/i386/util/machOconv.c +++ b/i386/util/machOconv.c @@ -1,12 +1,12 @@ /* - * 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. -- 2.45.2