1
0
mirror of git://projects.qi-hardware.com/iris.git synced 2025-04-21 12:27:27 +03:00

Add unbricking method

This commit is contained in:
Bas Wijnen
2010-10-10 10:46:12 +02:00
parent 5f9fd7cc0f
commit 9aff93c300
8 changed files with 405 additions and 312 deletions

View File

@@ -320,4 +320,4 @@ static void erase (unsigned a):
addr (row >> 8)
addr (row >> 16)
cmd (CMD_ERASE2)
debug ("nand erase %d done\n", a)
//debug ("nand erase %d done\n", a)

View File

@@ -17,16 +17,20 @@
start_load = 0x80600000
load = 0x80000000
UDC_BOOT = comment this out for sd boot
# Uncomment one of these to select the boot method for the image.
#UDC_BOOT = yes
#SD_BOOT = yes
UNBRICK = yes
arch_iris_sources = mips/interrupts.cc mips/arch.cc
boot_sources = mips/init.cc mips/nanonote/board.cc
arch_headers = mips/arch.hh mips/nanonote/jz4740.hh mips/nanonote/board.hh mips/nand.hh
udc_boot_programs = udc
sd_boot_programs = sd+mmc partition fat
unbrick_boot_programs = nand usb-mass-storage
standard_boot_programs = bootinit
programs = init usb-mass-storage gpio lcd bsquare ball buzzer metronome elfrun alarm rtc gui nand test boot booter $(udc_boot_programs) $(sd_boot_programs) $(standard_boot_programs)
programs = init gpio lcd bsquare ball buzzer metronome elfrun alarm rtc gui test boot booter $(udc_boot_programs) $(sd_boot_programs) $(unbrick_boot_programs) $(standard_boot_programs)
ARCH_CPPFLAGS = -I. -Imips -Imips/nanonote -Wa,-mips32 -DNANONOTE -DUSE_SERIAL
CROSS = mipsel-linux-gnu-
@@ -34,21 +38,35 @@ OBJDUMP = $(CROSS)objdump
junk = mdebug.abi32 reginfo comment pdr
OBJCOPYFLAGS = $(addprefix --remove-section=.,$(junk))
ifdef UDC_BOOT
ifneq ($(UDC_BOOT),)
boot_threads = $(standard_boot_programs) $(udc_boot_programs)
threadlist = mips/nanonote/threadlist-udc
ARCH_CXXFLAGS = -DNUM_THREADS=2
BOOT_CPPFLAGS = -DUDCBOOT
all: mips/nanonote/nand-boot.raw test
mips/start.o: TARGET =
else
ifneq ($(SD_BOOT),)
boot_threads = $(standard_boot_programs) $(sd_boot_programs)
threadlist = mips/nanonote/threadlist-sd
ARCH_CXXFLAGS = -DNUM_THREADS=4
BOOT_CPPFLAGS = -DSDBOOT
all: mips/nanonote/nand-boot.raw iris-sd.tar
mips/start.o: TARGET = -DWRAPPED
iris-sd.tar: $(addprefix fs/,$(addsuffix .elf,$(programs))) mips/start.raw.gz fs/init.config
mkimage -A mips -T kernel -a $(start_load) -e $(shell /bin/sh -c '$(OBJDUMP) -t mips/start.elf | grep __start$$ | cut -b1-8') -n Iris -d mips/start.raw.gz fs/uimage | sed -e 's/:/;/g'
cd fs && tar cvf ../$@ uimage init.config $(addsuffix .elf,$(programs)) --dereference
else
ifneq ($(UNBRICK),)
boot_threads = $(standard_boot_programs) $(unbrick_boot_programs)
ARCH_CXXFLAGS = -DNUM_THREADS=3
BOOT_CPPFLAGS = -DUNBRICK
all: mips/nanonote/nand-boot.raw iris.raw unbrick
mips/start.o: TARGET =
unbrick: mips/nanonote/unbrick.cc
g++ -Wall -Wextra -Werror `pkg-config --cflags --libs shevek` -lusb $< -o $@
else
error Please define your boot method.
endif
endif
endif
iris.elf: LDFLAGS = --omagic -Ttext $(load)
@@ -83,7 +101,7 @@ nanonote-boot: mips/nanonote/nanonote-boot.cc mips/nanonote/sdram-setup.raw
mips/nanonote/sdram-setup.elf: mips/nanonote/sdram-setup.ld
mips/nanonote/sdram-setup.elf: LDFLAGS = --omagic -T mips/nanonote/sdram-setup.ld
$(threadlist).o: $(addprefix fs/,$(addsuffix .elf,$(boot_threads)))
mips/nanonote/threadlist.o: $(addprefix fs/,$(addsuffix .elf,$(boot_threads)))
mips/boot.o: TARGET_FLAGS = -DMEMORY_SIZE="32 << 20"
mips/init.o: TARGET_FLAGS = -I/usr/include
source/bootinit.o: TARGET_FLAGS = -I/usr/include
@@ -99,10 +117,10 @@ source/charset.data: source/charset
$< > $@
%.o:%.S Makefile Makefile.arch mips/arch.hh
$(CC) $(CPPFLAGS) $(TARGET_FLAGS) -DKERNEL_STACK_SIZE=0x1000 -c $< -o $@
$(CC) $(CPPFLAGS) $(BOOT_CPPFLAGS) $(TARGET_FLAGS) -DKERNEL_STACK_SIZE=0x1000 -c $< -o $@
# entry.o must be the first file. threadlist.o must be the first of the init objects (which can be freed after loading).
iris.elf: mips/entry.o $(subst .cc,.o,$(iris_sources)) $(threadlist).o mips/boot.o $(subst .cc,.o,$(boot_sources))
iris.elf: mips/entry.o $(subst .cc,.o,$(iris_sources)) mips/nanonote/threadlist.o mips/boot.o $(subst .cc,.o,$(boot_sources))
$(LD) $(LDFLAGS) $^ -o $@
mips/start.elf: mips/start.o

