Exemple #1
0
        public void Memboot()
        {
            int progress    = 5;
            int maxProgress = 300;

            SetProgress(progress, maxProgress);

            byte[] kernel;
            if (!string.IsNullOrEmpty(Mod))
            {
                kernel = CreatePatchedKernel(Mod, true, OriginalGames, Games);
            }
            else
            {
                kernel = File.ReadAllBytes(KernelDump);
            }
            var size = CalKernelSize(kernel);

            if (size > kernel.Length || size > kernel_max_size)
            {
                throw new Exception(Resources.InvalidKernelSize + " " + size);
            }
            size = (size + sector_size - 1) / sector_size;
            size = size * sector_size;
            if (kernel.Length != size)
            {
                var newK = new byte[size];
                Array.Copy(kernel, newK, kernel.Length);
                kernel = newK;
            }

            progress   += 5;
            maxProgress = kernel.Length / 67000 + 15;
            SetProgress(progress, maxProgress);

            SetStatus(Resources.UploadingKernel);
            fel.WriteMemory(flash_mem_base, kernel,
                            delegate(Fel.CurrentAction action, string command)
            {
                switch (action)
                {
                case Fel.CurrentAction.WritingMemory:
                    SetStatus(Resources.UploadingKernel);
                    break;
                }
                progress++;
                SetProgress(progress, maxProgress);
            }
                            );

            var bootCommand = string.Format("boota {0:x}", kernel_base_m);

            SetStatus(Resources.ExecutingCommand + " " + bootCommand);
            fel.RunUbootCmd(bootCommand, true);
            SetStatus(Resources.Done);
            SetProgress(maxProgress, maxProgress);
        }
        public Conclusion MembootFel(Tasker tasker, Object syncObject = null)
        {
            tasker.SetStatus(Resources.Membooting);
            if (hakchi.Shell.IsOnline)
                return Conclusion.Abort;

            // check and adjust kernel size
            byte[] kernel = hakchi.GetMembootImage().ToArray();
            var size = Shared.CalcKernelSize(kernel);
            if (size > kernel.Length || size > Fel.transfer_max_size)
                throw new Exception(Resources.InvalidKernelSize + " " + size);
            size = (size + Fel.sector_size - 1) / Fel.sector_size;
            size = size * Fel.sector_size;
            if (kernel.Length != size)
            {
                var newK = new byte[size];
                Array.Copy(kernel, newK, kernel.Length);
                kernel = newK;
            }

            // clovershell override "hex-edit" boot.img
            if (ConfigIni.Instance.ForceClovershell || ConfigIni.Instance.ForceNetwork)
            {
                kernel.InPlaceStringEdit(64, 512, 0, (string str) => {
                    str.Replace("hakchi-shell", "").Replace("hakchi-clovershell", "");
                    if (ConfigIni.Instance.ForceClovershell)
                        str += " hakchi-clovershell";
                    else if (ConfigIni.Instance.ForceNetwork)
                        str += " hakchi-shell";
                    return str;
                });
            }

            // upload kernel through fel
            int progress = 0;
            int maxProgress = (int)((double)kernel.Length / (double)67000 + 50);
            fel.WriteMemory(Fel.transfer_base_m, kernel,
                delegate (Fel.CurrentAction action, string command)
                {
                    switch (action)
                    {
                        case Fel.CurrentAction.WritingMemory:
                            tasker.SetStatus(Resources.UploadingKernel);
                            break;
                    }
                    progress++;
                    tasker.SetProgress(progress, maxProgress);
                }
            );

            var bootCommand = string.Format("boota {0:x}", Fel.transfer_base_m);
            tasker.SetStatus(Resources.ExecutingCommand + " " + bootCommand);
            fel.RunUbootCmd(bootCommand, true);

            return Conclusion.Success;
        }
Exemple #3
0
        public void Memboot(byte[] fes, byte[] uboot, byte[] bootImage, Fel.WriteLineHandler writeLineHandler = null)
        {
            var fel = new Fel();

            fel.WriteLine += WriteLine;
            fel.Fes1Bin    = fes;
            fel.UBootBin   = uboot;
            if (!fel.Open())
            {
                throw new Exception("USB Device Not Found");
            }

            var size = CalcKernelSize(bootImage);

            if (size > bootImage.Length || size > Fel.transfer_max_size)
            {
                throw new Exception($"Invalid boot image size: {size}");
            }
            size = (size + Fel.sector_size - 1) / Fel.sector_size;
            size = size * Fel.sector_size;
            if (bootImage.Length != size)
            {
                var newK = new byte[size];
                Array.Copy(bootImage, newK, bootImage.Length);
                bootImage = newK;
            }

            long maxProgress = size / 65536, progress = 0;

            // upload kernel through fel
            fel.WriteMemory(Fel.transfer_base_m, bootImage,
                            delegate(Fel.CurrentAction action, string command)
            {
                switch (action)
                {
                case Fel.CurrentAction.WritingMemory:
                    SetStatus?.Invoke("Uploading boot image");
                    break;
                }
                progress++;
                SetProgress?.Invoke(Math.Min(progress, maxProgress), maxProgress);
            }
                            );

            var bootCommand = string.Format("boota {0:x}", Fel.transfer_base_m);

            RunCommand(fel, bootCommand, true);
        }
