first commit
This commit is contained in:
		
						commit
						66289aa8ec
					
				
							
								
								
									
										58
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,58 @@ | ||||
| # ---> C | ||||
| # Prerequisites | ||||
| *.d | ||||
| 
 | ||||
| # Object files | ||||
| *.o | ||||
| *.ko | ||||
| *.obj | ||||
| *.elf | ||||
| 
 | ||||
| # Linker output | ||||
| *.ilk | ||||
| *.map | ||||
| *.exp | ||||
| 
 | ||||
| # Precompiled Headers | ||||
| *.gch | ||||
| *.pch | ||||
| 
 | ||||
| # Libraries | ||||
| *.lib | ||||
| *.a | ||||
| *.la | ||||
| *.lo | ||||
| 
 | ||||
| # Shared objects (inc. Windows DLLs) | ||||
| *.dll | ||||
| *.so | ||||
| *.so.* | ||||
| *.dylib | ||||
| 
 | ||||
| # Executables | ||||
| *.exe | ||||
| *.out | ||||
| *.app | ||||
| *.i*86 | ||||
| *.x86_64 | ||||
| *.hex | ||||
| 
 | ||||
| # Debug files | ||||
| *.dSYM/ | ||||
| *.su | ||||
| *.idb | ||||
| *.pdb | ||||
| 
 | ||||
| # Kernel Module Compile Results | ||||
| *.mod* | ||||
| *.cmd | ||||
| .tmp_versions/ | ||||
| modules.order | ||||
| Module.symvers | ||||
| Mkfile.old | ||||
| dkms.conf | ||||
| 
 | ||||
| *.gz | ||||
| compiler/* | ||||
| !.gitignore | ||||
| !create_crosscompiler.sh | ||||
							
								
								
									
										625
									
								
								LICENSE
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										625
									
								
								LICENSE
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,625 @@ | ||||
| GNU GENERAL PUBLIC LICENSE | ||||
| 
 | ||||
| Version 3, 29 June 2007 | ||||
| 
 | ||||
| Copyright © 2007 Free Software Foundation, Inc. <https://fsf.org/> | ||||
| 
 | ||||
| Everyone is permitted to copy and distribute verbatim copies of this license | ||||
| document, but changing it is not allowed. | ||||
| 
 | ||||
| Preamble | ||||
| 
 | ||||
| The GNU General Public License is a free, copyleft license for software and | ||||
| other kinds of works. | ||||
| 
 | ||||
| The licenses for most software and other practical works are designed to take | ||||
| away your freedom to share and change the works. By contrast, the GNU General | ||||
| Public License is intended to guarantee your freedom to share and change all | ||||
| versions of a program--to make sure it remains free software for all its users. | ||||
| We, the Free Software Foundation, use the GNU General Public License for most | ||||
| of our software; it applies also to any other work released this way by its | ||||
| authors. You can apply it to your programs, too. | ||||
| 
 | ||||
| When we speak of free software, we are referring to freedom, not price. Our | ||||
| General Public Licenses are designed to make sure that you have the freedom | ||||
| to distribute copies of free software (and charge for them if you wish), that | ||||
| you receive source code or can get it if you want it, that you can change | ||||
| the software or use pieces of it in new free programs, and that you know you | ||||
| can do these things. | ||||
| 
 | ||||
| To protect your rights, we need to prevent others from denying you these rights | ||||
| or asking you to surrender the rights. Therefore, you have certain responsibilities | ||||
| if you distribute copies of the software, or if you modify it: responsibilities | ||||
| to respect the freedom of others. | ||||
| 
 | ||||
| For example, if you distribute copies of such a program, whether gratis or | ||||
| for a fee, you must pass on to the recipients the same freedoms that you received. | ||||
| You must make sure that they, too, receive or can get the source code. And | ||||
| you must show them these terms so they know their rights. | ||||
| 
 | ||||
| Developers that use the GNU GPL protect your rights with two steps: (1) assert | ||||
| copyright on the software, and (2) offer you this License giving you legal | ||||
| permission to copy, distribute and/or modify it. | ||||
| 
 | ||||
| For the developers' and authors' protection, the GPL clearly explains that | ||||
| there is no warranty for this free software. For both users' and authors' | ||||
| sake, the GPL requires that modified versions be marked as changed, so that | ||||
| their problems will not be attributed erroneously to authors of previous versions. | ||||
| 
 | ||||
| Some devices are designed to deny users access to install or run modified | ||||
| versions of the software inside them, although the manufacturer can do so. | ||||
| This is fundamentally incompatible with the aim of protecting users' freedom | ||||
| to change the software. The systematic pattern of such abuse occurs in the | ||||
| area of products for individuals to use, which is precisely where it is most | ||||
| unacceptable. Therefore, we have designed this version of the GPL to prohibit | ||||
| the practice for those products. If such problems arise substantially in other | ||||
| domains, we stand ready to extend this provision to those domains in future | ||||
| versions of the GPL, as needed to protect the freedom of users. | ||||
| 
 | ||||
| Finally, every program is threatened constantly by software patents. States | ||||
| should not allow patents to restrict development and use of software on general-purpose | ||||
| computers, but in those that do, we wish to avoid the special danger that | ||||
| patents applied to a free program could make it effectively proprietary. To | ||||
| prevent this, the GPL assures that patents cannot be used to render the program | ||||
| non-free. | ||||
| 
 | ||||
| The precise terms and conditions for copying, distribution and modification | ||||
| follow. | ||||
| 
 | ||||
| TERMS AND CONDITIONS | ||||
| 
 | ||||
|    0. Definitions. | ||||
| 
 | ||||
|    "This License" refers to version 3 of the GNU General Public License. | ||||
| 
 | ||||
| "Copyright" also means copyright-like laws that apply to other kinds of works, | ||||
| such as semiconductor masks. | ||||
| 
 | ||||
| "The Program" refers to any copyrightable work licensed under this License. | ||||
| Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals | ||||
| or organizations. | ||||
| 
 | ||||
| To "modify" a work means to copy from or adapt all or part of the work in | ||||
| a fashion requiring copyright permission, other than the making of an exact | ||||
| copy. The resulting work is called a "modified version" of the earlier work | ||||
| or a work "based on" the earlier work. | ||||
| 
 | ||||
| A "covered work" means either the unmodified Program or a work based on the | ||||
| Program. | ||||
| 
 | ||||
| To "propagate" a work means to do anything with it that, without permission, | ||||
| would make you directly or secondarily liable for infringement under applicable | ||||
| copyright law, except executing it on a computer or modifying a private copy. | ||||
| Propagation includes copying, distribution (with or without modification), | ||||
| making available to the public, and in some countries other activities as | ||||
| well. | ||||
| 
 | ||||
| To "convey" a work means any kind of propagation that enables other parties | ||||
| to make or receive copies. Mere interaction with a user through a computer | ||||
| network, with no transfer of a copy, is not conveying. | ||||
| 
 | ||||
| An interactive user interface displays "Appropriate Legal Notices" to the | ||||
| extent that it includes a convenient and prominently visible feature that | ||||
| (1) displays an appropriate copyright notice, and (2) tells the user that | ||||
| there is no warranty for the work (except to the extent that warranties are | ||||
| provided), that licensees may convey the work under this License, and how | ||||
| to view a copy of this License. If the interface presents a list of user commands | ||||
| or options, such as a menu, a prominent item in the list meets this criterion. | ||||
| 
 | ||||
|    1. Source Code. | ||||
| 
 | ||||
| The "source code" for a work means the preferred form of the work for making | ||||
| modifications to it. "Object code" means any non-source form of a work. | ||||
| 
 | ||||
| A "Standard Interface" means an interface that either is an official standard | ||||
| defined by a recognized standards body, or, in the case of interfaces specified | ||||
| for a particular programming language, one that is widely used among developers | ||||
| working in that language. | ||||
| 
 | ||||
| The "System Libraries" of an executable work include anything, other than | ||||
| the work as a whole, that (a) is included in the normal form of packaging | ||||
| a Major Component, but which is not part of that Major Component, and (b) | ||||
| serves only to enable use of the work with that Major Component, or to implement | ||||
| a Standard Interface for which an implementation is available to the public | ||||
| in source code form. A "Major Component", in this context, means a major essential | ||||
| component (kernel, window system, and so on) of the specific operating system | ||||
| (if any) on which the executable work runs, or a compiler used to produce | ||||
| the work, or an object code interpreter used to run it. | ||||
| 
 | ||||
| The "Corresponding Source" for a work in object code form means all the source | ||||
| code needed to generate, install, and (for an executable work) run the object | ||||
| code and to modify the work, including scripts to control those activities. | ||||
| However, it does not include the work's System Libraries, or general-purpose | ||||
| tools or generally available free programs which are used unmodified in performing | ||||
| those activities but which are not part of the work. For example, Corresponding | ||||
| Source includes interface definition files associated with source files for | ||||
| the work, and the source code for shared libraries and dynamically linked | ||||
| subprograms that the work is specifically designed to require, such as by | ||||
| intimate data communication or control flow between those subprograms and | ||||
| other parts of the work. | ||||
| 
 | ||||
| The Corresponding Source need not include anything that users can regenerate | ||||
| automatically from other parts of the Corresponding Source. | ||||
| 
 | ||||
|    The Corresponding Source for a work in source code form is that same work. | ||||
| 
 | ||||
|    2. Basic Permissions. | ||||
| 
 | ||||
| All rights granted under this License are granted for the term of copyright | ||||
| on the Program, and are irrevocable provided the stated conditions are met. | ||||
| This License explicitly affirms your unlimited permission to run the unmodified | ||||
| Program. The output from running a covered work is covered by this License | ||||
| only if the output, given its content, constitutes a covered work. This License | ||||
| acknowledges your rights of fair use or other equivalent, as provided by copyright | ||||
| law. | ||||
| 
 | ||||
| You may make, run and propagate covered works that you do not convey, without | ||||
| conditions so long as your license otherwise remains in force. You may convey | ||||
| covered works to others for the sole purpose of having them make modifications | ||||
| exclusively for you, or provide you with facilities for running those works, | ||||
| provided that you comply with the terms of this License in conveying all material | ||||
| for which you do not control copyright. Those thus making or running the covered | ||||
| works for you must do so exclusively on your behalf, under your direction | ||||
| and control, on terms that prohibit them from making any copies of your copyrighted | ||||
| material outside their relationship with you. | ||||
| 
 | ||||
| Conveying under any other circumstances is permitted solely under the conditions | ||||
| stated below. Sublicensing is not allowed; section 10 makes it unnecessary. | ||||
| 
 | ||||
|    3. Protecting Users' Legal Rights From Anti-Circumvention Law. | ||||
| 
 | ||||
| No covered work shall be deemed part of an effective technological measure | ||||
| under any applicable law fulfilling obligations under article 11 of the WIPO | ||||
| copyright treaty adopted on 20 December 1996, or similar laws prohibiting | ||||
| or restricting circumvention of such measures. | ||||
| 
 | ||||
| When you convey a covered work, you waive any legal power to forbid circumvention | ||||
| of technological measures to the extent such circumvention is effected by | ||||
| exercising rights under this License with respect to the covered work, and | ||||
| you disclaim any intention to limit operation or modification of the work | ||||
| as a means of enforcing, against the work's users, your or third parties' | ||||
| legal rights to forbid circumvention of technological measures. | ||||
| 
 | ||||
|    4. Conveying Verbatim Copies. | ||||
| 
 | ||||
| You may convey verbatim copies of the Program's source code as you receive | ||||
| it, in any medium, provided that you conspicuously and appropriately publish | ||||
| on each copy an appropriate copyright notice; keep intact all notices stating | ||||
| that this License and any non-permissive terms added in accord with section | ||||
| 7 apply to the code; keep intact all notices of the absence of any warranty; | ||||
| and give all recipients a copy of this License along with the Program. | ||||
| 
 | ||||
| You may charge any price or no price for each copy that you convey, and you | ||||
| may offer support or warranty protection for a fee. | ||||
| 
 | ||||
|    5. Conveying Modified Source Versions. | ||||
| 
 | ||||
| You may convey a work based on the Program, or the modifications to produce | ||||
| it from the Program, in the form of source code under the terms of section | ||||
| 4, provided that you also meet all of these conditions: | ||||
| 
 | ||||
| a) The work must carry prominent notices stating that you modified it, and | ||||
| giving a relevant date. | ||||
| 
 | ||||
| b) The work must carry prominent notices stating that it is released under | ||||
| this License and any conditions added under section 7. This requirement modifies | ||||
| the requirement in section 4 to "keep intact all notices". | ||||
| 
 | ||||
| c) You must license the entire work, as a whole, under this License to anyone | ||||
| who comes into possession of a copy. This License will therefore apply, along | ||||
| with any applicable section 7 additional terms, to the whole of the work, | ||||
| and all its parts, regardless of how they are packaged. This License gives | ||||
| no permission to license the work in any other way, but it does not invalidate | ||||
| such permission if you have separately received it. | ||||
| 
 | ||||
| d) If the work has interactive user interfaces, each must display Appropriate | ||||
| Legal Notices; however, if the Program has interactive interfaces that do | ||||
| not display Appropriate Legal Notices, your work need not make them do so. | ||||
| 
 | ||||
| A compilation of a covered work with other separate and independent works, | ||||
| which are not by their nature extensions of the covered work, and which are | ||||
| not combined with it such as to form a larger program, in or on a volume of | ||||
| a storage or distribution medium, is called an "aggregate" if the compilation | ||||
| and its resulting copyright are not used to limit the access or legal rights | ||||
| of the compilation's users beyond what the individual works permit. Inclusion | ||||
| of a covered work in an aggregate does not cause this License to apply to | ||||
| the other parts of the aggregate. | ||||
| 
 | ||||
|    6. Conveying Non-Source Forms. | ||||
| 
 | ||||
| You may convey a covered work in object code form under the terms of sections | ||||
| 4 and 5, provided that you also convey the machine-readable Corresponding | ||||
| Source under the terms of this License, in one of these ways: | ||||
| 
 | ||||
| a) Convey the object code in, or embodied in, a physical product (including | ||||
| a physical distribution medium), accompanied by the Corresponding Source fixed | ||||
| on a durable physical medium customarily used for software interchange. | ||||
| 
 | ||||
| b) Convey the object code in, or embodied in, a physical product (including | ||||
| a physical distribution medium), accompanied by a written offer, valid for | ||||
| at least three years and valid for as long as you offer spare parts or customer | ||||
| support for that product model, to give anyone who possesses the object code | ||||
| either (1) a copy of the Corresponding Source for all the software in the | ||||
| product that is covered by this License, on a durable physical medium customarily | ||||
| used for software interchange, for a price no more than your reasonable cost | ||||
| of physically performing this conveying of source, or (2) access to copy the | ||||
| Corresponding Source from a network server at no charge. | ||||
| 
 | ||||
| c) Convey individual copies of the object code with a copy of the written | ||||
| offer to provide the Corresponding Source. This alternative is allowed only | ||||
| occasionally and noncommercially, and only if you received the object code | ||||
| with such an offer, in accord with subsection 6b. | ||||
| 
 | ||||
| d) Convey the object code by offering access from a designated place (gratis | ||||
| or for a charge), and offer equivalent access to the Corresponding Source | ||||
| in the same way through the same place at no further charge. You need not | ||||
| require recipients to copy the Corresponding Source along with the object | ||||
| code. If the place to copy the object code is a network server, the Corresponding | ||||
| Source may be on a different server (operated by you or a third party) that | ||||
| supports equivalent copying facilities, provided you maintain clear directions | ||||
| next to the object code saying where to find the Corresponding Source. Regardless | ||||
| of what server hosts the Corresponding Source, you remain obligated to ensure | ||||
| that it is available for as long as needed to satisfy these requirements. | ||||
| 
 | ||||
| e) Convey the object code using peer-to-peer transmission, provided you inform | ||||
| other peers where the object code and Corresponding Source of the work are | ||||
| being offered to the general public at no charge under subsection 6d. | ||||
| 
 | ||||
| A separable portion of the object code, whose source code is excluded from | ||||
| the Corresponding Source as a System Library, need not be included in conveying | ||||
| the object code work. | ||||
| 
 | ||||
| A "User Product" is either (1) a "consumer product", which means any tangible | ||||
| personal property which is normally used for personal, family, or household | ||||
| purposes, or (2) anything designed or sold for incorporation into a dwelling. | ||||
| In determining whether a product is a consumer product, doubtful cases shall | ||||
| be resolved in favor of coverage. For a particular product received by a particular | ||||
| user, "normally used" refers to a typical or common use of that class of product, | ||||
| regardless of the status of the particular user or of the way in which the | ||||
| particular user actually uses, or expects or is expected to use, the product. | ||||
| A product is a consumer product regardless of whether the product has substantial | ||||
| commercial, industrial or non-consumer uses, unless such uses represent the | ||||
| only significant mode of use of the product. | ||||
| 
 | ||||
| "Installation Information" for a User Product means any methods, procedures, | ||||
| authorization keys, or other information required to install and execute modified | ||||
| versions of a covered work in that User Product from a modified version of | ||||
| its Corresponding Source. The information must suffice to ensure that the | ||||
| continued functioning of the modified object code is in no case prevented | ||||
| or interfered with solely because modification has been made. | ||||
| 
 | ||||
| If you convey an object code work under this section in, or with, or specifically | ||||
| for use in, a User Product, and the conveying occurs as part of a transaction | ||||
| in which the right of possession and use of the User Product is transferred | ||||
| to the recipient in perpetuity or for a fixed term (regardless of how the | ||||
| transaction is characterized), the Corresponding Source conveyed under this | ||||
| section must be accompanied by the Installation Information. But this requirement | ||||
| does not apply if neither you nor any third party retains the ability to install | ||||
| modified object code on the User Product (for example, the work has been installed | ||||
| in ROM). | ||||
| 
 | ||||
| The requirement to provide Installation Information does not include a requirement | ||||
| to continue to provide support service, warranty, or updates for a work that | ||||
| has been modified or installed by the recipient, or for the User Product in | ||||
| which it has been modified or installed. Access to a network may be denied | ||||
| when the modification itself materially and adversely affects the operation | ||||
| of the network or violates the rules and protocols for communication across | ||||
| the network. | ||||
| 
 | ||||
| Corresponding Source conveyed, and Installation Information provided, in accord | ||||
| with this section must be in a format that is publicly documented (and with | ||||
| an implementation available to the public in source code form), and must require | ||||
| no special password or key for unpacking, reading or copying. | ||||
| 
 | ||||
|    7. Additional Terms. | ||||
| 
 | ||||
| "Additional permissions" are terms that supplement the terms of this License | ||||
| by making exceptions from one or more of its conditions. Additional permissions | ||||
| that are applicable to the entire Program shall be treated as though they | ||||
| were included in this License, to the extent that they are valid under applicable | ||||
| law. If additional permissions apply only to part of the Program, that part | ||||
| may be used separately under those permissions, but the entire Program remains | ||||
| governed by this License without regard to the additional permissions. | ||||
| 
 | ||||
| When you convey a copy of a covered work, you may at your option remove any | ||||
| additional permissions from that copy, or from any part of it. (Additional | ||||
| permissions may be written to require their own removal in certain cases when | ||||
| you modify the work.) You may place additional permissions on material, added | ||||
| by you to a covered work, for which you have or can give appropriate copyright | ||||
| permission. | ||||
| 
 | ||||
| Notwithstanding any other provision of this License, for material you add | ||||
| to a covered work, you may (if authorized by the copyright holders of that | ||||
| material) supplement the terms of this License with terms: | ||||
| 
 | ||||
| a) Disclaiming warranty or limiting liability differently from the terms of | ||||
| sections 15 and 16 of this License; or | ||||
| 
 | ||||
| b) Requiring preservation of specified reasonable legal notices or author | ||||
| attributions in that material or in the Appropriate Legal Notices displayed | ||||
| by works containing it; or | ||||
| 
 | ||||
| c) Prohibiting misrepresentation of the origin of that material, or requiring | ||||
| that modified versions of such material be marked in reasonable ways as different | ||||
| from the original version; or | ||||
| 
 | ||||
| d) Limiting the use for publicity purposes of names of licensors or authors | ||||
| of the material; or | ||||
| 
 | ||||
| e) Declining to grant rights under trademark law for use of some trade names, | ||||
| trademarks, or service marks; or | ||||
| 
 | ||||
| f) Requiring indemnification of licensors and authors of that material by | ||||
| anyone who conveys the material (or modified versions of it) with contractual | ||||
| assumptions of liability to the recipient, for any liability that these contractual | ||||
| assumptions directly impose on those licensors and authors. | ||||
| 
 | ||||
| All other non-permissive additional terms are considered "further restrictions" | ||||
| within the meaning of section 10. If the Program as you received it, or any | ||||
| part of it, contains a notice stating that it is governed by this License | ||||
| along with a term that is a further restriction, you may remove that term. | ||||
| If a license document contains a further restriction but permits relicensing | ||||
| or conveying under this License, you may add to a covered work material governed | ||||
| by the terms of that license document, provided that the further restriction | ||||
| does not survive such relicensing or conveying. | ||||
| 
 | ||||
| If you add terms to a covered work in accord with this section, you must place, | ||||
| in the relevant source files, a statement of the additional terms that apply | ||||
| to those files, or a notice indicating where to find the applicable terms. | ||||
| 
 | ||||
| Additional terms, permissive or non-permissive, may be stated in the form | ||||
| of a separately written license, or stated as exceptions; the above requirements | ||||
| apply either way. | ||||
| 
 | ||||
|    8. Termination. | ||||
| 
 | ||||
| You may not propagate or modify a covered work except as expressly provided | ||||
| under this License. Any attempt otherwise to propagate or modify it is void, | ||||
| and will automatically terminate your rights under this License (including | ||||
| any patent licenses granted under the third paragraph of section 11). | ||||
| 
 | ||||
| However, if you cease all violation of this License, then your license from | ||||
| a particular copyright holder is reinstated (a) provisionally, unless and | ||||
| until the copyright holder explicitly and finally terminates your license, | ||||
| and (b) permanently, if the copyright holder fails to notify you of the violation | ||||
| by some reasonable means prior to 60 days after the cessation. | ||||
| 
 | ||||
| Moreover, your license from a particular copyright holder is reinstated permanently | ||||
| if the copyright holder notifies you of the violation by some reasonable means, | ||||
| this is the first time you have received notice of violation of this License | ||||
| (for any work) from that copyright holder, and you cure the violation prior | ||||
| to 30 days after your receipt of the notice. | ||||
| 
 | ||||
| Termination of your rights under this section does not terminate the licenses | ||||
| of parties who have received copies or rights from you under this License. | ||||
| If your rights have been terminated and not permanently reinstated, you do | ||||
| not qualify to receive new licenses for the same material under section 10. | ||||
| 
 | ||||
|    9. Acceptance Not Required for Having Copies. | ||||
| 
 | ||||
| You are not required to accept this License in order to receive or run a copy | ||||
| of the Program. Ancillary propagation of a covered work occurring solely as | ||||
| a consequence of using peer-to-peer transmission to receive a copy likewise | ||||
| does not require acceptance. However, nothing other than this License grants | ||||
| you permission to propagate or modify any covered work. These actions infringe | ||||
| copyright if you do not accept this License. Therefore, by modifying or propagating | ||||
| a covered work, you indicate your acceptance of this License to do so. | ||||
| 
 | ||||
|    10. Automatic Licensing of Downstream Recipients. | ||||
| 
 | ||||
| Each time you convey a covered work, the recipient automatically receives | ||||
| a license from the original licensors, to run, modify and propagate that work, | ||||
| subject to this License. You are not responsible for enforcing compliance | ||||
| by third parties with this License. | ||||
| 
 | ||||
| An "entity transaction" is a transaction transferring control of an organization, | ||||
| or substantially all assets of one, or subdividing an organization, or merging | ||||
| organizations. If propagation of a covered work results from an entity transaction, | ||||
| each party to that transaction who receives a copy of the work also receives | ||||
| whatever licenses to the work the party's predecessor in interest had or could | ||||
| give under the previous paragraph, plus a right to possession of the Corresponding | ||||
| Source of the work from the predecessor in interest, if the predecessor has | ||||
| it or can get it with reasonable efforts. | ||||
| 
 | ||||
| You may not impose any further restrictions on the exercise of the rights | ||||
| granted or affirmed under this License. For example, you may not impose a | ||||
| license fee, royalty, or other charge for exercise of rights granted under | ||||
| this License, and you may not initiate litigation (including a cross-claim | ||||
| or counterclaim in a lawsuit) alleging that any patent claim is infringed | ||||
| by making, using, selling, offering for sale, or importing the Program or | ||||
| any portion of it. | ||||
| 
 | ||||
|    11. Patents. | ||||
| 
 | ||||
| A "contributor" is a copyright holder who authorizes use under this License | ||||
| of the Program or a work on which the Program is based. The work thus licensed | ||||
| is called the contributor's "contributor version". | ||||
| 
 | ||||
| A contributor's "essential patent claims" are all patent claims owned or controlled | ||||
| by the contributor, whether already acquired or hereafter acquired, that would | ||||
| be infringed by some manner, permitted by this License, of making, using, | ||||
| or selling its contributor version, but do not include claims that would be | ||||
| infringed only as a consequence of further modification of the contributor | ||||
| version. For purposes of this definition, "control" includes the right to | ||||
| grant patent sublicenses in a manner consistent with the requirements of this | ||||
| License. | ||||
| 
 | ||||
| Each contributor grants you a non-exclusive, worldwide, royalty-free patent | ||||
| license under the contributor's essential patent claims, to make, use, sell, | ||||
| offer for sale, import and otherwise run, modify and propagate the contents | ||||
| of its contributor version. | ||||
| 
 | ||||
| In the following three paragraphs, a "patent license" is any express agreement | ||||
| or commitment, however denominated, not to enforce a patent (such as an express | ||||
| permission to practice a patent or covenant not to sue for patent infringement). | ||||
| To "grant" such a patent license to a party means to make such an agreement | ||||
| or commitment not to enforce a patent against the party. | ||||
| 
 | ||||
| If you convey a covered work, knowingly relying on a patent license, and the | ||||
| Corresponding Source of the work is not available for anyone to copy, free | ||||
| of charge and under the terms of this License, through a publicly available | ||||
| network server or other readily accessible means, then you must either (1) | ||||
| cause the Corresponding Source to be so available, or (2) arrange to deprive | ||||
| yourself of the benefit of the patent license for this particular work, or | ||||
| (3) arrange, in a manner consistent with the requirements of this License, | ||||
| to extend the patent license to downstream recipients. "Knowingly relying" | ||||
| means you have actual knowledge that, but for the patent license, your conveying | ||||
| the covered work in a country, or your recipient's use of the covered work | ||||
| in a country, would infringe one or more identifiable patents in that country | ||||
| that you have reason to believe are valid. | ||||
| 
 | ||||
| If, pursuant to or in connection with a single transaction or arrangement, | ||||
| you convey, or propagate by procuring conveyance of, a covered work, and grant | ||||
| a patent license to some of the parties receiving the covered work authorizing | ||||
| them to use, propagate, modify or convey a specific copy of the covered work, | ||||
| then the patent license you grant is automatically extended to all recipients | ||||
| of the covered work and works based on it. | ||||
| 
 | ||||
| A patent license is "discriminatory" if it does not include within the scope | ||||
| of its coverage, prohibits the exercise of, or is conditioned on the non-exercise | ||||
| of one or more of the rights that are specifically granted under this License. | ||||
| You may not convey a covered work if you are a party to an arrangement with | ||||
| a third party that is in the business of distributing software, under which | ||||
| you make payment to the third party based on the extent of your activity of | ||||
| conveying the work, and under which the third party grants, to any of the | ||||
| parties who would receive the covered work from you, a discriminatory patent | ||||
| license (a) in connection with copies of the covered work conveyed by you | ||||
| (or copies made from those copies), or (b) primarily for and in connection | ||||
| with specific products or compilations that contain the covered work, unless | ||||
| you entered into that arrangement, or that patent license was granted, prior | ||||
| to 28 March 2007. | ||||
| 
 | ||||
| Nothing in this License shall be construed as excluding or limiting any implied | ||||
| license or other defenses to infringement that may otherwise be available | ||||
| to you under applicable patent law. | ||||
| 
 | ||||
|    12. No Surrender of Others' Freedom. | ||||
| 
 | ||||
| If conditions are imposed on you (whether by court order, agreement or otherwise) | ||||
| that contradict the conditions of this License, they do not excuse you from | ||||
| the conditions of this License. If you cannot convey a covered work so as | ||||
| to satisfy simultaneously your obligations under this License and any other | ||||
| pertinent obligations, then as a consequence you may not convey it at all. | ||||
| For example, if you agree to terms that obligate you to collect a royalty | ||||
| for further conveying from those to whom you convey the Program, the only | ||||
| way you could satisfy both those terms and this License would be to refrain | ||||
| entirely from conveying the Program. | ||||
| 
 | ||||
|    13. Use with the GNU Affero General Public License. | ||||
| 
 | ||||
| Notwithstanding any other provision of this License, you have permission to | ||||
| link or combine any covered work with a work licensed under version 3 of the | ||||
| GNU Affero General Public License into a single combined work, and to convey | ||||
| the resulting work. The terms of this License will continue to apply to the | ||||
| part which is the covered work, but the special requirements of the GNU Affero | ||||
| General Public License, section 13, concerning interaction through a network | ||||
| will apply to the combination as such. | ||||
| 
 | ||||
|    14. Revised Versions of this License. | ||||
| 
 | ||||
| The Free Software Foundation may publish revised and/or new versions of the | ||||
| GNU General Public License from time to time. Such new versions will be similar | ||||
| in spirit to the present version, but may differ in detail to address new | ||||
| problems or concerns. | ||||
| 
 | ||||
| Each version is given a distinguishing version number. If the Program specifies | ||||
| that a certain numbered version of the GNU General Public License "or any | ||||
| later version" applies to it, you have the option of following the terms and | ||||
| conditions either of that numbered version or of any later version published | ||||
| by the Free Software Foundation. If the Program does not specify a version | ||||
| number of the GNU General Public License, you may choose any version ever | ||||
| published by the Free Software Foundation. | ||||
| 
 | ||||
| If the Program specifies that a proxy can decide which future versions of | ||||
| the GNU General Public License can be used, that proxy's public statement | ||||
| of acceptance of a version permanently authorizes you to choose that version | ||||
| for the Program. | ||||
| 
 | ||||
| Later license versions may give you additional or different permissions. However, | ||||
| no additional obligations are imposed on any author or copyright holder as | ||||
| a result of your choosing to follow a later version. | ||||
| 
 | ||||
|    15. Disclaimer of Warranty. | ||||
| 
 | ||||
| THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE | ||||
| LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR | ||||
| OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER | ||||
| EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | ||||
| OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS | ||||
| TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM | ||||
| PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR | ||||
| CORRECTION. | ||||
| 
 | ||||
|    16. Limitation of Liability. | ||||
| 
 | ||||
| IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL | ||||
| ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM | ||||
| AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, | ||||
| INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO | ||||
| USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED | ||||
| INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE | ||||
| PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER | ||||
| PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. | ||||
| 
 | ||||
|    17. Interpretation of Sections 15 and 16. | ||||
| 
 | ||||
| If the disclaimer of warranty and limitation of liability provided above cannot | ||||
| be given local legal effect according to their terms, reviewing courts shall | ||||
| apply local law that most closely approximates an absolute waiver of all civil | ||||
| liability in connection with the Program, unless a warranty or assumption | ||||
| of liability accompanies a copy of the Program in return for a fee. END OF | ||||
| TERMS AND CONDITIONS | ||||
| 
 | ||||
| How to Apply These Terms to Your New Programs | ||||
| 
 | ||||
| If you develop a new program, and you want it to be of the greatest possible | ||||
| use to the public, the best way to achieve this is to make it free software | ||||
| which everyone can redistribute and change under these terms. | ||||
| 
 | ||||
| To do so, attach the following notices to the program. It is safest to attach | ||||
| them to the start of each source file to most effectively state the exclusion | ||||
| of warranty; and each file should have at least the "copyright" line and a | ||||
| pointer to where the full notice is found. | ||||
| 
 | ||||
| <one line to give the program's name and a brief idea of what it does.> | ||||
| 
 | ||||
| Copyright (C) <year> <name of author> | ||||
| 
 | ||||
| This program is free software: you can redistribute it and/or modify it under | ||||
| the terms of the GNU General Public License as published by the Free Software | ||||
| Foundation, either version 3 of the License, or (at your option) any later | ||||
| version. | ||||
| 
 | ||||
| This program is distributed in the hope that it will be useful, but WITHOUT | ||||
| ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS | ||||
| FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. | ||||
| 
 | ||||
| You should have received a copy of the GNU General Public License along with | ||||
| this program. If not, see <https://www.gnu.org/licenses/>. | ||||
| 
 | ||||
| Also add information on how to contact you by electronic and paper mail. | ||||
| 
 | ||||
| If the program does terminal interaction, make it output a short notice like | ||||
| this when it starts in an interactive mode: | ||||
| 
 | ||||
| <program> Copyright (C) <year> <name of author> | ||||
| 
 | ||||
| This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. | ||||
| 
 | ||||
| This is free software, and you are welcome to redistribute it under certain | ||||
| conditions; type `show c' for details. | ||||
| 
 | ||||
| The hypothetical commands `show w' and `show c' should show the appropriate | ||||
| parts of the General Public License. Of course, your program's commands might | ||||
| be different; for a GUI interface, you would use an "about box". | ||||
| 
 | ||||
| You should also get your employer (if you work as a programmer) or school, | ||||
| if any, to sign a "copyright disclaimer" for the program, if necessary. For | ||||
| more information on this, and how to apply and follow the GNU GPL, see <https://www.gnu.org/licenses/>. | ||||
| 
 | ||||
| The GNU General Public License does not permit incorporating your program | ||||
| into proprietary programs. If your program is a subroutine library, you may | ||||
| consider it more useful to permit linking proprietary applications with the | ||||
| library. If this is what you want to do, use the GNU Lesser General Public | ||||
| License instead of this License. But first, please read <https://www.gnu.org/ | ||||
| licenses /why-not-lgpl.html>. | ||||
							
								
								
									
										13
									
								
								backup.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										13
									
								
								backup.sh
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,13 @@ | ||||
| #!/bin/bash | ||||
| if [ $# -ne 1 ] | ||||
| then | ||||
|  echo "Usage: $0 [file suffix]"  | ||||
|  exit 1 | ||||
| fi | ||||
| 
 | ||||
| archive_name=$(date +%m.%d.%y."$1".tar) | ||||
| shopt -s extglob | ||||
| tar -cf $archive_name !(*gz) | ||||
| pigz -9 $archive_name | ||||
| 
 | ||||
| 
 | ||||
							
								
								
									
										42
									
								
								compiler/create_crosscompiler.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										42
									
								
								compiler/create_crosscompiler.sh
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,42 @@ | ||||
| #!/bin/bash | ||||
| export PREFIX=/home/indigo/projects/small/indigo_os/compiler/indigo_gcc | ||||
| export TARGET=x86_64-elf | ||||
| export PATH="$PREFIX/bin:$PATH" | ||||
| 
 | ||||
| export JOBS=7 | ||||
| 
 | ||||
| mkdir -p indigo_gcc/ | ||||
| mkdir -p src/ | ||||
| 
 | ||||
| mkdir src/packs | ||||
| mkdir src/build_binutils | ||||
| mkdir src/build_gcc | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| #download the latest binutils | ||||
| lftp -c "set xfer:clobber on; connect ftp.gnu.org; get -O src/packs/ gnu/binutils/$(lftp -c 'connect ftp.gnu.org; ls gnu/binutils/binutils*.tar.gz' | awk '{print $NF}' | sort -V | tail -n 1)" | ||||
| 
 | ||||
| #download gcc | ||||
| #yes, I know, I'm making too many connections, I'm tired as fuck rn | ||||
| latest_gcc=$(lftp -c 'connect ftp.gnu.org; ls -d gnu/gcc/gcc-*' | grep -E "^d" | awk '{print $NF}' | sort -V | tail -1) | ||||
| lftp -c "set xfer:clobber on; connect ftp.gnu.org; get -O src/packs/ gnu/gcc/$latest_gcc/$latest_gcc.tar.gz" | ||||
| 
 | ||||
| cd src/packs/ | ||||
| 
 | ||||
| for f in *tar.gz; do  | ||||
|   tar -xf "$f" | ||||
| done | ||||
| 
 | ||||
| cd ../build_binutils | ||||
| ../packs/binutils-*/configure --target=$TARGET --enable-interwork --enable-multilib --disable-nls --disable-werror --prefix="$PREFIX" && | ||||
| make -j$JOBS all install 2>&1 | tee binutils_build_log | ||||
| make install | ||||
| 
 | ||||
