Skip to content
This repository was archived by the owner on Feb 27, 2023. It is now read-only.

Commit ff40607

Browse files
committed
Add support for installing to primary partitions, NTFS, partclone
- refactored parititioning code to support installing to primary partitions - adds "requires_partition_number" property to partitions.json for partitions that need to be at a fixed partition number (e.g. need to be at primary partition 3) - adds "offset" property to partitions.json for partitions that need to be at a fixed offset. - now does rewrite the MBR - outsources the writing of the partition table to sfdisk - enables NTFS support (through fuse/ntfs-3g) - adds OsInfo PartitionInfo model classes that parse the json files once and keep the information in normal variables - tries to reduce wasted space due to gaps between partitions - adds support for keeping partition unformatted (filesystem_type: "unformatted") - adds support for specifying hexadecimal partition type number (partition_type: "07") - adds support for marking partitions bootable (active: true) - kernel config: enable FUSE and UDF - zero out first sector of each partition (to prevent old file system label being detected) - parted: surpress warning about its file system manipulation code not being robust that distracts from real errors - adds support for partclone disk partition images - adds support for patching Windows BCD files
1 parent f0347db commit ff40607

20 files changed

+836
-400
lines changed

buildroot/.config

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#
22
# Automatically generated file; DO NOT EDIT.
3-
# Buildroot 2015.02-git-g661b7ed-dirty Configuration
3+
# Buildroot 2015.02-git-ge7d8e80-dirty Configuration
44
#
55
BR2_HAVE_DOT_CONFIG=y
66

@@ -337,6 +337,7 @@ BR2_PACKAGE_BUSYBOX_CONFIG="package/busybox/busybox.config"
337337
BR2_PACKAGE_BUSYBOX_SHOW_OTHERS=y
338338
# BR2_PACKAGE_BUSYBOX_WATCHDOG is not set
339339
BR2_PACKAGE_ARORA=y
340+
BR2_PACKAGE_PARTCLONE=y
340341
BR2_PACKAGE_RECOVERY=y
341342

342343
#
@@ -535,7 +536,9 @@ BR2_PACKAGE_E2FSPROGS_RESIZE2FS=y
535536
# BR2_PACKAGE_MTD is not set
536537
BR2_PACKAGE_MTOOLS=y
537538
# BR2_PACKAGE_NFS_UTILS is not set
538-
# BR2_PACKAGE_NTFS_3G is not set
539+
BR2_PACKAGE_NTFS_3G=y
540+
# BR2_PACKAGE_NTFS_3G_ENCRYPTED is not set
541+
BR2_PACKAGE_NTFS_3G_NTFSPROGS=y
539542
# BR2_PACKAGE_SIMICSFS is not set
540543
# BR2_PACKAGE_SQUASHFS is not set
541544
# BR2_PACKAGE_SSHFS is not set

buildroot/kernelconfig-recovery.armv6

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,8 @@ CONFIG_DMA_BCM2708=y
113113
# CONFIG_IOMMU_SUPPORT is not set
114114
CONFIG_EXT4_FS=y
115115
CONFIG_FANOTIFY=y
116+
CONFIG_FUSE_FS=y
117+
CONFIG_UDF_FS=y
116118
CONFIG_FSCACHE=y
117119
CONFIG_CACHEFILES=y
118120
CONFIG_MSDOS_FS=y

buildroot/kernelconfig-recovery.armv7

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,8 @@ CONFIG_DMA_BCM2708=y
118118
# CONFIG_IOMMU_SUPPORT is not set
119119
CONFIG_EXT4_FS=y
120120
CONFIG_FANOTIFY=y
121+
CONFIG_FUSE_FS=y
122+
CONFIG_UDF_FS=y
121123
CONFIG_FSCACHE=y
122124
CONFIG_CACHEFILES=y
123125
CONFIG_MSDOS_FS=y

buildroot/package/Config.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ menu "Target packages"
22

