Skip to content

Commit c779efa

Browse files
committed
Changes required for RISC OS to boot with a new partition offset
1 parent 331b30b commit c779efa

File tree

6 files changed

+121
-73
lines changed

6 files changed

+121
-73
lines changed

recovery/config.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
#define CONFIG_H
33

44
/* Version number displayed in the title bar */
5-
#define VERSION_NUMBER "1.3.2"
5+
#define VERSION_NUMBER "1.3.5"
66

77
/* Color of the background */
88
// #define BACKGROUND_COLOR Qt::white
@@ -21,7 +21,7 @@
2121
#define HOMEPAGE "http://www.raspberrypi.org/phpBB3/"
2222

2323
/* Location to download the list of available distributions from */
24-
#define DEFAULT_REPO_SERVER "http://downloads.raspberrypi.org/os_list.json"
24+
#define DEFAULT_REPO_SERVER "http://downloads.raspberrypi.org/os_list_v2.json"
2525

2626
/* Size of recovery FAT partition in MB.
2727
* First partition starts at offset 1 MB (sector 2048)
@@ -42,8 +42,9 @@
4242
#define FAT_PARTITION_OF_IMAGE "/dev/mmcblk0p5"
4343

4444
/* RiscOS magic */
45-
#define RISCOS_SECTOR_OFFSET (1536 * 2048)
46-
#define RISCOS_FAT_SIZE (48 * 2048)
45+
#define RISCOS_OFFSET_KEY "riscos_offset"
46+
#define RISCOS_OFFSET (1760)
47+
#define RISCOS_SECTOR_OFFSET (RISCOS_OFFSET * 2048)
4748

4849
#define RISCOS_BLOB_FILENAME "/mnt/riscos-boot.bin"
4950
#define RISCOS_BLOB_SECTOR_OFFSET (1)

recovery/mainwindow.cpp

Lines changed: 89 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,23 @@ void MainWindow::repopulate()
314314
}
315315
}
316316

317+
/* Whether this OS should be displayed in the list of installable OSes */
318+
bool canInstallOs(const QString& name, const QVariantMap& values)
319+
{
320+
/* Can't simply pull "name" from "values" because in some JSON files it's "os_name" and in others it's "name"
321+
322+
/* RISC_OS needs a matching riscos_offset */
323+
if (nameMatchesRiscOS(name))
324+
{
325+
if (!values.contains(RISCOS_OFFSET_KEY) || (values.value(RISCOS_OFFSET_KEY).toInt() != RISCOS_OFFSET))
326+
{
327+
return false;
328+
}
329+
}
330+
331+
return true;
332+
}
333+
317334
QMap<QString, QVariantMap> MainWindow::listImages()
318335
{
319336
QMap<QString,QVariantMap> images;
@@ -329,32 +346,36 @@ QMap<QString, QVariantMap> MainWindow::listImages()
329346
continue;
330347
QVariantMap osv = Json::loadFromFile(imagefolder+"/os.json").toMap();
331348

332-
if (QFile::exists(imagefolder+"/flavours.json"))
349+
QString basename = osv.value("name").toString();
350+
if (canInstallOs(basename, osv))
333351
{
334-
QVariantMap v = Json::loadFromFile(imagefolder+"/flavours.json").toMap();
335-
QVariantList fl = v.value("flavours").toList();
336-
337-
foreach (QVariant f, fl)
352+
if (QFile::exists(imagefolder+"/flavours.json"))
338353
{
339-
QVariantMap fm = f.toMap();
340-
if (fm.contains("name"))
354+
QVariantMap v = Json::loadFromFile(imagefolder+"/flavours.json").toMap();
355+
QVariantList fl = v.value("flavours").toList();
356+
357+
foreach (QVariant f, fl)
341358
{
342-
QString name = fm.value("name").toString();
343-
if (name == RECOMMENDED_IMAGE)
344-
fm["recommended"] = true;
345-
fm["folder"] = imagefolder;
346-
fm["release_date"] = osv.value("release_date");
347-
images[imagefolder+"#"+name] = fm;
359+
QVariantMap fm = f.toMap();
360+
if (fm.contains("name"))
361+
{
362+
QString name = fm.value("name").toString();
363+
if (name == RECOMMENDED_IMAGE)
364+
fm["recommended"] = true;
365+
fm["folder"] = imagefolder;
366+
fm["release_date"] = osv.value("release_date");
367+
images[imagefolder+"#"+name] = fm;
368+
}
348369
}
349370
}
350-
}
351-
else
352-
{
353-
QString name = osv.value("name").toString();
354-
if (name.contains(RECOMMENDED_IMAGE))
355-
osv["recommended"] = true;
356-
osv["folder"] = imagefolder;
357-
images[imagefolder+"#"+name] = osv;
371+
else
372+
{
373+
QString name = basename;
374+
if (name.contains(RECOMMENDED_IMAGE))
375+
osv["recommended"] = true;
376+
osv["folder"] = imagefolder;
377+
images[imagefolder+"#"+name] = osv;
378+
}
358379
}
359380
}
360381