Exemple #4
0
        public Conclusion Memboot(Tasker tasker, Object syncObject = null)
        {
            // load appropriate kernel
            byte[] kernel;
            if (stockKernel != null && stockKernel.Length > 0)
            {
                kernel = stockKernel.ToArray();
            }
            else
            {
                stockKernel = null; // double-safety
                kernel      = hakchi.GetMembootImage().ToArray();
            }

            tasker.SetStatus(Resources.Membooting);
            if (hakchi.Shell.IsOnline)
            {
                // override arguments
                string addedArgs = ConfigIni.Instance.ForceClovershell ? " hakchi-clovershell" : "";

                // skip to built-in recovery if running latest version
                if (stockKernel == null && hakchi.CanInteract && !hakchi.SystemEligibleForRootfsUpdate())
                {
                    if (hakchi.Shell.Execute("[ -e /bin/detached ]") == 0) // detached recovery function?
                    {
                        try
                        {
                            hakchi.Shell.ExecuteSimple("/bin/detached recovery" + addedArgs, 100);
                        }
                        catch { } // no-op
                        return(Conclusion.Success);
                    }
                }

                try
                {
                    hakchi.Shell.ExecuteSimple("uistop");
                    hakchi.Shell.ExecuteSimple("mkdir -p /tmp/kexec/", throwOnNonZero: true);
                    hakchi.UploadFile(
                        Path.Combine(Program.BaseDirectoryInternal, "tools", "arm", "kexec.static"),
                        "/tmp/kexec/kexec");

                    TrackableStream kernelStream = new TrackableStream(kernel);
                    kernelStream.OnProgress += tasker.OnProgress;
                    if (stockKernel == null)
                    {
                        hakchi.UploadFile(
                            Path.Combine(Program.BaseDirectoryInternal, "tools", "arm", "detached-fallback"),
                            "/tmp/kexec/detached-fallback");
                        hakchi.UploadFile(kernelStream, "/tmp/kexec/boot.img", false);
                        try
                        {
                            hakchi.Shell.ExecuteSimple("cd /tmp/kexec/; /bin/sh /tmp/kexec/detached-fallback recovery /tmp/kexec/boot.img" + addedArgs, 100);
                        }
                        catch { } // no-op
                    }
                    else
                    {
                        hakchi.UploadFile(
                            Path.Combine(Program.BaseDirectoryInternal, "tools", "arm", "unpackbootimg.static"),
                            "/tmp/kexec/unpackbootimg");
                        hakchi.Shell.Execute(
                            command: "cat > /tmp/kexec/boot.img; cd /tmp/kexec/; ./unpackbootimg -i boot.img",
                            stdin: kernelStream,
                            throwOnNonZero: true
                            );
                        hakchi.Shell.ExecuteSimple("cd /tmp/kexec/ && ./kexec -l -t zImage boot.img-zImage \"--command-line=$(cat boot.img-cmdline)\" --ramdisk=boot.img-ramdisk.gz --atags", 0, true);
                        hakchi.Shell.ExecuteSimple("cd /tmp/; umount -ar", 0);
                        try
                        {
                            hakchi.Shell.ExecuteSimple("/tmp/kexec/kexec -e", 100);
                        }
                        catch { } // no-op
                    }
                }
                catch
                {
                    try
                    {
                        hakchi.Shell.ExecuteSimple("uistart");
                    }
                    catch { } // no-op
                    throw;
                }
            }
            else
            {
                // check and adjust kernel size
                var size = Shared.CalcKernelSize(kernel);
                if (size > kernel.Length || size > Fel.transfer_max_size)
                {
                    throw new Exception(Resources.InvalidKernelSize + " " + size);
                }
                size = (size + Fel.sector_size - 1) / Fel.sector_size;
                size = size * Fel.sector_size;
                if (kernel.Length != size)
                {
                    var newK = new byte[size];
                    Array.Copy(kernel, newK, kernel.Length);
                    kernel = newK;
                }

                // clovershell override "hex-edit" boot.img
                if (stockKernel == null && ConfigIni.Instance.ForceClovershell)
                {
                    kernel.InPlaceStringEdit(64, 512, 0, (string str) => {
                        if (str.IndexOf("hakchi-shell") != -1)
                        {
                            return(str.Replace("hakchi-shell", "hakchi-clovershell"));
                        }
                        else
                        {
                            return(str + " hakchi-clovershell");
                        }
                    });
                }

                // upload kernel through fel
                int progress    = 0;
                int maxProgress = (int)((double)kernel.Length / (double)67000 + 50);
                fel.WriteMemory(Fel.transfer_base_m, kernel,
                                delegate(Fel.CurrentAction action, string command)
                {
                    switch (action)
                    {
                    case Fel.CurrentAction.WritingMemory:
                        tasker.SetStatus(Resources.UploadingKernel);
                        break;
                    }
                    progress++;
                    tasker.SetProgress(progress, maxProgress);
                }
                                );

                var bootCommand = string.Format("boota {0:x}", Fel.transfer_base_m);
                tasker.SetStatus(Resources.ExecutingCommand + " " + bootCommand);
                fel.RunUbootCmd(bootCommand, true);
            }
            return(Conclusion.Success);
        }