View File

@@ -1,39 +0,0 @@
// Iris: micro-kernel for a capability-based operating system.
// mips/nanonote/threadlist.S: List of initial threads.
// Copyright 2009 Bas Wijnen <wijnen@debian.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
.globl init_start
.globl thread_start
.set noreorder
.balign 0x1000
thread0:
.incbin "fs/bootinit.elf"
.balign 0x1000
thread1:
.incbin "fs/udc.elf"
.balign 0x1000
thread2:
// Everything from here may be freed after kernel initialization.
init_start:
thread_start:
.word thread0
.word thread1
.word thread2

View File

@@ -19,6 +19,27 @@
.globl thread_start
.set noreorder
#if defined (UDCBOOT)
.balign 0x1000
thread0:
.incbin "fs/bootinit.elf"
.balign 0x1000
thread1:
.incbin "fs/udc.elf"
.balign 0x1000
thread2:
// Everything from here may be freed after kernel initialization.
init_start:
thread_start:
.word thread0
.word thread1
.word thread2
#elif defined (SDBOOT)
.balign 0x1000
thread0:
.incbin "fs/bootinit.elf"
@@ -46,4 +67,31 @@ thread_start:
.word thread1
.word thread2
.word thread3
.word thread4
#elif defined (UNBRICK)
.balign 0x1000
thread0:
.incbin "fs/bootinit.elf"
.balign 0x1000
thread1:
.incbin "fs/nand.elf"
.balign 0x1000
thread2:
.incbin "fs/usb-mass-storage.elf"
.balign 0x1000
thread3:
// Everything from here may be freed after kernel initialization.
init_start:
thread_start:
.word thread0
.word thread1
.word thread2
.word thread3
#else
#error "boot method not defined"
#endif

135
mips/nanonote/unbrick.ccp Normal file
View File