@@ -885,61 +906,64 @@ void MainWindow::processJson(QVariant json)
885906
{
886907
QVariantMap os = osv.toMap();
887908

888-
if (os.contains("flavours"))
909+
QString basename = os.value("os_name").toString();
910+
if (canInstallOs(basename, os))
889911
{
890-
QVariantList flavours = os.value("flavours").toList();
891-
892-
foreach (QVariant flv, flavours)
912+
if (os.contains("flavours"))
893913
{
894-
QVariantMap flavour = flv.toMap();
895-
QVariantMap item = os;
896-
QString name = flavour.value("name").toString();
897-
QString description = flavour.value("description").toString();
898-
QString iconurl = flavour.value("icon").toString();
899-
900-
item.insert("name", name);
901-
item.insert("description", description);
902-
item.insert("icon", iconurl);
914+
QVariantList flavours = os.value("flavours").toList();
903915

904-
if (!alreadyHasItem(name, item.value("release_date")))
916+
foreach (QVariant flv, flavours)
917+
{
918+
QVariantMap flavour = flv.toMap();
919+
QVariantMap item = os;
920+
QString name = flavour.value("name").toString();
921+
QString description = flavour.value("description").toString();
922+
QString iconurl = flavour.value("icon").toString();
923+
924+
item.insert("name", name);
925+
item.insert("description", description);
926+
item.insert("icon", iconurl);
927+
928+
if (!alreadyHasItem(name, item.value("release_date")))
929+
{
930+
if (!iconurl.isEmpty())
931+
iconurls.insert(iconurl);
932+
933+
bool recommended = (name == RECOMMENDED_IMAGE);
934+
if (recommended)
935+
name += " ["+tr("RECOMMENDED")+"]";
936+
937+
QListWidgetItem *witem = new QListWidgetItem(name+"\n"+description);
938+
witem->setCheckState(Qt::Unchecked);
939+
witem->setData(Qt::UserRole, item);
940+
witem->setData(SecondIconRole, internetIcon);
941+
942+
if (recommended)
943+
ui->list->insertItem(0, witem);
944+
else
945+
ui->list->addItem(witem);
946+
}
947+
}
948+
}
949+
if (os.contains("description"))
950+
{
951+
QString name = basename;
952+
QString description = os.value("description").toString();
953+
if (!alreadyHasItem(name, os.value("release_date")))
905954
{
955+
os["name"] = name;
956+
QString iconurl = os.value("icon").toString();
906957
if (!iconurl.isEmpty())
907958
iconurls.insert(iconurl);
908959

909-
bool recommended = (name == RECOMMENDED_IMAGE);
910-
if (recommended)
911-
name += " ["+tr("RECOMMENDED")+"]";
912-
913-
QListWidgetItem *witem = new QListWidgetItem(name+"\n"+description);
960+
QListWidgetItem *witem = new QListWidgetItem(name+"\n"+description, ui->list);
914961
witem->setCheckState(Qt::Unchecked);
915-
witem->setData(Qt::UserRole, item);
962+
witem->setData(Qt::UserRole, os);
916963
witem->setData(SecondIconRole, internetIcon);
917-
918-
if (recommended)
919-
ui->list->insertItem(0, witem);
920-
else
921-
ui->list->addItem(witem);
922964
}
923965
}
924966
}
925-
if (os.contains("description"))
926-
{
927-
QString name = os.value("os_name").toString();
928-
QString description = os.value("description").toString();
929-
930-
if (!alreadyHasItem(name, os.value("release_date")))
931-
{
932-
os["name"] = name;
933-
QString iconurl = os.value("icon").toString();
934-
if (!iconurl.isEmpty())
935-
iconurls.insert(iconurl);
936-
937-
QListWidgetItem *witem = new QListWidgetItem(name+"\n"+description, ui->list);
938-
witem->setCheckState(Qt::Unchecked);
939-
witem->setData(Qt::UserRole, os);
940-
witem->setData(SecondIconRole, internetIcon);
941-
}
942-
}
943967
}
944968