33
source "package/busybox/Config.in"
44
source "package/arora/Config.in"
5+
source "package/partclone/Config.in"
56
source "package/recovery/Config.in"
67

78
menu "Audio and video applications"
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
--- partclone-0.2.84.orig/src/main.c 2015-10-13 08:27:56.000000000 +0200
2+
+++ partclone-0.2.84/src/main.c 2015-10-27 17:09:32.324546758 +0100
3+
@@ -20,7 +20,6 @@
4+
#include <sys/types.h>
5+
#include <stdio.h>
6+
#include <stdlib.h>
7+
-#include <mcheck.h>
8+
#include <stdint.h>
9+
#include <stdarg.h>
10+
#include <string.h>
11+

buildroot/package/partclone/Config.in

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
config BR2_PACKAGE_PARTCLONE
2+
bool "partclone"
3+
help
4+
Partclone
5+
Note: only installs partclone.restore
6+
7+
http://partclone.org
8+
9+
comment "partclone requires a toolchain with LARGEFILE+WCHAR support"
10+
depends on !(BR2_LARGEFILE && BR2_USE_WCHAR)
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
################################################################################
2+
#
3+
# partclone
4+
#
5+
################################################################################
6+
7+
PARTCLONE_VERSION = 0.2.84
8+
PARTCLONE_SOURCE = partclone-$(PARTCLONE_VERSION).tar.gz
9+
PARTCLONE_SITE = http://sourceforge.net/projects/partclone/files/testing/src
10+
PARTCLONE_LICENSE = GPLv2
11+
PARTCLONE_LICENSE_FILES = COPYING
12+
13+
define PARTCLONE_BUILD_CMDS
14+
$(MAKE) CC="$(TARGET_CC)" LD="$(TARGET_LD)" -C $(@D)/src partclone.restore
15+
endef
16+
17+
define PARTCLONE_INSTALL_TARGET_CMDS
18+
$(INSTALL) -D -m 0755 $(@D)/src/partclone.restore $(TARGET_DIR)/usr/bin/partclone.restore
19+
endef
20+
21+
$(eval $(autotools-package))

recovery/config.h

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,20 @@
3333
* If files they are larger than number of MB, try resizing the FAT partition instead */
3434
#define MAXIMUM_BOOTFILES_SIZE 64
3535

36-
#define SETTINGS_PARTITION "/dev/mmcblk0p3"
37-
#define SETTINGS_PARTITION_SIZE (32 * 2048)
36+
/* Partitioning settings */
37+
#define PARTITION_ALIGNMENT 8192
38+
#define PARTITION_GAP 2
39+
/* Allow partitions to be shrinked PARTITION_GAP sectors
40+
if that prevents having a 4 MiB gap between the next one */
41+
#define SHRINK_PARTITIONS_TO_MINIMIZE_GAPS
42+
43+
#define SETTINGS_PARTITION "/dev/mmcblk0p5"
44+
#define SETTINGS_PARTITION_SIZE (32 * 2048 - PARTITION_GAP)
3845

3946
/* If the image name matches this exactly, mark it as recommended */
4047
#define RECOMMENDED_IMAGE "Raspbian"
4148

42-
#define FAT_PARTITION_OF_IMAGE "/dev/mmcblk0p5"
49+
#define FAT_PARTITION_OF_IMAGE "/dev/mmcblk0p6"
4350

4451
/* RiscOS magic */
4552
#define RISCOS_OFFSET_KEY "riscos_offset"

recovery/initdrivethread.cpp

Lines changed: 28 additions & 146 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "initdrivethread.h"
1111
#include "mbr.h"
1212
#include "util.h"
13+
#include "config.h"
1314
#include <QProcess>
1415
#include <QFile>
1516
#include <QDir>
@@ -37,30 +38,22 @@ void InitDriveThread::run()
3738
emit statusUpdate(tr("Mounting FAT partition"));
3839
mountSystemPartition();
3940