| cd ../build_gcc | ||||
| ../packs/gcc-*/configure --target=$TARGET --prefix="$PREFIX" --disable-nls --disable-libssp --enable-languages=c --without-headers && | ||||
| make -j$JOBS all-gcc && | ||||
| make -j$JOBS all-target-libgcc && | ||||
| make install-gcc | ||||
| make install-target-libgcc | ||||
| 
 | ||||
							
								
								
									
										23
									
								
								notes
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								notes
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,23 @@ | ||||
| | type	start			end			size		  | | ||||
| | 1 1	0x0000000000000000	0x000000000009FC00	0x000000000009FC00 | | ||||
| | 2 1	0x000000000009FC00	0x00000000000A0000	0x0000000000000400 | | ||||
| | 2 1	0x00000000000E0000	0x0000000000100000	0x0000000000020000 | | ||||
| | 1 1	0x0000000000100000	0x00000000BA6E4000	0x00000000BA5E4000 | | ||||
| | 2 1	0x00000000BA6E4000	0x00000000BA868000	0x0000000000184000 | | ||||
| | 3 1	0x00000000BA868000	0x00000000BA878000	0x0000000000010000 | | ||||
| | 4 1	0x00000000BA878000	0x00000000BB67A000	0x0000000000E02000 | | ||||
| | 2 1	0x00000000BB67A000	0x00000000BCA37000	0x00000000013BD000 | | ||||
| | 1 1	0x00000000BCA37000	0x00000000BCA38000	0x0000000000001000 | | ||||
| | 4 1	0x00000000BCA38000	0x00000000BCC3E000	0x0000000000206000 | | ||||
| | 1 1	0x00000000BCC3E000	0x00000000BD083000	0x0000000000445000 | | ||||
| | 2 1	0x00000000BD083000	0x00000000BD7F4000	0x0000000000771000 | | ||||
| | 1 1	0x00000000BD7F4000	0x00000000BD800000	0x000000000000C000 | | ||||
| | 1 1	0x0000000100001000	0x000000043F000000	0x000000033EFFF000 | | ||||
| | 2 1	0x00000000F8000000	0x00000000FC000000	0x0000000004000000 | | ||||
| | 2 1	0x00000000FEC00000	0x00000000FEC01000	0x0000000000001000 | | ||||
| | 2 1	0x00000000FEC10000	0x00000000FEC11000	0x0000000000001000 | | ||||
| | 2 1	0x00000000FEC20000	0x00000000FEC21000	0x0000000000001000 | | ||||
| | 2 1	0x00000000FED00000	0x00000000FED01000	0x0000000000001000 | | ||||
| | 2 1	0x00000000FED61000	0x00000000FED71000	0x0000000000010000 | | ||||
| | 2 1	0x00000000FED80000	0x00000000FED90000	0x0000000000010000 | | ||||
| | 2 1	0x00000000FEF00000	0x0000000100000000	0x0000000001100000 | | ||||
							
								
								
									
										256
									
								
								src/.gdb_history
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										256
									
								
								src/.gdb_history
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,256 @@ | ||||
| x 0x7FFE1667  | ||||
| x 0x7FFE1667 | ||||
| x 0x200000 | ||||
| quit | ||||
| break main | ||||
| c | ||||
| next | ||||
| stepi | ||||
| next | ||||
| x 0x200000 | ||||
| return | ||||
| next | ||||
| x 0x20000 | ||||
| x 0x20000 4096 | ||||
| dq 0x20000 (4096/8) | ||||
| dq 0x20000 1 | ||||
| dq 0x20000 2 | ||||
| dq 0x20000 3 | ||||
| dq 0x200000 3 | ||||
| print rsdp.v1->rsdp | ||||
| print rsdp->v1.rsdt_addr | ||||
| print (void*)rsdp->v1.rsdt_addr | ||||
| print (page table*)0x4000 | ||||
| print (page_table*)0x4000 | ||||
| print (page_table*)0x4000->pml4e | ||||
| print (page_table*)0x4000.pml4e | ||||
| print (page_table*)0x4000->pml4e | ||||
| print *(page_table*)0x4000->pml4e | ||||
| print (page_table*)0x4000.pml4e | ||||
| print (page_table*)0x4000.pml4e[0] | ||||
| print (page_table*)0x4000->pml4e[0] | ||||
| print (page_table*)0x4000.pml4e[0] | ||||
| print (page_table*)0x4000.pdpe | ||||
| print (page_table*)0x4000.pde | ||||
| print (page_table*)0x4000 | ||||
| print *(page_table*)0x4000 | ||||
| print *((page_table*)0x4000) | ||||
| print *((page_table*)0x4000).pde | ||||
| print *((page_table*)0x4000).pml4e | ||||
| print *((page_table*)0x3000).pml4e | ||||
| print *((page_table*)0x4000).pml4e | ||||
| print *((page_table*)0x4000).pde | ||||
| print *((page_table*)0x4000).pte | ||||
| print rsdp.v1.base_addr | ||||
| print rsdp.v1.rsdt_addr  | ||||
| print (void*)rsdp.v1.rsdt_addr  | ||||
| print *((page_table*)0x4000).pte | ||||
| print *((page_table*)0x4000).pte[1] | ||||
| print *((page_table*)0x4000).pte | ||||
| print *((page_table*)0x4000)->pte[1] | ||||
| print *((page_table*)0x4000).pte | ||||
| print *((page_table*)0x4000).pte[0] | ||||
| print ((page_table*)0x4000).pte | ||||
| print ((page_table*)0x4000)->pte | ||||
| print ((page_table*)0x4000)->pte[0] | ||||
| print ((page_table*)0x4000)->pte[1] | ||||
| print ((page_table*)0x4000)->pte[2] | ||||
| print ((page_table*)0x4000)->pte[3] | ||||
| print ((page_table*)0x4000)->pte[4] | ||||
| print ((page_table*)0x4000)->pte[5] | ||||
| print ((page_table*)0x4000)->pte[10] | ||||
| print ((page_table*)0x4000)->pte[1512] | ||||
| print ((page_table*)0x4000)->pte[512] | ||||
| print ((page_table*)0x4000)->pte[513] | ||||
| print ((page_table*)0x4000)->pte[512] | ||||
| print ((page_table*)0x4000)->pte[511] | ||||
| print ((page_table*)0x4000)->pte[510] | ||||
| print ((page_table*)0x4000)->pte | ||||
| quit | ||||
| break main | ||||
| c | ||||
| next | ||||
| print rsdp.v1.rsdt_addr | ||||
| print (void*)rsdp.v1.rsdt_addr | ||||
| quit | ||||
| break map_page | ||||
| c | ||||
| next | ||||
| print size | ||||
| next | ||||
| print table->pde[pde_i] | ||||
| next | ||||
| print table->pde[pde_i] | ||||
| next | ||||
| print table->pde[pde_i] | ||||
| next | ||||
| print table->pde[pde_i] | ||||
| print table->pte[pte_i] | ||||
| next | ||||
| print table->pte[pte_i] | ||||
| next | ||||
| x 0x20000 | ||||
| dq 0x20000 30 | ||||
| dq 0x20000 40 | ||||
| print table->pte[pte_i] | ||||
| context | ||||
| quit | ||||
| break map_page | ||||
| c | ||||
| next | ||||
| print table->pte[pte_i0 | ||||
| print table->pte[pte_i] | ||||
| quit | ||||
| r | ||||
| c | ||||
| quit | ||||
| c | ||||
| quit | ||||
| break panic | ||||
| c | ||||
| x 0x7ffe1000 | ||||
| quit | ||||
| break panic | ||||
| c | ||||
| x 0x200000 | ||||
| dq 0x200000 | ||||
| dq 0x200000 4 | ||||
| dq 0x200000 8 | ||||
| search -4 FACP | ||||
| search -4 FACP | ||||
| search -4 'FACP' | ||||
| search -s 'FACP' | ||||
| search -s 'ACPI' | ||||
| search -s 'RSDT' | ||||
| x 0x200000 + 0x667 | ||||
| dq 0x200000 + 0x667 | ||||
| dq (0x200000 + 0x667) | ||||
| x 0x200000 + 0x667 | ||||
| x/20i 0x200000 + 0x667 | ||||
| x/20x 0x200000 + 0x667 | ||||
| x/100x 0x200000 + 0x667 | ||||
| x/400x 0x200000 + 0x667 | ||||
| x/400x 0x200000 + 0x1000 | ||||
| x/400x 0x200000 + (0x1000) | ||||
| x/400x 0x200000 + (0x1000-8) | ||||
| x/400x 0x200000 + (0x1000-8) | ||||
| quit | ||||
| break panic | ||||
| c | ||||
| x 0x2000 | ||||
| x 0x20000 | ||||
| x 0x200000 | ||||
| x 0x2000000 | ||||
| x 0x200000 | ||||
| x 0x2000000 | ||||
| x 0x200000 | ||||
| x 0x202000 | ||||
| x 0x20b000 | ||||
| x 0x20b000+8 | ||||
| x 0x20b000 | ||||
| x 0x202000 | ||||
| x 0x201000 | ||||
| x 0x200000 | ||||
| x 0x201000 | ||||
| x 0x201000-8 | ||||
| x 0x200000-8 | ||||
| x 0x200000 | ||||
| quit | ||||
| break panic | ||||
| c | ||||
| 0x200000 | ||||
| x 0x200000 | ||||
| x/s 0x200000 | ||||
| quit | ||||
| break panic | ||||
| c | ||||
| quit | ||||
| break panic | ||||
| c | ||||
| quit | ||||
| break panic | ||||
| c | ||||
| quit | ||||
| break panic | ||||
| c | ||||
| x 0x20000 | ||||
| x 0x21667 | ||||
| x 0x20667 | ||||
| x 0x200000 | ||||
| x 0x200667 | ||||
| x 0x200667 | ||||
| x/s 0x200667 | ||||
| quit | ||||
| break panic | ||||
| c | ||||
| x apic | ||||
| quit | ||||
| break main | ||||
| c | ||||
| next | ||||
| pirnt apic | ||||
| print apic | ||||
| print rsdp | ||||
| print apic | ||||
| print *apic | ||||
| (struct apic_header *)((uint64_t)0x200000 + (rsdp->v1.rsdt_addr % 0x1000) | ||||
| print (struct apic_header *)((uint64_t)0x200000 + (rsdp->v1.rsdt_addr % 0x1000) | ||||
| quit | ||||
| break panic | ||||
| c | ||||
| prit apic | ||||
| print apic | ||||
| print acpi | ||||
| print *acpi | ||||
| print acpi | ||||
| print acpi.sig | ||||
| quit | ||||
| break main | ||||
| c | ||||
| next | ||||
| print apic | ||||
| ptype apic_header | ||||
| quit | ||||
| ptype acpi | ||||
| ptype acpi_header | ||||
| break main | ||||
| c | ||||
| next | ||||
| print apic | ||||
| print acpi | ||||
| print acpi.* | ||||
| context | ||||
| print apic | ||||
| quit | ||||
| break main | ||||
| c | ||||
| next | ||||
| print apic | ||||
| print apci_header  | ||||
| ptype apci_header  | ||||
| ptype apci_header  | ||||
| quit | ||||
| break main | ||||
| c | ||||
| next | ||||
| print acpi | ||||
| next | ||||
| print acpi | ||||
| quit | ||||
| print acpi | ||||
| break main | ||||
| c | ||||
| print acpi | ||||
| next | ||||
| print acpi | ||||
| next | ||||
| print acpi | ||||
| next | ||||
| print acpi | ||||
| next | ||||
| print acpi | ||||
| ptype acpi_header | ||||
| quit | ||||
| quit | ||||
| quit | ||||
| quit | ||||
							
								
								
									
										
											BIN
										
									
								
								src/amd64_vol2.pdf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								src/amd64_vol2.pdf
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										38
									
								
								src/bootloader/bios_functions/bios_disk.asm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								src/bootloader/bios_functions/bios_disk.asm
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,38 @@ | ||||
| bios_disk: | ||||
| .load_sectors: | ||||
| pusha | ||||
| mov es, dx | ||||
| 
 | ||||
| mov ah, 0x02      ; read disc sectors | ||||
| mov ch, 0x00      ; track 0 | ||||
| mov dh, 0x00      ; head 0 | ||||
| mov dl, [stage0.boot_device] | ||||
| 
 | ||||
| int 0x13 | ||||
| 
 | ||||
| jc .failed | ||||
| 
 | ||||
| mov ah, 0 | ||||
| popa | ||||
| ret | ||||
| 
 | ||||
| .failed: | ||||
| 
 | ||||
| mov bx, .loadsectors_error | ||||
| mov cx, 0 | ||||
| call bios_print | ||||
| 
 | ||||
| push 0 | ||||
| mov al, ah | ||||
| mov ah, 0   ; you need to clean up the bios print function! | ||||
| push ax | ||||
| mov cx, 1 | ||||
| mov bx, sp | ||||
| call bios_print | ||||
| 
 | ||||
| 
 | ||||
| mov ah, 1 | ||||
| popa | ||||
| ret | ||||
| 
 | ||||
| .loadsectors_error: db "Error loading sectors: ", 0 | ||||
							
								
								
									
										59
									
								
								src/bootloader/bios_functions/print.asm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								src/bootloader/bios_functions/print.asm
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,59 @@ | ||||
| ;TODO fix null problem, allow direct passes | ||||
| bios_print: | ||||
| ;push ax       ; we need to use ax, so let's push it in case whoever called needs it | ||||
| pusha | ||||
| mov ah, 0x0e  ; tells bios we're in tty mode | ||||
| 
 | ||||
| .print_loop: | ||||
| mov al, [bx]          ; al is the char MEANT TO BE CX | ||||
| cmp al, 0             ; compare the char we're about to print with null | ||||
| je .fini   ; if it is null, we gonna scoot the fuck outta here | ||||
| 
 | ||||
| test cx, cx           ; if cx is zero, ascii, otherwise hex string | ||||
| jne .print_hex | ||||
| int 0x10              ; bios call, actually prints the char | ||||
| .print_hex_ret: | ||||
| inc bx                ; adds to the pointer | ||||
| jmp .print_loop   ; goes back to loop start | ||||
| 
 | ||||
| .fini: | ||||
| mov al, 0xd           ; \r | ||||
| int 0x10 | ||||
| mov al, 0xa           ; \n | ||||
| int 0x10 | ||||
| popa | ||||
| ret | ||||
| 
 | ||||
| 
 | ||||
| .print_hex: | ||||
| mov al, '0' | ||||
| int 0x10 | ||||
| 
 | ||||
| mov al, 'x' | ||||
| int 0x10 | ||||
| 
 | ||||
| mov al, [bx]              ; shift bits to get first nibble | ||||
| shr al, 4 | ||||
| call .bios_print_nibble | ||||
| 
 | ||||
| mov al, [bx] | ||||
| and al, 0x0f | ||||
| call .bios_print_nibble | ||||
| 
 | ||||
| mov al, ' ' | ||||
| int 0x10 | ||||
| 
 | ||||
| jmp .print_hex_ret | ||||
| 
 | ||||
| 
 | ||||
| .bios_print_nibble: | ||||
| cmp al, 9                 ; see if letter worthy | ||||
| ja .print_hex_letter | ||||
| add al, 0x30              ;'1' | ||||
| int 0x10 | ||||
| ret | ||||
| 
 | ||||
| .print_hex_letter: | ||||
| add al, 0x57              ;'a' | ||||
| int 0x10 | ||||
| ret | ||||
							
								
								
									
										145
									
								
								src/bootloader/bootloader.asm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										145
									
								
								src/bootloader/bootloader.asm
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,145 @@ | ||||
| [bits 16] | ||||
| [extern _kernel_size] | ||||
| [extern _bootloader_stage1_size] | ||||
| [extern _kernel_loc] | ||||
| 
 | ||||
| ;TODO clean up unreal mode | ||||
| jmp stage0  | ||||
| times 3-($-$$) db 0x90 ; a temporary dirty fix to emulate a floppy disk insted of a hard risk  | ||||
| times 59 db 0          ; (TODO support hard disks)  | ||||
| 
 | ||||
| stage0: | ||||
| 
 | ||||
| jmp 0:.entry | ||||
| .entry: | ||||
| 
 | ||||
| mov ax, 0 | ||||
| mov ds, ax | ||||
| mov bp, ax  | ||||
| 
 | ||||
| mov ds, ax | ||||
| mov es, ax | ||||
| 
 | ||||
| mov ax, 0x8fc0 | ||||
| mov ss, ax | ||||
| mov ax, 0xfffe  | ||||
| mov sp, ax | ||||
| 
 | ||||
| mov al, 0x92 | ||||
| or al, 2 | ||||
| out 0x92, al | ||||
| 
 | ||||
| mov [.boot_device], dl | ||||
| 
 | ||||
| mov bx, .loadstage2_msg | ||||
| mov cx, 0  | ||||
| call bios_print | ||||
| 
 | ||||
| ; TODO put in an error message and a maximum fail count | ||||
| .load_stage1: | ||||
| mov al, _bootloader_stage1_size | ||||
| mov cl, 0x2       ; read sector 2  | ||||
| mov dx, 0x0       ; dest segment 0 | ||||
| mov bx, 0x7e00    ; dest offst 0  | ||||
| call bios_disk.load_sectors  | ||||
| 
 | ||||
| 
 | ||||
| jmp mbr_end.entry | ||||
| 
 | ||||
| .boot_device: db 0 | ||||
| 
 | ||||
| .loadstage2_msg: db "Loading (stage 2) bootloader...", 0 | ||||
| 
 | ||||
| %include "bootloader/bios_functions/bios_disk.asm" | ||||
| %include "bootloader/bios_functions/print.asm" | ||||
| 
 | ||||
| times 510 - ($-$$) db 0   | ||||
| dw 0xaa55 | ||||
| 
 | ||||
| %include "bootloader/gdt.asm" | ||||
| 
 | ||||
| boot_msg: | ||||
| .debugmsg: db "debugeroni", 0 | ||||
| .kernel_loaded: db `Kernel loaded!\r\nBooting to protected, then long mode...`, 0 | ||||
| .stage2_loaded: db `Done loading bootloader!\r\nLoading kernel...`, 0 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| mbr_end: | ||||
| .entry: | ||||
| ; entering unreal mode | ||||
| mov bx, boot_msg.stage2_loaded | ||||
| mov cx, 0 | ||||
| call bios_print | ||||
| 
 | ||||
| 
 | ||||
| cli | ||||
| push ds | ||||
| 
 | ||||
| lgdt [protected_gdt.descriptor] | ||||
| 
 | ||||
| mov eax, cr0 | ||||
| or al, 1 | ||||
| mov cr0, eax | ||||
| 
 | ||||
| jmp $+2 | ||||
| 
 | ||||
| mov bx, 0x10 ; descriptor 2, the data descriptor | ||||
| mov ds, bx   ; put it into the segment register | ||||
| mov es, bx   ;  | ||||
| 
 | ||||
| and al, 0xfe | ||||
| mov cr0, eax | ||||
| 
 | ||||
| pop ds | ||||
| sti | ||||
| ;we are now in unreal mode | ||||
| 
 | ||||
| mov cl, 5   ; starting sector TODO automate this | ||||
| mov edi, _kernel_loc | ||||
| .loop: | ||||
| mov al, 0x1   ; sector count | ||||
| mov dx, 0x0   ; dest addr segment | ||||
| mov bx, 0x500 ; dest addr offset | ||||
| call bios_disk.load_sectors | ||||
| 
 | ||||
| 
 | ||||
| inc cl | ||||
| 
 | ||||
| push cx | ||||
| 
 | ||||
| mov esi, 0x500 | ||||
| mov ecx, 512 | ||||
| a32 rep movsb | ||||
| nop | ||||
| 
 | ||||
| mov bx, boot_msg.debugmsg | ||||
| mov cx, 0 | ||||
| call bios_print | ||||
| 
 | ||||
| pop cx | ||||
| 
 | ||||
| cmp cl, _kernel_size | ||||
| je .loop_end | ||||
| 
 | ||||
| jmp .loop | ||||
| 
 | ||||
| .loop_end: | ||||
| 
 | ||||
| mov bx, boot_msg.kernel_loaded | ||||
| mov cx, 0 | ||||
| call bios_print | ||||
| 
 | ||||
| 
 | ||||
| call detect_arch | ||||
| call vbe_init | ||||
| done: | ||||
| 
 | ||||
| call enter_longmode | ||||
| jmp $ | ||||
| 
 | ||||
| %include "bootloader/cpu_check.asm" | ||||
| %include "bootloader/video.asm" | ||||
| %include "bootloader/enter_kernel.asm" | ||||
| times 2048 - ($ - $$) db 0 | ||||
							
								
								
									
										100
									
								
								src/bootloader/cpu_check.asm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										100
									
								
								src/bootloader/cpu_check.asm
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,100 @@ | ||||
| ; TODO move this file to something like "system_check", now that we do ram checks here | ||||
| [extern _meminfo_loc] | ||||
| detect_arch: | ||||
| ; todo: figure out how to just handle invalid opcode exceptions, it would be faster and (maybe?) easier  | ||||
| ; todo: digest this part a little better when it's _not_ 1am. | ||||
| pushfd    ; pushes eflags to stack | ||||
| pushfd    ; pushes eflags to stack a second time | ||||
| xor dword [esp], 0x00200000 ; inverses the ID bit to see if cpuid is a thing | ||||
| pop eax         ;gets our modified cpuid back | ||||
| xor eax, [esp]  ; checks with the first time we pushed it; the OG eflag | ||||
| popfd           ; pops the flags back I guess? | ||||
| and eax, 0x00200000 ; checks to see if the bit was inverted | ||||
| jz .print_cpuid_error | ||||
| ;now we detect if we support long slong (aka 64 bit) | ||||
| 
 | ||||
| ;https://www.amd.com/system/files/TechDocs/25481.pdf page 21 | ||||
| ;So apperently some dumbass engineers thought it would be funny to sell CPUs that have the long mode bit set without it being supported, dispite including it in their own documentation. | ||||
| ;there's a work around by checking other bits, and it's a low priority TODO. However, I really think us coming accross this will be extremely rare. | ||||
| mov eax, 0x80000001 | ||||
| cpuid ;cpuid returns into edx | ||||
| and edx, 0x0020000000 ; the 21st bit is cpuid. | ||||
| jz .print_long_error | ||||
| 
 | ||||
| mov eax, 0x00000001 | ||||
| cpuid | ||||
| and edx, 0x00000200 | ||||
| jz .print_apic_error | ||||
| 
 | ||||
| 
 | ||||
| mov bx, .no_error | ||||
| mov cx, 0 | ||||
| call bios_print | ||||
| 
 | ||||
| 
 | ||||
| ;mapping memory | ||||
| mov ax, 0 | ||||
| mov es, ax | ||||
| mov ax, _meminfo_loc | ||||
| mov di, ax | ||||
| 
 | ||||
| mov eax, 0xe820 | ||||
| mov ebx, 0 | ||||
| mov ecx, 24 | ||||
| mov edx, 0x534d4150 | ||||
| int 0x15 | ||||
| 
 | ||||
| jc .print_mem_error | ||||
| cmp eax, 0x534D4150 | ||||
| jne .print_mem_error | ||||
| 
 | ||||
| .mem_detect_loop: | ||||
| add di, 24 | ||||
| mov [di + 20], dword 1 | ||||
| mov eax, 0xe820 | ||||
| mov ecx, 24 | ||||
| 
 | ||||
| int 0x15 | ||||
| jc .mem_detected | ||||
| cmp ebx, 0 | ||||
| je .mem_detected | ||||
| jmp .mem_detect_loop | ||||
| .mem_detected: | ||||
| 
 | ||||
| ret | ||||
| 
 | ||||
| 
 | ||||
| .print_cpuid_error: | ||||
| mov bx, .cpuid_error | ||||
| mov cx, 0 | ||||
| call bios_print | ||||
| jmp $ | ||||
| 
 | ||||
| .print_long_error: | ||||
| mov bx, .arch_error ; lets just test for now | ||||
| mov cx, 0 | ||||
| call bios_print | ||||
| jmp $ | ||||
| 
 | ||||
| .print_apic_error: | ||||
| mov bx, .apic_error | ||||
| mov cx, 0 | ||||
| call bios_print | ||||
| 
 | ||||
| .print_mem_error: | ||||
| mov bx, .mem_error | ||||
| mov cx, 0 | ||||
| call bios_print | ||||
| 
 | ||||
| 
 | ||||
| .cpuid_error: | ||||
|   db "No CPUID capabilitity", 0x0 | ||||
| .arch_error: | ||||
|  db "This operating system was compiled to run in 64 bit mode!", 0x0 | ||||
| .apic_error: | ||||
|   db "No apic support", 0x0 | ||||
| .mem_error: | ||||
|   db "Could not get information on memory!", 0x0 | ||||
| .no_error: | ||||
|   db "CPU info gathered!", 0x0 | ||||
| 
 | ||||
							
								
								
									
										80
									
								
								src/bootloader/enter_kernel.asm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								src/bootloader/enter_kernel.asm
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,80 @@ | ||||
| [extern main] | ||||
| [extern _kernel_stack_loc] | ||||
| enter_longmode: | ||||
| cli | ||||
| 
 | ||||
| ; TODO check if a20 is already set | ||||
| mov al, 0x92 | ||||
| or al, 2 | ||||
| out 0x92, al | ||||
| 
 | ||||
| lgdt [protected_gdt.descriptor] | ||||
| mov eax, cr0 | ||||
| or eax, 0x1 | ||||
| mov cr0, eax | ||||
| 
 | ||||
| mov eax, 0x8 | ||||
| mov ds, eax | ||||
| 
 | ||||
| jmp 0x8:init_longmode | ||||
| 
 | ||||
| bits 32 | ||||
| init_longmode: | ||||
| mov ebp, 0xffff | ||||
| mov esp, ebp | ||||
| mov ax, PROTECTED_DATA_SEGMENT | ||||
| mov ds, ax | ||||
| mov ss, ax | ||||
| mov es, ax | ||||
| mov fs, ax | ||||
| mov gs, ax | ||||
| 
 | ||||
| mov edi, 0x4000 ; 0x3000 | ||||
| mov cr3, edi      | ||||
| mov eax, 0       | ||||
| mov ecx, 0xc00 ; 0x1000 | ||||
| rep stosd        | ||||
| mov edi, cr3 | ||||
| 
 | ||||
| 
 | ||||
| mov DWORD [edi], 0x5003 ; pml4e[0] = pdpe | ||||
| add edi, 0x1000 | ||||
| mov DWORD [edi], 0x6003 ; pdpe[0] = pde | ||||
| add edi, 0x1000 | ||||
| mov DWORD [edi], 0x83 ; pde[0] = pte | ||||
| 
 | ||||
| mov eax, cr4          | ||||
| or eax, 1 << 5      | ||||
| mov cr4, eax          | ||||
| 
 | ||||
| ;end of setting up pages | ||||
| 
 | ||||
| mov ecx, 0xc0000080 | ||||
| rdmsr | ||||
| or eax, 1 << 8 | ||||
| wrmsr | ||||
| 
 | ||||
| mov eax, cr0 | ||||
| or eax, 1 << 31 | 1 << 0 ; this is where we set paging and protected mode (respectively)! | ||||
| mov cr0, eax | ||||
| 
 | ||||
| 
 | ||||
| mov ecx, 0xc0000080 | ||||
| rdmsr | ||||
| or eax, 1 << 8 | ||||
| wrmsr | ||||
| 
 | ||||
| mov eax, cr0 | ||||
| or eax, 1 << 31 | ||||
| mov cr0, eax | ||||
| 
 | ||||
| lgdt [long_gdt.descriptor] | ||||
| 
 | ||||
| jmp LONG_CODE_SEGMENT:enter_kernel | ||||
| enter_kernel: | ||||
| bits 64 | ||||
| mov rbp, _kernel_stack_loc | ||||
| mov rsp, _kernel_stack_loc | ||||
| call main ; where we actually call the kernel | ||||
| jmp $ | ||||
| ret | ||||
							
								
								
									
										87
									
								
								src/bootloader/enter_kernel_backup
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								src/bootloader/enter_kernel_backup
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,87 @@ | ||||
| [extern main] | ||||
| [extern _kernel_stack_loc] | ||||
| enter_longmode: | ||||
| cli | ||||
| 
 | ||||
| ; TODO check if a20 is already set | ||||
| mov al, 0x92 | ||||
| or al, 2 | ||||
| out 0x92, al | ||||
| 
 | ||||
| lgdt [protected_gdt.descriptor] | ||||
| mov eax, cr0 | ||||
| or eax, 0x1 | ||||
| mov cr0, eax | ||||
| 
 | ||||
| mov eax, 0x8 | ||||
| mov ds, eax | ||||
| 
 | ||||
| jmp 0x8:init_longmode | ||||
| 
 | ||||
| bits 32 | ||||
| init_longmode: | ||||
| mov ebp, 0xffff | ||||
| mov esp, ebp | ||||
| mov ax, PROTECTED_DATA_SEGMENT | ||||
| mov ds, ax | ||||
| mov ss, ax | ||||
| mov es, ax | ||||
| mov fs, ax | ||||
| mov gs, ax | ||||
| 
 | ||||
| mov edi, 0x3000 ; this is where our page tables will be | ||||
| mov cr3, edi      | ||||
| mov eax, 0      ; what we'll be putting there | ||||
| mov ecx, 4096   ; how many times we'll put it there | ||||
| rep stosd       ; kinda like memset(&edi, ecx, edi) | ||||
| mov edi, cr3 | ||||
| 
 | ||||
| mov DWORD [edi], 0x4003 ; pml4e[0] = pdpe | ||||
| add edi, 0x1000 | ||||
| mov DWORD [edi], 0x5003 ; pdpe[0] = pde | ||||
| add edi, 0x1000 | ||||
| mov DWORD [edi], 0x6003 ; pde[0] = pte | ||||
| add edi, 0x1000 | ||||
| 
 | ||||
| mov ebx, 0x00000003 ; the flags | ||||
| mov ecx, 512; the loop counter, will map 2 mib | ||||
| 
 | ||||
| .idmap_pte_loop: | ||||
| mov DWORD [edi], ebx | ||||
| add ebx, 0x1000 ; physical address. Should leave us at 0x7000 | ||||
| add edi, 8      ; position in page table | ||||
| loop .idmap_pte_loop | ||||
| 
 | ||||
| mov eax, cr4          | ||||
| or eax, 1 << 5      | ||||
| mov cr4, eax          | ||||
| 
 | ||||
| mov ecx, 0xc0000080 | ||||
| rdmsr | ||||
| or eax, 1 << 8 | ||||
| wrmsr | ||||
| 
 | ||||
| mov eax, cr0 | ||||
| or eax, 1 << 31 | 1 << 0 ; this is where we set paging and protected mode (respectively)! | ||||
| mov cr0, eax | ||||
| 
 | ||||
| 
 | ||||
| mov ecx, 0xc0000080 | ||||
| rdmsr | ||||
| or eax, 1 << 8 | ||||
| wrmsr | ||||
| 
 | ||||
| mov eax, cr0 | ||||
| or eax, 1 << 31 | ||||
| mov cr0, eax | ||||
| 
 | ||||
| lgdt [long_gdt.descriptor] | ||||
| 
 | ||||
| jmp LONG_CODE_SEGMENT:enter_kernel | ||||
| enter_kernel: | ||||
| bits 64 | ||||
| mov rbp, _kernel_stack_loc | ||||
| mov rsp, _kernel_stack_loc | ||||
| call main ; where we actually call the kernel | ||||
| jmp $ | ||||
| ret | ||||
							
								
								
									
										70
									
								
								src/bootloader/gdt.asm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								src/bootloader/gdt.asm
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,70 @@ | ||||
| protected_gdt: | ||||
| .gdt_start: ; we need to start with a null gdt | ||||
| dd 0 | ||||
| dd 0 | ||||
| 
 | ||||
| .gdt_code: | ||||
| dw 0xffff | ||||
| dw 0x0000 | ||||
| db 0x00 | ||||
| db 10011010b  | ||||
| db 11001111b | ||||
| db 0x0000 | ||||
| 
 | ||||
| 
 | ||||
| .gdt_data: | ||||
| dw 0xffff | ||||
| dw 0x0000 | ||||
| db 0x00 | ||||
| db 10010010b  | ||||
| db 11001111b | ||||
| db 0x0000 | ||||
| 
 | ||||
| .gdt_end: | ||||
| 
 | ||||
| .descriptor:  | ||||
|   dw .gdt_end - .gdt_start - 1  | ||||
| dq .gdt_start | ||||
| 
 | ||||
| PROTECTED_CODE_SEGMENT equ .gdt_code - .gdt_start | ||||
| PROTECTED_DATA_SEGMENT equ .gdt_data - .gdt_start | ||||
| 
 | ||||
| 
 | ||||
| long_gdt: | ||||
| .gdt_start: | ||||
| ;and now we set up a temporary GDT creating a 1:1 mapping | ||||
| dw 0xffff | ||||
| dw 0 | ||||
| db 0 ;this is the invalid GDT | ||||
| db 0 | ||||
| db 1 | ||||
| db 0 | ||||
| 
 | ||||
| ;now for the code GDT: | ||||
| .gdt_code: | ||||
| dw 0 ; segment limit 15:00 (I don't think this matters in 64 bit mode!) | ||||
| dw 0 ; base address 15:00 | ||||
| db 0 ; base address 23:16 | ||||
| db 10011010b  ;1st flags and type. The first four bits (1010) are type, and the last are flags. See https://www.cs.bham.ac.uk/~exr/lectures/opsys/10_11/lectures/os-dev.pdf | ||||
| db 10101111b  ;1111 is segment limit continued. 0: available, 0: 64 bit (change?), 1: 32 bit segment, 1: granularity (shifts 3 hex didgets to get all of memory) | ||||
| db 0 | ||||
| 
 | ||||
| ; the data GDT is the exact same, and it overlaps. We don't care, we'll be booting into long mode right after then programming in C | ||||
| ; TODO: clarify once you figure out what you're doing | ||||
| .gdt_data: | ||||
| dw 0  | ||||
| dw 0  | ||||
| db 0  | ||||
| db 10010010b   | ||||
| db 00000000b   | ||||
| db 0 | ||||
| 
 | ||||
| .gdt_end: ; later calculates offset in defs below | ||||
| 
 | ||||
| 
 | ||||
| .descriptor:  | ||||
|   dw .gdt_end - .gdt_start - 1  | ||||
| dq .gdt_start | ||||
| 
 | ||||
| LONG_CODE_SEGMENT equ .gdt_code - .gdt_start | ||||
| LONG_DATA_SEGMENT equ .gdt_data - .gdt_start | ||||
							
								
								
									
										10
									
								
								src/bootloader/multicore.asm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								src/bootloader/multicore.asm
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,10 @@ | ||||
| multicore_boot: | ||||
| jmp $ | ||||
| 
 | ||||
| mov ecx, 0x0000001b | ||||
| rdmsr | ||||
| ;mov [apic_register] dx:ax | ||||
| 
 | ||||
| apic_register: dq 0 | ||||
| multicore_msg1: db "CPUs available: ", 0 | ||||
| 
 | ||||
							
								
								
									
										0
									
								
								src/bootloader/notes
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								src/bootloader/notes
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										179
									
								
								src/bootloader/video.asm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										179
									
								
								src/bootloader/video.asm
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,179 @@ | ||||
| [extern _vbe_infoblock] | ||||
| vbe_init: | ||||
| .init_video: | ||||
| ;getting edid | ||||
| 
 | ||||
| mov ax, 0 | ||||
| mov es, ax | ||||
| mov di, 0x500 | ||||
| 
 | ||||
| mov ax, 0x4f15 | ||||
| mov bx, 0x1 | ||||
| mov cx, 0  | ||||
| mov dx, 0 | ||||
| 
 | ||||
| int 0x10 | ||||
| 
 | ||||
| cmp al, 0x4f | ||||
| jne .vbe_unsupported | ||||
| cmp ah, 0x00 | ||||
| jne .edid_error | ||||
| 
 | ||||
| 
 | ||||
| mov ah, [0x500+58] | ||||
| shr ah, 4 | ||||
| mov al, [0x500+56] | ||||
| push ax | ||||
| 
 | ||||
| mov ah, [0x500+61] | ||||
| shr ah, 4 | ||||
| mov al, [0x500+59] | ||||
| push ax | ||||
| 
 | ||||
| mov al, BYTE [0x500+20] | ||||
| test al, 0x80 | ||||
| jz .res_unsupported ; uses an analog signal | ||||
| 
 | ||||
| shr al, 4 | ||||
| and al, 7 | ||||
| 
 | ||||
| .cdp_6: | ||||
| cmp al, 0b001 | ||||
| jne .cdp_8 | ||||
| mov ax, 18 | ||||
| jmp .colordepth_found | ||||
| 
 | ||||
| .cdp_8: | ||||
| cmp al, 0b010 | ||||
| jne .cdp_10 | ||||
| mov ax, 24 | ||||
| jmp .colordepth_found | ||||
| 
 | ||||
| .cdp_10: | ||||
| cmp al, 0b011 | ||||
| jne .cdp_12 | ||||
| mov ax, 30 | ||||
| jmp .colordepth_found | ||||
| 
 | ||||
| .cdp_12: | ||||
| cmp al, 0b100 | ||||
| jne .cdp_14 | ||||
| mov ax, 36 | ||||
| jmp .colordepth_found | ||||
| 
 | ||||
| .cdp_14: | ||||
| cmp al, 0b101 | ||||
| jne .cdp_16 | ||||
| mov ax, 42 | ||||
| jmp .colordepth_found | ||||
| 
 | ||||
| .cdp_16: | ||||
| cmp al, 0b110 | ||||
| jne .cdp_undefined | ||||
| mov ax, 48 | ||||
| jmp .colordepth_found | ||||
| 
 | ||||
| .cdp_undefined: | ||||
| mov ax, 24 | ||||
| ; TODO print warning, this only happens when we can't find bitdepth | ||||
| 
 | ||||
| .colordepth_found: | ||||
| push ax | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| ; _______________________________________________________________________________________________________ | ||||
| 
 | ||||
| ; When we get things sorted out, some time you should come back here and find a good resolution that isn't | ||||
| ; native as a fallback. | ||||
| ; Maybe redo this part in C? | ||||
| 
 | ||||
| ;getting available modes | ||||
| mov ax, 0 | ||||
| mov es, ax | ||||
| mov ax, 0x500  | ||||
| mov di, ax | ||||
| 
 | ||||
| ;get vbe capabilities | ||||
| mov ax, 0x4f00 | ||||
| int 0x10 | ||||
| cmp ax, 0x4f | ||||
| jne .vbe_generic_error | ||||
| cmp DWORD [0x500], "VESA" | ||||
| jne .vbe_generic_error | ||||
| 
 | ||||
| ; now we loop through the modes | ||||
| mov ebx, [0x500+14] ; pointer to modes | ||||
| mov di, 0x600 | ||||
| mov ax, 0 | ||||
| mov es, ax | ||||
| .mode_loop: | ||||
| mov ax, 0x4f01  | ||||
| mov cx, [ebx] | ||||
| cmp cx, 0xffff | ||||
| je .res_unsupported | ||||
| 
 | ||||
| int 0x10 | ||||
| 
 | ||||
| mov ax, [esp] | ||||
| cmp al, BYTE [0x600+25] ; might be wrong | ||||
| jne .mode_loop_next | ||||
| 
 | ||||
| ; width (1920) | ||||
| mov ax, [esp+4] | ||||
| cmp ax, [0x600+18] | ||||
| jne .mode_loop_next | ||||
| 
 | ||||
| ; height | ||||
| mov ax, [esp+2] | ||||
| cmp ax, [0x600+20] | ||||
| jne .mode_loop_next | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| jmp .mode_found | ||||
| 
 | ||||
| .mode_loop_next: | ||||
| add ebx, 2 | ||||
| jmp .mode_loop | ||||
|   | ||||
| .mode_found: | ||||
| mov ax, 0x4f02  | ||||
| mov bx, cx | ||||
| int 0x10 | ||||
| ;getting rid of stack | ||||
| pop ax | ||||
| pop ax | ||||
| pop ax | ||||
| ret | ||||
| ; ________________________________________________________________________________________________________ | ||||
| 
 | ||||
| .vbe_unsupported: | ||||
| mov bx, .unsupported_msg | ||||
| mov cx, 0 | ||||
| call bios_print | ||||
| jmp $ | ||||
| 
 | ||||
| .vbe_generic_error: | ||||
| mov bx, .lazyerror_msg | ||||
| mov cx, 0 | ||||
| call bios_print | ||||
| jmp $ | ||||
| 
 | ||||
| .edid_error: | ||||
| mov bx, .ediderror_msg | ||||
| mov cx, 0 | ||||
| call bios_print | ||||
| jmp $ | ||||
| 
 | ||||
| .res_unsupported: | ||||
| mov bx, .res_unsupported_msg | ||||
| mov cx, 0 | ||||
| call bios_print | ||||
| jmp $ | ||||
| 
 | ||||
| .unsupported_msg: db "Your BIOS doesn't support VESA. It's probably time to get a new computer!", 0 | ||||
| .lazyerror_msg: db "A VESA error has occured.", 0 | ||||
| .ediderror_msg: db "EDID error", 0 | ||||
| .res_unsupported_msg: db "Native resolution not supported!", 0 | ||||
							
								
								
									
										4
									
								
								src/debug/.gdb_history
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								src/debug/.gdb_history
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,4 @@ | ||||
| quit | ||||
| quit | ||||
| c | ||||
| quit | ||||
							
								
								
									
										
											BIN
										
									
								
								src/indigo_os
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								src/indigo_os
									
									
									
									
									
										Executable file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										39
									
								
								src/kernel/include/acpi.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								src/kernel/include/acpi.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,39 @@ | ||||
| #include <stdint.h> | ||||
| #include <libc.h> | ||||
| 
 | ||||
| struct rsdp_v1 { | ||||
|   char sig[8]; | ||||
|   uint8_t checksum; | ||||
|   char OEMID[6]; | ||||
|   uint8_t version; | ||||
|   uint32_t rsdt_addr; | ||||
| 
 | ||||
| } __attribute__((packed)); | ||||
| 
 | ||||
| struct rsdp_v2 { | ||||
|   struct rsdp_v1 v1; | ||||
|   uint32_t len; | ||||
|   uint64_t xsdt_addr; | ||||
|   uint8_t extended_checksum; | ||||
|   uint8_t reserved[3];  | ||||
| } __attribute__((packed)); | ||||
| 
 | ||||
| 
 | ||||
| typedef union rsdp_t {  | ||||
|   struct rsdp_v1 v1; | ||||
|   struct rsdp_v2 v2; | ||||
| } rsdp_t; | ||||
| 
 | ||||
| struct acpi_header { | ||||
|   char sig[4]; | ||||
|   uint32_t length; | ||||
|   uint8_t revision; | ||||
|   uint8_t checksum; | ||||
|   char OEMID[6]; | ||||
|   char OEMTableID[8]; | ||||
|   uint32_t OEMRevision; | ||||
|   uint32_t creator_id; | ||||
|   uint32_t creator_revision; | ||||
| } __attribute__((packed)); | ||||
| 
 | ||||
| rsdp_t *find_RSDP(); | ||||
							
								
								
									
										10
									
								
								src/kernel/include/libc.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								src/kernel/include/libc.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,10 @@ | ||||
| #ifndef _STRING_H_ | ||||
| #define _STRING_H_ | ||||
| #include <stddef.h> | ||||
| 
 | ||||
| int strcmp(const char *str1, const char *str2); | ||||
| int strncmp(const char *str1, const char *str2, size_t n); | ||||
| void strcpy(char *dest, char *src); | ||||
| void memcpy(void *dest, void *src, size_t n); //TODO
 | ||||
| int memcmp(const void *s1, const void *s2, size_t n); | ||||
| #endif | ||||
							
								
								
									
										60
									
								
								src/kernel/include/paging.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								src/kernel/include/paging.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,60 @@ | ||||
| #include <stdbool.h> | ||||
| //paging errors
 | ||||
| #define PAGEMAP_LOCATION 0x4000 | ||||
| #ifndef _PAGE_H_ | ||||
| #define _PAGE_H_  | ||||
| #include <stdint.h> | ||||
| 
 | ||||
| #define PAGE_VIRT_UNALIGNED 0x01  | ||||
| #define PAGE_PHYS_UNALIGNED 0x02 | ||||
| #define PAGE_PHYS_INVALID   0x03 | ||||
| #define PAGE_VIRT_INVALID   0x04 | ||||
| 
 | ||||
| //*
 | ||||
| typedef struct __attribute__((packed)) { | ||||
|   unsigned int present : 1;            // present, must be one when accessed.
 | ||||
|   unsigned int read_write : 1;         // if set to one, read and write is set
 | ||||
|   unsigned int user : 1;               // another bit we'll never use, for seperating CPL 0-2 and 3+
 | ||||
|   unsigned int writethrough_cache : 1; // honestly maybe I should look into caching
 | ||||
|   unsigned int cachable : 1;           // hardware chaching. 0 is enabled, whats the worst that could happen? 
 | ||||
|   unsigned int accessed : 1;           // we'll never use any of these!
 | ||||
|   unsigned int zg0 : 1;                // needs to be (and will be) zero'd
 | ||||
|   unsigned int size : 1; | ||||
|   unsigned int zg1 : 1;                // needs to be (and will be) zero'd
 | ||||
|   unsigned int software_marks : 3;     // available for our own use, I doubt we'll use it in such a simple thing
 | ||||
|    | ||||
|   uintptr_t base_ptr : 40; | ||||
|   unsigned int available:11; | ||||
| } page_entry; | ||||
| 
 | ||||
| 
 | ||||
| typedef struct __attribute__((packed)) { | ||||
|   page_entry pml4e[512]; | ||||
|   page_entry pdpe[512]; | ||||
|   page_entry pde[512]; | ||||
|   page_entry pte[512]; | ||||
| } page_table; | ||||
| 
 | ||||
| #define MEM_AVAILABLE             0 | ||||
| #define MEM_RESERVED              1 | ||||
| #define MEM_APCI_RECLAIMABLE      2 | ||||
| #define MEM_APCI_NVS              3 | ||||
| #define MEM_BAD                   4 | ||||
| 
 | ||||
| #define PAGE_SIZE_4K              12 | ||||
| #define PAGE_SIZE_2M              21 | ||||
| #define PAGE_SIZE_1G              30 | ||||
| 
 | ||||
| struct memory_table { | ||||
|   uint64_t base; | ||||
|   uint64_t length; | ||||
|   uint32_t type; | ||||
|   uint32_t ACPI; //we'll never use this
 | ||||
| } __attribute__((packed)); | ||||
| 
 | ||||
| 
 | ||||
| extern void* _meminfo_loc; | ||||
| 
 | ||||
| bool map_page(uintptr_t virtual_addr, uintptr_t physical_addr, uint8_t PAGE_SIZE); | ||||
| void debug_print_memory(); | ||||
| #endif | ||||
							
								
								
									
										117
									
								
								src/kernel/include/printf.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										117
									
								
								src/kernel/include/printf.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,117 @@ | ||||
| ///////////////////////////////////////////////////////////////////////////////
 | ||||
| // \author (c) Marco Paland (info@paland.com)
 | ||||
| //             2014-2019, PALANDesign Hannover, Germany
 | ||||
| //
 | ||||
| // \license The MIT License (MIT)
 | ||||
| //
 | ||||
| // Permission is hereby granted, free of charge, to any person obtaining a copy
 | ||||
| // of this software and associated documentation files (the "Software"), to deal
 | ||||
| // in the Software without restriction, including without limitation the rights
 | ||||
| // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | ||||
| // copies of the Software, and to permit persons to whom the Software is
 | ||||
| // furnished to do so, subject to the following conditions:
 | ||||
| // 
 | ||||
| // The above copyright notice and this permission notice shall be included in
 | ||||
| // all copies or substantial portions of the Software.
 | ||||
| // 
 | ||||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | ||||
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | ||||
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | ||||
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | ||||
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | ||||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | ||||
| // THE SOFTWARE.
 | ||||
| //
 | ||||
| // \brief Tiny printf, sprintf and snprintf implementation, optimized for speed on
 | ||||
| //        embedded systems with a very limited resources.
 | ||||
| //        Use this instead of bloated standard/newlib printf.
 | ||||
| //        These routines are thread safe and reentrant.
 | ||||
| //
 | ||||
| ///////////////////////////////////////////////////////////////////////////////
 | ||||
| 
 | ||||
| #ifndef _PRINTF_H_ | ||||
| #define _PRINTF_H_ | ||||
| 
 | ||||
| #include <stdarg.h> | ||||
| #include <stddef.h> | ||||
| 
 | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
| extern "C" { | ||||
| #endif | ||||
| 
 | ||||
| 
 | ||||
| /**
 | ||||
|  * Output a character to a custom device like UART, used by the printf() function | ||||
|  * This function is declared here only. You have to write your custom implementation somewhere | ||||
|  * \param character Character to output | ||||
|  */ | ||||
| void _putchar(char character); | ||||
| 
 | ||||
| 
 | ||||
| /**
 | ||||
|  * Tiny printf implementation | ||||
|  * You have to implement _putchar if you use printf() | ||||
|  * To avoid conflicts with the regular printf() API it is overridden by macro defines | ||||
|  * and internal underscore-appended functions like printf_() are used | ||||
|  * \param format A string that specifies the format of the output | ||||
|  * \return The number of characters that are written into the array, not counting the terminating null character | ||||
|  */ | ||||
| #define printf printf_ | ||||
| int printf_(const char* format, ...); | ||||
| 
 | ||||
| 
 | ||||
| /**
 | ||||
|  * Tiny sprintf implementation | ||||
|  * Due to security reasons (buffer overflow) YOU SHOULD CONSIDER USING (V)SNPRINTF INSTEAD! | ||||
|  * \param buffer A pointer to the buffer where to store the formatted string. MUST be big enough to store the output! | ||||
|  * \param format A string that specifies the format of the output | ||||
|  * \return The number of characters that are WRITTEN into the buffer, not counting the terminating null character | ||||
|  */ | ||||
| #define sprintf sprintf_ | ||||
| int sprintf_(char* buffer, const char* format, ...); | ||||
| 
 | ||||
| 
 | ||||
| /**
 | ||||
|  * Tiny snprintf/vsnprintf implementation | ||||
|  * \param buffer A pointer to the buffer where to store the formatted string | ||||
|  * \param count The maximum number of characters to store in the buffer, including a terminating null character | ||||
|  * \param format A string that specifies the format of the output | ||||
|  * \param va A value identifying a variable arguments list | ||||
|  * \return The number of characters that COULD have been written into the buffer, not counting the terminating | ||||
|  *         null character. A value equal or larger than count indicates truncation. Only when the returned value | ||||
|  *         is non-negative and less than count, the string has been completely written. | ||||
|  */ | ||||
| #define snprintf  snprintf_ | ||||
| #define vsnprintf vsnprintf_ | ||||
| int  snprintf_(char* buffer, size_t count, const char* format, ...); | ||||
| int vsnprintf_(char* buffer, size_t count, const char* format, va_list va); | ||||
| 
 | ||||
| 
 | ||||
| /**
 | ||||
|  * Tiny vprintf implementation | ||||
|  * \param format A string that specifies the format of the output | ||||
|  * \param va A value identifying a variable arguments list | ||||
|  * \return The number of characters that are WRITTEN into the buffer, not counting the terminating null character | ||||
|  */ | ||||
| #define vprintf vprintf_ | ||||
| int vprintf_(const char* format, va_list va); | ||||
| 
 | ||||
| 
 | ||||
| /**
 | ||||
|  * printf with output function | ||||
|  * You may use this as dynamic alternative to printf() with its fixed _putchar() output | ||||
|  * \param out An output function which takes one character and an argument pointer | ||||
|  * \param arg An argument pointer for user data passed to output function | ||||
|  * \param format A string that specifies the format of the output | ||||
|  * \return The number of characters that are sent to the output function, not counting the terminating null character | ||||
|  */ | ||||
| int fctprintf(void (*out)(char character, void* arg), void* arg, const char* format, ...); | ||||
| 
 | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| 
 | ||||
| #endif  // _PRINTF_H_
 | ||||
							
								
								
									
										16
									
								
								src/kernel/include/serial.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								src/kernel/include/serial.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,16 @@ | ||||
| //these com values are just guesses! Figure out how to find em later if you want
 | ||||
| #ifndef _SERIAL_H_ | ||||
| #define _SERIAL_H_ | ||||
| 
 | ||||
| #include <stdint.h> | ||||
| #define COM1 0x3f8 | ||||
| #define COM2 0x2f8 | ||||
| #define COM3 0x3e8 | ||||
| #define COM4 0x2e8 | ||||
| 
 | ||||
| 
 | ||||
| int init_serial(uint16_t port); | ||||
| void serial_out(uint16_t port, char *string); | ||||
| void _putchar_serial(uint16_t port, char character); | ||||
| 
 | ||||
| #endif | ||||
							
								
								
									
										49
									
								
								src/kernel/include/video.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								src/kernel/include/video.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,49 @@ | ||||
| #include <stdint.h> | ||||
| void dump_video(); | ||||
| 
 | ||||
| //this struct was stolen from wiki.osdev.org
 | ||||
| struct mode_info { | ||||
|   uint16_t attributes;		 | ||||
| 	uint8_t window_a;			 | ||||
| 	uint8_t window_b;			 | ||||
| 	uint16_t granularity;		 | ||||
| 	uint16_t window_size; | ||||
| 	uint16_t segment_a; | ||||
| 	uint16_t segment_b; | ||||
| 	uint32_t win_func_ptr;		 | ||||
| 	uint16_t pitch;			 | ||||
| 	uint16_t width;			 | ||||
| 	uint16_t height;			 | ||||
| 	uint8_t w_char;			 | ||||
| 	uint8_t y_char;			 | ||||
| 	uint8_t planes; | ||||
| 	uint8_t bpp;			 | ||||
| 	uint8_t banks;			 | ||||
| 	uint8_t memory_model; | ||||
| 	uint8_t bank_size;		 | ||||
| 	uint8_t image_pages; | ||||
| 	uint8_t reserved0; | ||||
| 	uint8_t red_mask; | ||||
| 	uint8_t red_position; | ||||
| 	uint8_t green_mask; | ||||
| 	uint8_t green_position; | ||||
| 	uint8_t blue_mask; | ||||
| 	uint8_t blue_position; | ||||
| 	uint8_t reserved_mask; | ||||
| 	uint8_t reserved_position; | ||||
| 	uint8_t direct_color_attributes; | ||||
| 
 | ||||
| 	uint32_t framebuffer;		 | ||||
| 	uint32_t off_screen_mem_off; | ||||
| 	uint16_t off_screen_mem_size;	 | ||||
| 	uint8_t reserved1[206]; | ||||
| } __attribute__((packed)); | ||||
| 
 | ||||
| struct vbe_infoblock { | ||||
|   char vbe_signature[4]; | ||||
|   uint16_t vbe_version; | ||||
|   uint16_t oem_ptr[2]; | ||||
|   uint8_t capabilities[4]; | ||||
|   uint32_t videomodeptr; | ||||
|   uint16_t total_memory; | ||||
| } __attribute__((packed)); | ||||
							
								
								
									
										42
									
								
								src/kernel/kernel.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								src/kernel/kernel.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,42 @@ | ||||
| #include <stdbool.h> | ||||
| #include <serial.h> | ||||
| #include <printf.h> | ||||
| #include <paging.h> | ||||
| #include <video.h> | ||||
| #include <acpi.h> | ||||
| 
 | ||||
| void panic() { // will fill with debugging info latter
 | ||||
|   printf("Kernel panic!\n"); | ||||
|   for(;;); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| void main() { | ||||
|   if(!(init_serial(COM1))) { | ||||
|     printf("\nKernal started on CPU 1!\n"); // will detect cpu later
 | ||||
|   } | ||||
| 
 | ||||
|   rsdp_t *rsdp; | ||||
|   struct memory_table *table = (struct memory_table *)&_meminfo_loc; | ||||
|   struct vbe_infoblock *vbe_info = (struct vbe_infoblock *)0x500; | ||||
|   debug_print_memory(); | ||||
| 
 | ||||
|   rsdp = find_RSDP(); | ||||
|   if(!(rsdp)) { | ||||
|     printf("Couldn't find the RSDP... uhh, not sure what to do now.\n"); | ||||
|     panic(); | ||||
|   } | ||||
|   dump_video(); | ||||
|    | ||||
|   if(rsdp->v1.version) {  | ||||
|     map_page(0x200000, (rsdp->v2.xsdt_addr / 0x1000) * 0x1000, PAGE_SIZE_4K); | ||||
|   } | ||||
|   else { | ||||
|     map_page(0x200000, (rsdp->v1.rsdt_addr / 0x1000) * 0x1000, PAGE_SIZE_4K); | ||||
|     struct acpi_header *acpi = (struct acpi_header *)((uint64_t)0x200000 + (rsdp->v1.rsdt_addr % 0x1000)); | ||||
|   } | ||||
| 
 | ||||
|   printf("kernel is done, you can ignore this panic\n"); | ||||
|   panic(); | ||||
| 
 | ||||
| } | ||||
							
								
								
									
										61
									
								
								src/kernel/libs/acpi.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								src/kernel/libs/acpi.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,61 @@ | ||||
| #include <acpi.h> | ||||
| #include <stdint.h> | ||||
| #include <printf.h> | ||||
| 
 | ||||
| static int RSDP_verify(void *rsdp_pointer) { | ||||
|   printf("Verifying potential RSDP at address 0x%p... ", rsdp_pointer);   | ||||
|   union rsdp_t *rsdp = rsdp_pointer; | ||||
|   uint8_t checksum = 0; | ||||
|   char *rsdp_csm_ptr = rsdp_pointer;  | ||||
|   int i; | ||||
|   if(checksum) return 0; | ||||
|   if(rsdp->v1.version) { | ||||
|     printf("APCI revision > 2.\n"); | ||||
|     checksum = 0; | ||||
|     printf("len : %i\n", rsdp->v2.len); | ||||
|     for(i = 0; i < rsdp->v2.len; i++) { | ||||
|       checksum += rsdp_csm_ptr[i]; | ||||
|     } | ||||
|   } | ||||
|   else { | ||||
|     printf("APCI revision 1.\n"); | ||||
|     for(i = 0; i <= 20; i++) { | ||||
|       checksum += rsdp_csm_ptr[i]; | ||||
|     } | ||||
|   } | ||||
|   if(checksum) { | ||||
|     return 0; | ||||
|     printf("Invalid, searching on.\n"); | ||||
|   } | ||||
|   printf("RSDP Verified!\n"); | ||||
|   return 1; | ||||
| } | ||||
| 
 | ||||
| // TODO: move these when you gain your sanity
 | ||||
| rsdp_t *find_RSDP() { // finds root descriptor
 | ||||
|   const char sig[9] = "RSD PTR "; | ||||
|   uintptr_t *p = (void *)0x040e; | ||||
|   uintptr_t *ebda_unshifted = (void *)p; | ||||
| 
 | ||||
|   // TODO you REALLY need to verify this.
 | ||||
|   void *ebda = (void *)((uintptr_t)ebda_unshifted << (uintptr_t)4 & (uintptr_t)0xfffff);  | ||||
| 
 | ||||
| 
 | ||||
|   for(void *i = ebda; i <= ebda + 64000; i += 16) { | ||||
|     if(!(memcmp(sig, i, 8))) { | ||||
|       if(RSDP_verify(i)) { | ||||
|         return(i); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   for(void *i = (void *)0xe0000; i <= (void *)0xfffff; i += 16) { | ||||
|     if(!(memcmp(sig, i, 8))) { | ||||
|       if(RSDP_verify(i)) { | ||||
|         return(i); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
							
								
								
									
										43
									
								
								src/kernel/libs/drivers/serial.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								src/kernel/libs/drivers/serial.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,43 @@ | ||||
| #include <stdint.h> | ||||
| #include <serial.h> | ||||
| //you can add more options if you need to later
 | ||||
| // PORT + 3: values are from bit zero (right) to left
 | ||||
| // dlab(1) | misteryyy bone(1) | paraty(3) | stop bits (1) | character length (2)
 | ||||
| static inline void outb(uint16_t port, uint8_t value) { | ||||
|   //here "a" is the a register, and "Nd" is inteter (I think?) in the d register
 | ||||
|   asm volatile( | ||||
|       "outb %0, %1" :: "a"(value), "Nd"(port) | ||||
|       ); | ||||
| } | ||||
| 
 | ||||
| static inline uint8_t inb(uint16_t port) { | ||||
|   uint8_t ret; | ||||
|   asm volatile( | ||||
|       "inb %1, %0" : "=a"(ret) : "Nd"(port) | ||||
|       ); | ||||
|   return(ret); | ||||
| } | ||||
| 
 | ||||
| int init_serial(uint16_t port) { | ||||
|   outb(port + 1, 0x00); // disable them fuckin interupts
 | ||||
|   outb(port + 3, 0x80); // sets dlab, allowing custom serial speeds
 | ||||
|   outb(port + 0, 0x06); // speed is 115200/6
 | ||||
|   outb(port + 1, 0x00); | ||||
|   outb(port + 3, 0x03); // disables dlab, as well as 8 bit char len, 1 stop bit, no paraty, no mystery
 | ||||
|   outb(port + 2, 0xc7); // I have no fucking clue what this means
 | ||||
|   outb(port + 4, 0x0b); // don't know what this means eather... delete if you can
 | ||||
|   outb(port + 4, 0x1e); // loopback mode (where the hell is this documented????)
 | ||||
| 
 | ||||
|   outb(port + 0, 0xae); // test char
 | ||||
| 
 | ||||
|   if(inb(port + 0) != 0xae) | ||||
|     return 1; | ||||
| 
 | ||||
|   outb(port + 4, 0x0f); // dissable interupts
 | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| void _putchar_serial(uint16_t port, char msg) { | ||||
|   while(!(inb(port + 5) & 0x20)); //wait for transmit to be doneroni
 | ||||
|   outb(port, msg); | ||||
| } | ||||
							
								
								
									
										6
									
								
								src/kernel/libs/drivers/video.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								src/kernel/libs/drivers/video.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,6 @@ | ||||
| #include <printf.h> | ||||
| #include <video.h> | ||||
| void dump_video() { | ||||
|   struct mode_info *video = (struct mode_info *)0x600; | ||||
|   printf("Video info:\nx:\t%u\ny:\t%u\nbbp:\t%u\nloc:\t0x%p\n", video->width, video->height, video->bpp, video->framebuffer); | ||||
| } | ||||
							
								
								
									
										47
									
								
								src/kernel/libs/libc.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								src/kernel/libs/libc.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,47 @@ | ||||
| #include <stddef.h> | ||||
| #include <stdint.h> | ||||
| //#include <printf.h>
 | ||||
| // you need to sort all these into diffrent files! TODO
 | ||||
| int strncmp(const char *s1, const char *s2, unsigned int n) { | ||||
|   int i; | ||||
|   for(i = 0; ((i <= n) && (s1[i] != '\0') && (s2[i] != '\0')); i++) { | ||||
|     if(s1[i] != s2[i]) { | ||||
|       return(s1[i] - s2[i]); | ||||
|     } | ||||
|   } | ||||
|   return(s1[i] - s2[i]); | ||||
| } | ||||
| 
 | ||||
| int strcmp(const char *s1, const char *s2) { | ||||
|   int i; | ||||
|   for(i = 0; ((s1[i] != '\0') && (s2[i] != '\0')); i++) { | ||||
|     if(s1[i] != s2[i]) { | ||||
|       return(s1[i] - s2[i]); | ||||
|     } | ||||
|   } | ||||
|   return(s1[i] - s2[i]); | ||||
| } | ||||
| 
 | ||||
| int memcmp(const void *s1, const void *s2, size_t n) { | ||||
|   const unsigned char *p1 = s1; // Why is c such a bitch? 
 | ||||
|   const unsigned char *p2 = s2; | ||||
|   int i; | ||||
|   for(i = 0; i < n; i++) { | ||||
|     if(p1[i] != p2[i]) { | ||||
|       return(p1[i] - p2[i]); | ||||
|     } | ||||
|   } | ||||
|   return(p1[n-1] - p2[n-1]); | ||||
| } | ||||
| 
 | ||||
| void strcpy(char *dest, char *src) { | ||||
|   for(unsigned int i = 0; src[i] != '\0'; i++){ | ||||
|     dest[i] = src[i]; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| void memcpy(char *dest, char *src, size_t n) { | ||||
|   for(unsigned int i = 0; i <= n; i++) { | ||||
|     dest[i] = src[i]; | ||||
|   } | ||||
| } | ||||
							
								
								
									
										107
									
								
								src/kernel/libs/page.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										107
									
								
								src/kernel/libs/page.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,107 @@ | ||||
| #include <printf.h> | ||||
| #include <paging.h> | ||||
| #include <stdint.h> | ||||
| 
 | ||||
| // for now, this will always remain the same. 
 | ||||
| // If this ever isn't the case, we'll add paramaters to the paging functions.
 | ||||
| // We will also never need to mess with many bits, 
 | ||||
| // as we are not implimenting security for a bare metal fractal generator.
 | ||||
| // Also, is this really the cleanest way to do things?
 | ||||
| 
 | ||||
| //after we get paging working, we can probably remove these structs and replace them with plain old uint_16ts.
 | ||||
| 
 | ||||
| void debug_print_memory() { | ||||
|   struct memory_table *memtable = (struct memory_table *)&_meminfo_loc;  | ||||
|   printf(" __________________________________________________________________________\n"); | ||||
|   printf("| type\tstart\t\t\tend\t\t\tsize\t\t   |\n"); | ||||
|   printf("|--------------------------------------------------------------------------|\n"); | ||||
|   for(unsigned int i = 0; memtable[i].length > 0; i++) { | ||||
|     printf("| %u %u\t0x%p\t0x%p\t0x%p |\n", memtable[i].type, memtable[i].ACPI, memtable[i].base, (memtable[i].base + memtable[i].length), memtable[i].length); | ||||
|   } | ||||
|   printf("----------------------------------------------------------------------------\n"); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| /**
 | ||||
|  * You can critisise the quality of this function all you want, it's messy due to planning mistakes | ||||
|  * and I'm planning on sanatising it.  | ||||
|  * BUT, don't critisise it _just_ for using goto, that's bullshit. See the following links. | ||||
|  *     | ||||
|  *    https://www.kernel.org/doc/html/v4.17/process/coding-style.html "goto" section
 | ||||
|  *    https://koblents.com/Ches/Links/Month-Mar-2013/20-Using-Goto-in-Linux-Kernel-Code/
 | ||||
| **/ | ||||
| 
 | ||||
| bool map_page(uintptr_t virtual_addr, uintptr_t physical_addr, uint8_t size) { | ||||
|   printf("map page called\n"); | ||||
|   if((virtual_addr % (1 << size)) || (physical_addr % (1 << size))) { | ||||
|     return 0;  | ||||
|   } | ||||
|   page_table *table = (page_table *)PAGEMAP_LOCATION; | ||||
|   int pte_i = (virtual_addr >> 12) & 0x1ff; | ||||
|   int pde_i = (virtual_addr >> 21) & 0x1ff; | ||||
|   int pdpe_i = (virtual_addr >> 30) & 0x1ff; | ||||
|   int pml4e_i = (virtual_addr >> 39) & 0x1ff; | ||||
|   //TODO remove this debugging info
 | ||||
|   printf("Virtual offsets:\npte:\t\t%i\npde:\t\t%i\npdpe:\t\t%i\npml4e\t\t%i\n", pte_i, pde_i, pdpe_i, pml4e_i); | ||||
| 
 | ||||
|   if(table->pml4e[pml4e_i].present) { | ||||
|     if(table->pml4e[pml4e_i].base_ptr != (uintptr_t)&table->pdpe[pdpe_i] >> 12) goto error; | ||||
|     if(table->pdpe[pdpe_i].present) { | ||||
|       if(size == PAGE_SIZE_1G) { | ||||
|         if(table->pdpe[pdpe_i].base_ptr == (uintptr_t)physical_addr >> 30 & 0x1ff) | ||||
|           return true; | ||||
|         goto error; | ||||
|       } | ||||
|       if(table->pdpe[pdpe_i].base_ptr != (uintptr_t)&table->pde[pde_i] >> 12) goto error; | ||||
| 
 | ||||
|       if(table->pde[pde_i].present) {  | ||||
|         if(size == PAGE_SIZE_2M) { | ||||
|           if(table->pde[pde_i].base_ptr == (uintptr_t)physical_addr >> 21 & 0x1ff) | ||||
|             return true; | ||||
|           goto error; | ||||
|         } | ||||
|         if(table->pde[pde_i].base_ptr != (uintptr_t)&table->pte[pte_i] >> 12) goto error; | ||||
|         if(table->pte[pte_i].present) { | ||||
|           if(table->pte[pte_i].base_ptr != ((physical_addr >> 12) & 0x1ff)) goto error; | ||||
|           return true; | ||||
|         } | ||||
|         else goto mod_page_pte; | ||||
|       } | ||||
|       else goto mod_page_pde; | ||||
|     } | ||||
|     else goto mod_page_pdpe; | ||||
|   } | ||||
|   else { | ||||
|     table->pml4e[pml4e_i].base_ptr = (uintptr_t)&table->pdpe[pdpe_i] >> 12; | ||||
|     table->pdpe[pml4e_i].read_write = 1; | ||||
|     table->pml4e[pml4e_i].present = 1; | ||||
| mod_page_pdpe: | ||||
|     table->pdpe[pdpe_i].read_write = 1; | ||||
|     if(size == PAGE_SIZE_1G) { | ||||
|       table->pdpe[pdpe_i].size = 1; | ||||
|       table->pdpe[pdpe_i].base_ptr = physical_addr >> 30; | ||||
|       table->pdpe[pdpe_i].present = 1; | ||||
|       return true; | ||||
|     } | ||||
|     table->pdpe[pdpe_i].base_ptr = (uintptr_t)&table->pde[pde_i] >> 12; | ||||
|     table->pdpe[pdpe_i].present = 1; | ||||
| mod_page_pde: | ||||
|     table->pde[pde_i].read_write = 1; | ||||
|     if(size == PAGE_SIZE_2M) { | ||||
|       table->pde[pde_i].size = 1; | ||||
|       table->pde[pde_i].base_ptr = physical_addr >> 21; | ||||
|       table->pde[pde_i].present = 1; | ||||
|       return true; | ||||
|     } | ||||
|     table->pde[pde_i].base_ptr = (uintptr_t)&table->pte[pte_i] >> 12; | ||||
|     table->pde[pde_i].present = 1; | ||||
| mod_page_pte: | ||||
|     table->pte[pte_i].base_ptr = (physical_addr >> 12); | ||||
|     table->pte[pte_i].read_write = 1; | ||||
|     table->pte[pte_i].present = 1; | ||||
|     return true; | ||||
|   } | ||||
| error: | ||||
|   printf("Page allocation error!\n"); | ||||
|   return false; | ||||
| } | ||||
							
								
								
									
										924
									
								
								src/kernel/libs/printf.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										924
									
								
								src/kernel/libs/printf.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,924 @@ | ||||
| ///////////////////////////////////////////////////////////////////////////////
 | ||||
| // \author (c) Marco Paland (info@paland.com)
 | ||||
| //             2014-2019, PALANDesign Hannover, Germany
 | ||||
| //
 | ||||
| // \license The MIT License (MIT)
 | ||||
| //
 | ||||
| // Permission is hereby granted, free of charge, to any person obtaining a copy
 | ||||
| // of this software and associated documentation files (the "Software"), to deal
 | ||||
| // in the Software without restriction, including without limitation the rights
 | ||||
| // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | ||||
| // copies of the Software, and to permit persons to whom the Software is
 | ||||
| // furnished to do so, subject to the following conditions:
 | ||||
| //
 | ||||
| // The above copyright notice and this permission notice shall be included in
 | ||||
| // all copies or substantial portions of the Software.
 | ||||
| //
 | ||||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | ||||
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | ||||
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | ||||
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | ||||
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | ||||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | ||||
| // THE SOFTWARE.
 | ||||
| //
 | ||||
| // \brief Tiny printf, sprintf and (v)snprintf implementation, optimized for speed on
 | ||||
| //        embedded systems with a very limited resources. These routines are thread
 | ||||
| //        safe and reentrant!
 | ||||
| //        Use this instead of the bloated standard/newlib printf cause these use
 | ||||
| //        malloc for printf (and may not be thread safe).
 | ||||
| //
 | ||||
| ///////////////////////////////////////////////////////////////////////////////
 | ||||
| 
 | ||||
| #include <stdbool.h> | ||||
| #include <stdint.h> | ||||
| 
 | ||||
| #include "printf.h" | ||||
| 
 | ||||
| //this is my own ugly library
 | ||||
| #include <serial.h> | ||||
| 
 | ||||
| //and my options
 | ||||
| #define PRINTF_DISABLE_SUPPORT_FLOAT | ||||
| #define PRINTF_DISABLE_SUPPORT_EXPONENTIAL | ||||
| #define PRINTF_DISABLE_SUPPORT_LONG_LONG | ||||
| #define PRINTF_DISABLE_SUPPORT_PTRDIFF_T  | ||||
| 
 | ||||
| 
 | ||||
| // define this globally (e.g. gcc -DPRINTF_INCLUDE_CONFIG_H ...) to include the
 | ||||
| // printf_config.h header file
 | ||||
| // default: undefined
 | ||||
| #ifdef PRINTF_INCLUDE_CONFIG_H | ||||
| #include "printf_config.h" | ||||
| #endif | ||||
| 
 | ||||
| 
 | ||||
| // 'ntoa' conversion buffer size, this must be big enough to hold one converted
 | ||||
| // numeric number including padded zeros (dynamically created on stack)
 | ||||
| // default: 32 byte
 | ||||
| #ifndef PRINTF_NTOA_BUFFER_SIZE | ||||
| #define PRINTF_NTOA_BUFFER_SIZE    32U | ||||
| #endif | ||||
| 
 | ||||
| // 'ftoa' conversion buffer size, this must be big enough to hold one converted
 | ||||
| // float number including padded zeros (dynamically created on stack)
 | ||||
| // default: 32 byte
 | ||||
| #ifndef PRINTF_FTOA_BUFFER_SIZE | ||||
| #define PRINTF_FTOA_BUFFER_SIZE    32U | ||||
| #endif | ||||
| 
 | ||||
| // support for the floating point type (%f)
 | ||||
| // default: activated
 | ||||
| #ifndef PRINTF_DISABLE_SUPPORT_FLOAT | ||||
| #define PRINTF_SUPPORT_FLOAT | ||||
| #endif | ||||
| 
 | ||||
| // support for exponential floating point notation (%e/%g)
 | ||||
| // default: activated
 | ||||
| #ifndef PRINTF_DISABLE_SUPPORT_EXPONENTIAL | ||||
| #define PRINTF_SUPPORT_EXPONENTIAL | ||||
| #endif | ||||
| 
 | ||||
| // define the default floating point precision
 | ||||
| // default: 6 digits
 | ||||
| #ifndef PRINTF_DEFAULT_FLOAT_PRECISION | ||||
| #define PRINTF_DEFAULT_FLOAT_PRECISION  6U | ||||
| #endif | ||||
| 
 | ||||
| // define the largest float suitable to print with %f
 | ||||
| // default: 1e9
 | ||||
| #ifndef PRINTF_MAX_FLOAT | ||||
| #define PRINTF_MAX_FLOAT  1e9 | ||||
| #endif | ||||
| 
 | ||||
| // support for the long long types (%llu or %p)
 | ||||
| // default: activated
 | ||||
| #ifndef PRINTF_DISABLE_SUPPORT_LONG_LONG | ||||
| #define PRINTF_SUPPORT_LONG_LONG | ||||
| #endif | ||||
| 
 | ||||
| // support for the ptrdiff_t type (%t)
 | ||||
| // ptrdiff_t is normally defined in <stddef.h> as long or long long type
 | ||||
| // default: activated
 | ||||
| #ifndef PRINTF_DISABLE_SUPPORT_PTRDIFF_T | ||||
| #define PRINTF_SUPPORT_PTRDIFF_T | ||||
| #endif | ||||
| 
 | ||||
| ///////////////////////////////////////////////////////////////////////////////
 | ||||
| 
 | ||||
| // internal flag definitions
 | ||||
| #define FLAGS_ZEROPAD   (1U <<  0U) | ||||
| #define FLAGS_LEFT      (1U <<  1U) | ||||
| #define FLAGS_PLUS      (1U <<  2U) | ||||
| #define FLAGS_SPACE     (1U <<  3U) | ||||
| #define FLAGS_HASH      (1U <<  4U) | ||||
| #define FLAGS_UPPERCASE (1U <<  5U) | ||||
| #define FLAGS_CHAR      (1U <<  6U) | ||||
| #define FLAGS_SHORT     (1U <<  7U) | ||||
| #define FLAGS_LONG      (1U <<  8U) | ||||
| #define FLAGS_LONG_LONG (1U <<  9U) | ||||
| #define FLAGS_PRECISION (1U << 10U) | ||||
| #define FLAGS_ADAPT_EXP (1U << 11U) | ||||
| 
 | ||||
| 
 | ||||
| // import float.h for DBL_MAX
 | ||||
| #if defined(PRINTF_SUPPORT_FLOAT) | ||||
| #include <float.h> | ||||
| #endif | ||||
| 
 | ||||
| 
 | ||||
| // output function type
 | ||||
| typedef void (*out_fct_type)(char character, void* buffer, size_t idx, size_t maxlen); | ||||
| 
 | ||||
| 
 | ||||
| // wrapper (used as buffer) for output function type
 | ||||
| typedef struct { | ||||
|   void  (*fct)(char character, void* arg); | ||||
|   void* arg; | ||||
| } out_fct_wrap_type; | ||||
| 
 | ||||
| 
 | ||||
| // internal buffer output
 | ||||
| static inline void _out_buffer(char character, void* buffer, size_t idx, size_t maxlen) | ||||
| { | ||||
|   if (idx < maxlen) { | ||||
|     ((char*)buffer)[idx] = character; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| // internal null output
 | ||||
| static inline void _out_null(char character, void* buffer, size_t idx, size_t maxlen) | ||||
| { | ||||
|   (void)character; (void)buffer; (void)idx; (void)maxlen; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| // internal _putchar wrapper
 | ||||
| static inline void _out_char(char character, void* buffer, size_t idx, size_t maxlen) | ||||
| { | ||||
|   (void)buffer; (void)idx; (void)maxlen; | ||||
|   if (character) { | ||||
|     _putchar_serial(COM1, character); // later we should figure out a way to not specifify exclusively com1
 | ||||
| 
 | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| // internal output function wrapper
 | ||||
| static inline void _out_fct(char character, void* buffer, size_t idx, size_t maxlen) | ||||
| { | ||||
|   (void)idx; (void)maxlen; | ||||
|   if (character) { | ||||
|     // buffer is the output fct pointer
 | ||||
|     ((out_fct_wrap_type*)buffer)->fct(character, ((out_fct_wrap_type*)buffer)->arg); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| // internal secure strlen
 | ||||
| // \return The length of the string (excluding the terminating 0) limited by 'maxsize'
 | ||||
| static inline unsigned int _strnlen_s(const char* str, size_t maxsize) | ||||
| { | ||||
|   const char* s; | ||||
|   for (s = str; *s && maxsize--; ++s); | ||||
|   return (unsigned int)(s - str); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| // internal test if char is a digit (0-9)
 | ||||
| // \return true if char is a digit
 | ||||
| static inline bool _is_digit(char ch) | ||||
| { | ||||
|   return (ch >= '0') && (ch <= '9'); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| // internal ASCII string to unsigned int conversion
 | ||||
| static unsigned int _atoi(const char** str) | ||||
| { | ||||
|   unsigned int i = 0U; | ||||
|   while (_is_digit(**str)) { | ||||
|     i = i * 10U + (unsigned int)(*((*str)++) - '0'); | ||||
|   } | ||||
|   return i; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| // output the specified string in reverse, taking care of any zero-padding
 | ||||
| static size_t _out_rev(out_fct_type out, char* buffer, size_t idx, size_t maxlen, const char* buf, size_t len, unsigned int width, unsigned int flags) | ||||
| { | ||||
|   const size_t start_idx = idx; | ||||
| 
 | ||||
|   // pad spaces up to given width
 | ||||
|   if (!(flags & FLAGS_LEFT) && !(flags & FLAGS_ZEROPAD)) { | ||||
|     for (size_t i = len; i < width; i++) { | ||||
|       out(' ', buffer, idx++, maxlen); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   // reverse string
 | ||||
|   while (len) { | ||||
|     out(buf[--len], buffer, idx++, maxlen); | ||||
|   } | ||||
| 
 | ||||
|   // append pad spaces up to given width
 | ||||
|   if (flags & FLAGS_LEFT) { | ||||
|     while (idx - start_idx < width) { | ||||
|       out(' ', buffer, idx++, maxlen); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   return idx; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| // internal itoa format
 | ||||
| static size_t _ntoa_format(out_fct_type out, char* buffer, size_t idx, size_t maxlen, char* buf, size_t len, bool negative, unsigned int base, unsigned int prec, unsigned int width, unsigned int flags) | ||||
| { | ||||
|   // pad leading zeros
 | ||||
|   if (!(flags & FLAGS_LEFT)) { | ||||
|     if (width && (flags & FLAGS_ZEROPAD) && (negative || (flags & (FLAGS_PLUS | FLAGS_SPACE)))) { | ||||
|       width--; | ||||
|     } | ||||
|     while ((len < prec) && (len < PRINTF_NTOA_BUFFER_SIZE)) { | ||||
|       buf[len++] = '0'; | ||||
|     } | ||||
|     while ((flags & FLAGS_ZEROPAD) && (len < width) && (len < PRINTF_NTOA_BUFFER_SIZE)) { | ||||
|       buf[len++] = '0'; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   // handle hash
 | ||||
|   if (flags & FLAGS_HASH) { | ||||
|     if (!(flags & FLAGS_PRECISION) && len && ((len == prec) || (len == width))) { | ||||
|       len--; | ||||
|       if (len && (base == 16U)) { | ||||
|         len--; | ||||
|       } | ||||
|     } | ||||
|     if ((base == 16U) && !(flags & FLAGS_UPPERCASE) && (len < PRINTF_NTOA_BUFFER_SIZE)) { | ||||
|       buf[len++] = 'x'; | ||||
|     } | ||||
|     else if ((base == 16U) && (flags & FLAGS_UPPERCASE) && (len < PRINTF_NTOA_BUFFER_SIZE)) { | ||||
|       buf[len++] = 'X'; | ||||
|     } | ||||
|     else if ((base == 2U) && (len < PRINTF_NTOA_BUFFER_SIZE)) { | ||||
|       buf[len++] = 'b'; | ||||
|     } | ||||
|     if (len < PRINTF_NTOA_BUFFER_SIZE) { | ||||
|       buf[len++] = '0'; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   if (len < PRINTF_NTOA_BUFFER_SIZE) { | ||||
|     if (negative) { | ||||
|       buf[len++] = '-'; | ||||
|     } | ||||
|     else if (flags & FLAGS_PLUS) { | ||||
|       buf[len++] = '+';  // ignore the space if the '+' exists
 | ||||
|     } | ||||
|     else if (flags & FLAGS_SPACE) { | ||||
|       buf[len++] = ' '; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   return _out_rev(out, buffer, idx, maxlen, buf, len, width, flags); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| // internal itoa for 'long' type
 | ||||
| static size_t _ntoa_long(out_fct_type out, char* buffer, size_t idx, size_t maxlen, unsigned long value, bool negative, unsigned long base, unsigned int prec, unsigned int width, unsigned int flags) | ||||
| { | ||||
|   char buf[PRINTF_NTOA_BUFFER_SIZE]; | ||||
|   size_t len = 0U; | ||||
| 
 | ||||
|   // no hash for 0 values
 | ||||
|   if (!value) { | ||||
|     flags &= ~FLAGS_HASH; | ||||
|   } | ||||
| 
 | ||||
|   // write if precision != 0 and value is != 0
 | ||||
|   if (!(flags & FLAGS_PRECISION) || value) { | ||||
|     do { | ||||
|       const char digit = (char)(value % base); | ||||
|       buf[len++] = digit < 10 ? '0' + digit : (flags & FLAGS_UPPERCASE ? 'A' : 'a') + digit - 10; | ||||
|       value /= base; | ||||
|     } while (value && (len < PRINTF_NTOA_BUFFER_SIZE)); | ||||
|   } | ||||
| 
 | ||||
|   return _ntoa_format(out, buffer, idx, maxlen, buf, len, negative, (unsigned int)base, prec, width, flags); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| // internal itoa for 'long long' type
 | ||||
| #if defined(PRINTF_SUPPORT_LONG_LONG) | ||||
| static size_t _ntoa_long_long(out_fct_type out, char* buffer, size_t idx, size_t maxlen, unsigned long long value, bool negative, unsigned long long base, unsigned int prec, unsigned int width, unsigned int flags) | ||||
| { | ||||
|   char buf[PRINTF_NTOA_BUFFER_SIZE]; | ||||
|   size_t len = 0U; | ||||
| 
 | ||||
|   // no hash for 0 values
 | ||||
|   if (!value) { | ||||
|     flags &= ~FLAGS_HASH; | ||||
|   } | ||||
| 
 | ||||
|   // write if precision != 0 and value is != 0
 | ||||
|   if (!(flags & FLAGS_PRECISION) || value) { | ||||
|     do { | ||||
|       const char digit = (char)(value % base); | ||||
|       buf[len++] = digit < 10 ? '0' + digit : (flags & FLAGS_UPPERCASE ? 'A' : 'a') + digit - 10; | ||||
|       value /= base; | ||||
|     } while (value && (len < PRINTF_NTOA_BUFFER_SIZE)); | ||||
|   } | ||||
| 
 | ||||
|   return _ntoa_format(out, buffer, idx, maxlen, buf, len, negative, (unsigned int)base, prec, width, flags); | ||||
| } | ||||
| #endif  // PRINTF_SUPPORT_LONG_LONG
 | ||||
| 
 | ||||
| 
 | ||||
| #if defined(PRINTF_SUPPORT_FLOAT) | ||||
| 
 | ||||
| #if defined(PRINTF_SUPPORT_EXPONENTIAL) | ||||
| // forward declaration so that _ftoa can switch to exp notation for values > PRINTF_MAX_FLOAT
 | ||||
| static size_t _etoa(out_fct_type out, char* buffer, size_t idx, size_t maxlen, double value, unsigned int prec, unsigned int width, unsigned int flags); | ||||
| #endif | ||||
| 
 | ||||
| 
 | ||||
| // internal ftoa for fixed decimal floating point
 | ||||
| static size_t _ftoa(out_fct_type out, char* buffer, size_t idx, size_t maxlen, double value, unsigned int prec, unsigned int width, unsigned int flags) | ||||
| { | ||||
|   char buf[PRINTF_FTOA_BUFFER_SIZE]; | ||||
|   size_t len  = 0U; | ||||
|   double diff = 0.0; | ||||
| 
 | ||||
|   // powers of 10
 | ||||
|   static const double pow10[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 }; | ||||
| 
 | ||||
|   // test for special values
 | ||||
|   if (value != value) | ||||
|     return _out_rev(out, buffer, idx, maxlen, "nan", 3, width, flags); | ||||
|   if (value < -DBL_MAX) | ||||
|     return _out_rev(out, buffer, idx, maxlen, "fni-", 4, width, flags); | ||||
|   if (value > DBL_MAX) | ||||
|     return _out_rev(out, buffer, idx, maxlen, (flags & FLAGS_PLUS) ? "fni+" : "fni", (flags & FLAGS_PLUS) ? 4U : 3U, width, flags); | ||||
| 
 | ||||
|   // test for very large values
 | ||||
|   // standard printf behavior is to print EVERY whole number digit -- which could be 100s of characters overflowing your buffers == bad
 | ||||
|   if ((value > PRINTF_MAX_FLOAT) || (value < -PRINTF_MAX_FLOAT)) { | ||||
| #if defined(PRINTF_SUPPORT_EXPONENTIAL) | ||||
|     return _etoa(out, buffer, idx, maxlen, value, prec, width, flags); | ||||
| #else | ||||
|     return 0U; | ||||
| #endif | ||||
|   } | ||||
| 
 | ||||
|   // test for negative
 | ||||
|   bool negative = false; | ||||
|   if (value < 0) { | ||||
|     negative = true; | ||||
|     value = 0 - value; | ||||
|   } | ||||
| 
 | ||||
|   // set default precision, if not set explicitly
 | ||||
|   if (!(flags & FLAGS_PRECISION)) { | ||||
|     prec = PRINTF_DEFAULT_FLOAT_PRECISION; | ||||
|   } | ||||
|   // limit precision to 9, cause a prec >= 10 can lead to overflow errors
 | ||||
|   while ((len < PRINTF_FTOA_BUFFER_SIZE) && (prec > 9U)) { | ||||
|     buf[len++] = '0'; | ||||
|     prec--; | ||||
|   } | ||||
| 
 | ||||
|   int whole = (int)value; | ||||
|   double tmp = (value - whole) * pow10[prec]; | ||||
|   unsigned long frac = (unsigned long)tmp; | ||||
|   diff = tmp - frac; | ||||
| 
 | ||||
|   if (diff > 0.5) { | ||||
|     ++frac; | ||||
|     // handle rollover, e.g. case 0.99 with prec 1 is 1.0
 | ||||
|     if (frac >= pow10[prec]) { | ||||
|       frac = 0; | ||||
|       ++whole; | ||||
|     } | ||||
|   } | ||||
|   else if (diff < 0.5) { | ||||
|   } | ||||
|   else if ((frac == 0U) || (frac & 1U)) { | ||||
|     // if halfway, round up if odd OR if last digit is 0
 | ||||
|     ++frac; | ||||
|   } | ||||
| 
 | ||||
|   if (prec == 0U) { | ||||
|     diff = value - (double)whole; | ||||
|     if ((!(diff < 0.5) || (diff > 0.5)) && (whole & 1)) { | ||||
|       // exactly 0.5 and ODD, then round up
 | ||||
|       // 1.5 -> 2, but 2.5 -> 2
 | ||||
|       ++whole; | ||||
|     } | ||||
|   } | ||||
|   else { | ||||
|     unsigned int count = prec; | ||||
|     // now do fractional part, as an unsigned number
 | ||||
|     while (len < PRINTF_FTOA_BUFFER_SIZE) { | ||||
|       --count; | ||||
|       buf[len++] = (char)(48U + (frac % 10U)); | ||||
|       if (!(frac /= 10U)) { | ||||
|         break; | ||||
|       } | ||||
|     } | ||||
|     // add extra 0s
 | ||||
|     while ((len < PRINTF_FTOA_BUFFER_SIZE) && (count-- > 0U)) { | ||||
|       buf[len++] = '0'; | ||||
|     } | ||||
|     if (len < PRINTF_FTOA_BUFFER_SIZE) { | ||||
|       // add decimal
 | ||||
|       buf[len++] = '.'; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   // do whole part, number is reversed
 | ||||
|   while (len < PRINTF_FTOA_BUFFER_SIZE) { | ||||
|     buf[len++] = (char)(48 + (whole % 10)); | ||||
|     if (!(whole /= 10)) { | ||||
|       break; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   // pad leading zeros
 | ||||
|   if (!(flags & FLAGS_LEFT) && (flags & FLAGS_ZEROPAD)) { | ||||
|     if (width && (negative || (flags & (FLAGS_PLUS | FLAGS_SPACE)))) { | ||||
|       width--; | ||||
|     } | ||||
|     while ((len < width) && (len < PRINTF_FTOA_BUFFER_SIZE)) { | ||||
|       buf[len++] = '0'; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   if (len < PRINTF_FTOA_BUFFER_SIZE) { | ||||
|     if (negative) { | ||||
|       buf[len++] = '-'; | ||||
|     } | ||||
|     else if (flags & FLAGS_PLUS) { | ||||
|       buf[len++] = '+';  // ignore the space if the '+' exists
 | ||||
|     } | ||||
|     else if (flags & FLAGS_SPACE) { | ||||
|       buf[len++] = ' '; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   return _out_rev(out, buffer, idx, maxlen, buf, len, width, flags); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| #if defined(PRINTF_SUPPORT_EXPONENTIAL) | ||||
| // internal ftoa variant for exponential floating-point type, contributed by Martijn Jasperse <m.jasperse@gmail.com>
 | ||||
| static size_t _etoa(out_fct_type out, char* buffer, size_t idx, size_t maxlen, double value, unsigned int prec, unsigned int width, unsigned int flags) | ||||
| { | ||||
|   // check for NaN and special values
 | ||||
|   if ((value != value) || (value > DBL_MAX) || (value < -DBL_MAX)) { | ||||
|     return _ftoa(out, buffer, idx, maxlen, value, prec, width, flags); | ||||
|   } | ||||
| 
 | ||||
|   // determine the sign
 | ||||
|   const bool negative = value < 0; | ||||
|   if (negative) { | ||||
|     value = -value; | ||||
|   } | ||||
| 
 | ||||
|   // default precision
 | ||||
|   if (!(flags & FLAGS_PRECISION)) { | ||||
|     prec = PRINTF_DEFAULT_FLOAT_PRECISION; | ||||
|   } | ||||
| 
 | ||||
|   // determine the decimal exponent
 | ||||
|   // based on the algorithm by David Gay (https://www.ampl.com/netlib/fp/dtoa.c)
 | ||||
|   union { | ||||
|     uint64_t U; | ||||
|     double   F; | ||||
|   } conv; | ||||
| 
 | ||||
|   conv.F = value; | ||||
|   int exp2 = (int)((conv.U >> 52U) & 0x07FFU) - 1023;           // effectively log2
 | ||||
|   conv.U = (conv.U & ((1ULL << 52U) - 1U)) | (1023ULL << 52U);  // drop the exponent so conv.F is now in [1,2)
 | ||||
|   // now approximate log10 from the log2 integer part and an expansion of ln around 1.5
 | ||||
|   int expval = (int)(0.1760912590558 + exp2 * 0.301029995663981 + (conv.F - 1.5) * 0.289529654602168); | ||||
|   // now we want to compute 10^expval but we want to be sure it won't overflow
 | ||||
|   exp2 = (int)(expval * 3.321928094887362 + 0.5); | ||||
|   const double z  = expval * 2.302585092994046 - exp2 * 0.6931471805599453; | ||||
|   const double z2 = z * z; | ||||
|   conv.U = (uint64_t)(exp2 + 1023) << 52U; | ||||
|   // compute exp(z) using continued fractions, see https://en.wikipedia.org/wiki/Exponential_function#Continued_fractions_for_ex
 | ||||
|   conv.F *= 1 + 2 * z / (2 - z + (z2 / (6 + (z2 / (10 + z2 / 14))))); | ||||
|   // correct for rounding errors
 | ||||
|   if (value < conv.F) { | ||||
|     expval--; | ||||
|     conv.F /= 10; | ||||
|   } | ||||
| 
 | ||||
|   // the exponent format is "%+03d" and largest value is "307", so set aside 4-5 characters
 | ||||
|   unsigned int minwidth = ((expval < 100) && (expval > -100)) ? 4U : 5U; | ||||
| 
 | ||||
|   // in "%g" mode, "prec" is the number of *significant figures* not decimals
 | ||||
|   if (flags & FLAGS_ADAPT_EXP) { | ||||
|     // do we want to fall-back to "%f" mode?
 | ||||
|     if ((value >= 1e-4) && (value < 1e6)) { | ||||
|       if ((int)prec > expval) { | ||||
|         prec = (unsigned)((int)prec - expval - 1); | ||||
|       } | ||||
|       else { | ||||
|         prec = 0; | ||||
|       } | ||||
|       flags |= FLAGS_PRECISION;   // make sure _ftoa respects precision
 | ||||
|       // no characters in exponent
 | ||||
|       minwidth = 0U; | ||||
|       expval   = 0; | ||||
|     } | ||||
|     else { | ||||
|       // we use one sigfig for the whole part
 | ||||
|       if ((prec > 0) && (flags & FLAGS_PRECISION)) { | ||||
|         --prec; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   // will everything fit?
 | ||||
|   unsigned int fwidth = width; | ||||
|   if (width > minwidth) { | ||||
|     // we didn't fall-back so subtract the characters required for the exponent
 | ||||
|     fwidth -= minwidth; | ||||
|   } else { | ||||
|     // not enough characters, so go back to default sizing
 | ||||
|     fwidth = 0U; | ||||
|   } | ||||
|   if ((flags & FLAGS_LEFT) && minwidth) { | ||||
|     // if we're padding on the right, DON'T pad the floating part
 | ||||
|     fwidth = 0U; | ||||
|   } | ||||
| 
 | ||||
|   // rescale the float value
 | ||||
|   if (expval) { | ||||
|     value /= conv.F; | ||||
|   } | ||||
| 
 | ||||
|   // output the floating part
 | ||||
|   const size_t start_idx = idx; | ||||
|   idx = _ftoa(out, buffer, idx, maxlen, negative ? -value : value, prec, fwidth, flags & ~FLAGS_ADAPT_EXP); | ||||
| 
 | ||||
|   // output the exponent part
 | ||||
|   if (minwidth) { | ||||
|     // output the exponential symbol
 | ||||
|     out((flags & FLAGS_UPPERCASE) ? 'E' : 'e', buffer, idx++, maxlen); | ||||
|     // output the exponent value
 | ||||
|     idx = _ntoa_long(out, buffer, idx, maxlen, (expval < 0) ? -expval : expval, expval < 0, 10, 0, minwidth-1, FLAGS_ZEROPAD | FLAGS_PLUS); | ||||
|     // might need to right-pad spaces
 | ||||
|     if (flags & FLAGS_LEFT) { | ||||
|       while (idx - start_idx < width) out(' ', buffer, idx++, maxlen); | ||||
|     } | ||||
|   } | ||||
|   return idx; | ||||
| } | ||||
| #endif  // PRINTF_SUPPORT_EXPONENTIAL
 | ||||
| #endif  // PRINTF_SUPPORT_FLOAT
 | ||||
| 
 | ||||
| 
 | ||||
| // internal vsnprintf
 | ||||
| static int _vsnprintf(out_fct_type out, char* buffer, const size_t maxlen, const char* format, va_list va) | ||||
| { | ||||
|   unsigned int flags, width, precision, n; | ||||
|   size_t idx = 0U; | ||||
| 
 | ||||
|   if (!buffer) { | ||||
|     // use null output function
 | ||||
|     out = _out_null; | ||||
|   } | ||||
| 
 | ||||
|   while (*format) | ||||
|   { | ||||
|     // format specifier?  %[flags][width][.precision][length]
 | ||||
|     if (*format != '%') { | ||||
|       // no
 | ||||
|       out(*format, buffer, idx++, maxlen); | ||||
|       format++; | ||||
|       continue; | ||||
|     } | ||||
|     else { | ||||
|       // yes, evaluate it
 | ||||
|       format++; | ||||
|     } | ||||
| 
 | ||||
|     // evaluate flags
 | ||||
|     flags = 0U; | ||||
|     do { | ||||
|       switch (*format) { | ||||
|         case '0': flags |= FLAGS_ZEROPAD; format++; n = 1U; break; | ||||
|         case '-': flags |= FLAGS_LEFT;    format++; n = 1U; break; | ||||
|         case '+': flags |= FLAGS_PLUS;    format++; n = 1U; break; | ||||
|         case ' ': flags |= FLAGS_SPACE;   format++; n = 1U; break; | ||||
|         case '#': flags |= FLAGS_HASH;    format++; n = 1U; break; | ||||
|         default :                                   n = 0U; break; | ||||
|       } | ||||
|     } while (n); | ||||
| 
 | ||||
|     // evaluate width field
 | ||||
|     width = 0U; | ||||
|     if (_is_digit(*format)) { | ||||
|       width = _atoi(&format); | ||||
|     } | ||||
|     else if (*format == '*') { | ||||
|       const int w = va_arg(va, int); | ||||
|       if (w < 0) { | ||||
|         flags |= FLAGS_LEFT;    // reverse padding
 | ||||
|         width = (unsigned int)-w; | ||||
|       } | ||||
|       else { | ||||
|         width = (unsigned int)w; | ||||
|       } | ||||
|       format++; | ||||
|     } | ||||
| 
 | ||||
|     // evaluate precision field
 | ||||
|     precision = 0U; | ||||
|     if (*format == '.') { | ||||
|       flags |= FLAGS_PRECISION; | ||||
|       format++; | ||||
|       if (_is_digit(*format)) { | ||||
|         precision = _atoi(&format); | ||||
|       } | ||||
|       else if (*format == '*') { | ||||
|         const int prec = (int)va_arg(va, int); | ||||
|         precision = prec > 0 ? (unsigned int)prec : 0U; | ||||
|         format++; | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|     // evaluate length field
 | ||||
|     switch (*format) { | ||||
|       case 'l' : | ||||
|         flags |= FLAGS_LONG; | ||||
|         format++; | ||||
|         if (*format == 'l') { | ||||
|           flags |= FLAGS_LONG_LONG; | ||||
|           format++; | ||||
|         } | ||||
|         break; | ||||
|       case 'h' : | ||||
|         flags |= FLAGS_SHORT; | ||||
|         format++; | ||||
|         if (*format == 'h') { | ||||
|           flags |= FLAGS_CHAR; | ||||
|           format++; | ||||
|         } | ||||
|         break; | ||||
| #if defined(PRINTF_SUPPORT_PTRDIFF_T) | ||||
|       case 't' : | ||||
|         flags |= (sizeof(ptrdiff_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG); | ||||
|         format++; | ||||
|         break; | ||||
| #endif | ||||
|       case 'j' : | ||||
|         flags |= (sizeof(intmax_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG); | ||||
|         format++; | ||||
|         break; | ||||
|       case 'z' : | ||||
|         flags |= (sizeof(size_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG); | ||||
|         format++; | ||||
|         break; | ||||
|       default : | ||||
|         break; | ||||
|     } | ||||
| 
 | ||||
|     // evaluate specifier
 | ||||
|     switch (*format) { | ||||
|       case 'd' : | ||||
|       case 'i' : | ||||
|       case 'u' : | ||||
|       case 'x' : | ||||
|       case 'X' : | ||||
|       case 'o' : | ||||
|       case 'b' : { | ||||
|         // set the base
 | ||||
|         unsigned int base; | ||||
|         if (*format == 'x' || *format == 'X') { | ||||
|           base = 16U; | ||||
|         } | ||||
|         else if (*format == 'o') { | ||||
|           base =  8U; | ||||
|         } | ||||
|         else if (*format == 'b') { | ||||
|           base =  2U; | ||||
|         } | ||||
|         else { | ||||
|           base = 10U; | ||||
|           flags &= ~FLAGS_HASH;   // no hash for dec format
 | ||||
|         } | ||||
|         // uppercase
 | ||||
|         if (*format == 'X') { | ||||
|           flags |= FLAGS_UPPERCASE; | ||||
|         } | ||||
| 
 | ||||
|         // no plus or space flag for u, x, X, o, b
 | ||||
|         if ((*format != 'i') && (*format != 'd')) { | ||||
|           flags &= ~(FLAGS_PLUS | FLAGS_SPACE); | ||||
|         } | ||||
| 
 | ||||
|         // ignore '0' flag when precision is given
 | ||||
|         if (flags & FLAGS_PRECISION) { | ||||
|           flags &= ~FLAGS_ZEROPAD; | ||||
|         } | ||||
| 
 | ||||
|         // convert the integer
 | ||||
|         if ((*format == 'i') || (*format == 'd')) { | ||||
|           // signed
 | ||||
|           if (flags & FLAGS_LONG_LONG) { | ||||
| #if defined(PRINTF_SUPPORT_LONG_LONG) | ||||
|             const long long value = va_arg(va, long long); | ||||
|             idx = _ntoa_long_long(out, buffer, idx, maxlen, (unsigned long long)(value > 0 ? value : 0 - value), value < 0, base, precision, width, flags); | ||||
| #endif | ||||
|           } | ||||
|           else if (flags & FLAGS_LONG) { | ||||
|             const long value = va_arg(va, long); | ||||
|             idx = _ntoa_long(out, buffer, idx, maxlen, (unsigned long)(value > 0 ? value : 0 - value), value < 0, base, precision, width, flags); | ||||
|           } | ||||
|           else { | ||||
|             const int value = (flags & FLAGS_CHAR) ? (char)va_arg(va, int) : (flags & FLAGS_SHORT) ? (short int)va_arg(va, int) : va_arg(va, int); | ||||
|             idx = _ntoa_long(out, buffer, idx, maxlen, (unsigned int)(value > 0 ? value : 0 - value), value < 0, base, precision, width, flags); | ||||
|           } | ||||
|         } | ||||
|         else { | ||||
|           // unsigned
 | ||||
|           if (flags & FLAGS_LONG_LONG) { | ||||
| #if defined(PRINTF_SUPPORT_LONG_LONG) | ||||
|             idx = _ntoa_long_long(out, buffer, idx, maxlen, va_arg(va, unsigned long long), false, base, precision, width, flags); | ||||
| #endif | ||||
|           } | ||||
|           else if (flags & FLAGS_LONG) { | ||||
|             idx = _ntoa_long(out, buffer, idx, maxlen, va_arg(va, unsigned long), false, base, precision, width, flags); | ||||
|           } | ||||
|           else { | ||||
|             const unsigned int value = (flags & FLAGS_CHAR) ? (unsigned char)va_arg(va, unsigned int) : (flags & FLAGS_SHORT) ? (unsigned short int)va_arg(va, unsigned int) : va_arg(va, unsigned int); | ||||
|             idx = _ntoa_long(out, buffer, idx, maxlen, value, false, base, precision, width, flags); | ||||
|           } | ||||
|         } | ||||
|         format++; | ||||
|         break; | ||||
|       } | ||||
| #if defined(PRINTF_SUPPORT_FLOAT) | ||||
|       case 'f' : | ||||
|       case 'F' : | ||||
|         if (*format == 'F') flags |= FLAGS_UPPERCASE; | ||||
|         idx = _ftoa(out, buffer, idx, maxlen, va_arg(va, double), precision, width, flags); | ||||
|         format++; | ||||
|         break; | ||||
| #if defined(PRINTF_SUPPORT_EXPONENTIAL) | ||||
|       case 'e': | ||||
|       case 'E': | ||||
|       case 'g': | ||||
|       case 'G': | ||||
|         if ((*format == 'g')||(*format == 'G')) flags |= FLAGS_ADAPT_EXP; | ||||
|         if ((*format == 'E')||(*format == 'G')) flags |= FLAGS_UPPERCASE; | ||||
|         idx = _etoa(out, buffer, idx, maxlen, va_arg(va, double), precision, width, flags); | ||||
|         format++; | ||||
|         break; | ||||
| #endif  // PRINTF_SUPPORT_EXPONENTIAL
 | ||||
| #endif  // PRINTF_SUPPORT_FLOAT
 | ||||
|       case 'c' : { | ||||
|         unsigned int l = 1U; | ||||
|         // pre padding
 | ||||
|         if (!(flags & FLAGS_LEFT)) { | ||||
|           while (l++ < width) { | ||||
|             out(' ', buffer, idx++, maxlen); | ||||
|           } | ||||
|         } | ||||
|         // char output
 | ||||
|         out((char)va_arg(va, int), buffer, idx++, maxlen); | ||||
|         // post padding
 | ||||
|         if (flags & FLAGS_LEFT) { | ||||
|           while (l++ < width) { | ||||
|             out(' ', buffer, idx++, maxlen); | ||||
|           } | ||||
|         } | ||||
|         format++; | ||||
|         break; | ||||
|       } | ||||
| 
 | ||||
|       case 's' : { | ||||
|         const char* p = va_arg(va, char*); | ||||
|         unsigned int l = _strnlen_s(p, precision ? precision : (size_t)-1); | ||||
|         // pre padding
 | ||||
|         if (flags & FLAGS_PRECISION) { | ||||
|           l = (l < precision ? l : precision); | ||||
|         } | ||||
|         if (!(flags & FLAGS_LEFT)) { | ||||
|           while (l++ < width) { | ||||
|             out(' ', buffer, idx++, maxlen); | ||||
|           } | ||||
|         } | ||||
|         // string output
 | ||||
|         while ((*p != 0) && (!(flags & FLAGS_PRECISION) || precision--)) { | ||||
|           out(*(p++), buffer, idx++, maxlen); | ||||
|         } | ||||
|         // post padding
 | ||||
|         if (flags & FLAGS_LEFT) { | ||||
|           while (l++ < width) { | ||||
|             out(' ', buffer, idx++, maxlen); | ||||
|           } | ||||
|         } | ||||
|         format++; | ||||
|         break; | ||||
|       } | ||||
| 
 | ||||
|       case 'p' : { | ||||
|         width = sizeof(void*) * 2U; | ||||
|         flags |= FLAGS_ZEROPAD | FLAGS_UPPERCASE; | ||||
| #if defined(PRINTF_SUPPORT_LONG_LONG) | ||||
|         const bool is_ll = sizeof(uintptr_t) == sizeof(long long); | ||||
|         if (is_ll) { | ||||
|           idx = _ntoa_long_long(out, buffer, idx, maxlen, (uintptr_t)va_arg(va, void*), false, 16U, precision, width, flags); | ||||
|         } | ||||
|         else { | ||||
| #endif | ||||
|           idx = _ntoa_long(out, buffer, idx, maxlen, (unsigned long)((uintptr_t)va_arg(va, void*)), false, 16U, precision, width, flags); | ||||
| #if defined(PRINTF_SUPPORT_LONG_LONG) | ||||
|         } | ||||
| #endif | ||||
|         format++; | ||||
|         break; | ||||
|       } | ||||
| 
 | ||||
|       case '%' : | ||||
|         out('%', buffer, idx++, maxlen); | ||||
|         format++; | ||||
|         break; | ||||
| 
 | ||||
|       default : | ||||
|         out(*format, buffer, idx++, maxlen); | ||||
|         format++; | ||||
|         break; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   // termination
 | ||||
|   out((char)0, buffer, idx < maxlen ? idx : maxlen - 1U, maxlen); | ||||
| 
 | ||||
|   // return written chars without terminating \0
 | ||||
|   return (int)idx; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| ///////////////////////////////////////////////////////////////////////////////
 | ||||
| 
 | ||||
| int printf_(const char* format, ...) | ||||
| { | ||||
|   va_list va; | ||||
|   va_start(va, format); | ||||
|   char buffer[1]; | ||||
|   const int ret = _vsnprintf(_out_char, buffer, (size_t)-1, format, va); | ||||
|   va_end(va); | ||||
|   return ret; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| int sprintf_(char* buffer, const char* format, ...) | ||||
| { | ||||
|   va_list va; | ||||
|   va_start(va, format); | ||||
|   const int ret = _vsnprintf(_out_buffer, buffer, (size_t)-1, format, va); | ||||
|   va_end(va); | ||||
|   return ret; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| int snprintf_(char* buffer, size_t count, const char* format, ...) | ||||
| { | ||||
|   va_list va; | ||||
|   va_start(va, format); | ||||
|   const int ret = _vsnprintf(_out_buffer, buffer, count, format, va); | ||||
|   va_end(va); | ||||
|   return ret; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| int vprintf_(const char* format, va_list va) | ||||
| { | ||||
|   char buffer[1]; | ||||
|   return _vsnprintf(_out_char, buffer, (size_t)-1, format, va); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| int vsnprintf_(char* buffer, size_t count, const char* format, va_list va) | ||||
| { | ||||
|   return _vsnprintf(_out_buffer, buffer, count, format, va); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| int fctprintf(void (*out)(char character, void* arg), void* arg, const char* format, ...) | ||||
| { | ||||
|   va_list va; | ||||
|   va_start(va, format); | ||||
|   const out_fct_wrap_type out_fct_wrap = { out, arg }; | ||||
|   const int ret = _vsnprintf(_out_fct, (char*)(uintptr_t)&out_fct_wrap, (size_t)-1, format, va); | ||||
|   va_end(va); | ||||
|   return ret; | ||||
| } | ||||
							
								
								
									
										117
									
								
								src/kernel/libs/printf.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										117
									
								
								src/kernel/libs/printf.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,117 @@ | ||||
| ///////////////////////////////////////////////////////////////////////////////
 | ||||
| // \author (c) Marco Paland (info@paland.com)
 | ||||
| //             2014-2019, PALANDesign Hannover, Germany
 | ||||
| //
 | ||||
| // \license The MIT License (MIT)
 | ||||
| //
 | ||||
| // Permission is hereby granted, free of charge, to any person obtaining a copy
 | ||||
| // of this software and associated documentation files (the "Software"), to deal
 | ||||
| // in the Software without restriction, including without limitation the rights
 | ||||
| // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | ||||
| // copies of the Software, and to permit persons to whom the Software is
 | ||||
| // furnished to do so, subject to the following conditions:
 | ||||
| // 
 | ||||
| // The above copyright notice and this permission notice shall be included in
 | ||||
| // all copies or substantial portions of the Software.
 | ||||
| // 
 | ||||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | ||||
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | ||||
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | ||||
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | ||||
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | ||||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | ||||
| // THE SOFTWARE.
 | ||||
| //
 | ||||
| // \brief Tiny printf, sprintf and snprintf implementation, optimized for speed on
 | ||||
| //        embedded systems with a very limited resources.
 | ||||
| //        Use this instead of bloated standard/newlib printf.
 | ||||
| //        These routines are thread safe and reentrant.
 | ||||
| //
 | ||||
| ///////////////////////////////////////////////////////////////////////////////
 | ||||
| 
 | ||||
| #ifndef _PRINTF_H_ | ||||
| #define _PRINTF_H_ | ||||
| 
 | ||||
| #include <stdarg.h> | ||||
| #include <stddef.h> | ||||
| 
 | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
| extern "C" { | ||||
| #endif | ||||
| 
 | ||||
| 
 | ||||
| /**
 | ||||
|  * Output a character to a custom device like UART, used by the printf() function | ||||
|  * This function is declared here only. You have to write your custom implementation somewhere | ||||
|  * \param character Character to output | ||||
|  */ | ||||
| void _putchar(char character); | ||||
| 
 | ||||
| 
 | ||||
| /**
 | ||||
|  * Tiny printf implementation | ||||
|  * You have to implement _putchar if you use printf() | ||||
|  * To avoid conflicts with the regular printf() API it is overridden by macro defines | ||||
|  * and internal underscore-appended functions like printf_() are used | ||||
|  * \param format A string that specifies the format of the output | ||||
|  * \return The number of characters that are written into the array, not counting the terminating null character | ||||
|  */ | ||||
| #define printf printf_ | ||||
| int printf_(const char* format, ...); | ||||
| 
 | ||||
| 
 | ||||
| /**
 | ||||
|  * Tiny sprintf implementation | ||||
|  * Due to security reasons (buffer overflow) YOU SHOULD CONSIDER USING (V)SNPRINTF INSTEAD! | ||||
|  * \param buffer A pointer to the buffer where to store the formatted string. MUST be big enough to store the output! | ||||
|  * \param format A string that specifies the format of the output | ||||
|  * \return The number of characters that are WRITTEN into the buffer, not counting the terminating null character | ||||
|  */ | ||||
| #define sprintf sprintf_ | ||||
| int sprintf_(char* buffer, const char* format, ...); | ||||
| 
 | ||||
| 
 | ||||
| /**
 | ||||
|  * Tiny snprintf/vsnprintf implementation | ||||
|  * \param buffer A pointer to the buffer where to store the formatted string | ||||
|  * \param count The maximum number of characters to store in the buffer, including a terminating null character | ||||
|  * \param format A string that specifies the format of the output | ||||
|  * \param va A value identifying a variable arguments list | ||||
|  * \return The number of characters that COULD have been written into the buffer, not counting the terminating | ||||
|  *         null character. A value equal or larger than count indicates truncation. Only when the returned value | ||||
|  *         is non-negative and less than count, the string has been completely written. | ||||
|  */ | ||||
| #define snprintf  snprintf_ | ||||
| #define vsnprintf vsnprintf_ | ||||
| int  snprintf_(char* buffer, size_t count, const char* format, ...); | ||||
| int vsnprintf_(char* buffer, size_t count, const char* format, va_list va); | ||||
| 
 | ||||
| 
 | ||||
| /**
 | ||||
|  * Tiny vprintf implementation | ||||
|  * \param format A string that specifies the format of the output | ||||
|  * \param va A value identifying a variable arguments list | ||||
|  * \return The number of characters that are WRITTEN into the buffer, not counting the terminating null character | ||||
|  */ | ||||
| #define vprintf vprintf_ | ||||
| int vprintf_(const char* format, va_list va); | ||||
| 
 | ||||
| 
 | ||||
| /**
 | ||||
|  * printf with output function | ||||
|  * You may use this as dynamic alternative to printf() with its fixed _putchar() output | ||||
|  * \param out An output function which takes one character and an argument pointer | ||||
|  * \param arg An argument pointer for user data passed to output function | ||||
|  * \param format A string that specifies the format of the output | ||||
|  * \return The number of characters that are sent to the output function, not counting the terminating null character | ||||
|  */ | ||||
| int fctprintf(void (*out)(char character, void* arg), void* arg, const char* format, ...); | ||||
| 
 | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| 
 | ||||
| #endif  // _PRINTF_H_
 | ||||
							
								
								
									
										37
									
								
								src/link.ld
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								src/link.ld
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,37 @@ | ||||
| SEARCH_DIR(objects) | ||||
| 
 | ||||
| INPUT( | ||||
| bootloader.o | ||||
| libc.o | ||||
| serial.o | ||||
| video.o | ||||
| printf.o | ||||
| page.o | ||||
| acpi.o | ||||
| kernel.o | ||||
| ) | ||||
| 
 | ||||
| /*while we do need to worry about the stack converging on our kernel,  | ||||
| this is only temporary, and it will be more noticable then if it were to hit bios (we want to find bugs, not ignore them!)*/ | ||||
| _kernel_stack_loc = 0x200000 - 16; | ||||
| _kernel_loc = 0x100000;  | ||||
| _meminfo_loc = 0x7000; | ||||
| _vbe_infoblock = 0x500; /* this does not account for segmentation to get over 0xffff*/ | ||||
| 
 | ||||
| SECTIONS | ||||
| { | ||||
|   . = 0x0; | ||||
|   bootloader 0x7c00 : | ||||
|   { | ||||
|   bootloader.o(.text) | ||||
|   } | ||||
|   kernel _kernel_loc : | ||||
|   AT (ADDR(bootloader) + SIZEOF(bootloader)) | ||||
|   /*ALIGN(4096)*/ | ||||
|   { | ||||
|     EXCLUDE_FILE (*bootloader.o) *(.text .data .bss .rodata .comment .eh_frame) | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| _kernel_size = (SIZEOF(kernel) / 512) + (SIZEOF(bootloader) / 512) + 2;  | ||||
| _bootloader_stage1_size = (SIZEOF(bootloader) / 512) - 1; | ||||
							
								
								
									
										53
									
								
								src/makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								src/makefile
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,53 @@ | ||||
| LD=../compiler/indigo_gcc/bin/x86_64-elf-ld | ||||
| CC=../compiler/indigo_gcc/bin/x86_64-elf-gcc | ||||
| OBJCPY=../compiler/indigo_gcc/bin/x86_64-elf-objcopy | ||||
| INC=-Ikernel/include | ||||
| 
 | ||||
| EMU_CORES=4 | ||||
| EMU_RAM=2G | ||||
| XRES=1024 | ||||
| YRES=768 | ||||
| 
 | ||||
| #TODO clean up make vs debug
 | ||||
| 
 | ||||
| make:  | ||||
| 	nasm -g -felf64 bootloader/bootloader.asm -o objects/bootloader.o | ||||
| 	$(CC) $(INC) -g -ffreestanding -c kernel/kernel.c -o objects/kernel.o | ||||
| 	$(CC) $(INC) -g -ffreestanding -c kernel/libs/acpi.c -o objects/acpi.o | ||||
| 	$(CC) $(INC) -g -ffreestanding -c kernel/libs/drivers/serial.c -o objects/serial.o | ||||
| 	$(CC) $(INC) -g -ffreestanding -c kernel/libs/drivers/video.c -o objects/video.o | ||||
| 	$(CC) $(INC) -g -ffreestanding -c kernel/libs/printf.c -o objects/printf.o | ||||
| 	$(CC) $(INC) -g -ffreestanding -c kernel/libs/page.c -o objects/page.o | ||||
| 	$(CC) $(INC) -g -ffreestanding -c kernel/libs/libc.c -o objects/libc.o | ||||
| 	$(LD) -o indigo_os.elf --oformat=elf64-x86-64 -T link.ld | ||||
| 	$(OBJCPY) --only-keep-debug indigo_os.elf debug/debug_syms.o | ||||
| 	$(OBJCPY) -O binary --strip-all indigo_os.elf indigo_os | ||||
| ifneq ("$(wildcard $(./debug/serial.in))","") | ||||
| 	mkfifo debug/serial.in | ||||
| endif | ||||
| ifneq ("$(wildcard $(./debug/serial.out))","") | ||||
| 	mkfifo debug/serial.out | ||||
| endif | ||||
| 	rm -f indigo_os.elf | ||||
| 
 | ||||
| 
 | ||||
| run: | ||||
| 	qemu-system-x86_64 -smp $(EMU_CORES) -m $(EMU_RAM) -nographic -drive format=raw,file=./indigo_os | ||||
| 	 | ||||
| 
 | ||||
| gdb: indigo_os | ||||
| 	tmux new-session -s os_gdb "qemu-system-x86_64 -smp $(EMU_CORES) -nographic -S -s -drive format=raw,file=./indigo_os -m $(EMU_RAM)"\;\
 | ||||
| 		split-window -h "gdb -x debug/gdbinit.gdb; killall qemu-system-x86_64" | ||||
| 
 | ||||
| run-graphical: | ||||
| 	qemu-system-x86_64 -S -s -smp $(EMU_CORES) -serial pipe:debug/serial -device VGA,edid=on,xres=$(XRES),yres=$(YRES) -drive format=raw,file=./indigo_os &\
 | ||||
| 		gdb -x debug/gdbinit.gdb; killall qemu-system-x86_64 | ||||
| 
 | ||||
| clean: | ||||
| 	rm -f objects/* | ||||
| 	rm -f indigo_os | ||||
| 	rm -f bin/* | ||||
| 	rm -f debug/debug_syms.o | ||||
| 	rm -f debug/serial.in | ||||
| 	rm -f debug/serial.out | ||||
| 	rm -f indigo_os.elf | ||||
							
								
								
									
										16
									
								
								tools/edid/bparse-edid
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										16
									
								
								tools/edid/bparse-edid
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,16 @@ | ||||
| #!/usr/bin/env python3 | ||||
| import argparse | ||||
| 
 | ||||
| parser = argparse.ArgumentParser() | ||||
| parser.add_argument('edid_file', type=str, help="edid file") | ||||
| args = parser.parse_args() | ||||
| 
 | ||||
| f = open(args.edid_file, 'rb') | ||||
| edid = f.read() | ||||
| x = edid[56] | ((edid[58] & 0xf0) << 4) | ||||
| y = edid[59] | ((edid[61] & 0xf0) << 4) | ||||
| 
 | ||||
| print("resolution: {} x {}".format(x, y)) | ||||
| 
 | ||||
| f.close() | ||||
| 
 | ||||
							
								
								
									
										
											BIN
										
									
								
								tools/edid/desktop_edid
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								tools/edid/desktop_edid
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								tools/edid/laptop_edid
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								tools/edid/laptop_edid
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										29
									
								
								tools/page/page.py
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										29
									
								
								tools/page/page.py
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,29 @@ | ||||
| #!/usr/bin/env python3 | ||||
| from math import ceil as c | ||||
| def get_offsets(addr): | ||||
|     if addr % 4096: | ||||
|         print("You must align to 4096!") | ||||
|         return 0 | ||||
|     if addr > 2 ** 47: | ||||
|         print("Address too big!") | ||||
|         return 0 | ||||
| 
 | ||||
| 
 | ||||
|     pte = (addr >> 12) & 0x1ff  | ||||
|     pde = (addr >> 21) & 0x1ff  | ||||
|     pdpe =(addr >> 30) & 0x1ff  | ||||
|     pml4 =(addr >> 39) & 0x1ff  | ||||
|     print("pte:\t{}\npde:\t{}\npdpe:\t{}\npml4:\t{}".format(pte, pde, pdpe, pml4)) | ||||
| 
 | ||||
| def get_table_size(addr): | ||||
|     pte_cnt = c(c(addr / (1 << 12)) / 512) * 512 | ||||
|     pde_cnt = c(c(addr / (1 << 21)) / 512) * 512 | ||||
|     pdpe_cnt = c(c(addr / (1 << 30)) / 512) * 512 | ||||
|     pml4_cnt = c(c(addr / (1 << 39)) / 512) * 512 | ||||
| 
 | ||||
| 
 | ||||
|     return((pte_cnt + pde_cnt + pdpe_cnt + pml4_cnt) * 8) | ||||
| 
 | ||||
| ts = get_table_size(68719476736)  | ||||
| print(hex(ts)) | ||||
| 
 | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Brett Weiland
						Brett Weiland