Exemple #5
0
        public void Memboot(int maxProgress = -1, int progress = 0)
        {
            SetProgress(progress, maxProgress < 0 ? 1000 : maxProgress);
            // Connecting to NES Mini
            if (WaitForFelFromThread() != DialogResult.OK)
            {
                DialogResult = DialogResult.Abort;
                return;
            }
            progress += 5;
            SetProgress(progress, maxProgress > 0 ? maxProgress : 1000);

            byte[] kernel;
            if (!string.IsNullOrEmpty(Mod))
            {
                kernel = CreatePatchedKernel();
            }
            else
            {
                kernel = File.ReadAllBytes(KernelDump);
            }
            var size = CalcKernelSize(kernel);

            if (size > kernel.Length || size > Fel.kernel_max_size)
            {
                throw new Exception(Resources.InvalidKernelSize + " " + size);
            }
            size = (size + Fel.sector_size - 1) / Fel.sector_size;
            size = size * Fel.sector_size;
            if (kernel.Length != size)
            {
                var newK = new byte[size];
                Array.Copy(kernel, newK, kernel.Length);
                kernel = newK;
            }
            progress += 5;
            if (maxProgress < 0)
            {
                maxProgress = (int)((double)kernel.Length / (double)67000 + 20);
            }
            SetProgress(progress, maxProgress);

            SetStatus(Resources.UploadingKernel);
            fel.WriteMemory(Fel.flash_mem_base, kernel,
                            delegate(Fel.CurrentAction action, string command)
            {
                switch (action)
                {
                case Fel.CurrentAction.WritingMemory:
                    SetStatus(Resources.UploadingKernel);
                    break;
                }
                progress++;
                SetProgress(progress, maxProgress);
            }
                            );

            var bootCommand = string.Format("boota {0:x}", Fel.kernel_base_m);

            SetStatus(Resources.ExecutingCommand + " " + bootCommand);
            fel.RunUbootCmd(bootCommand, true);
            Thread.Sleep(7000);
            SetStatus(Resources.Done);
            SetProgress(maxProgress, maxProgress);
        }
Exemple #6
0
        public void Memboot()
        {
            int pos = 0, totalFiles = 0;
            int progress = 5;

            SetProgress(progress, 300);
            int maxProgress = -1;

            do
            {
                if (pos > 0)
                {
                    ShowMessage(Resources.ParticallyBody, Resources.ParticallyTitle);
                    DeviceWaitResult = DialogResult.None;
                    WaitForDeviceFromThread();
                    while (DeviceWaitResult == DialogResult.None)
                    {
                        Thread.Sleep(500);
                    }
                    if (DeviceWaitResult != DialogResult.OK)
                    {
                        DialogResult = DialogResult.Abort;
                        return;
                    }
                    fel          = new Fel();
                    fel.Fes1Bin  = File.ReadAllBytes(fes1Path);
                    fel.UBootBin = File.ReadAllBytes(ubootPath);
                    fel.Open(vid, pid);
                    SetStatus(Resources.UploadingFes1);
                    fel.InitDram(true);
                }

                byte[] kernel;
                if (!string.IsNullOrEmpty(Mod))
                {
                    kernel = CreatePatchedKernel(ref pos, out totalFiles);
                }
                else
                {
                    kernel = File.ReadAllBytes(KernelDump);
                }
                var size = CalKernelSize(kernel);
                if (size > kernel.Length || size > Fel.kernel_max_size)
                {
                    throw new Exception(Resources.InvalidKernelSize + " " + size);
                }
                size = (size + Fel.sector_size - 1) / Fel.sector_size;
                size = size * Fel.sector_size;
                if (kernel.Length != size)
                {
                    var newK = new byte[size];
                    Array.Copy(kernel, newK, kernel.Length);
                    kernel = newK;
                }

                progress += 5;
                if (maxProgress < 0)
                {
                    if (pos > 0)
                    {
                        maxProgress = (kernel.Length / 67000 + 15) * totalFiles / pos + 75 * ((int)Math.Ceiling((float)totalFiles / (float)pos) - 1);
                    }
                    else
                    {
                        maxProgress = (kernel.Length / 67000 + 15);
                    }
                }
                SetProgress(progress, maxProgress);

                SetStatus(Resources.UploadingKernel);
                fel.WriteMemory(Fel.flash_mem_base, kernel,
                                delegate(Fel.CurrentAction action, string command)
                {
                    switch (action)
                    {
                    case Fel.CurrentAction.WritingMemory:
                        SetStatus(Resources.UploadingKernel);
                        break;
                    }
                    progress++;
                    SetProgress(progress, maxProgress);
                }
                                );

                var bootCommand = string.Format("boota {0:x}", Fel.kernel_base_m);
                SetStatus(Resources.ExecutingCommand + " " + bootCommand);
                fel.RunUbootCmd(bootCommand, true);
            } while (pos < totalFiles);
            SetStatus(Resources.Done);
            SetProgress(maxProgress, maxProgress);
        }
