/*
* system_unlock.c
*/
#include <linux/kernel.h>
#include <linux/module.h>
#define PATCHADDR 0xC05C2FA9
#define PATCHADDR2 0xC05C2FB1
#define LOCK_INFO_ADDR 0xC08FCEA8
static int s_patchaddr = PATCHADDR;
static int s_lockinfoaddr = LOCK_INFO_ADDR;
module_param_named(patchaddr, s_patchaddr, int, 0644);
module_param_named(lockinfoaddr, s_lockinfoaddr, int, 0644);
#define NAND_LOCK_PARTITION_NUM 3
struct nand_lock_info
{
uint64_t start_addr;
uint64_t end_addr;
unsigned char name[20];
};
static struct nand_lock_info msm_nand_lock_info_bak[NAND_LOCK_PARTITION_NUM];
static unsigned int msm_nand_lock_info_num_bak;
static int __init system_unlock_init(void)
{
int i;
unsigned char* mem = (void*)s_patchaddr;
if(strncmp("/system", mem, 8)){
s_patchaddr = PATCHADDR2;
mem = (void*)s_patchaddr;
if(strncmp("/system", mem, 8)){
printk(KERN_ERR "not match \"%s\"\n", mem);
return -1;
}
}
msm_nand_lock_info_num_bak = *(unsigned int*)(s_lockinfoaddr+0x78);
if(msm_nand_lock_info_num_bak > 3){
printk(KERN_ERR "not match lock_info_num=%d\n",
msm_nand_lock_info_num_bak);
return -1;
}
printk(KERN_DEBUG "\"%s\" ->", mem);
mem[5] = 'o'; // "/system\0" -> "/systom\0"
printk(" \"%s\"\n", mem);
memcpy(msm_nand_lock_info_bak, (void*)s_lockinfoaddr, 0x78);
memset((void*)s_lockinfoaddr, 0, 0x78);
for(i=0; i<msm_nand_lock_info_num_bak; i++){
printk("part[%d] : start=%llx, end=%llx, name=\"%s\"\n",
i,
msm_nand_lock_info_bak[i].start_addr,
msm_nand_lock_info_bak[i].end_addr,
msm_nand_lock_info_bak[i].name);
}
*(unsigned int*)(s_lockinfoaddr+0x78) = 0;
return 0;
}
module_init(system_unlock_init)
static void __exit system_unlock_exit(void)
{
unsigned char* mem = (void*)s_patchaddr;
memcpy((void*)s_lockinfoaddr, msm_nand_lock_info_bak, 0x78);
*(unsigned int*)(s_lockinfoaddr+0x78) = msm_nand_lock_info_num_bak;
printk(KERN_DEBUG "\"%s\" ->", mem);
mem[5] = 'e'; // "/systom\0" -> "/system\0"
printk(" \"%s\"\n", mem);
}
module_exit(system_unlock_exit)
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("unlock system permission");