-- -- Copyright (C) 2005 dahua Technologies, All Rights Reserved. -- 2006-4-25 15:54 Z:\wjj\ven\152\DAHUA\Install.lua -- 2006-9-21 modified by zhongjl for new partition -- -- Flash 块的大小为64K local flashSectorSize = 0x20000; local Installer = {}; Installer.TotalSize = 0; -- 总的要写到Flash中的数据大小 Installer.InProgressSize = 0; -- 用来在升级过程中控制进度 -- 通知上层应用程序升级的进度信息 -- params: -- 无 -- return: -- 无 function Installer:notify() self.InProgressSize = self.InProgressSize + flashSectorSize; local progress = self.InProgressSize / self.TotalSize * 100; if(progress > 100) then progress = 100; end; progress = tonumber(string.format("%d", progress)); -- 注意调用方式,不是self::callback,否则会导致回调出错 self.callback(0x01, progress); end -- 根据应用程序提供的信息判断是否可以升级 -- params: -- 无 -- return: -- 成功返回True, 失败返回False以及失败的原因 function Installer:preInstall() -- 这里我们需要考虑那些因数? -- 硬件版本号 ? -- 原有软件的版本号? -- local board = Global.Hardware.board; local hwproduct; local hwchannel; local hwversion; local hwfunction; print(string.format("Checking hardware information,board name:%s version:%s", board.name, board.version)); -- if(board.name ~= "DVRxx04HF-X-4H") then -- return false, "Invalid board"; -- end --升级程序直接从硬件中取值。意义如下 --hwproduct取值如下: 2 -- LB; 3 -- LBN; 4 -- LB_ATM; 5 -- GBE; 6 -- LK; 7 -- LS --hwproduct取值如下: 2 -- IPC4X5; 3 -- A6; 4 -- A8; 5 -- IPVM; --hwchannel取值如下: x -- x chans --hwfunction取值如下: 0 -- AUDIO; 1 -- MATRIX; 3 -- LOOP if(mtd.getinfo)then hwproduct,hwchannel,hwversion,hwfunction = mtd.getinfo(); print(string.format("Checking hardware id info: product = %x; channel = %x; version = %x; function = %x", hwproduct,hwchannel,hwversion,hwfunction)); if((hwproduct ~= 3) and (hwproduct ~= 4)) then print(string.format("product not match")); return false, "Invalid board"; end end -- 这里我们需要校验不同板本的板子程序是否可以通用, -- 如目前LB 1.22的与 LB 2.00的板子就不能通用 -- if(board.version ~= "1.22") then -- print(string.format("XXXXXXXXXXXX")); -- return false, "Invalid board version"; -- end local vendor = Global.Vendor; -- if(vendor.Name ~= 'General_N6' and vendor.Name ~= 'DAHUA') then -- return false, "Invalid vendor"; -- end return true; end -- 升级完成后的处理,如控制系统重启 -- params: -- 无 -- return: -- 无 function Installer:postInstall() end -- 升级Flash分区,对于不同的应用,升级的处理可能不一样 -- params : -- part : 表格,包含分区的起始位置以及结束位置 -- filename : 在升级包中的文件名 -- return : 无 function Installer:updatePart(part, filename) local myfile = self.ZipArchive:open(filename); -- 如果该文件打不开,则不需要对此部分进行升级 if(not myfile) then print(string.format("%s not exist", filename)); return ; end local addr = part.baseAddr; local endAddr= part.endAddr; local data; local fldata; -- 跳过前面64字节的头,在新的升级程序版本中不需要对此进行校验 myfile:seek("set", 64); while(addr < endAddr) do fldata = mtd.read(addr,flashSectorSize); data = myfile:read(flashSectorSize); -- 读入一块Flash扇区大小的数据 -- if (fldata and data and (fldata ~= data)) then -- 当fldata为空的时候为老的程序,直接擦除 if(data) then if((not fldata) or (data and (fldata ~= data))) then mtd.erase(addr); mtd.write(addr, data); end self:notify(); addr = addr + flashSectorSize; else addr = endAddr; end end myfile:close(); end function Installer:InstallPlayer(filename) local myfile = self.ZipArchive:open(filename); -- 如果该文件打不开,则不需要对此部分进行升级 if(not myfile) then return ; end -- -- TODO: -- 读入自动播放器的内容,通过IDE接口写入到硬盘 -- end -- 在这里控制整个升级过程 -- params: -- 无 -- return: -- 成功返回True,失败返回Flase以及错误原因 function Installer:execute() --[[ 分区配置信息表,来自知识库 "Flash 分区规划" 0xa0000000 - 0xa0040000 256K armboot u-boot 0xa0060000 - 0xa0460000 4096K kernel + root romfs 0xa0460000 - 0xa0a60000 6144K application + modules user 0xa0a60000 - 0xa0c60000 1536K web web 0xa0c60000 - 0xa0e60000 2560K slave:romfs + kernel + pcidriver slave 0xa0e60000 - 0xa0e80000 128K custom custom 0xa0e80000 - 0xa0ec0000 256K logo logo 0xa0ec0000 - 0xa0f40000 1024K config 0xa0f40000 - 0xa1000000 1024K config1 ]] local flashPartions = { boot = { baseAddr = 0xa0000000 , endAddr = 0xa0040000 }, rootfs = { baseAddr = 0xa0060000 , endAddr = 0xa0CE0000 }, web = { baseAddr = 0xa0CE0000 , endAddr = 0xa0E60000 }, custom = { baseAddr = 0xa0E60000 , endAddr = 0xa0E80000 }, logo = { baseAddr = 0xa0E80000 , endAddr = 0xa0EC0000 }, config = { baseAddr = 0xa0EC0000 , endAddr = 0xa0f40000 }, config1 = { baseAddr = 0xa0f40000 , endAddr = 0xa1000000 }, } -- self.ZipArchive 这个变量由外部程序设置,如果没有设置程序不应该运行到这里 assert(self.ZipArchive); local zfile = self.ZipArchive; local ret, info = self:preInstall(); if(not ret) then return false, info; end -- 计算要升级的文件大小以及打印升级文件清单 local TotalSize = 0; print("==>Files in archive"); for file in zfile:files() do print(file.filename); TotalSize = TotalSize + file.uncompressed_size; end self.TotalSize = TotalSize; -- 总的文件大小 mtd.init(); self:updatePart(flashPartions["boot"], "u-boot.bin.img"); --mtd.saveenv(); self:updatePart(flashPartions["rootfs"], "romfs-x.cramfs.img"); --self:updatePart(flashPartions["user"], "user-x.cramfs.img"); self:updatePart(flashPartions["web"], "web-x.cramfs.img"); --self:updatePart(flashPartions["slave"], "slave-x.cramfs.img"); self:updatePart(flashPartions["custom"], "custom-x.cramfs.img"); self:updatePart(flashPartions["logo"], "logo-x.cramfs.img"); --self:InstallPlayer("autoplayer.bin"); self:postInstall(); print("==>Upgrade finished."); return true; end return Installer;