945969
/* Download icons */
@@ -1053,7 +1077,7 @@ void MainWindow::updateNeeded()
10531077
QVariantMap entry = item->data(Qt::UserRole).toMap();
10541078
_neededMB += entry.value("nominal_size").toInt();
10551079

1056-
if (entry.value("name").toString().contains("risc", Qt::CaseInsensitive))
1080+
if (nameMatchesRiscOS(entry.value("name").toString()))
10571081
{
10581082
/* RiscOS needs to start at a predetermined sector, calculate the extra space needed for that */
10591083
int startSector = getFileContents("/sys/class/block/mmcblk0p2/start").trimmed().toULongLong();

recovery/multiimagewritethread.cpp

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,26 @@ void MultiImageWriteThread::run()
6262
}
6363
}
6464
}
65-
if (folder.contains("risc", Qt::CaseInsensitive))
65+
if (nameMatchesRiscOS(folder))
6666
{
67+
/* Check the riscos_offset in os.json matches what we're expecting.
68+
In theory we shouldn't hit either of these errors because the invalid RISC_OS
69+
should have been filtered out already (not added to OS-list) in mainwindow.cpp */
70+
QVariantMap vos = Json::loadFromFile(folder+"/os.json").toMap();
71+
if (vos.contains(RISCOS_OFFSET_KEY))
72+
{
73+
int riscos_offset = vos.value(RISCOS_OFFSET_KEY).toInt();
74+
if (riscos_offset != RISCOS_OFFSET)
75+
{
76+
emit error(tr("RISCOS cannot be installed. RISCOS offset value mismatch."));
77+
return;
78+
}
79+
}
80+
else
81+
{
82+
emit error(tr("RISCOS cannot be installed. RISCOS offset value missing."));
83+
return;
84+
}
6785
if (startSector > RISCOS_SECTOR_OFFSET-2048)
6886
{
6987
emit error(tr("RISCOS cannot be installed. Size of recovery partition too large."));
@@ -102,7 +120,7 @@ void MultiImageWriteThread::run()
102120
{
103121
for (QMultiMap<QString,QString>::const_iterator iter = _images.constBegin(); iter != _images.constEnd(); iter++)
104122
{
105-
if (iter.key().contains("risc", Qt::CaseInsensitive))
123+
if (nameMatchesRiscOS(iter.key()))
106124
{
107125
if (!processImage(iter.key(), iter.value()))
108126
return;
@@ -197,7 +215,7 @@ bool MultiImageWriteThread::processImage(const QString &folder, const QString &f
197215
else
198216
parttype = 0x83; /* Linux native */
199217

200-
if (folder.contains("risc", Qt::CaseInsensitive) && (fstype == "FAT" || fstype == "fat"))
218+
if (nameMatchesRiscOS(folder) && (fstype == "FAT" || fstype == "fat"))
201219
{
202220
/* Let Risc OS start at known offset */
203221
int startSector = getFileContents("/sys/class/block/mmcblk0p2/start").trimmed().toULongLong();

recovery/util.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,3 +89,8 @@ void getOverscan(int &top, int &bottom, int &left, int &right)
8989
::close(fd);
9090
}
9191
}
92+
93+
bool nameMatchesRiscOS(const QString &name)
94+
{
95+
return name.contains("risc", Qt::CaseInsensitive);
96+
}

recovery/util.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,5 @@
1616
QByteArray getFileContents(const QString &filename);
1717
void putFileContents(const QString &filename, const QByteArray &data);
1818
void getOverscan(int &top, int &bottom, int &left, int &right);
19-
19+
bool nameMatchesRiscOS(const QString &name);
2020
#endif // UTIL_H

sdcontent/riscos-boot.bin

0 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)