2012-01-04 19:19:02 +00:00
|
|
|
/***************************************************************************
|
|
|
|
* __________ __ ___.
|
|
|
|
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
|
|
|
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
|
|
|
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
|
|
|
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
|
|
|
* \/ \/ \/ \/ \/
|
|
|
|
*
|
|
|
|
* Copyright (C) 2011 by Jean-Louis Biasini
|
|
|
|
*
|
|
|
|
* All files in this archive are subject to the GNU General Public License.
|
|
|
|
* See the file COPYING in the source tree root for full license agreement.
|
|
|
|
*
|
|
|
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
|
|
|
* KIND, either express or implied.
|
|
|
|
*
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
#include <QtCore>
|
|
|
|
#include <QtDebug>
|
|
|
|
#include "bootloaderinstallbase.h"
|
|
|
|
#include "bootloaderinstallimx.h"
|
|
|
|
#include "../mkimxboot/mkimxboot.h"
|
|
|
|
|
|
|
|
// class for running mkimxboot() in a separate thread to keep the UI responsive.
|
|
|
|
class BootloaderThreadImx : public QThread
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
void run(void);
|
|
|
|
void setInputFile(QString f)
|
|
|
|
{ m_inputfile = f; }
|
|
|
|
void setOutputFile(QString f)
|
|
|
|
{ m_outputfile = f; }
|
|
|
|
void setBootloaderFile(QString f)
|
|
|
|
{ m_bootfile = f; }
|
|
|
|
enum imx_error_t error(void)
|
|
|
|
{ return m_error; }
|
|
|
|
private:
|
|
|
|
QString m_inputfile;
|
|
|
|
QString m_bootfile;
|
|
|
|
QString m_outputfile;
|
|
|
|
enum imx_error_t m_error;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
void BootloaderThreadImx::run(void)
|
|
|
|
{
|
|
|
|
qDebug() << "[BootloaderThreadImx] Thread started.";
|
|
|
|
struct imx_option_t opt;
|
|
|
|
opt.debug = false;
|
|
|
|
opt.output = IMX_DUALBOOT;
|
2012-06-09 20:03:43 +00:00
|
|
|
opt.fw_variant = VARIANT_DEFAULT;
|
2012-01-04 19:19:02 +00:00
|
|
|
|
|
|
|
m_error = mkimxboot(m_inputfile.toLocal8Bit().constData(),
|
|
|
|
m_bootfile.toLocal8Bit().constData(),
|
|
|
|
m_outputfile.toLocal8Bit().constData(), opt);
|
|
|
|
qDebug() << "[BootloaderThreadImx] Thread finished, result:" << m_error;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
BootloaderInstallImx::BootloaderInstallImx(QObject *parent)
|
|
|
|
: BootloaderInstallBase(parent)
|
|
|
|
{
|
|
|
|
m_thread = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
QString BootloaderInstallImx::ofHint()
|
|
|
|
{
|
|
|
|
return tr("Bootloader installation requires you to provide "
|
|
|
|
"a copy of the original Sandisk firmware (firmware.sb file). "
|
|
|
|
"This file will be patched with the Rockbox bootloader and "
|
|
|
|
"installed to your player. You need to download this file "
|
|
|
|
"yourself due to legal reasons. Please browse the "
|
|
|
|
"<a href='http://forums.sandisk.com/sansa/'>Sansa Forums</a> "
|
|
|
|
"or refer to the "
|
|
|
|
"<a href= 'http://www.rockbox.org/wiki/SansaFuzePlus'>SansaFuzePlus</a> "
|
|
|
|
"wiki page on how to obtain this file.<br/>"
|
|
|
|
"Press Ok to continue and browse your computer for the firmware "
|
|
|
|
"file.");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/** Start bootloader installation.
|
|
|
|
*/
|
|
|
|
bool BootloaderInstallImx::install(void)
|
|
|
|
{
|
|
|
|
if(!QFileInfo(m_offile).isReadable())
|
|
|
|
{
|
|
|
|
qDebug() << "[BootloaderInstallImx] could not read original firmware file"
|
|
|
|
<< m_offile;
|
|
|
|
emit logItem(tr("Could not read original firmware file"), LOGERROR);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
qDebug() << "[BootloaderInstallImx] downloading bootloader";
|
|
|
|
// download bootloader from server
|
|
|
|
emit logItem(tr("Downloading bootloader file"), LOGINFO);
|
|
|
|
connect(this, SIGNAL(downloadDone()), this, SLOT(installStage2()));
|
|
|
|
downloadBlStart(m_blurl);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void BootloaderInstallImx::installStage2(void)
|
|
|
|
{
|
|
|
|
qDebug() << "[BootloaderInstallImx] patching file...";
|
|
|
|
emit logItem(tr("Patching file..."), LOGINFO);
|
|
|
|
m_tempfile.open();
|
|
|
|
|
|
|
|
// we have not detailed progress on the patching so just show a busy
|
|
|
|
// indicator instead.
|
|
|
|
emit logProgress(0, 0);
|
|
|
|
m_patchedFile.open();
|
|
|
|
m_thread = new BootloaderThreadImx();
|
|
|
|
m_thread->setInputFile(m_offile);
|
|
|
|
m_thread->setBootloaderFile(m_tempfile.fileName());
|
|
|
|
m_thread->setOutputFile(m_patchedFile.fileName());
|
|
|
|
m_tempfile.close();
|
|
|
|
m_patchedFile.close();
|
|
|
|
connect(m_thread, SIGNAL(finished()), this, SLOT(installStage3()));
|
|
|
|
connect(m_thread, SIGNAL(terminated()), this, SLOT(installStage3()));
|
|
|
|
m_thread->start();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void BootloaderInstallImx::installStage3(void)
|
|
|
|
{
|
|
|
|
enum imx_error_t err = m_thread->error();
|
|
|
|
emit logProgress(1, 1);
|
|
|
|
// if the patch failed
|
|
|
|
if (err != IMX_SUCCESS)
|
|
|
|
{
|
|
|
|
qDebug() << "[BootloaderInstallImx] Could not patch the original firmware file";
|
|
|
|
emit logItem(tr("Patching the original firmware failed"), LOGERROR);
|
|
|
|
emit done(true);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
qDebug() << "[BootloaderInstallImx] Original Firmware succesfully patched";
|
|
|
|
emit logItem(tr("Succesfully patched firmware file"), LOGINFO);
|
|
|
|
|
|
|
|
// if a bootloader is already present delete it.
|
|
|
|
QString fwfile(m_blfile);
|
|
|
|
if(QFileInfo(fwfile).isFile())
|
|
|
|
{
|
|
|
|
qDebug() << "[BootloaderInstallImx] deleting old target file";
|
|
|
|
QFile::remove(fwfile);
|
|
|
|
}
|
|
|
|
|
|
|
|
// place (new) bootloader. Copy, since the temporary file will be removed
|
|
|
|
// automatically.
|
|
|
|
qDebug() << "[BootloaderInstallImx] moving patched bootloader to" << fwfile;
|
|
|
|
if(m_patchedFile.copy(fwfile))
|
|
|
|
{
|
|
|
|
emit logItem(tr("Bootloader successful installed"), LOGOK);
|
|
|
|
logInstall(LogAdd);
|
|
|
|
emit done(false);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
emit logItem(tr("Patched bootloader could not be installed"), LOGERROR);
|
|
|
|
emit done(true);
|
|
|
|
}
|
|
|
|
// clean up thread object.
|
|
|
|
delete m_thread;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool BootloaderInstallImx::uninstall(void)
|
|
|
|
{
|
|
|
|
emit logItem(tr("To uninstall, perform a normal upgrade with an unmodified "
|
|
|
|
"original firmware."), LOGINFO);
|
|
|
|
logInstall(LogRemove);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
BootloaderInstallBase::BootloaderType BootloaderInstallImx::installed(void)
|
|
|
|
{
|
|
|
|
return BootloaderUnknown;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
BootloaderInstallBase::Capabilities BootloaderInstallImx::capabilities(void)
|
|
|
|
{
|
|
|
|
return (Install | NeedsOf);
|
|
|
|
}
|
|
|
|
|