module "luci.sys.mtdow"
-local WRITE_IMAGE = 0
-local WRITE_COMBINED = 1
-local WRITE_EMULATED = 2
+WRITE_IMAGE = 0
+WRITE_COMBINED = 1
+WRITE_EMULATED = 2
+
+ERROR_INTERNAL = 1
+ERROR_NOTFOUND = 2
+ERROR_RESOURCE = 3
+ERROR_NODETECT = 4
+ERROR_NOTAVAIL = 5
+ERROR_NOSTREAM = 6
+ERROR_INVMAGIC = 7
Writer = util.class()
image = {
magic = "eb48",
device = "/dev/hda",
- write = WRITE_SEPARATELY
+ write = WRITE_EMULATED
}
}
+function EmulatedWriter.write_block(self, name, imagestream, appendpattern)
+ if appendpattern then
+ os.execute("grep rootfs /proc/mtd >/dev/null || "
+ .. "{ echo /dev/hda2,65536,rootfs > "
+ .. "/sys/module/block2mtd/parameters/block2mtd }")
+ end
+ return Writer.write_block(self, name, imagestream, appendpattern)
+end
+
-- Broadcom
-TRXWriter = util.class(Writer)
-TRXWriter.blocks = {
+CFEWriter = util.class(Writer)
+CFEWriter.blocks = {
image = {
magic = {"4844", "5735"},
device = "linux",
- write = WRITE_COMBINED
+ write = WRITE_IMAGE
}
}
}
}
-function EmulatedWriter.write_block(self, name, imagestream, appendpattern)
- if appendpattern then
- os.execute("grep rootfs /proc/mtd >/dev/null || "
- .. "{ echo /dev/hda2,65536,rootfs > "
- .. "/sys/module/block2mtd/parameters/block2mtd }")
+-- Auto Detect
+function native_writer()
+ local w = Writer()
+
+ -- Detect amd64 / x86
+ local x86 = {"x86_64", "i386", "i486", "i586", "i686"}
+ if util.contains(x86, posix.uname("%m")) then
+ return EmulatedWriter()
+ end
+
+ -- Detect CFE
+ if w:_find_mtdblock("cfe") and w:_find_mtdblock("linux") then
+ return CFEWriter()
+ end
+
+ -- Detect Redboot
+ if w:_find_mtdblock("RedBoot") and w:_find_mtdblock("vmlinux.bin.l7") then
+ return RedWriter()
+ end
+
+ -- Detect MagicBox
+ if fs.readfile("/proc/cpuinfo"):find("MagicBox") then
+ return CommonWriter()
end
- return Writer.write_block(self, name, imagestream, appendpattern)
end
+
Writer.MTD = "/sbin/mtd"
Writer.SAFEMTD = "/tmp/mtd"
Writer.IMAGEFIFO = "/tmp/mtdimage.fifo"
function Writer.write_block(self, name, imagestream, appendfile)
- assert(self.blocks[name], "Undefined block: " % name)
+ assert(self.blocks[name], ERROR_NOTFOUND)
local block = self.blocks[name]
local device = block.device
device = fs.stat(device) and device or self:_find_mtdblock(device)
- assert(device, "Unable to determine device file")
+ assert(device, ERROR_NODETECT)
if block.magic then
imagestream = self:_check_magic(imagestream, block.magic)
end
- assert(imagestream, "Invalid image file")
+ assert(imagestream, ERROR_INVMAGIC)
if appendfile then
if block.write == WRITE_COMBINED then
elseif block.write == WRITE_EMULATED then
return (self:_write_emulated(device, imagestream, appendfile) == 0)
else
- error("Appending is not supported for selected platform.")
+ error(ERROR_NOTAVAIL)
end
else
return (self:_write_memory(device, imagestream) == 0)
magic = type(magic) == "table" and magic or {magic}
local block = imagestream()
- assert(block, "Invalid image stream")
+ assert(block, ERROR_NOSTREAM)
local cm = "%x%x" % {block:byte(1), block:byte(2)}
if util.contains(magic, cm) then
function Writer._find_mtdblock(self, mtdname)
local k
- local prefix = "/dev/mtdblock"
+ local prefix = "/dev/mtd"
prefix = prefix .. (fs.stat(prefix) and "/" or "")
for l in io.lines("/proc/mtd") do
- local k = l:match('([%w-_]+):.*-"%s"' % mtdname)
+ local k = l:match('mtd([%%w-_]+):.*"%s"' % mtdname)
if k then return prefix..k end
end
end
-function Write._write_emulated(self, devicename, imagestream, appendfile)
+function Writer._write_emulated(self, devicename, imagestream, appendfile)
local stat = (self:_write_memory(device, imagestream) == 0)
stat = stat and (self:_refresh_block("rootfs") == 0)
local squash = self:_find_mtdblock("rootfs_data")
end
function Writer._write_memory(self, devicename, imagestream)
- local devicestream = ltn12.sink.file(io.open(devicename, "w"))
- local stat, err = ltn12.pump.all(imagestream, devicestream)
- if stat then
- return os.execute("sync")
+ local imageproc = posix.fork()
+ assert(imageproc ~= -1, ERROR_RESOURCE)
+ if imageproc == 0 then
+ fs.unlink(self.IMAGEFIFO)
+ assert(posix.mkfifo(self.IMAGEFIFO), ERROR_RESOURCE)
+ local imagefifo = io.open(self.IMAGEFIFO, "w")
+ assert(imagefifo, ERROR_RESOURCE)
+ ltn12.pump.all(imagestream, ltn12.sink.file(imagefifo))
+ os.exit(0)
end
+
+ return os.execute(
+ "%s write '%s' '%s' >/dev/null 2>&1" % {
+ self.MTD, self.IMAGEFIFO, devicename
+ }
+ )
end
function Writer._write_combined(self, devicename, imagestream, appendfile)
- assert(fs.copy(self.MTD, self.SAFEMTD), "Unable to copy mtd writer")
- assert(posix.mkfifo(self.IMAGEFIFO), "Unable to create image pipe")
-
- local imagefifo = io.open(self.IMAGEFIFO, "w")
-
- assert(imagefifo, "Unable to open image pipe")
-
local imageproc = posix.fork()
- assert(imageproc ~= -1, "Unable to fork()")
+ assert(imageproc ~= -1, ERROR_RESOURCE)
if imageproc == 0 then
+ fs.unlink(self.IMAGEFIFO)
+ assert(posix.mkfifo(self.IMAGEFIFO), ERROR_RESOURCE)
+ local imagefifo = io.open(self.IMAGEFIFO, "w")
+ assert(imagefifo, ERROR_RESOURCE)
ltn12.pump.all(imagestream, ltn12.sink.file(imagefifo))
os.exit(0)
end
return os.execute(
- "%s -j '%s' write '%s' '%s'" % {
- self.SAFEMTD, appendfile, devicename, self.IMAGEFIFO
+ "%s -j '%s' write '%s' '%s' >/dev/null 2>&1" % {
+ self.MTD, appendfile, self.IMAGEFIFO, devicename
}
)
end
function Writer._refresh_block(self, devicename)
- assert(fs.copy(self.MTD, self.SAFEMTD), "Unable to copy mtd writer")
- return os.execute("%s refresh '%s'" % {self.SAFEMTD, devicename})
+ return os.execute("%s refresh '%s' >/dev/null 2>&1" % {self.MTD, devicename})
end
function Writer._append(self, devicename, appendfile, erase)
- assert(fs.copy(self.MTD, self.SAFEMTD), "Unable to copy mtd writer")
erase = erase and ("-e '%s' " % devicename) or ''
return os.execute(
- "%s %s jffs2write '%s' '%s'" % {
- self.SAFEMTD, erase, appendfile, devicename
+ "%s %s jffs2write '%s' '%s' >/dev/null 2>&1" % {
+ self.MTD, erase, appendfile, devicename
}
)
end
\ No newline at end of file