@@ -0,0 +1,135 @@
#pypp 0
// Iris: micro-kernel for a capability-based operating system.
// mips/nanonote/unbrick.ccp: Host-side helper for USB boot.
// Copyright 2009-2010 Bas Wijnen <wijnen@debian.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <unistd.h>
#include <usb.h>
#include <fstream>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstring>
#include <shevek/args.hh>
#include <shevek/error.hh>
#define STAGE1_FILE "stage1.raw"
static usb_dev_handle *handle
static int const boot_vendor = 0x601a
static int const boot_product = 0x4740
static int const run_vendor = 0xfffe
static int const run_product = 0x0002
static unsigned const timeout = 10000
void boot (std::string const &filename, unsigned load, unsigned entry)
static unsigned const STAGE1_LOAD = 0x80002000
static unsigned const STAGE1_ENTRY = STAGE1_LOAD
enum requests:
VR_GET_CPU_INFO = 0
VR_SET_DATA_ADDRESS = 1
VR_SET_DATA_LENGTH = 2
VR_FLUSH_CACHES = 3
VR_PROGRAM_START1 = 4
VR_PROGRAM_START2 = 5
void request (requests num, unsigned data = 0)
void get_device (unsigned vendor, unsigned product, unsigned tries)
void request (requests r, unsigned data):
if usb_control_msg (handle, USB_ENDPOINT_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, r, (data >> 16) & 0xffff, data & 0xffff, NULL, 0, timeout) < 0:
std::cerr << "unable to send control message to NanoNote: " << usb_strerror () << ".\n"
usb_release_interface (handle, 0)
usb_close (handle)
handle = NULL
void send_file (unsigned address, int size, char const *data):
request (VR_SET_DATA_ADDRESS, address)
char const *ptr = data
while ptr - data < size:
int ret = usb_bulk_write (handle, 1, ptr, size - (ptr - data), timeout)
if ret <= 0:
std::cerr << "failed to write to NanoNote.\n"
usb_release_interface (handle, 0)
usb_close (handle)
handle = NULL
return
ptr += ret
void get_device (unsigned vendor, unsigned product, unsigned tries):
for unsigned i = 0; i < tries; ++i:
usb_find_busses ()
usb_find_devices ()
for struct usb_bus *bus = usb_busses; bus; bus = bus->next:
for struct usb_device *dev = bus->devices; dev; dev = dev->next:
if dev->descriptor.idProduct != product || dev->descriptor.idVendor != vendor:
//std::cerr << shevek::ostring ("Not using %04x:%04x when looking for %04x:%04x\n", dev->descriptor.idVendor, dev->descriptor.idProduct, vendor, product)
continue
handle = usb_open (dev)
if usb_claim_interface (handle, 0) < 0:
std::cerr << "unable to claim interface: " << usb_strerror () << "\n"
usb_close (handle)
handle = NULL
continue
return
if i + 1 < tries:
//std::cerr << "failed to find device, still trying...\n"
sleep (1)
std::cerr << shevek::ostring ("giving up finding device %04x:%04x\n", vendor, product)
void boot (std::string const &filename, unsigned load, unsigned entry):
std::cerr << "booting " << shevek::ostring ("%s from %x@%x", Glib::ustring (filename), load, entry) << "\n"
get_device (boot_vendor, boot_product, 1)
if !handle:
std::cerr << "unable to find device\n"
return
std::cerr << "sending stage 1\n"
std::ifstream file (STAGE1_FILE)
std::ostringstream stage1
stage1 << file.rdbuf ()
send_file (STAGE1_LOAD, stage1.str ().size (), stage1.str ().data ())
std::cerr << "running stage 1\n"
request (VR_PROGRAM_START1, STAGE1_ENTRY)
usleep (100)
std::ostringstream stage2
usb_release_interface (handle, 0)
file.close ()
file.open (filename.c_str ())
stage2 << file.rdbuf ()
std::cerr << shevek::ostring ("sending Iris (size 0x%x)\n", stage2.str ().size ())
send_file (load, stage2.str ().size (), stage2.str ().data ())
std::cerr << "flushing caches\n"
request (VR_FLUSH_CACHES)
std::cerr << "running Iris\n"
request (VR_PROGRAM_START2, entry)
usb_release_interface (handle, 0)
usb_close (handle)
handle = NULL
std::cerr << "done\n"
int main (int argc, char **argv):
std::string filename ("iris.raw")
unsigned load (0x80000000), entry (0)
handle = NULL
usb_init ()
shevek::args::option opts[] = {
shevek::args::option ('f', "file", "image file", true, filename),
shevek::args::option ('l', "load", "load address", true, load),
shevek::args::option ('e', "entry", "entry point address", false, entry)
}
shevek::args args (argc, argv, opts, 0, 0, "unbrick program for NanoNote", "2009-2010")
if !entry:
shevek_error ("You must specify the entry point")
boot (filename, load, entry)
return 0