Exemple #7
0
 void ExecCommand(string command, bool nopause = false)
 {
     SetStatus(Resources.ExecutingCommand + " " + command);
     fel.WriteMemory((uint)(uboot_base_m + cmdOffset), Encoding.ASCII.GetBytes(command + "\0"));
     fel.Exec((uint)uboot_base_m, nopause ? 0 : 10);
 }
Exemple #8
0
        public void Memboot()
        {
            int progress    = 0;
            int maxProgress = -1;
            var stats       = new GamesTreeStats();

            if (Games != null)
            {
                SetStatus(Resources.BuildingFolders);
                if (FoldersMode == NesMenuCollection.SplitStyle.Custom)
                {
                    if (FolderManagerFromThread(Games) != System.Windows.Forms.DialogResult.OK)
                    {
                        DialogResult = DialogResult.Abort;
                        return;
                    }
                    Games.AddBack();
                }
                else
                {
                    Games.Split(FoldersMode, MaxGamesPerFolder);
                }
            }
            progress += 5;
            SetProgress(progress, 300);

            do
            {
                if (stats.GamesProceed > 0)
                {
                    ShowMessage(Resources.ParticallyBody, Resources.ParticallyTitle);
                }
                GC.Collect();

                // Connecting to NES Mini
                if (WaitForDeviceFromThread() != DialogResult.OK)
                {
                    DialogResult = DialogResult.Abort;
                    return;
                }
                progress += 5;
                SetProgress(progress, maxProgress > 0 ? maxProgress : 300);

                byte[] kernel;
                if (!string.IsNullOrEmpty(Mod))
                {
                    kernel = CreatePatchedKernel(stats);
                }
                else
                {
                    kernel = File.ReadAllBytes(KernelDump);
                }
                var size = CalKernelSize(kernel);
                if (size > kernel.Length || size > Fel.kernel_max_size)
                {
                    throw new Exception(Resources.InvalidKernelSize + " " + size);
                }
                size = (size + Fel.sector_size - 1) / Fel.sector_size;
                size = size * Fel.sector_size;
                if (kernel.Length != size)
                {
                    var newK = new byte[size];
                    Array.Copy(kernel, newK, kernel.Length);
                    kernel = newK;
                }
                progress += 5;
                if (maxProgress < 0)
                {
                    if (stats.GamesProceed > 0)
                    {
                        maxProgress = (kernel.Length / 67000 + 20) * stats.GamesTotal / stats.GamesProceed + 75 * ((int)Math.Ceiling((float)stats.GamesTotal / (float)stats.GamesProceed) - 1);
                    }
                    else
                    {
                        maxProgress = (kernel.Length / 67000 + 20);
                    }
                }
                SetProgress(progress, maxProgress);

                SetStatus(Resources.UploadingKernel);
                fel.WriteMemory(Fel.flash_mem_base, kernel,
                                delegate(Fel.CurrentAction action, string command)
                {
                    switch (action)
                    {
                    case Fel.CurrentAction.WritingMemory:
                        SetStatus(Resources.UploadingKernel);
                        break;
                    }
                    progress++;
                    SetProgress(progress, maxProgress);
                }
                                );

                var bootCommand = string.Format("boota {0:x}", Fel.kernel_base_m);
                SetStatus(Resources.ExecutingCommand + " " + bootCommand);
                fel.RunUbootCmd(bootCommand, true);
            } while (stats.GamesProceed < stats.GamesTotal);
            SetStatus(Resources.Done);
            SetProgress(maxProgress, maxProgress);
        }