40-
//if (sizeofBootFilesInKB() > (MAXIMUM_BOOTFILES_SIZE*1024))
41-
//{
42-
//emit error(tr("SD card contains extra files that do not belong to this distribution. Please copy them to another disk and delete them from card."));
43-
//return;
44-
45-
// Try to resize existing partitions
46-
if (!method_resizePartitions())
47-
{
48-
return;
49-
}
50-
//}
51-
// else
52-
// {
53-
// // Reformat the drive
54-
//if (!method_reformatDrive())
55-
//{
56-
//return;
57-
// }
58-
// }
41+
// Try to resize existing partitions
42+
if (!method_resizePartitions())
43+
return;
5944

6045
emit statusUpdate(tr("Formatting settings partition"));
6146
if (!formatSettingsPartition())
6247
{
6348
emit error(tr("Error formatting settings partition"));
49+
return;
50+
}
51+
52+
emit statusUpdate(tr("Mounting FAT partition"));
53+
if (!mountSystemPartition())
54+
{
55+
emit error(tr("Error mounting system partition."));
56+
return;
6457
}
6558

6659
dir.mkdir("/mnt/os");
@@ -128,53 +121,10 @@ void InitDriveThread::run()
128121
emit completed();
129122
}
130123

131-
bool InitDriveThread::method_reformatDrive()
132-
{
133-
emit statusUpdate(tr("Saving boot files to memory"));
134-
if (!saveBootFiles() )
135-
{
136-
emit error(tr("Error saving boot files to memory. SD card may be damaged."));
137-
return false;
138-
}
139-
if (!umountSystemPartition())
140-
{
141-
emit error(tr("Error unmounting system partition."));
142-
return false;
143-
}
144-
145-
emit statusUpdate(tr("Zeroing partition table"));
146-
if (!zeroMbr())
147-
{
148-
emit error(tr("Error zero'ing MBR/GPT. SD card may be broken or advertising wrong capacity."));
149-
return false;
150-
}
151-
152-
emit statusUpdate(tr("Creating partitions"));
153-
154-
if (!partitionDrive())
155-
{
156-
emit error(tr("Error partitioning"));
157-
return false;
158-
}
159-
160-
emit statusUpdate(tr("Formatting boot partition (fat)"));
161-
if (!formatBootPartition())
162-
{
163-
emit error(tr("Error formatting boot partition (fat)"));
164-
return false;
165-
}
166-
167-
emit statusUpdate(tr("Copying boot files to storage"));
168-
mountSystemPartition();
169-
restoreBootFiles();
170-
171-
return true;
172-
}
173-
174124
bool InitDriveThread::method_resizePartitions()
175125
{
176126
int newStartOfRescuePartition = getFileContents("/sys/class/block/mmcblk0p1/start").trimmed().toInt();
177-
int newSizeOfRescuePartition = sizeofBootFilesInKB()/1000 + 100;
127+
int newSizeOfRescuePartition = sizeofBootFilesInKB()*1.024/1000 + 100;
178128

179129
if (!umountSystemPartition())
180130
{
@@ -250,12 +200,17 @@ bool InitDriveThread::method_resizePartitions()
250200
* only move it when it is not aligned on a MiB boundary already */
251201
if (newStartOfRescuePartition < 2048 || newStartOfRescuePartition % 2048 != 0)
252202
{
253-
newStartOfRescuePartition = 8192; /* 4 MiB */
203+
newStartOfRescuePartition = PARTITION_ALIGNMENT; /* 4 MiB */
254204
}
255205

256206
QString cmd = "/usr/sbin/parted --script /dev/mmcblk0 resize 1 "+QString::number(newStartOfRescuePartition)+"s "+QString::number(newSizeOfRescuePartition)+"M";
257207
qDebug() << "Executing" << cmd;
258208
QProcess p;
209+
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
210+
/* Suppress parted's big fat warning about its file system manipulation code not being robust.
211+
It distracts from any real error messages that may follow it. */
212+
env.insert("PARTED_SUPPRESS_FILE_SYSTEM_MANIPULATION_WARNING", "1");
213+
p.setProcessEnvironment(env);
259214
p.setProcessChannelMode(p.MergedChannels);
260215
p.start(cmd);
261216
p.closeWriteChannel();
@@ -271,33 +226,25 @@ bool InitDriveThread::method_resizePartitions()
271226

272227
emit statusUpdate(tr("Creating extended partition"));
273228

274-
mbr_table extended_mbr;
275229
QByteArray partitionTable;
276230
int startOfOurPartition = getFileContents("/sys/class/block/mmcblk0p1/start").trimmed().toInt();
277231
int sizeOfOurPartition = getFileContents("/sys/class/block/mmcblk0p1/size").trimmed().toInt();
278232
int startOfExtended = startOfOurPartition+sizeOfOurPartition;
279-
// Align on 4 MiB boundary
280-
startOfExtended += 8192-(startOfExtended % 8192);
281233

282-
int sizeOfDisk = getFileContents("/sys/class/block/mmcblk0/size").trimmed().toULongLong();
283-
int sizeOfExtended = sizeOfDisk - startOfExtended - SETTINGS_PARTITION_SIZE ;
284-
int startOfSettings = startOfExtended+sizeOfExtended;
234+
// Align start of settings partition on 4 MiB boundary
235+
int startOfSettings = startOfExtended + PARTITION_GAP;
236+
if (startOfSettings % PARTITION_ALIGNMENT != 0)
237+
startOfSettings += PARTITION_ALIGNMENT-(startOfSettings % PARTITION_ALIGNMENT);
285238

239+
// Primary partitions
286240
partitionTable = QByteArray::number(startOfOurPartition)+","+QByteArray::number(sizeOfOurPartition)+",0E\n"; /* FAT partition */
287-
partitionTable += QByteArray::number(startOfExtended)+","+QByteArray::number(sizeOfExtended)+",X\n"; /* Extended partition with all remaining space */
288-
partitionTable += QByteArray::number(startOfSettings)+",,L\n"; /* Settings partition */
241+
partitionTable += QByteArray::number(startOfExtended)+",,X\n"; /* Extended partition with all remaining space */
289242
partitionTable += "0,0\n";
243+
partitionTable += "0,0\n";
244+
// Logical partitions
245+
partitionTable += QByteArray::number(startOfSettings)+","+QByteArray::number(SETTINGS_PARTITION_SIZE)+",L\n"; /* Settings partition */
290246
qDebug() << "Writing partition table" << partitionTable;
291247

292-
/* Write out empty extended partition table with signature */
293-
memset(&extended_mbr, 0, sizeof extended_mbr);
294-
extended_mbr.signature[0] = 0x55;
295-
extended_mbr.signature[1] = 0xAA;
296-
f.open(f.ReadWrite);
297-
f.seek(startOfExtended*512);
298-
f.write((char *) &extended_mbr, sizeof(extended_mbr));
299-
f.close();
300-
301248
/* Let sfdisk write a proper partition table */
302249
cmd = QString("/sbin/sfdisk -uS /dev/mmcblk0");
303250
QProcess proc;
@@ -325,28 +272,9 @@ bool InitDriveThread::method_resizePartitions()
325272

326273
QProcess::execute("/sbin/mlabel p:RECOVERY");
327274

328-
emit statusUpdate(tr("Mounting FAT partition"));
329-
if (!mountSystemPartition())
330-
{
331-
emit error(tr("Error mounting system partition."));
332-
return false;
333-
}
334-
335275
return true;
336276
}
337277

338-
bool InitDriveThread::saveBootFiles()
339-
{
340-
return QProcess::execute("cp -a /mnt /tmp") == 0;
341-
}
342-
343-
bool InitDriveThread::restoreBootFiles()
344-
{
345-
bool status = QProcess::execute("cp -a /tmp/mnt /") == 0;
346-
QProcess::execute("rm -rf /tmp/mnt");
347-
return status;
348-
}
349-
350278
int InitDriveThread::sizeofBootFilesInKB()
351279
{
352280
QProcess proc;
@@ -397,52 +325,6 @@ bool InitDriveThread::zeroMbr()
397325
&& QProcess::execute("/bin/dd conv=fsync count=8 bs=512 if=/dev/zero seek="+QString::number(sizeofSDCardInBlocks()-8)+" of=/dev/mmcblk0") == 0;
398326
}
399327

400-
bool InitDriveThread::partitionDrive()
401-
{
402-
/* Partition layout:
403-
*
404-
* First 1MB (2048 blocks) kept empty for alignment
405-
* Followed by FAT partition of RESCUE_PARTITION_SIZE (default 1 GB)
406-
* Followed by extended partition spanning remainder of space
407-
* Followed by NOOBS persistent settings partition
408-
*/
409-
QByteArray partitionTable;
410-
int rescueBlocks = RESCUE_PARTITION_SIZE*1024*2;
411-
412-
mbr_table extended_mbr;
413-
int startOfExtended = 2048+rescueBlocks;
414-
int sizeOfDisk = getFileContents("/sys/class/block/mmcblk0/size").trimmed().toULongLong();
415-
int sizeOfExtended = sizeOfDisk - startOfExtended - SETTINGS_PARTITION_SIZE;
416-
int startOfSettings = startOfExtended + sizeOfExtended;
417-
418-
partitionTable = "2048,"+QByteArray::number(rescueBlocks)+",0E\n"; /* FAT partition */
419-
partitionTable += QByteArray::number(startOfExtended)+","+QByteArray::number(sizeOfExtended)+",X\n"; /* Extended partition with all remaining space */
420-
partitionTable += QByteArray::number(startOfSettings)+",,L\n"; /* Settings partition */
421-
partitionTable += "0,0\n";
422-
423-
/* Write out empty extended partition table with signature */
424-
memset(&extended_mbr, 0, sizeof extended_mbr);
425-
extended_mbr.signature[0] = 0x55;
426-
extended_mbr.signature[1] = 0xAA;
427-
QFile f("/dev/mmcblk0");
428-
f.open(f.ReadWrite);
429-
f.seek(startOfExtended*512);
430-
f.write((char *) &extended_mbr, sizeof(extended_mbr));
431-
f.close();
432-
433-
/* Write main partition table */
434-
QString cmd = QString("/sbin/sfdisk -uS /dev/mmcblk0");
435-
QProcess proc;
436-
proc.setProcessChannelMode(proc.MergedChannels);
437-
proc.start(cmd);
438-
proc.write(partitionTable);
439-
proc.closeWriteChannel();
440-
proc.waitForFinished(-1);
441-
QThread::msleep(500);
442-
443-
return proc.exitCode() == 0;
444-
}
445-
446328
#ifdef RISCOS_BLOB_FILENAME
447329
bool InitDriveThread::writeRiscOSblob()
448330
{

recovery/initdrivethread.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,17 +23,13 @@ class InitDriveThread : public QThread
2323
protected:
2424
virtual void run();
2525

26-
bool method_reformatDrive();
2726
bool method_resizePartitions();
28-
bool saveBootFiles();
29-
bool restoreBootFiles();
3027
int sizeofBootFilesInKB();
3128
int sizeofSDCardInBlocks();
3229
bool mountSystemPartition();
3330
bool umountSystemPartition();
3431
bool zeroMbr();
3532
bool formatBootPartition();
36-
bool partitionDrive();
3733
bool formatSettingsPartition();
3834
#ifdef RISCOS_BLOB_FILENAME
3935
bool writeRiscOSblob();

0 commit comments

Comments
 (0)