Initial commit

This commit is contained in:
Hector Martin 2022-08-08 15:33:53 +09:00
commit 5eb67e005e
61 changed files with 2435 additions and 0 deletions

8
.gitignore vendored Normal file
View File

@ -0,0 +1,8 @@
git_version.h
*.d
*.bin
*.elf
*.map
*~
*.o
.*.swp

3
.gitmodules vendored Normal file
View File

@ -0,0 +1,3 @@
[submodule "mini"]
path = mini
url = https://github.com/fail0verflow/mini

340
COPYING Normal file
View File

@ -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.
<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 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.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

14
Makefile Normal file
View File

@ -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

54
README.md Normal file
View File

@ -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.

1
common.mk Symbolic link
View File

@ -0,0 +1 @@
mini/common.mk

14
describe.sh Executable file
View File

@ -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

15
describesimple.sh Executable file
View File

@ -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

7
loader/.gitignore vendored Normal file
View File

@ -0,0 +1,7 @@
*.d
*.bin
*.elf
*.o
*.map
loader_version.txt

43
loader/Makefile Normal file
View File

@ -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

1
loader/bsdtypes.h Symbolic link
View File

@ -0,0 +1 @@
../mini/bsdtypes.h

1
loader/diskio.c Symbolic link
View File

@ -0,0 +1 @@
../mini/diskio.c

1
loader/diskio.h Symbolic link
View File

@ -0,0 +1 @@
../mini/diskio.h

1
loader/elf.h Symbolic link
View File

@ -0,0 +1 @@
../mini/elf.h

1
loader/errno.h Symbolic link
View File

@ -0,0 +1 @@
../mini/errno.h

1
loader/ff.c Symbolic link
View File

@ -0,0 +1 @@
../mini/ff.c

1
loader/ff.h Symbolic link
View File

@ -0,0 +1 @@
../mini/ff.h

173
loader/gecko.c Normal file
View File

