From 5eb67e005ef64731fd6ec97f94768df19bdbac88 Mon Sep 17 00:00:00 2001 From: Hector Martin Date: Mon, 8 Aug 2022 15:33:53 +0900 Subject: [PATCH] Initial commit --- .gitignore | 8 + .gitmodules | 3 + COPYING | 340 +++++++++++++++++++++++++++++++++++++ Makefile | 14 ++ README.md | 54 ++++++ common.mk | 1 + describe.sh | 14 ++ describesimple.sh | 15 ++ loader/.gitignore | 7 + loader/Makefile | 43 +++++ loader/bsdtypes.h | 1 + loader/diskio.c | 1 + loader/diskio.h | 1 + loader/elf.h | 1 + loader/errno.h | 1 + loader/ff.c | 1 + loader/ff.h | 1 + loader/gecko.c | 173 +++++++++++++++++++ loader/gecko.h | 31 ++++ loader/gpio.h | 1 + loader/hollywood.h | 1 + loader/integer.h | 1 + loader/irq.h | 1 + loader/lcd.c | 225 +++++++++++++++++++++++++ loader/lcd.h | 37 ++++ loader/loader.ld | 90 ++++++++++ loader/main.c | 390 +++++++++++++++++++++++++++++++++++++++++++ loader/memory.c | 1 + loader/memory.h | 1 + loader/memory_asm.S | 1 + loader/sdhc.c | 1 + loader/sdhc.h | 1 + loader/sdmmc.c | 1 + loader/sdmmc.h | 1 + loader/start.S | 78 +++++++++ loader/start.h | 1 + loader/string.c | 1 + loader/string.h | 1 + loader/types.h | 1 + loader/utils.c | 1 + loader/utils.h | 1 + loader/version.c | 1 + loader/vsprintf.c | 1 + loader/vsprintf.h | 1 + mini | 1 + resetstub/.gitignore | 1 + resetstub/Makefile | 23 +++ resetstub/stub.S | 31 ++++ resetstub/stub.ld | 78 +++++++++ starlet.mk | 1 + stub/.gitignore | 6 + stub/Makefile | 27 +++ stub/elf.h | 54 ++++++ stub/hollywood.h | 31 ++++ stub/start.S | 144 ++++++++++++++++ stub/start.h | 18 ++ stub/stub.c | 116 +++++++++++++ stub/stub.ld | 108 ++++++++++++ stub/types.h | 38 +++++ stub/utils.c | 31 ++++ stub/utils.h | 177 ++++++++++++++++++++ 61 files changed, 2435 insertions(+) create mode 100644 .gitignore create mode 100644 .gitmodules create mode 100644 COPYING create mode 100644 Makefile create mode 100644 README.md create mode 120000 common.mk create mode 100755 describe.sh create mode 100755 describesimple.sh create mode 100644 loader/.gitignore create mode 100644 loader/Makefile create mode 120000 loader/bsdtypes.h create mode 120000 loader/diskio.c create mode 120000 loader/diskio.h create mode 120000 loader/elf.h create mode 120000 loader/errno.h create mode 120000 loader/ff.c create mode 120000 loader/ff.h create mode 100644 loader/gecko.c create mode 100644 loader/gecko.h create mode 120000 loader/gpio.h create mode 120000 loader/hollywood.h create mode 120000 loader/integer.h create mode 120000 loader/irq.h create mode 100644 loader/lcd.c create mode 100644 loader/lcd.h create mode 100644 loader/loader.ld create mode 100644 loader/main.c create mode 120000 loader/memory.c create mode 120000 loader/memory.h create mode 120000 loader/memory_asm.S create mode 120000 loader/sdhc.c create mode 120000 loader/sdhc.h create mode 120000 loader/sdmmc.c create mode 120000 loader/sdmmc.h create mode 100644 loader/start.S create mode 120000 loader/start.h create mode 120000 loader/string.c create mode 120000 loader/string.h create mode 120000 loader/types.h create mode 120000 loader/utils.c create mode 120000 loader/utils.h create mode 100644 loader/version.c create mode 120000 loader/vsprintf.c create mode 120000 loader/vsprintf.h create mode 160000 mini create mode 100644 resetstub/.gitignore create mode 100644 resetstub/Makefile create mode 100644 resetstub/stub.S create mode 100644 resetstub/stub.ld create mode 120000 starlet.mk create mode 100644 stub/.gitignore create mode 100644 stub/Makefile create mode 100644 stub/elf.h create mode 100644 stub/hollywood.h create mode 100644 stub/start.S create mode 100644 stub/start.h create mode 100644 stub/stub.c create mode 100644 stub/stub.ld create mode 100644 stub/types.h create mode 100644 stub/utils.c create mode 100644 stub/utils.h diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..171e03d --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +git_version.h +*.d +*.bin +*.elf +*.map +*~ +*.o +.*.swp diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..9be399a --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "mini"] + path = mini + url = https://github.com/fail0verflow/mini diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..3912109 --- /dev/null +++ b/COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..3c006bb --- /dev/null +++ b/Makefile @@ -0,0 +1,14 @@ +all: bootmii.bin + +.PHONY: bootmii.bin +bootmii.bin: + @$(MAKE) -C loader + @$(MAKE) -C stub + @$(MAKE) -C resetstub + python2 mini/makebin.py stub/bootmii.bin resetstub/resetstub.elf bootmii.bin + +clean: + @$(MAKE) -C loader clean + @$(MAKE) -C stub clean + @$(MAKE) -C resetstub clean + diff --git a/README.md b/README.md new file mode 100644 index 0000000..1555139 --- /dev/null +++ b/README.md @@ -0,0 +1,54 @@ +# BootMii loader + +This repository contains the public release of the source code for +the BootMii stub loader. + +Included portions: + +* ELF loader stub +* BootMii SD loader proper +* Reset stub +* mini (submodule) + +Not included: + +* boot2-style-wad packaging stuff +* PyWii (see hbc) +* UI/PPC side (CE1LING_CAT) +* Installer + +Note that the code in this repository may differ from the source code used to +build the official version of BootMii. + +This code is released with no warranty, and has only been build tested. +If you release this to anyone but yourself without extensive testing, you are an +irresponsible person and we will forever hate you. + +## Build instructions + +You need armeb-eabi cross compilers. Same build setup as +[mini](https://github.com/fail0verflow/mini). See +[bootmii-utils](https://github.com/fail0verflow/bootmii-utils) for some outdated +toolchain build scripts. Type `make` to compile. Good luck. + +Output is at `bootmii.bin`, which is the main `armboot.bin` style executable +for BootMii-as-IOS, with a dummy reset stub as payload. Installation as boot2 +would replace the ELF payload with the original boot2 instead. + +## Seriously + +Do NOT release this to users unless you've read +[this](https://marcan.st/2011/01/safe-hacking/) and spent months testing +hardware variations and building an installer that cross checks every step +including boot1 simulation prior to actually committing to NAND. There's a +reason we didn't brick any Wiis with this stuff. We're releasing this because +it's been over a decade and some people are asking for it to experiment with +devkits and other weird stuff, not because anyone should try using this on their +Wii. + +## License + +Unless otherwise noted in an individual file header, all source code in this +repository is released under the terms of the GNU General Public License, +version 2 or later. The full text of the license can be found in the COPYING +file. diff --git a/common.mk b/common.mk new file mode 120000 index 0000000..a3e8d5d --- /dev/null +++ b/common.mk @@ -0,0 +1 @@ +mini/common.mk \ No newline at end of file diff --git a/describe.sh b/describe.sh new file mode 100755 index 0000000..e643438 --- /dev/null +++ b/describe.sh @@ -0,0 +1,14 @@ +#!/bin/sh + +cd "$(dirname "$0")" + +# Check for git and a git repo. +if head=`git rev-parse --verify HEAD 2>/dev/null`; then + printf "%s" `git describe --always --match bootmii-\* \`git log --pretty=oneline -n1 | awk ' { print $1 }'\` | awk '{ sub (/bootmii-/, ""); print;}'` + + # Are there uncommitted changes? + git update-index --refresh --unmerged > /dev/null + git diff-index --quiet HEAD loader stub || printf "%s" -dirty +fi + +echo diff --git a/describesimple.sh b/describesimple.sh new file mode 100755 index 0000000..821229d --- /dev/null +++ b/describesimple.sh @@ -0,0 +1,15 @@ +#!/bin/sh + +cd "$(dirname "$0")" + +# Check for git and a git repo. +if head=`git rev-parse --verify HEAD 2>/dev/null`; then + comm=`git log --pretty=oneline -n1 | awk ' { print $1 }'` + printf "%s" ""`printf "%s" \`git describe --always --abbrev=4 --match bootmii-\* $comm | awk '{ sub (/bootmii-/, ""); print;}'\`` + + # Are there uncommitted changes? + git update-index --refresh --unmerged > /dev/null + git diff-index --quiet HEAD loader stub || printf "%s" '*' +fi + +echo diff --git a/loader/.gitignore b/loader/.gitignore new file mode 100644 index 0000000..5e11f85 --- /dev/null +++ b/loader/.gitignore @@ -0,0 +1,7 @@ +*.d +*.bin +*.elf +*.o +*.map +loader_version.txt + diff --git a/loader/Makefile b/loader/Makefile new file mode 100644 index 0000000..4a3dd7a --- /dev/null +++ b/loader/Makefile @@ -0,0 +1,43 @@ +include ../starlet.mk + +TARGET = bootmii-sym.elf +TARGET_STRIPPED = bootmii.elf + +OBJS = start.o main.o vsprintf.o string.o gecko.o memory.o memory_asm.o \ + sdhc.o sdmmc.o utils.o ff.o diskio.o lcd.o version.o + +CFLAGS = -mbig-endian -mthumb -march=armv5t +CFLAGS += -fomit-frame-pointer -ffunction-sections +CFLAGS += -Wall -Wextra -Os -pipe + +# uncomment to enabled LCD debug output +#DEFINES += -DENABLE_LCD +DEFINES += -DLOADER + +LDFLAGS += -Wl,-N +LDSCRIPT = loader.ld +LIBS = -lgcc + +include ../common.mk + +all: $(TARGET_STRIPPED) loader_version.txt + +$(TARGET_STRIPPED): $(TARGET) + @echo " STRIP $@" + @cp $< $@ + @$(STRIP) -R .comment -R .ARM.attributes -s $@ + +version.o: version.c ../describe.sh + @echo " VERSION $@" + @cat $< | sed "s/%VERSION%/`../describe.sh`/" | $(CC) $(CFLAGS) -c -x c - -o $@ + +loader_version.txt: ../describe.sh + @../describe.sh > loader_version.txt + +clean: myclean + +myclean: + -rm -f $(TARGET_STRIPPED) loader_version.txt + +.PHONY: version.o + diff --git a/loader/bsdtypes.h b/loader/bsdtypes.h new file mode 120000 index 0000000..42841c5 --- /dev/null +++ b/loader/bsdtypes.h @@ -0,0 +1 @@ +../mini/bsdtypes.h \ No newline at end of file diff --git a/loader/diskio.c b/loader/diskio.c new file mode 120000 index 0000000..784113e --- /dev/null +++ b/loader/diskio.c @@ -0,0 +1 @@ +../mini/diskio.c \ No newline at end of file diff --git a/loader/diskio.h b/loader/diskio.h new file mode 120000 index 0000000..4c69508 --- /dev/null +++ b/loader/diskio.h @@ -0,0 +1 @@ +../mini/diskio.h \ No newline at end of file diff --git a/loader/elf.h b/loader/elf.h new file mode 120000 index 0000000..430152d --- /dev/null +++ b/loader/elf.h @@ -0,0 +1 @@ +../mini/elf.h \ No newline at end of file diff --git a/loader/errno.h b/loader/errno.h new file mode 120000 index 0000000..ab85a4f --- /dev/null +++ b/loader/errno.h @@ -0,0 +1 @@ +../mini/errno.h \ No newline at end of file diff --git a/loader/ff.c b/loader/ff.c new file mode 120000 index 0000000..ecab8ff --- /dev/null +++ b/loader/ff.c @@ -0,0 +1 @@ +../mini/ff.c \ No newline at end of file diff --git a/loader/ff.h b/loader/ff.h new file mode 120000 index 0000000..0f2ca3b --- /dev/null +++ b/loader/ff.h @@ -0,0 +1 @@ +../mini/ff.h \ No newline at end of file diff --git a/loader/gecko.c b/loader/gecko.c new file mode 100644 index 0000000..74e725b --- /dev/null +++ b/loader/gecko.c @@ -0,0 +1,173 @@ +/* + bootmii - a Free Software replacement for the Nintendo/BroadOn boot2. + USBGecko support code + +Copyright (c) 2008 Nuke - +Copyright (C) 2008, 2009 Hector Martin "marcan" +Copyright (C) 2008, 2009 Sven Peter +Copyright (C) 2009 Andre Heider "dhewg" + +# This code is licensed to you under the terms of the GNU GPL, version 2; +# see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt +*/ + +#include "types.h" +#include "start.h" +#include "vsprintf.h" +#include "string.h" +#include "utils.h" +#include "hollywood.h" +#include "gecko.h" + +static int gecko_active = 0; + +static u32 _gecko_command(u32 command) +{ + u32 i; + // Memory Card Port B (Channel 1, Device 0, Frequency 3 (32Mhz Clock)) + write32(EXI1_CSR, 0xd0); + write32(EXI1_DATA, command); + write32(EXI1_CR, 0x19); + while (read32(EXI1_CR) & 1); + i = read32(EXI1_DATA); + write32(EXI1_CSR, 0); + return i; +} + +static u32 _gecko_getid(void) +{ + u32 i; + // Memory Card Port B (Channel 1, Device 0, Frequency 3 (32Mhz Clock)) + write32(EXI1_CSR, 0xd0); + write32(EXI1_DATA, 0); + write32(EXI1_CR, 0x19); + while (read32(EXI1_CR) & 1); + write32(EXI1_CR, 0x39); + while (read32(EXI1_CR) & 1); + i = read32(EXI1_DATA); + write32(EXI1_CSR, 0); + return i; +} + +static u32 _gecko_sendbyte(char sendbyte) +{ + u32 i = 0; + i = _gecko_command(0xB0000000 | (sendbyte<<20)); + if (i&0x04000000) + return 1; // Return 1 if byte was sent + return 0; +} + +static u32 _gecko_checksend(void) +{ + u32 i = 0; + i = _gecko_command(0xC0000000); + if (i&0x04000000) + return 1; // Return 1 if safe to send + return 0; +} + +int gecko_isalive(void) +{ + u32 i; + u32 id; + id = _gecko_getid(); + if(id != 0x00000000) + return 0; + i = _gecko_command(0x90000000); + if ((i&0xFFFF0000) != 0x04700000) + return 0; + return 1; +} + +void gecko_init(void) +{ + write32(EXI0_CSR, 0); + write32(EXI1_CSR, 0); + write32(EXI2_CSR, 0); + write32(EXI0_CSR, 0x2000); + write32(EXI0_CSR, 3<<10); + write32(EXI1_CSR, 3<<10); + + gecko_active = 0; + if(gecko_isalive()) + gecko_active = 1; +} + +#if 0 +int gecko_sendbuffer(const void *buffer, u32 size) +{ + u32 left = size; + char *ptr = (char*)buffer; + + while(left>0) { + if(!_gecko_sendbyte(*ptr)) + break; + ptr++; + left--; + } + return (size - left); +} +#endif + +int gecko_sendbuffer_safe(const void *buffer, u32 size) +{ + u32 left = size; + char *ptr = (char*)buffer; + + int tries = 10000; // about 200ms of tries + + if((read32(HW_EXICTRL) & EXICTRL_ENABLE_EXI) == 0) + return left; + + while(left>0) { + if(_gecko_checksend()) { + if(!_gecko_sendbyte(*ptr)) + break; + ptr++; + left--; + } else { + // if gecko is hung, time out and disable further attempts + // only affects gecko users without an active terminal + if(tries-- == 0) { + gecko_active = 0; + break; + } + } + } + return (size - left); +} + +#if 0 +int gecko_putchar(int ic) +{ + char b = ic; + + if(!gecko_active) + return -1; + return gecko_sendbuffer(&b, 1); +} +#endif + +int gecko_puts(const char *s) +{ + if(!gecko_active) + return -1; + return gecko_sendbuffer_safe(s, strlen(s)); +} + +int gecko_printf( const char *fmt, ...) +{ + va_list args; + char buffer[256]; + int i; + + if(!gecko_active) + return -1; + + va_start(args, fmt); + i = vsprintf(buffer, fmt, args); + va_end(args); + gecko_puts(buffer); + return i; +} diff --git a/loader/gecko.h b/loader/gecko.h new file mode 100644 index 0000000..969cd4c --- /dev/null +++ b/loader/gecko.h @@ -0,0 +1,31 @@ +/* + bootmii - a Free Software replacement for the Nintendo/BroadOn boot2. + USBGecko support code + +Copyright (c) 2008 Nuke - +Copyright (C) 2008, 2009 Hector Martin "marcan" +Copyright (C) 2008, 2009 Sven Peter +Copyright (C) 2009 Andre Heider "dhewg" + +# This code is licensed to you under the terms of the GNU GPL, version 2; +# see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt +*/ + +#ifndef __GECKO_H__ +#define __GECKO_H__ + +#include "types.h" + +void gecko_flush(void); +int gecko_isalive(void); +int gecko_recvbuffer(void *buffer, u32 size); +int gecko_sendbuffer(const void *buffer, u32 size); +int gecko_recvbuffer_safe(void *buffer, u32 size); +int gecko_sendbuffer_safe(const void *buffer, u32 size); +int gecko_putchar(int c); +int gecko_getchar(void); +int gecko_puts(const char *s); +int gecko_printf( const char *fmt, ...); +void gecko_init(void); + +#endif diff --git a/loader/gpio.h b/loader/gpio.h new file mode 120000 index 0000000..9687b89 --- /dev/null +++ b/loader/gpio.h @@ -0,0 +1 @@ +../mini/gpio.h \ No newline at end of file diff --git a/loader/hollywood.h b/loader/hollywood.h new file mode 120000 index 0000000..19e5223 --- /dev/null +++ b/loader/hollywood.h @@ -0,0 +1 @@ +../mini/hollywood.h \ No newline at end of file diff --git a/loader/integer.h b/loader/integer.h new file mode 120000 index 0000000..02c2853 --- /dev/null +++ b/loader/integer.h @@ -0,0 +1 @@ +../mini/integer.h \ No newline at end of file diff --git a/loader/irq.h b/loader/irq.h new file mode 120000 index 0000000..48957e4 --- /dev/null +++ b/loader/irq.h @@ -0,0 +1 @@ +../mini/irq.h \ No newline at end of file diff --git a/loader/lcd.c b/loader/lcd.c new file mode 100644 index 0000000..0ec4a33 --- /dev/null +++ b/loader/lcd.c @@ -0,0 +1,225 @@ +/* + bootmii - a Free Software replacement for the Nintendo/BroadOn boot2. + GPIO LCD display support + + (yes, that thing in that youtube video) + +Copyright (C) 2008, 2009 Hector Martin "marcan" + +# This code is licensed to you under the terms of the GNU GPL, version 2; +# see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt +*/ + +#ifdef ENABLE_LCD + +#include "types.h" +#include "lcd.h" +#include "start.h" +#include "vsprintf.h" +#include "string.h" +#include "utils.h" +#include "hollywood.h" + +void lcdinit(void); + +char ddram[0x80]; +u8 ddaddr = 0; +u32 chardelay = 0; + +#define WIDTH 16 +#define HEIGHT 2 + +u8 linestarts[HEIGHT] = { 0x00, 0x40 }; + +u8 cx, cy; + +// for 4x20 +//u8 linestarts[HEIGHT] = { 0x00, 0x40, 0x14, 0x54 }; + +#define LCD_HOME_CLEAR 0x01 +#define LCD_HOME 0x02 +#define LCD_ENTRY_MODE 0x04 +# define EM_INC 0x02 +# define EM_DEC 0x00 +# define EM_SHIFT 0x01 +#define LCD_DISPLAY_ONOFF 0x08 +# define D_DISPLAY 0x04 +# define D_CURSOR 0x02 +# define D_BLINK 0x01 +#define LCD_SHIFT 0x10 +# define SH_SHIFT 0x08 +# define SH_CURSOR 0x00 +# define SH_RIGHT 0x04 +# define SH_LEFT 0x00 +#define LCD_FUNCTION_SET 0x20 +# define FS_8BIT 0x10 +# define FS_4BIT 0x00 +# define FS_2LINE 0x08 +# define FS_1LINE 0x00 +# define FS_5X10 0x04 +# define FS_5X8 0x00 +#define LCD_CGRAM 0x40 +#define LCD_DDRAM 0x80 + +#define LCD_PORT HW_GPIO1OUT +#define LCD_MASK 0x00FC0000 +#define LCD_E 0x00040000 +#define LCD_RS 0x00080000 +#define LCD_DSHIFT 20 + +static void _lcdnybble(char rs, char n) +{ + if(rs) + mask32(LCD_PORT, LCD_MASK, ((n&0xF) << LCD_DSHIFT) | LCD_RS); + else + mask32(LCD_PORT, LCD_MASK, ((n&0xF) << LCD_DSHIFT)); + + udelay(4); + set32(HW_GPIO1OUT, LCD_E); + udelay(4); + clear32(HW_GPIO1OUT, LCD_E); + udelay(4); +} + +static void _lcdcmd(char c) +{ + _lcdnybble(0, c>>4); + _lcdnybble(0, c&0x0F); + udelay(50); +} + +static void _lcdwrite(char c) +{ + _lcdnybble(1, c>>4); + _lcdnybble(1, c&0x0F); + ddram[ddaddr] = c; + ddaddr = (ddaddr+1)&0x7F; + udelay(50); +} + +static void _lcdgoto(u8 addr) +{ + _lcdcmd(LCD_DDRAM | addr); + ddaddr = addr; +} + +static void _lcdgotoxy(u8 x, u8 y) +{ + u8 addr = (x + linestarts[y]); + _lcdcmd(LCD_DDRAM | addr); + ddaddr = addr; +} + +static void _lcdclear(void) +{ + int i; + _lcdcmd(LCD_HOME_CLEAR); + udelay(2000); + for(i=0;i<0x80;i++) { + ddram[i] = ' '; + } +} + +static void _lcdscroll(u8 count) +{ + int x,y; + _lcdcmd(LCD_HOME_CLEAR); + udelay(2000); + for(y=0;y<(HEIGHT-count);y++) { + _lcdgotoxy(0,y); + for(x=0;x>4); + udelay(10000); + _lcdnybble(0, (LCD_FUNCTION_SET | FS_8BIT)>>4); + udelay(1000); + _lcdnybble(0, (LCD_FUNCTION_SET | FS_8BIT)>>4); + udelay(1000); + _lcdnybble(0, (LCD_FUNCTION_SET | FS_4BIT)>>4); + udelay(1000); + _lcdcmd(LCD_FUNCTION_SET | FS_4BIT | FS_2LINE | FS_5X8); + _lcdcmd(LCD_DISPLAY_ONOFF); + _lcdcmd(LCD_HOME_CLEAR); + udelay(2000); + _lcdcmd(LCD_ENTRY_MODE | EM_INC); + _lcdcmd(LCD_DISPLAY_ONOFF | D_DISPLAY | D_CURSOR); +} + +int lcd_putchar(int ic) +{ + char c = ic; + // defer newlines to keep last line of LCD full + if(c == '\n') { + cx = 0; + cy++; + if(cy < HEIGHT) + _lcdgotoxy(cx,cy); + } else { + if(cx >= 16) { + cx = 0; + cy++; + if(cy < HEIGHT) + _lcdgotoxy(cx,cy); + } + if(cy >= (2*HEIGHT-1)) { + _lcdclear(); + _lcdgoto(linestarts[HEIGHT-1]); + cy = HEIGHT - 1; + cx = 0; + } else if(cy >= HEIGHT) { + _lcdscroll(cy - HEIGHT + 1); + cy = HEIGHT - 1; + cx = 0; + } + _lcdwrite(c); + cx++; + } + return (u8)c; +} + +void lcd_setdelay(u32 delay) +{ + chardelay = delay; +} + +int lcd_puts(const char *s) +{ + while(*s) { + lcd_putchar(*s++); + udelay(chardelay); + } + return 0; +} + +int lcd_printf( const char *fmt, ...) +{ + va_list args; + char buffer[1024]; + int i; + + va_start(args, fmt); + i = vsprintf(buffer, fmt, args); + va_end(args); + lcd_puts(buffer); + return i; +} + +#endif + diff --git a/loader/lcd.h b/loader/lcd.h new file mode 100644 index 0000000..929ef07 --- /dev/null +++ b/loader/lcd.h @@ -0,0 +1,37 @@ +/* + bootmii - a Free Software replacement for the Nintendo/BroadOn boot2. + GPIO LCD display support + + (yes, that thing in that youtube video) + +Copyright (C) 2008, 2009 Hector Martin "marcan" + +# This code is licensed to you under the terms of the GNU GPL, version 2; +# see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt +*/ + +#ifndef __LCD_H__ +#define __LCD_H__ + +#ifdef ENABLE_LCD + +#include "types.h" + +void lcd_init(void); +int lcd_putchar(int c); +int lcd_puts(const char *s); +void lcd_setdelay(u32 delay); +int lcd_printf( const char *fmt, ...); + +#else + +#define lcd_init(...) +#define lcd_putchar(...) +#define lcd_puts(...) +#define lcd_setdelay(...) +#define lcd_printf(...) + +#endif + +#endif + diff --git a/loader/loader.ld b/loader/loader.ld new file mode 100644 index 0000000..a3eb796 --- /dev/null +++ b/loader/loader.ld @@ -0,0 +1,90 @@ +/* + mini - a Free Software replacement for the Nintendo/BroadOn IOS. + linker script + +Copyright (C) 2008, 2009 Hector Martin "marcan" + +# This code is licensed to you under the terms of the GNU GPL, version 2; +# see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt +*/ + +OUTPUT_FORMAT("elf32-bigarm") +OUTPUT_ARCH(arm) +EXTERN(_start) +ENTRY(_start) + +__base_addr = 0x10400000; + +PHDRS +{ + init PT_LOAD FLAGS(5); + text PT_LOAD FLAGS(5); + data PT_LOAD FLAGS(6); + bss PT_LOAD FLAGS(6); +} + +SECTIONS +{ + . = __base_addr; + + .init : + { + *(.init) + *(.init.*) + . = ALIGN(4); + } :init + + .text : + { + *(.text) + *(.text.*) + *(.gnu.warning) + *(.gnu.linkonce.t*) + *(.glue_7) + *(.glue_7t) + . = ALIGN(4); + } :text + + __text_end = . ; + + .rodata : + { + *(.rodata) + *all.rodata*(*) + *(.roda) + *(.rodata.*) + *(.gnu.linkonce.r*) + . = ALIGN(4); + } :data + + .data : + { + *(.data) + *(.data.*) + *(.gnu.linkonce.d*) + . = ALIGN(4); + } :data + + .bss : + { + __bss_start = . ; + *(.dynbss) + *(.gnu.linkonce.b*) + *(.bss*) + *(.sbss*) + *(COMMON) + . = ALIGN(4); + __bss_end = . ; + } :bss + + . = ALIGN(4); + __stack_end = .; + __stack_addr = (__stack_end + 0x4000); + __end = __stack_addr ; +} + +PROVIDE (__stack_end = __stack_end); +PROVIDE (__stack_addr = __stack_addr); +PROVIDE (__bss_start = __bss_start); +PROVIDE (__bss_end = __bss_end); +PROVIDE (__end = __end); diff --git a/loader/main.c b/loader/main.c new file mode 100644 index 0000000..af9e8e4 --- /dev/null +++ b/loader/main.c @@ -0,0 +1,390 @@ +/* + bootmii - a Free Software replacement for the Nintendo/BroadOn boot2. + Main loader code + +Copyright (C) 2008, 2009 Haxx Enterprises +Copyright (C) 2008, 2009 Sven Peter +Copyright (C) 2008, 2009 Hector Martin "marcan" +Copyright (C) 2009 Andre Heider "dhewg" +Copyright (C) 2009 John Kelley + +# This code is licensed to you under the terms of the GNU GPL, version 2; +# see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt +*/ + +#include "types.h" +#include "utils.h" +#include "start.h" +#include "hollywood.h" +#include "sdhc.h" +#include "string.h" +#include "memory.h" +#include "elf.h" +#include "gecko.h" +#include "ff.h" +#include "lcd.h" +#include "gpio.h" + +#define BOOT_FILE "/bootmii/armboot.bin" + +extern void *__end; +extern const char *bootmii_version; + +static FATFS fatfs; + +static void hexline(void *addr, int len) +{ + u8 *p = (u8*)addr; + while(len--) { + gecko_printf("%02x",*p++); + } +} + +static void printhdr(ioshdr *hdr) { + gecko_printf("ARMBOOT header (@%p):\n",hdr); + gecko_printf(" Header size: %08x\n", hdr->hdrsize); + gecko_printf(" Loader size: %08x\n", hdr->loadersize); + gecko_printf(" ELF size: %08x\n", hdr->elfsize); + gecko_printf(" Argument: %08x\n", hdr->argument); + gecko_printf(" ELF at %p\n", (u8 *) hdr + hdr->hdrsize + hdr->loadersize); +} + +static void loadelf(u8 *elf) { + gecko_puts("Loading ELF...\n"); + + if(memcmp("\x7F" "ELF\x01\x02\x01\x61\x01",elf,9)) { + gecko_printf("Invalid ELF header:\n"); + hexline(elf, 9); + gecko_printf("\n"); + panic(0xE3); + } + + Elf32_Ehdr *ehdr = (Elf32_Ehdr*)elf; + if(ehdr->e_phoff == 0) { + gecko_printf("ELF has no program headers!\n"); + panic(0xE4); + } + + int count = ehdr->e_phnum; + Elf32_Phdr *phdr = (Elf32_Phdr*)(elf + ehdr->e_phoff); + gecko_printf("PHDRS at %p\n",phdr); + while(count--) + { + if(phdr->p_type != PT_LOAD) { + gecko_printf(" Skipping PHDR of type %d\n",phdr->p_type); + } else { + void *src = elf + phdr->p_offset; + gecko_printf(" LOAD %p -> %x [0x%x]\n",src, phdr->p_paddr, phdr->p_filesz); + memcpy((void *)phdr->p_paddr, src, phdr->p_filesz); + } + phdr++; + } +} + +static void turn_stuff_on(void) +{ + clear32(HW_GPIO1OUT, 0x10); + udelay(100); + set32(HW_RESETS, 0x7ffffcf); +} + +static void reset_audio(void) +{ + mask32(HW_DIFLAGS, 0x180, 0x100); + + clear32(0xd8001d0, 0x80000000); + udelay(2); + clear32(0xd8001d0, 0x40000000); + + clear32(0xd8001d0, 0x10000000); + mask32(0xd8001cc, 0x7ffffff, 0x4b0ffce); + + udelay(10); + set32(0xd8001d0, 0x40000000); + udelay(500); + set32(0xd8001d0, 0x80000000); + udelay(2); +} + +static void boot2_init1() +{ + //func_ffff5d08 + u32 reg = read32(0xd8001c8); + + if((reg & 0xc0000000) == 0xc0000000) + return; + + clear32(0xd8001c8, 0x80000000); + udelay(2); + clear32(0xd8001c8, 0x40000000); + udelay(10); + set32(0xd8001c8, 0x40000000); + udelay(50); + set32(0xd8001c8, 0x80000000); + udelay(2); +} + +static void boot2_init2(u32 hlywdVerHi) +{ + //func_ffff5c40 + + write32(0xd800088, 0xFE); + udelay(2); + + clear32(0xd8001d8, 0x80000000); + udelay(2); + clear32(0xd8001d8, 0x40000000); + udelay(10); + set32(0xd8001d8, 0x40000000); + udelay(50); + set32(0xd8001d8, 0x80000000); + udelay(2); + + write32(0xd800088, 0xF6); + udelay(50); + write32(0xd800088, 0xF4); + udelay(1); + write32(0xd800088, 0xF0); + udelay(1); + write32(0xd800088, 0x70); + udelay(1); + write32(0xd800088, 0x60); + udelay(1); + write32(0xd800088, 0x40); + udelay(1); + write32(0xd800088, 0); + udelay(1); + write32(0xd0400b4, 0x2214); + if (hlywdVerHi) + write32(0xd0400b0, 0x20600); + else + write32(0xd0400b0, 0x20400); + write32(0xd0400a4, 0x26); + udelay(1); + write32(0xd0400a4, 0x2026); + udelay(1); + write32(0xd0400a4, 0x4026); + udelay(20); + write32(0xd0400cc, 0x111); +} + +static void setup_gpios() +{ + write32(HW_GPIO1OWNER, GP_OWNER_PPC); + mask32(HW_GPIO1OUT, GP_ARM_OUTPUTS, GP_ARM_DEFAULT_ON); + write32(HW_GPIO1DIR, GP_ARM_OUTPUTS); + mask32(HW_GPIO1BOUT, GP_PPC_OUTPUTS, GP_PPC_DEFAULT_ON); + write32(HW_GPIO1BDIR, GP_PPC_OUTPUTS); + write32(HW_GPIO1ENABLE, GP_ALL); + udelay(2000); + write32(HW_GPIO1INTLVL, 0); + write32(HW_GPIO1INTFLAG, GP_ALL); + write32(HW_GPIO1INTENABLE, 0); + write32(HW_GPIO1BINTLVL, 0); + write32(HW_GPIO1BINTFLAG, GP_ALL); + write32(HW_GPIO1BINTENABLE, 0); +} + +static void hardware_setup(void) +{ + u8 hwood_ver, hwood_hi, hwood_lo; + hwood_ver = read32(HW_VERSION) & 0xFF; + hwood_hi = hwood_ver >> 4; + hwood_lo = hwood_ver & 0xF; + + debug_output(0x03); + + set32(HW_EXICTRL, EXICTRL_ENABLE_EXI); + + mem_protect(1, (void*)0x13420000, (void*)0x1fffffff); + + clear32(HW_EXICTRL, 0x10); + if(hwood_hi == 0) + write32(0xd8b0010, 0); + write32(0xd8b0010, 0); + if(hwood_hi == 1 && hwood_lo == 0) + mask32(0xd800140, 0x0000FFF0, 1); + + set32(0xd80018c, 0x400); + set32(0xd80018c, 0x800); + + reset_audio(); + boot2_init1(); + boot2_init2(hwood_hi); + setup_gpios(); + turn_stuff_on(); + + write32(0xd8001e0, 0x65244A); + write32(0xd8001e4, 0x46A024); + + debug_output(0x73); + + clear32(HW_GPIO1OWNER, 0x10); + set32(HW_GPIO1DIR, 0x10); +} + +void *_main(void *base) +{ + FRESULT fres; + + ioshdr *hdr = (ioshdr*)base; + ioshdr *filehdr; + u8 *elf; + + u32 bypass = 0; + + elf = (u8*) base; + elf += hdr->hdrsize + hdr->loadersize; + + debug_output(0xF0); + lcd_init(); + hardware_setup(); + debug_output(0xF1); + + if (read32(0x150effc) == 0x53544655) + write32(0x150effc, 0); + else + gecko_init(); + + lcd_puts("BootMii\n"); + lcd_puts("\n"); + + gecko_puts("\n\nBootMii v"); + gecko_puts(bootmii_version); + gecko_puts("\n"); + + gecko_puts("Copyright (C) 2008-2010 Team Twiizers.\n"); + gecko_puts("Licensed under the GNU GPL version 2.\n"); + + printhdr(hdr); + + if(hdr->argument == 0x42) { + bypass = 1; + goto boot2; + } + + if (read32(0x150f000) == 0x424d454d) { + gecko_puts("Trying to boot ELF from memory\n"); + + filehdr = (ioshdr *) read32(0x150f004); + write32(0x150f000, 0); + write32(0x150f004, 0); + + printhdr(filehdr); + void *entry = (void*)(((u32)filehdr) + filehdr->hdrsize); + + lcd_puts(" ~ ARMBOOT \n"); + gecko_printf("Launching ARMBOOT @ %p\n\n",entry); + + debug_output(0xF3); + + return entry; + } + + gecko_puts("Trying to mount SD...\n"); + + sdhc_init(); + fres = f_mount(0, &fatfs); + + if(fres != FR_OK) { + gecko_printf("Error %d while trying to mount SD\n", fres); + debug_output(0x12); + debug_output(fres&0xFF); + goto boot2; + } + + //debug_output(0xF2); + + gecko_puts("Trying to open SD:" BOOT_FILE "\n"); + + FIL fd; + u32 read; + + fres = f_open(&fd, BOOT_FILE, FA_READ); + if(fres != FR_OK) { + gecko_printf("Error %d while trying to open file\n", fres); + //debug_output(0x13); + //debug_output(fres&0xFF); + goto boot2; + } + + lcd_puts("."); + debug_output(0xF2); + + filehdr = (ioshdr *)ALIGN_FORWARD(((u32)&__end) + 0x100, 0x100); + + gecko_printf("Trying to read ARMBOOT header to %p\n", filehdr); + + fres = f_read(&fd, filehdr, sizeof(ioshdr), &read); + if(fres != FR_OK) { + gecko_printf("Error %d while trying to read file header\n", fres); + //debug_output(0x14); + //debug_output(fres&0xFF); + goto boot2; + } + if(read != sizeof(ioshdr)) { + gecko_printf("Got %d bytes, expected %d\n", read, sizeof(ioshdr)); + //debug_output(0x24); + goto boot2; + } + + lcd_puts("."); + //debug_output(0xF5); + + printhdr(filehdr); + + u32 totalsize = filehdr->hdrsize + filehdr->loadersize + filehdr->elfsize; + + gecko_printf("Total ARMBOOT size: 0x%x\n", totalsize); + gecko_printf("Trying to read ARMBOOT to %p\n", filehdr); + + fres = f_read(&fd, filehdr+1, totalsize-sizeof(ioshdr), &read); + if(fres != FR_OK) { + gecko_printf("Error %d while trying to read file header\n", fres); + //debug_output(0x15); + //debug_output(fres&0xFF); + goto boot2; + } + if(read != (totalsize-sizeof(ioshdr))) { + gecko_printf("Got %d bytes, expected %d\n", read, (totalsize-sizeof(ioshdr))); + //debug_output(0x25); + goto boot2; + } + + lcd_puts("."); + + //debug_output(0xF6); + + gecko_puts("ARMBOOT read\n"); + + void *entry = (void*)(((u32)filehdr) + filehdr->hdrsize); + + lcd_puts(" ~ ARMBOOT \n"); + + gecko_printf("Launching ARMBOOT @ %p\n\n",entry); + + debug_output(0xF3); + + return entry; + +boot2: + debug_output(0xC8); + if(bypass) { + gecko_puts("In bypass mode, loading boot2\n"); + } else { + gecko_puts("Couldn't load from SD, falling back to boot2\n"); + set32(HW_GPIO1BOUT, GP_SLOTLED); + udelay(30000); + clear32(HW_GPIO1BOUT, GP_SLOTLED); + udelay(50000); + set32(HW_GPIO1BOUT, GP_SLOTLED); + udelay(30000); + clear32(HW_GPIO1BOUT, GP_SLOTLED); + udelay(50000); + } + lcd_puts(" ~ BOOT2 \n"); + loadelf(elf); + debug_output(0xC9); + gecko_puts("Starting boot2...\n\n"); + return (void *) 0xFFFF0000; +} diff --git a/loader/memory.c b/loader/memory.c new file mode 120000 index 0000000..2129fe8 --- /dev/null +++ b/loader/memory.c @@ -0,0 +1 @@ +../mini/memory.c \ No newline at end of file diff --git a/loader/memory.h b/loader/memory.h new file mode 120000 index 0000000..328e48e --- /dev/null +++ b/loader/memory.h @@ -0,0 +1 @@ +../mini/memory.h \ No newline at end of file diff --git a/loader/memory_asm.S b/loader/memory_asm.S new file mode 120000 index 0000000..f4811a9 --- /dev/null +++ b/loader/memory_asm.S @@ -0,0 +1 @@ +../mini/memory_asm.S \ No newline at end of file diff --git a/loader/sdhc.c b/loader/sdhc.c new file mode 120000 index 0000000..8ae61e6 --- /dev/null +++ b/loader/sdhc.c @@ -0,0 +1 @@ +../mini/sdhc.c \ No newline at end of file diff --git a/loader/sdhc.h b/loader/sdhc.h new file mode 120000 index 0000000..2a4eaeb --- /dev/null +++ b/loader/sdhc.h @@ -0,0 +1 @@ +../mini/sdhc.h \ No newline at end of file diff --git a/loader/sdmmc.c b/loader/sdmmc.c new file mode 120000 index 0000000..ac5cf6b --- /dev/null +++ b/loader/sdmmc.c @@ -0,0 +1 @@ +../mini/sdmmc.c \ No newline at end of file diff --git a/loader/sdmmc.h b/loader/sdmmc.h new file mode 120000 index 0000000..695881b --- /dev/null +++ b/loader/sdmmc.h @@ -0,0 +1 @@ +../mini/sdmmc.h \ No newline at end of file diff --git a/loader/start.S b/loader/start.S new file mode 100644 index 0000000..e9d0bdc --- /dev/null +++ b/loader/start.S @@ -0,0 +1,78 @@ +/* + bootmii - a Free Software replacement for the Nintendo/BroadOn boot2. + system startup + +Copyright (C) 2008, 2009 Hector Martin "marcan" + +# This code is licensed to you under the terms of the GNU GPL, version 2; +# see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt +*/ + +.arm + +.extern _main +.extern __got_start +.extern __got_end +.extern __bss_start +.extern __bss_end +.extern __stack_addr +.globl _start +.globl debug_output + +.section .init + +_start: + @ Get loader base from parent + mov r4, r0 + + @ Output 0x42 to the debug port + mov r0, #0x42 + bl debug_output + + @ Set up a stack + ldr sp, =__stack_addr + + @ Output 0x43 to the debug port + mov r0, #0x43 + bl debug_output + + @ clear BSS + ldr r1, =__bss_start + ldr r2, =__bss_end + mov r3, #0 +bss_loop: + @ check for the end + cmp r1, r2 + bge done_bss + @ clear the word and move on + str r3, [r1] + add r1, r1, #4 + b bss_loop + +done_bss: + mov r0, #0x44 + bl debug_output + @ take the plunge + mov r0, r4 + ldr r1, =_main+1 + mov lr, pc + bx r1 + @ _main returned! Go to whatever address it returned... + mov pc, r0 + +.pool + +debug_output: + @ load address of port + mov r3, #0xd800000 + @ load old value + ldr r2, [r3, #0xe0] + @ clear debug byte + bic r2, r2, #0xFF0000 + @ insert new value + and r0, r0, #0xFF + orr r2, r2, r0, LSL #16 + @ store back + str r2, [r3, #0xe0] + bx lr + diff --git a/loader/start.h b/loader/start.h new file mode 120000 index 0000000..9abaeac --- /dev/null +++ b/loader/start.h @@ -0,0 +1 @@ +../mini/start.h \ No newline at end of file diff --git a/loader/string.c b/loader/string.c new file mode 120000 index 0000000..92bbfe5 --- /dev/null +++ b/loader/string.c @@ -0,0 +1 @@ +../mini/string.c \ No newline at end of file diff --git a/loader/string.h b/loader/string.h new file mode 120000 index 0000000..48c55a6 --- /dev/null +++ b/loader/string.h @@ -0,0 +1 @@ +../mini/string.h \ No newline at end of file diff --git a/loader/types.h b/loader/types.h new file mode 120000 index 0000000..777aee0 --- /dev/null +++ b/loader/types.h @@ -0,0 +1 @@ +../mini/types.h \ No newline at end of file diff --git a/loader/utils.c b/loader/utils.c new file mode 120000 index 0000000..13e7651 --- /dev/null +++ b/loader/utils.c @@ -0,0 +1 @@ +../mini/utils.c \ No newline at end of file diff --git a/loader/utils.h b/loader/utils.h new file mode 120000 index 0000000..e7cc5a7 --- /dev/null +++ b/loader/utils.h @@ -0,0 +1 @@ +../mini/utils.h \ No newline at end of file diff --git a/loader/version.c b/loader/version.c new file mode 100644 index 0000000..19fd8ba --- /dev/null +++ b/loader/version.c @@ -0,0 +1 @@ +const char *bootmii_version = "%VERSION%"; diff --git a/loader/vsprintf.c b/loader/vsprintf.c new file mode 120000 index 0000000..f398df8 --- /dev/null +++ b/loader/vsprintf.c @@ -0,0 +1 @@ +../mini/vsprintf.c \ No newline at end of file diff --git a/loader/vsprintf.h b/loader/vsprintf.h new file mode 120000 index 0000000..bd61433 --- /dev/null +++ b/loader/vsprintf.h @@ -0,0 +1 @@ +../mini/vsprintf.h \ No newline at end of file diff --git a/mini b/mini new file mode 160000 index 0000000..befb64c --- /dev/null +++ b/mini @@ -0,0 +1 @@ +Subproject commit befb64ce1cd493946c9a9a0a412262a998f478d9 diff --git a/resetstub/.gitignore b/resetstub/.gitignore new file mode 100644 index 0000000..5099253 --- /dev/null +++ b/resetstub/.gitignore @@ -0,0 +1 @@ +*.elf diff --git a/resetstub/Makefile b/resetstub/Makefile new file mode 100644 index 0000000..2a23f0d --- /dev/null +++ b/resetstub/Makefile @@ -0,0 +1,23 @@ +include ../starlet.mk + +CFLAGS += -fpic +LDSCRIPT = stub.ld +LIBS = + +TARGET = resetstub-sym.elf +TARGET_STRIPPED = resetstub.elf +OBJS = stub.o + +include ../common.mk + +all: $(TARGET_STRIPPED) + +$(TARGET_STRIPPED): $(TARGET) + @echo "STRIP $@" + @$(STRIP) $< -o $@ + +clean: myclean + +myclean: + -rm -f $(TARGET) $(TARGET_STRIPPED) + diff --git a/resetstub/stub.S b/resetstub/stub.S new file mode 100644 index 0000000..6605043 --- /dev/null +++ b/resetstub/stub.S @@ -0,0 +1,31 @@ +/* + bootmii - a Free Software replacement for the Nintendo/BroadOn boot2. + dummy reset stub + +Copyright (C) 2008, 2009 Sven Peter + +# This code is licensed to you under the terms of the GNU GPL, version 2; +# see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt +*/ + +.global _start + +.arm +_start: + # enable boot0 memory mapping + ldr r0, =0x0d80018c + ldr r1, =0x1000 + ldr r2, [r0] + bic r2, r1 + str r2, [r0] + + # setup boot0 memory mirror to x'ffff_0000 + ldr r0, =0x0d800060 + mov r2, #0x20 + ldr r1, [r0] + bic r1, r2 + str r1, [r0] + + # jump to boot0 + ldr r0, =0xffff0000 + bx r0 diff --git a/resetstub/stub.ld b/resetstub/stub.ld new file mode 100644 index 0000000..094b4dc --- /dev/null +++ b/resetstub/stub.ld @@ -0,0 +1,78 @@ +/* + bootmii - a Free Software replacement for the Nintendo/BroadOn boot2. + reset stub linker script + +Copyright (C) 2008, 2009 Hector Martin "marcan" +Copyright (C) 2009 Andre Heider "dhewg" + +# This code is licensed to you under the terms of the GNU GPL, version 2; +# see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt +*/ + +OUTPUT_FORMAT("elf32-bigarm") +OUTPUT_ARCH(arm) +EXTERN(_start) +EXTERN(__ipc_info) +ENTRY(_start) + +MEMORY { + ram : ORIGIN = 0x93ff0000, LENGTH = 64K +} + +SECTIONS +{ + .init : + { + *(.init) + . = ALIGN(4); + } >ram + + .text : + { + *(.text*) + *(.text.*) + *(.gnu.warning) + *(.gnu.linkonce.t*) + *(.glue_7) + *(.glue_7t) + . = ALIGN(4); + } >ram + + .rodata : + { + *(.rodata) + *all.rodata*(*) + *(.roda) + *(.rodata.*) + *(.gnu.linkonce.r*) + . = ALIGN(4); + } >ram + + .data : + { + *(.data) + *(.data.*) + *(.gnu.linkonce.d*) + . = ALIGN(4); + } >ram + + .bss : + { + __bss_start = . ; + *(.dynbss) + *(.gnu.linkonce.b*) + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end = . ; + } >ram + + /DISCARD/ : + { + *(.ARM.exidx*) + *(.ARM.extab*) + } + +} + + diff --git a/starlet.mk b/starlet.mk new file mode 120000 index 0000000..41e9eba --- /dev/null +++ b/starlet.mk @@ -0,0 +1 @@ +mini/starlet.mk \ No newline at end of file diff --git a/stub/.gitignore b/stub/.gitignore new file mode 100644 index 0000000..bfbdbf1 --- /dev/null +++ b/stub/.gitignore @@ -0,0 +1,6 @@ +*.d +*.bin +*.elf +*.o +*.map + diff --git a/stub/Makefile b/stub/Makefile new file mode 100644 index 0000000..5d86bca --- /dev/null +++ b/stub/Makefile @@ -0,0 +1,27 @@ +include ../starlet.mk + +CFLAGS += -fpic +LDSCRIPT = stub.ld +LIBS = -lgcc + +TARGET = bootmii.elf +TARGET_BIN = bootmii.bin +OBJS = start.o stub.o loader.o utils.o + +include ../common.mk + +all: $(TARGET_BIN) + +$(TARGET_BIN): $(TARGET) + @echo " OBJCPY $@" + @$(OBJCOPY) -O binary $< $@ + +loader.o : ../loader/bootmii.elf + @echo " BIN2O $@" + @$(BIN2S) -a 32 $< | $(AS) -o $(@) + +clean: myclean + +myclean: + -rm -f $(TARGET_BIN) + diff --git a/stub/elf.h b/stub/elf.h new file mode 100644 index 0000000..4eac370 --- /dev/null +++ b/stub/elf.h @@ -0,0 +1,54 @@ +/* + bootmii - a Free Software replacement for the Nintendo/BroadOn boot2. + ELF structures + +Copyright (C) 2008, 2009 Hector Martin "marcan" + +# This code is licensed to you under the terms of the GNU GPL, version 2; +# see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt +*/ + +#ifndef __ELF_H__ +#define __ELF_H__ + +#include "types.h" + +#define EI_NIDENT 16 + +typedef struct { + unsigned char e_ident[EI_NIDENT]; + u16 e_type; + u16 e_machine; + u32 e_version; + void *e_entry; + u32 e_phoff; + u32 e_shoff; + u32 e_flags; + u16 e_ehsize; + u16 e_phentsize; + u16 e_phnum; + u16 e_shentsize; + u16 e_shnum; + u16 e_shtrndx; +} Elf32_Ehdr; + +typedef struct { + u32 p_type; + u32 p_offset; + void *p_vaddr; + void *p_paddr; + u32 p_filesz; + u32 p_memsz; + u32 p_flags; + u32 p_align; +} Elf32_Phdr; + +#define PT_NULL 0 +#define PT_LOAD 1 +#define PT_DYNAMIC 2 +#define PT_INTERP 3 +#define PT_NOTE 4 +#define PT_SHLIB 5 +#define PT_PHDR 6 + +#endif diff --git a/stub/hollywood.h b/stub/hollywood.h new file mode 100644 index 0000000..ad6924f --- /dev/null +++ b/stub/hollywood.h @@ -0,0 +1,31 @@ +/* + bootmii - a Free Software replacement for the Nintendo/BroadOn boot2. + Hollywood register definitions + +Copyright (C) 2008, 2009 Haxx Enterprises +Copyright (C) 2008, 2009 Sven Peter +Copyright (C) 2008, 2009 Hector Martin "marcan" +Copyright (C) 2008, 2009 John Kelley + +# This code is licensed to you under the terms of the GNU GPL, version 2; +# see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt +*/ + +#ifndef __HOLLYWOOD_H__ +#define __HOLLYWOOD_H__ + +/* Hollywood Registers */ + +#define HW_REG_BASE 0xd800000 +#define HW_TIMER (HW_REG_BASE + 0x010) +#define HW_IRQENABLE (HW_REG_BASE + 0x03c) +#define HW_MEMMIRR (HW_REG_BASE + 0x060) +#define HW_GPIO1ENABLE (HW_REG_BASE + 0x0dc) +#define HW_GPIO1OUT (HW_REG_BASE + 0x0e0) +#define HW_GPIO1DIR (HW_REG_BASE + 0x0e4) +#define HW_GPIO1IN (HW_REG_BASE + 0x0e8) +#define HW_GPIO1INTLVL (HW_REG_BASE + 0x0ec) +#define HW_GPIO1INTFLAG (HW_REG_BASE + 0x0f0) +#define HW_GPIO1OWNER (HW_REG_BASE + 0x0fc) + +#endif diff --git a/stub/start.S b/stub/start.S new file mode 100644 index 0000000..f476c35 --- /dev/null +++ b/stub/start.S @@ -0,0 +1,144 @@ +/* + bootmii - a Free Software replacement for the Nintendo/BroadOn boot2. + system startup + +Copyright (C) 2008, 2009 Hector Martin "marcan" + +# This code is licensed to you under the terms of the GNU GPL, version 2; +# see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt +*/ + +.arm + +.extern _main +.extern __got_start +.extern __got_end +.extern __bss_start +.extern __bss_end +.extern __stack_addr +.globl _start +.globl debug_output + + +.section .init + +_start: + @ Get real address of _start + sub r4, pc, #8 + @ Subtract offset to get the address that we were loaded at + ldr r0, =_start + sub r4, r4, r0 + @ Output 0x42 to the debug port + mov r0, #0x42 + bl debug_output + + @ Set up a stack + ldr sp, =__stack_addr + add sp, r4 + + @ perform boot2v3 memory controller poke + bl memctrl_do_sub_sub_poke + + @ Output 0x43 to the debug port + mov r0, #0x43 + bl debug_output + + @ check for a previous GOT relocation + ldr r1, [pc, #_is_reloced - . - 8] + cmp r1, #0 + bne done_got + + @ relocate the GOT entries + ldr r1, =__got_start + add r1, r4 + ldr r2, =__got_end + add r2, r4 +got_loop: + @ check for the end + cmp r1, r2 + beq done_got + @ read the GOT entry + ldr r3, [r1] + @ add our base address + add r3, r4 + str r3, [r1] + @ move on + add r1, r1, #4 + b got_loop + +done_got: + + @ note that we have already reloced GOT + mov r1, #1 + str r1, [pc, #_is_reloced - . - 8] + + @ clear BSS + ldr r1, =__bss_start + add r1, r4 + ldr r2, =__bss_end + add r2, r4 + mov r3, #0 +bss_loop: + @ check for the end + cmp r1, r2 + beq done_bss + @ clear the word and move on + str r3, [r1] + add r1, r1, #4 + b bss_loop + +done_bss: + mov r0, #0x44 + bl debug_output + @ take the plunge + mov r0, r4 + bl _main + @ _main returned! Go to whatever address it returned... + mov r1, r0 + mov r0, r4 + mov pc, r1 + +_is_reloced: + .long 0 + +memctrl_do_sub_sub_poke: + stmdb sp!, {lr} + ldr r0, =0x163 @ reg_address + mov r1, #0x4C @ address + bl memctrl_sub_poke + ldr r0, =0x163 @ read address back (flush?) + bl memctrl_sub_peek + ldr r0, =0x162 @ reg_data + mov r1, #1 @ data + bl memctrl_sub_poke + ldmia sp!, {pc} + +memctrl_sub_poke: + ldr r2, =0xD8B4000 + strh r0, [r2, #0x74] @ reg_address <= address + ldrh r0, [r2, #0x74] @ read reg_address back + strh r1, [r2, #0x76] @ reg_data <= data + mov pc, lr + +memctrl_sub_peek: + ldr r2, =0xD8B4000 + strh r0, [r2, #0x74] @ reg_address <= address + ldrh r0, [r2, #0x74] @ read reg_address back + ldrh r0, [r2, #0x76] @ data <= reg_data + mov pc, lr + +.pool + +debug_output: + @ load address of port + mov r3, #0xd800000 + @ load old value + ldr r2, [r3, #0xe0] + @ clear debug byte + bic r2, r2, #0xFF0000 + @ insert new value + and r0, r0, #0xFF + orr r2, r2, r0, LSL #16 + @ store back + str r2, [r3, #0xe0] + mov pc, lr diff --git a/stub/start.h b/stub/start.h new file mode 100644 index 0000000..f64a0b7 --- /dev/null +++ b/stub/start.h @@ -0,0 +1,18 @@ +/* + bootmii - a Free Software replacement for the Nintendo/BroadOn boot2. + system startup + +Copyright (C) 2008, 2009 Hector Martin "marcan" + +# This code is licensed to you under the terms of the GNU GPL, version 2; +# see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt +*/ + +#ifndef __START_H__ +#define __START_H__ + +#include "types.h" + +void debug_output(u8 byte); + +#endif diff --git a/stub/stub.c b/stub/stub.c new file mode 100644 index 0000000..a348f03 --- /dev/null +++ b/stub/stub.c @@ -0,0 +1,116 @@ +/* + bootmii - a Free Software replacement for the Nintendo/BroadOn boot2. + ELF loader stub + +Copyright (C) 2008, 2009 Haxx Enterprises +Copyright (C) 2008, 2009 Sven Peter +Copyright (C) 2008, 2009 Hector Martin "marcan" +Copyright (C) 2009 Andre Heider "dhewg" +Copyright (C) 2009 John Kelley + +# This code is licensed to you under the terms of the GNU GPL, version 2; +# see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt +*/ + +#include "types.h" +#include "utils.h" +#include "start.h" +#include "hollywood.h" +#include "elf.h" + +typedef struct { + u32 hdrsize; + u32 loadersize; + u32 elfsize; + u32 argument; +} ioshdr; + +static inline void _memcpy(void *dst, const void *src, size_t len) +{ + size_t i; + + for (i = 0; i < len; i++) + ((unsigned char *)dst)[i] = ((unsigned char *)src)[i]; +} + +static inline int memcmp(const char *s1, const u8 *s2, size_t len) +{ + size_t i; + + for (i = 0; i < len; i++) + if (s1[i] != s2[i]) return s1[i] - s2[i]; + + return 0; +} + +void *loadelf(const u8 *elf) { + if(memcmp("\x7F" "ELF\x01\x02\x01",elf,7)) { + panic(0xE3); + } + + Elf32_Ehdr *ehdr = (Elf32_Ehdr*)elf; + if(ehdr->e_phoff == 0) { + panic(0xE4); + } + int count = ehdr->e_phnum; + Elf32_Phdr *phdr = (Elf32_Phdr*)(elf + ehdr->e_phoff); + while(count--) + { + if(phdr->p_type == PT_LOAD) { + const void *src = elf + phdr->p_offset; + _memcpy(phdr->p_paddr, src, phdr->p_filesz); + } + phdr++; + } + return ehdr->e_entry; +} + +static inline void mem_setswap(void) +{ + u32 d = read32(HW_MEMMIRR); + if(!(d & 0x20)) + write32(HW_MEMMIRR, d | 0x20); +} + +extern const u8 bootmii_elf[]; +extern const u8 bootmii_elf_end[]; +extern const u32 bootmii_elf_size; + +#define GP_POWER 0x000001 + +void *_main(void *base) +{ + ioshdr *hdr = (ioshdr*)base; + u8 *elf; + void *entry; + + elf = (u8*) base; + elf += hdr->hdrsize + hdr->loadersize; + + debug_output(0xF1); + mem_setswap(); + + write32(HW_IRQENABLE, 0); + + set32(HW_GPIO1ENABLE, GP_POWER); + clear32(HW_GPIO1DIR, GP_POWER); + clear32(HW_GPIO1OWNER, GP_POWER); + set32(HW_GPIO1INTLVL, GP_POWER); + udelay(1000); + set32(HW_GPIO1INTFLAG, GP_POWER); + udelay(400000); + if(read32(HW_GPIO1INTFLAG) & GP_POWER) { + debug_output(0xC0); + loadelf(elf); + debug_output(0xC1); + return (void *) 0xFFFF0000; + } + + // NOTE: END CRITICAL ZONE + + debug_output(0xF2); + entry = loadelf(bootmii_elf); + debug_output(0xF3); + + return entry; +} diff --git a/stub/stub.ld b/stub/stub.ld new file mode 100644 index 0000000..4ba674c --- /dev/null +++ b/stub/stub.ld @@ -0,0 +1,108 @@ +/* + bootmii - a Free Software replacement for the Nintendo/BroadOn boot2. + ELF loader stub linker script + +Copyright (C) 2008, 2009 Hector Martin "marcan" + +# This code is licensed to you under the terms of the GNU GPL, version 2; +# see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt +*/ + +OUTPUT_FORMAT("elf32-bigarm") +OUTPUT_ARCH(arm) +EXTERN(_start) +ENTRY(_start) + +__base_addr = 0; + +SECTIONS +{ + . = __base_addr; + .header : + { + __header = .; + /* Entry point (offset) */ + LONG(__code_start); + /* Loader size */ + LONG(__loader_size); + /* ELF size */ + LONG(0); + /* Boot argument? */ + LONG(0); + . = ALIGN(16); + } + + __code_start = .; + + .init : + { + *(.init) + . = ALIGN(4); + } + + .got : + { + __got_start = .; + *(.got.*) + *(.got) + . = ALIGN(4); + __got_end = . ; + } + + .text : + { + *(.text) + *(.text.*) + *(.gnu.warning) + *(.gnu.linkonce.t*) + *(.glue_7) + *(.glue_7t) + . = ALIGN(4); + } + + __text_end = . ; + + .rodata : + { + *(.rodata) + *all.rodata*(*) + *(.roda) + *(.rodata.*) + *(.gnu.linkonce.r*) + . = ALIGN(4); + } + + .data : + { + *(.data) + *(.data.*) + *(.gnu.linkonce.d*) + . = ALIGN(4); + } + + .bss : + { + __bss_start = . ; + *(.dynbss) + *(.gnu.linkonce.b*) + *(.bss*) + *(.sbss*) + *(COMMON) + . = ALIGN(32); + __bss_end = . ; + } + +} + +__stack_end = (__bss_end); +__stack_addr = (__bss_end + 0x100); + +__end = __stack_addr ; +__loader_size = __end - __code_start; + +PROVIDE (__stack_end = __stack_end); +PROVIDE (__stack_addr = __stack_addr); +PROVIDE (__got_start = __got_start); +PROVIDE (__got_end = __got_end); +PROVIDE (__bss_start = __bss_start); +PROVIDE (__bss_end = __bss_end); diff --git a/stub/types.h b/stub/types.h new file mode 100644 index 0000000..4118d80 --- /dev/null +++ b/stub/types.h @@ -0,0 +1,38 @@ +/* + bootmii - a Free Software replacement for the Nintendo/BroadOn boot2. + types, memory areas, etc + +Copyright (C) 2008, 2009 Hector Martin "marcan" + +# This code is licensed to you under the terms of the GNU GPL, version 2; +# see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt +*/ + +#ifndef __TYPES_H__ +#define __TYPES_H__ + +typedef unsigned char u8; +typedef unsigned short u16; +typedef unsigned int u32; +typedef unsigned long long u64; + +typedef signed char s8; +typedef signed short s16; +typedef signed int s32; +typedef signed long long s64; + +typedef volatile unsigned char vu8; +typedef volatile unsigned short vu16; +typedef volatile unsigned int vu32; +typedef volatile unsigned long long vu64; + +typedef volatile signed char vs8; +typedef volatile signed short vs16; +typedef volatile signed int vs32; +typedef volatile signed long long vs64; + +typedef s32 size_t; + +#define NULL ((void *)0) + +#endif diff --git a/stub/utils.c b/stub/utils.c new file mode 100644 index 0000000..bbc8d58 --- /dev/null +++ b/stub/utils.c @@ -0,0 +1,31 @@ +/* + bootmii - a Free Software replacement for the Nintendo/BroadOn boot2. + random utilities + +Copyright (C) 2008, 2009 Hector Martin "marcan" + +# This code is licensed to you under the terms of the GNU GPL, version 2; +# see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt +*/ + +#include "types.h" +#include "utils.h" +#include "hollywood.h" +#include "start.h" + +void delay(u32 d) +{ + write32(HW_TIMER, 0); + while(read32(HW_TIMER) < d); +} + +void panic(u8 v) +{ + while(1) { + debug_output(v); + udelay(500000); + debug_output(0); + udelay(500000); + } +} + diff --git a/stub/utils.h b/stub/utils.h new file mode 100644 index 0000000..2c32d72 --- /dev/null +++ b/stub/utils.h @@ -0,0 +1,177 @@ +/* + bootmii - a Free Software replacement for the Nintendo/BroadOn boot2. + random utilities + +Copyright (C) 2008, 2009 Hector Martin "marcan" + +# This code is licensed to you under the terms of the GNU GPL, version 2; +# see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt +*/ + +#ifndef __UTILS_H__ +#define __UTILS_H__ + +static inline u32 read32(u32 addr) +{ + u32 data; + __asm__ volatile ("ldr\t%0, [%1]" : "=r" (data) : "r" (addr)); + return data; +} + +static inline void write32(u32 addr, u32 data) +{ + __asm__ volatile ("str\t%0, [%1]" : : "r" (data), "r" (addr)); +} + +static inline u32 set32(u32 addr, u32 set) +{ + u32 data; + __asm__ volatile ( + "ldr\t%0, [%1]\n" + "\torr\t%0, %2\n" + "\tstr\t%0, [%1]" + : "=&r" (data) + : "r" (addr), "r" (set) + ); + return data; +} + +static inline u32 clear32(u32 addr, u32 clear) +{ + u32 data; + __asm__ volatile ( + "ldr\t%0, [%1]\n" + "\tbic\t%0, %2\n" + "\tstr\t%0, [%1]" + : "=&r" (data) + : "r" (addr), "r" (clear) + ); + return data; +} + + +static inline u32 mask32(u32 addr, u32 clear, u32 set) +{ + u32 data; + __asm__ volatile ( + "ldr\t%0, [%1]\n" + "\tbic\t%0, %3\n" + "\torr\t%0, %2\n" + "\tstr\t%0, [%1]" + : "=&r" (data) + : "r" (addr), "r" (set), "r" (clear) + ); + return data; +} + +static inline u16 read16(u32 addr) +{ + u32 data; + __asm__ volatile ("ldrh\t%0, [%1]" : "=r" (data) : "r" (addr)); + return data; +} + +static inline void write16(u32 addr, u16 data) +{ + __asm__ volatile ("strh\t%0, [%1]" : : "r" (data), "r" (addr)); +} + +static inline u16 set16(u32 addr, u16 set) +{ + u16 data; + __asm__ volatile ( + "ldrh\t%0, [%1]\n" + "\torr\t%0, %2\n" + "\tstrh\t%0, [%1]" + : "=&r" (data) + : "r" (addr), "r" (set) + ); + return data; +} + +static inline u16 clear16(u32 addr, u16 clear) +{ + u16 data; + __asm__ volatile ( + "ldrh\t%0, [%1]\n" + "\tbic\t%0, %2\n" + "\tstrh\t%0, [%1]" + : "=&r" (data) + : "r" (addr), "r" (clear) + ); + return data; +} + + +static inline u16 mask16(u32 addr, u16 clear, u16 set) +{ + u16 data; + __asm__ volatile ( + "ldrh\t%0, [%1]\n" + "\tbic\t%0, %3\n" + "\torr\t%0, %2\n" + "\tstrh\t%0, [%1]" + : "=&r" (data) + : "r" (addr), "r" (set), "r" (clear) + ); + return data; +} + +static inline u8 read8(u32 addr) +{ + u32 data; + __asm__ volatile ("ldrb\t%0, [%1]" : "=r" (data) : "r" (addr)); + return data; +} + +static inline void write8(u32 addr, u8 data) +{ + __asm__ volatile ("strb\t%0, [%1]" : : "r" (data), "r" (addr)); +} + +static inline u8 set8(u32 addr, u8 set) +{ + u8 data; + __asm__ volatile ( + "ldrb\t%0, [%1]\n" + "\torr\t%0, %2\n" + "\tstrb\t%0, [%1]" + : "=&r" (data) + : "r" (addr), "r" (set) + ); + return data; +} + +static inline u8 clear8(u32 addr, u8 clear) +{ + u8 data; + __asm__ volatile ( + "ldrb\t%0, [%1]\n" + "\tbic\t%0, %2\n" + "\tstrb\t%0, [%1]" + : "=&r" (data) + : "r" (addr), "r" (clear) + ); + return data; +} + + +static inline u8 mask8(u32 addr, u8 clear, u8 set) +{ + u8 data; + __asm__ volatile ( + "ldrb\t%0, [%1]\n" + "\tbic\t%0, %3\n" + "\torr\t%0, %2\n" + "\tstrb\t%0, [%1]" + : "=&r" (data) + : "r" (addr), "r" (set), "r" (clear) + ); + return data; +} + +#define udelay(x) delay((x) * 19 / 10) +void delay(u32 d); +void panic(u8 v); + +#endif