diff --git a/src/main.zig b/src/main.zig index dfe4b88..550a2d4 100644 --- a/src/main.zig +++ b/src/main.zig @@ -10,25 +10,30 @@ pub fn main() !u8 { try mtd_rw.load(); defer mtd_rw.unload(); - try mtd.ensure_size("mtd0", uboot_bin.len); + const mtd_dev = "/dev/mtd0"; - const no_write_needed = try mtd.verify("/dev/mtd0", uboot_bin); + // Ensure the partition is large enough to hold the new data + try mtd.ensure_size(mtd_dev, uboot_bin.len); + + // Bail if the partition matches our payload already + const no_write_needed = try mtd.verify(mtd_dev, uboot_bin); if (no_write_needed) { std.debug.warn("U-Boot is up to date. Exiting.\n", .{}); return 0; } + // Erase and Write + try mtd.erase_device(mtd_dev); + std.debug.warn("Writing {} bytes to {}\n", .{uboot_bin.len, mtd_dev}); + try mtd.write_device(mtd_dev, uboot_bin); - try mtd.erase_device("/dev/mtd0"); - std.debug.warn("Writing {} bytes to /dev/mtd0\n", .{uboot_bin.len}); - try mtd.write_device("/dev/mtd0", uboot_bin); - - // Verify mtd0 - const writing_verified = try mtd.verify("/dev/mtd0", uboot_bin); + // Verify + const writing_verified = try mtd.verify(mtd_dev, uboot_bin); if (!writing_verified) { std.debug.warn("Verify Failed!\n", .{}); return 2; } + std.debug.warn("Success\n", .{}); return 0; } diff --git a/src/mtd-rw.zig b/src/mtd-rw.zig index 4de9a21..ba9e3c2 100644 --- a/src/mtd-rw.zig +++ b/src/mtd-rw.zig @@ -13,7 +13,6 @@ const InitModuleError = error { AlreadyLoaded, BadParams, InvalidModule, - }; const DeleteModuleError = error { @@ -37,7 +36,7 @@ pub fn unload() void { pub fn insmod(buf: []const u8, args: [*:0]const u8) !void { const errno = os.linux.getErrno( os.linux.syscall3( - os.linux.SYS_init_module, @ptrToInt(&buf), buf.len, @ptrToInt(args))); + os.linux.SYS_init_module, @ptrToInt(&buf[0]), buf.len, @ptrToInt(args))); switch (errno) { 0 => return, os.EEXIST => return, // Module already loaded, this is fine diff --git a/src/mtd.zig b/src/mtd.zig index 24bcfcb..d00348c 100644 --- a/src/mtd.zig +++ b/src/mtd.zig @@ -8,9 +8,10 @@ const Allocator = std.heap.c_allocator; const MEMUNLOCK = 2148027654; const MEMERASE = 2148027650; -pub fn mtd_info_get(name: []const u8, out: []u8) !void { +pub fn mtd_info_get(dev: []const u8, name: []const u8, out: []u8) !void { + const nonabs = dev[5..]; var path_buf: [64]u8 = undefined; - const path = try std.fmt.bufPrint(path_buf[0..], "{}/{}", .{"/sys/class/mtd/mtd0/", name}); + const path = try std.fmt.bufPrint(path_buf[0..], "{}/{}/{}", .{"/sys/class/mtd", nonabs, name}); var f = try std.fs.openFileAbsolute(path, .{.read = true}); defer f.close(); @@ -18,10 +19,10 @@ pub fn mtd_info_get(name: []const u8, out: []u8) !void { out = out[0..num_read-1]; } -pub fn mtd_info_get_usize(name: []const u8) !usize { +pub fn mtd_info_get_usize(dev: []const u8, name: []const u8) !usize { var buf: [64]u8 = undefined; var buf_sl = buf[0..]; - try mtd_info_get(name, buf_sl); + try mtd_info_get(dev, name, buf_sl); return try std.fmt.parseUnsigned(usize, buf_sl, 10); } @@ -57,7 +58,7 @@ const MtdError = error { }; pub fn ensure_size(dev: []const u8, size: usize) !void { - const part_size = try mtd_info_get_usize("size"); + const part_size = try mtd_info_get_usize(dev, "size"); if (size > part_size) { std.debug.warn("Error: {} isn\'t large enough to hold the new image ({} > {})\n", .{dev, size, part_size}); @@ -72,8 +73,8 @@ pub fn write_device(dev: []const u8, buf: []const u8) !void { } pub fn erase_device(dev: []const u8) !void { - const erasesize = try mtd_info_get_usize("erasesize"); - const size = try mtd_info_get_usize("size"); + const erasesize = try mtd_info_get_usize(dev, "erasesize"); + const size = try mtd_info_get_usize(dev, "size"); var erased: usize = 0; const fd = try os.open(dev, os.O_RDWR, 0); defer os.close(fd); @@ -92,7 +93,7 @@ pub fn erase_page(fd: os.fd_t, start: usize, len: usize) !void { } pub fn verify(dev: []const u8, buf: []const u8) !bool { - const size = try mtd_info_get_usize("size"); + const size = try mtd_info_get_usize(dev, "size"); var current = try Allocator.alloc(u8, size); var f = try std.fs.openFileAbsolute(dev, .{.read = true});