@ -0,0 +1,173 @@
/*
bootmii - a Free Software replacement for the Nintendo/BroadOn boot2.
USBGecko support code
Copyright (c) 2008 Nuke - <wiinuke@gmail.com>
Copyright (C) 2008, 2009 Hector Martin "marcan" <marcan@marcan.st>
Copyright (C) 2008, 2009 Sven Peter <sven@svenpeter.dev>
Copyright (C) 2009 Andre Heider "dhewg" <dhewg@wiibrew.org>
# 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;
}

31
loader/gecko.h Normal file
View File

@ -0,0 +1,31 @@
/*
bootmii - a Free Software replacement for the Nintendo/BroadOn boot2.
USBGecko support code
Copyright (c) 2008 Nuke - <wiinuke@gmail.com>
Copyright (C) 2008, 2009 Hector Martin "marcan" <marcan@marcan.st>
Copyright (C) 2008, 2009 Sven Peter <sven@svenpeter.dev>
Copyright (C) 2009 Andre Heider "dhewg" <dhewg@wiibrew.org>
# 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

1
loader/gpio.h Symbolic link
View File

@ -0,0 +1 @@
../mini/gpio.h

1
loader/hollywood.h Symbolic link
View File

@ -0,0 +1 @@
../mini/hollywood.h

1
loader/integer.h Symbolic link
View File

@ -0,0 +1 @@
../mini/integer.h

1
loader/irq.h Symbolic link
View File

@ -0,0 +1 @@
../mini/irq.h

225
loader/lcd.c Normal file
View File

@ -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" <marcan@marcan.st>
# 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<WIDTH;x++) {
_lcdwrite(ddram[x + linestarts[y+count]]);
}
}
for(;y<HEIGHT;y++) {
for(x=0;x<WIDTH;x++) {
ddram[linestarts[y] + x] = ' ';
}
}
_lcdgoto(linestarts[HEIGHT-1]);
}
void lcd_init(void)
{
cx = cy = 0;
ddaddr = 0;
memset(ddram, ' ', 0x80);
clear32(LCD_PORT, LCD_MASK);
udelay(100000);
_lcdnybble(0, (LCD_FUNCTION_SET | FS_8BIT)>>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

37
loader/lcd.h Normal file
View File

@ -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" <marcan@marcan.st>
# 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

90
loader/loader.ld Normal file
View File

@ -0,0 +1,90 @@
/*
mini - a Free Software replacement for the Nintendo/BroadOn IOS.
linker script
Copyright (C) 2008, 2009 Hector Martin "marcan" <marcan@marcansoft.com>
# 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);

390
loader/main.c Normal file
View File

@ -0,0 +1,390 @@
/*
bootmii - a Free Software replacement for the Nintendo/BroadOn boot2.
Main loader code
Copyright (C) 2008, 2009 Haxx Enterprises <bushing@gmail.com>
Copyright (C) 2008, 2009 Sven Peter <sven@svenpeter.dev>
Copyright (C) 2008, 2009 Hector Martin "marcan" <marcan@marcan.st>
Copyright (C) 2009 Andre Heider "dhewg" <dhewg@wiibrew.org>
Copyright (C) 2009 John Kelley <wiidev@kelley.ca>
# 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;
}

1
loader/memory.c Symbolic link
View File

@ -0,0 +1 @@
../mini/memory.c

1
loader/memory.h Symbolic link
View File

@ -0,0 +1 @@
../mini/memory.h

1
loader/memory_asm.S Symbolic link
View File

@ -0,0 +1 @@
../mini/memory_asm.S

1
loader/sdhc.c Symbolic link
View File

@ -0,0 +1 @@
../mini/sdhc.c

1
loader/sdhc.h Symbolic link
View File

@ -0,0 +1 @@
../mini/sdhc.h

1
loader/sdmmc.c Symbolic link
View File

@ -0,0 +1 @@
../mini/sdmmc.c

1
loader/sdmmc.h Symbolic link
View File

@ -0,0 +1 @@
../mini/sdmmc.h

78
loader/start.S Normal file
View File

@ -0,0 +1,78 @@
/*
bootmii - a Free Software replacement for the Nintendo/BroadOn boot2.
system startup
Copyright (C) 2008, 2009 Hector Martin "marcan" <marcan@marcan.st>
# 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

1
loader/start.h Symbolic link
View File

@ -0,0 +1 @@
../mini/start.h

1
loader/string.c Symbolic link
View File

@ -0,0 +1 @@
../mini/string.c

1
loader/string.h Symbolic link
View File

@ -0,0 +1 @@
../mini/string.h

1
loader/types.h Symbolic link
View File

@ -0,0 +1 @@
../mini/types.h

1
loader/utils.c Symbolic link
View File

@ -0,0 +1 @@
../mini/utils.c

1
loader/utils.h Symbolic link
View File

@ -0,0 +1 @@
../mini/utils.h

1
loader/version.c Normal file
View File

@ -0,0 +1 @@
const char *bootmii_version = "%VERSION%";

1
loader/vsprintf.c Symbolic link
View File

@ -0,0 +1 @@
../mini/vsprintf.c

1
loader/vsprintf.h Symbolic link
View File

@ -0,0 +1 @@
../mini/vsprintf.h

1
mini Submodule

@ -0,0 +1 @@
Subproject commit befb64ce1cd493946c9a9a0a412262a998f478d9

1
resetstub/.gitignore vendored Normal file
View File

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

23
resetstub/Makefile Normal file
View File

@ -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)

31
resetstub/stub.S Normal file
View File

@ -0,0 +1,31 @@
/*
bootmii - a Free Software replacement for the Nintendo/BroadOn boot2.
dummy reset stub
Copyright (C) 2008, 2009 Sven Peter <sven@svenpeter.dev>
# 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

78
resetstub/stub.ld Normal file
View File

@ -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" <marcan@marcansoft.com>
Copyright (C) 2009 Andre Heider "dhewg" <dhewg@wiibrew.org>
# 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*)
}
}

1
starlet.mk Symbolic link
View File

@ -0,0 +1 @@
mini/starlet.mk

6
stub/.gitignore vendored Normal file
View File

@ -0,0 +1,6 @@
*.d
*.bin
*.elf
*.o
*.map

27
stub/Makefile Normal file
View File

@ -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)

54
stub/elf.h Normal file
View File

@ -0,0 +1,54 @@
/*
bootmii - a Free Software replacement for the Nintendo/BroadOn boot2.
ELF structures
Copyright (C) 2008, 2009 Hector Martin "marcan" <marcan@marcan.st>
# 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

31
stub/hollywood.h Normal file
View File

@ -0,0 +1,31 @@
/*
bootmii - a Free Software replacement for the Nintendo/BroadOn boot2.
Hollywood register definitions
Copyright (C) 2008, 2009 Haxx Enterprises <bushing@gmail.com>
Copyright (C) 2008, 2009 Sven Peter <sven@svenpeter.dev>
Copyright (C) 2008, 2009 Hector Martin "marcan" <marcan@marcan.st>
Copyright (C) 2008, 2009 John Kelley <wiidev@kelley.ca>
# 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

144
stub/start.S Normal file
View File

@ -0,0 +1,144 @@
/*
bootmii - a Free Software replacement for the Nintendo/BroadOn boot2.
system startup
Copyright (C) 2008, 2009 Hector Martin "marcan" <marcan@marcan.st>
# 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

18
stub/start.h Normal file
View File

@ -0,0 +1,18 @@
/*
bootmii - a Free Software replacement for the Nintendo/BroadOn boot2.
system startup
Copyright (C) 2008, 2009 Hector Martin "marcan" <marcan@marcan.st>
# 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

116
stub/stub.c Normal file
View File

@ -0,0 +1,116 @@
/*
bootmii - a Free Software replacement for the Nintendo/BroadOn boot2.
ELF loader stub
Copyright (C) 2008, 2009 Haxx Enterprises <bushing@gmail.com>
Copyright (C) 2008, 2009 Sven Peter <sven@svenpeter.dev>
Copyright (C) 2008, 2009 Hector Martin "marcan" <marcan@marcan.st>
Copyright (C) 2009 Andre Heider "dhewg" <dhewg@wiibrew.org>
Copyright (C) 2009 John Kelley <wiidev@kelley.ca>
# 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;
}

108
stub/stub.ld Normal file
View File

@ -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" <marcan@marcansoft.com>
# 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);

38
stub/types.h Normal file
View File

@ -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" <marcan@marcan.st>
# 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

31
stub/utils.c Normal file
View File

@ -0,0 +1,31 @@
/*
bootmii - a Free Software replacement for the Nintendo/BroadOn boot2.
random utilities
Copyright (C) 2008, 2009 Hector Martin "marcan" <marcan@marcan.st>
# 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);
}
}

177
stub/utils.h Normal file
View File

@ -0,0 +1,177 @@
/*
bootmii - a Free Software replacement for the Nintendo/BroadOn boot2.
random utilities
Copyright (C) 2008, 2009 Hector Martin "marcan" <marcan@marcan.st>
# 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