Exemplo n.º 1
0
bool InitDriveThread::formatSettingsPartition()
{
    return QProcess::execute("/usr/sbin/mkfs.ext4 -L SETTINGS "+partdev(_drive, SETTINGS_PARTNR)) == 0;
}
Exemplo n.º 2
0
bool InitDriveThread::mountSystemPartition()
{
    return QProcess::execute("mount "+partdev(_drive, 1)+" /mnt") == 0 || QProcess::execute("mount "+_drive+" /mnt") == 0;
}
Exemplo n.º 3
0
BootSelectionDialog::BootSelectionDialog(
        const QString &drive,               //PINN drive where boot partitions are stored for DSI mod
        const QString &defaultPartition,    //Could be provided on cmdline. Only used if no previoous OS had been used.
        bool stickyBoot,                    //Use Stickyboot i.e. when NOT going through recovery menu
        bool dsi,                           //Adapt config.txt according to fitted monitor
        QWidget *parent) :
    QDialog(parent),
    _countdown(11),
    _dsi(dsi),
    ui(new Ui::BootSelectionDialog),
    _inSelection(false),
    _drive(drive.toAscii())
{
    setWindowFlags(Qt::Window | Qt::CustomizeWindowHint | Qt::WindowTitleHint);
    ui->setupUi(this);
    QRect s = QApplication::desktop()->screenGeometry();
    if (s.height() < 500)
        resize(s.width()-10, s.height()-100);
    QDir dir;
    dir.mkdir("/settings");
    if (QProcess::execute("mount -o remount,ro /settings") != 0
        && QProcess::execute("mount -t ext4 -o ro "+partdev(drive, SETTINGS_PARTNR)+" /settings") != 0)
    {
        QMessageBox::critical(this, tr("Cannot display boot menu"), tr("Error mounting settings partition"));
        return;
    }

    _altered=false;

    cec->setWindow("bootSelection");
    cec->setMenu("any");
    connect(cec, SIGNAL(keyPress(int)), this, SLOT(onKeyPress(int)));

    /* Also mount recovery partition as it may contain icons we need */
    if (QProcess::execute("mount -t vfat -o ro "+partdev(drive, 1)+" /mnt") != 0)
    {
        /* Not fatal if this fails */
    }
    installed_os = Json::loadFromFile("/settings/installed_os.json").toList();
    QSize currentsize = ui->list->iconSize();

    QSettings settings("/settings/noobs.conf", QSettings::IniFormat, this);
    int oldSticky = settings.value("sticky_boot", 800).toInt();

    foreach (QVariant v, installed_os)
    {
        QVariantMap m = v.toMap();
        QString iconfilename = m.value("icon").toString();
        QIcon icon;

        if (!iconfilename.isEmpty() && QFile::exists(iconfilename))
        {
            icon = QIcon(iconfilename);
            QList<QSize> avs = icon.availableSizes();
            if (avs.isEmpty())
            {
                /* Icon file corrupt */
                icon = QIcon();
            }
            else
            {
                QSize iconsize = avs.first();

                if (iconsize.width() > currentsize.width() || iconsize.height() > currentsize.height())
                {
                    /* Make all icons as large as the largest icon we have */
                    currentsize = QSize(qMax(iconsize.width(), currentsize.width()),qMax(iconsize.height(), currentsize.height()));
                    ui->list->setIconSize(currentsize);
                }
            }
        }
        QString name = CORE(m.value("name").toString());
        if (canBootOs(name, m))
        {
            name=NICKNAME(m.value("name").toString());
            QListWidgetItem *item = new QListWidgetItem(icon, name+"\n"+m.value("description").toString(), ui->list);
            item->setData(Qt::UserRole, m);
            item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
            item->setCheckState(Qt::Unchecked);
         }
    }
Exemplo n.º 4
0
bool InitDriveThread::method_resizePartitions()
{
    uint newStartOfRescuePartition = getFileContents(sysclassblock(_drive, 1)+"/start").trimmed().toUInt();
    uint newSizeOfRescuePartition  = sizeofBootFilesInKB()*1.024/1000 + 100;

    if (!umountSystemPartition())
    {
        emit error(tr("Error unmounting system partition."));
        return false;
    }

    if (!QFile::exists(partdev(_drive, 1)))
    {
        // SD card does not have a MBR.

        // Warn user that their SD card does not have an MBR and ask
        // if they would like us to create one for them
        QMessageBox::StandardButton answer;
        emit query(tr("Would you like NOOBS to create one for you?\nWARNING: This will erase all data on your SD card"),
                   tr("Error: No MBR present on SD Card"),
                   &answer);

        if(answer == QMessageBox::Yes)
        {
            emit statusUpdate(tr("Zeroing partition table"));
            if (!zeroMbr())
            {
                emit error(tr("Error zero'ing MBR/GPT. SD card may be broken or advertising wrong capacity."));
                return false;
            }

            // Create MBR containing single FAT partition
            emit statusUpdate(tr("Writing new MBR"));
            QProcess proc;
            proc.setProcessChannelMode(proc.MergedChannels);
            proc.start("/usr/sbin/parted "+_drive+" --script -- mktable msdos mkpartfs primary fat32 8192s -1");
            proc.waitForFinished(-1);
            if (proc.exitCode() != 0)
            {
                // Warn user if we failed to create an MBR on their card
                emit error(tr("Error creating MBR")+"\n"+proc.readAll());
                return false;
            }
            qDebug() << "Created missing MBR on SD card. parted output:" << proc.readAll();

            // Advise user that their SD card has now been formatted
            // suitably for installing NOOBS and that they will have to
            // re-copy the files before rebooting
            emit error(tr("SD card has now been formatted ready for NOOBS installation. Please re-copy the NOOBS files onto the card and reboot"));
            return false;
        }
        else
        {
            emit error(tr("SD card has not been formatted correctly. Please reformat using the SD Association Formatting Tool and try again."));
            return false;
        }

    }

    emit statusUpdate(tr("Removing partitions 2,3,4"));

    QFile f(_drive);
    f.open(f.ReadWrite);
    // Seek to partition entry 2
    f.seek(462);
    // Zero out partition 2,3,4 to prevent parted complaining about invalid constraints
    f.write(QByteArray(16*3, '\0'));
    f.flush();
    // Tell Linux to re-read the partition table
    ioctl(f.handle(), BLKRRPART);
    f.close();
    QThread::msleep(500);

    emit statusUpdate(tr("Resizing FAT partition"));

    /* Relocating the start of the FAT partition is a write intensive operation
     * only move it when it is not aligned on a MiB boundary already */
    if (newStartOfRescuePartition < 2048 || newStartOfRescuePartition % 2048 != 0)
    {
        newStartOfRescuePartition = PARTITION_ALIGNMENT; /* 4 MiB */
    }

    QString cmd = "/usr/sbin/parted --script "+_drive+" resize 1 "+QString::number(newStartOfRescuePartition)+"s "+QString::number(newSizeOfRescuePartition)+"M";
    qDebug() << "Executing" << cmd;
    QProcess p;
    QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
    /* Suppress parted's big fat warning about its file system manipulation code not being robust.
       It distracts from any real error messages that may follow it. */
    env.insert("PARTED_SUPPRESS_FILE_SYSTEM_MANIPULATION_WARNING", "1");
    p.setProcessEnvironment(env);
    p.setProcessChannelMode(p.MergedChannels);
    p.start(cmd);
    p.closeWriteChannel();
    p.waitForFinished(-1);

    if (p.exitCode() != 0)
    {
        emit error(tr("Error resizing existing FAT partition")+"\n"+p.readAll());
        return false;
    }
    qDebug() << "parted done, output:" << p.readAll();
    QThread::msleep(500);

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

    QByteArray partitionTable;
    uint startOfOurPartition = getFileContents(sysclassblock(_drive, 1)+"/start").trimmed().toUInt();
    uint sizeOfOurPartition  = getFileContents(sysclassblock(_drive, 1)+"/size").trimmed().toUInt();
    uint startOfExtended = startOfOurPartition+sizeOfOurPartition;

    // Align start of settings partition on 4 MiB boundary
    uint startOfSettings = startOfExtended + PARTITION_GAP;
    if (startOfSettings % PARTITION_ALIGNMENT != 0)
         startOfSettings += PARTITION_ALIGNMENT-(startOfSettings % PARTITION_ALIGNMENT);

    // Primary partitions
    partitionTable  = QByteArray::number(startOfOurPartition)+","+QByteArray::number(sizeOfOurPartition)+",0E\n"; /* FAT partition */
    partitionTable += QByteArray::number(startOfExtended)+",,E\n"; /* Extended partition with all remaining space */
    partitionTable += "0,0\n";
    partitionTable += "0,0\n";
    // Logical partitions
    partitionTable += QByteArray::number(startOfSettings)+","+QByteArray::number(SETTINGS_PARTITION_SIZE)+",L\n"; /* Settings partition */
    qDebug() << "Writing partition table" << partitionTable;

    /* Let sfdisk write a proper partition table */
    cmd = QString("/sbin/sfdisk -uS --force "+_drive);
    QProcess proc;
    proc.setProcessChannelMode(proc.MergedChannels);
    proc.start(cmd);
    proc.write(partitionTable);
    proc.closeWriteChannel();
    proc.waitForFinished(-1);
    if (proc.exitCode() != 0)
    {
        emit error(tr("Error creating extended partition")+"\n"+proc.readAll());
        return false;
    }
    qDebug() << "sfdisk done, output:" << proc.readAll();
    QThread::msleep(500);

    QProcess::execute("/sbin/mlabel -i "+partdev(_drive, 1)+" ::RECOVERY");

    return true;
}
Exemplo n.º 5
0
bool InitDriveThread::formatBootPartition()
{
    return QProcess::execute("/sbin/mkfs.fat -n RECOVERY "+partdev(_drive, 1)) == 0;
}