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; }
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); }
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); }
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); }
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); }
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); }
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); }