1.3.2: updated

* ROMHDR base addr is spl virtual 0x80000000 = 11800000 physical, LK will relocate to correct address (MEMBASE)
* save reboot reason at 0x2FFB0000 (ramconsole - 0x1000 (PAGE_SIZE)) and @0x2FFB0004 XOR 0x004b4c63 (cLK signature)
* added oem cmd to fastboot and oemcmd.bat for PC
This commit is contained in:
Arif Ali 2011-11-07 00:03:59 +00:00
parent cb8df35955
commit 6092922424
13 changed files with 388 additions and 29 deletions

BIN
bin/oem_filter.exe Normal file

Binary file not shown.

1
bin/oemcmd.bat Normal file
View File

@ -0,0 +1 @@
@fastboot oem %* 2>&1 | oem_filter

10
changelog.txt Normal file
View File

@ -0,0 +1,10 @@
1.3.2
- ROMHDR base addr is spl virtual 0x80000000 = 11800000 physical, LK will relocate to correct address (MEMBASE)
- save reboot reason at 0x2FFB0000 (ramconsole - 0x1000 (PAGE_SIZE)) and @0x2FFB0004 XOR 0x004b4c63 (cLK signature)
- added oem cmd to fastboot and oemcmd.bat for PC. supported commands are:
dmesg - kernel debug messages
smesg - spl messages
pwf addr len - dump memory
set[c,w,s] addr value - set char(1byte), word(4 byes), or string

View File

@ -228,23 +228,15 @@ void fastboot_okay(const char *info)
fastboot_ack("OKAY", info);
}
int fastboot_write(void *buf, unsigned len)
{
return usb_write(buf, len);
}
static void cmd_getvar(const char *arg, void *data, unsigned sz)
{
struct fastboot_var *var;
if(!strcmp(arg,"dmesg"))
{
char response[64];
for(char* c=(char*) 0x2FFC0000; c<(char*)(0x2FFC0000+0x00040000); c+=59)
{
memcpy(response, "INFO",4);memcpy(response+4, c, 59); response[63]=0;
//snprintf(response, 64, "%s%s", "INFO", c);
usb_write(response, 64);
}
fastboot_okay("");
return;
}
for (var = varlist; var; var = var->next) {
if (!strcmp(var->name, arg)) {
fastboot_okay(var->value);

View File

@ -24,6 +24,10 @@ static struct ptentry board_part_list[MAX_PTABLE_PARTS] __attribute__ ((aligned
{
.name = "PTABLE-MB", // PTABLE-BLK or PTABLE-MB for length in MB or BLOCKS
},
{
.name = "misc",
.length = 1 /* In MB */,
},
{
.name = "recovery",
.length = 5 /* In MB */,
@ -96,6 +100,7 @@ void cmd_dmesg(const char *arg, void *data, unsigned sz);
void reboot(unsigned reboot_reason);
void target_display_init();
unsigned get_boot_reason(void);
void cmd_oem_register();
void target_init(void)
{
struct flash_info *flash_info;
@ -180,6 +185,7 @@ void display_lk_version()
{
_dputs("cedesmith's LK (CLK) v1.3\n");
}
struct fbcon_config* fbcon_display(void);
void htcleo_fastboot_init()
{
// off charge and recovery boot failed, reboot to normal mode
@ -192,6 +198,8 @@ void htcleo_fastboot_init()
display_lk_version();
htcleo_ptable_dump(&flash_ptable);
}
cmd_oem_register();
}
void target_early_init(void)
{
@ -206,20 +214,37 @@ unsigned board_machtype(void)
void reboot_device(unsigned reboot_reason)
{
writel(reboot_reason, 0x2FFB0000);
writel(reboot_reason^0x004b4c63, 0x2FFB0004); //XOR with cLK signature
reboot(reboot_reason);
}
unsigned boot_reason = 0xFFFFFFFF;
unsigned android_reboot_reason = 0;
unsigned check_reboot_mode(void);
unsigned get_boot_reason(void)
{
if(boot_reason==0xFFFFFFFF)
{
boot_reason = readl(MSM_SHARED_BASE+0xef244);
dprintf(INFO, "boot reason %x\n", boot_reason);
if(boot_reason==1 || boot_reason==6)
{
if(readl(0x2FFB0000)==(readl(0x2FFB0004)^0x004b4c63))
{
android_reboot_reason = readl(0x2FFB0000);
dprintf(INFO, "android reboot reason %x\n", android_reboot_reason);
writel(0, 0x2FFB0000);
}
}
}
return boot_reason;
}
unsigned check_reboot_mode(void)
{
get_boot_reason();
return android_reboot_reason;
}
unsigned target_pause_for_battery_charge(void)
{

148
lk/target/htcleo/oem_cmd.c Normal file
View File

@ -0,0 +1,148 @@
/*
* License: GPL
* Author: cedesmith
*/
#include <debug.h>
#include <string.h>
#include <stdlib.h>
#include <reg.h>
void fastboot_okay(const char *info);
void fastboot_fail(const char *reason);
int fastboot_write(void *buf, unsigned len);
void fastboot_register(const char *prefix, void (*handle)(const char *arg, void *data, unsigned sz));
static char charVal(char c)
{
c&=0xf;
if(c<=9) return '0'+c;
return 'A'+(c-10);
}
static void send_mem(char* start, int len)
{
char response[64];
while(len>0)
{
int slen = len > 29 ? 29 : len;
memcpy(response, "INFO", 4);
response[4]=slen;
for(int i=0; i<slen; i++)
{
response[5+i*2] = charVal(start[i]>>4);
response[5+i*2+1]= charVal(start[i]);
}
response[5+slen*2+1]=0;
fastboot_write(response, 5+slen*2);
start+=slen;
len-=slen;
}
}
static void cmd_oem_smesg()
{
send_mem((char*)0x1fe00018, MIN(0x200000, readl(0x1fe00000)));
fastboot_okay("");
}
static void cmd_oem_dmesg()
{
if(*((unsigned*)0x2FFC0000) == 0x43474244 /* DBGC */ ) //see ram_console_buffer in kernel ram_console.c
{
send_mem((char*)0x2FFC000C, *((unsigned*)0x2FFC0008));
}
fastboot_okay("");
}
static int str2u(const char *x)
{
while(*x==' ')x++;
unsigned base=10;
int sign=1;
unsigned n = 0;
if(strstr(x,"-")==x) { sign=-1; x++;};
if(strstr(x,"0x")==x) {base=16; x+=2;}
while(*x) {
char d=0;
switch(*x) {
case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':
d = *x - '0';
break;
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
d = (*x - 'a' + 10);
break;
case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
d = (*x - 'A' + 10);
break;
default:
return sign*n;
}
if(d>=base) return sign*n;
n*=base;n+=d;
x++;
}
return sign*n;
}
static void cmd_oem_dumpmem(const char *arg)
{
char *sStart = strtok((char*)arg, " ");
char *sLen = strtok(NULL, " ");
if(sStart==NULL || sLen==NULL)
{
fastboot_fail("usage:oem dump start len");
return;
}
send_mem((char*)str2u(sStart), str2u(sLen));
fastboot_okay("");
}
static void cmd_oem_set(const char *arg)
{
char type=*arg; arg++;
char *sAddr = strtok((char*) arg, " ");
char *sVal = strtok(NULL, "\0");
if(sAddr==NULL || sVal==NULL)
{
fastboot_fail("usage:oem set[s,c,w] address value");
return;
}
char buff[64];
switch(type)
{
case 's':
memcpy((void*)str2u(sAddr), sVal, strlen(sVal));
send_mem((char*)str2u(sAddr), strlen(sVal));
break;
case 'c':
*((char*)str2u(sAddr)) = (char)str2u(sVal);
sprintf(buff, "%x", *((char*)str2u(sAddr)));
send_mem(buff, strlen(buff));
break;
case 'w':
default:
*((int*)str2u(sAddr)) = str2u(sVal);
sprintf(buff, "%x", *((int*)str2u(sAddr)));
send_mem(buff, strlen(buff));
}
fastboot_okay("");
}
static void cmd_oem(const char *arg, void *data, unsigned sz)
{
while(*arg==' ') arg++;
if(memcmp(arg, "dmesg", 5)==0) cmd_oem_dmesg();
if(memcmp(arg, "smesg", 5)==0) cmd_oem_smesg();
if(memcmp(arg, "pwf ", 4)==0) cmd_oem_dumpmem(arg+4);
if(memcmp(arg, "set", 3)==0) cmd_oem_set(arg+3);
}
void cmd_oem_register()
{
fastboot_register("oem", cmd_oem);
}

View File

@ -5,30 +5,19 @@ INCLUDES += -I$(LOCAL_DIR)/include -I$(LK_TOP_DIR)/platform/msm_shared
PLATFORM := qsd8k
#define system partition size (in MB), if not defined my custom (from magldr) layout is used. see init.c
#DEFINES += SYSTEM_PARTITION_SIZE=150
DEFINES += SYSTEM_PARTITION_SIZE=150
#DEFINES += SYSTEM_PARTITION_SIZE=250
#cedesmith note: MEMBASE requires edit in platform/qsd8k/rules.mk
#MEMBASE := 0x20000000
#MEMBASE := 0x27000000
#MEMBASE := 0x2E000000
#MEMSIZE := 0x00800000
# maximum partition size will be about 340mb ( MEMBASE-SCRATCH_ADDR)
MEMBASE := 0x28000000
MEMSIZE := 0x00100000
#SPL virtual address where LK is loaded
#DEFINES += WSPL_VADDR=0x80000000
#SPL 0x26600000=>0x95100000 so VADDR = (0x28000000-0x26600000)+0x95100000
DEFINES += WSPL_VADDR=0x96B00000
#SPL 0x28500000=>0x98B00000
MEMSIZE := 0x00100000
DEFINES += WSPL_VADDR=0x80000000
BASE_ADDR := 0x11800000
TAGS_ADDR := "(BASE_ADDR+0x00000100)"
KERNEL_ADDR := "(BASE_ADDR+0x00008000)"
RAMDISK_ADDR := "(BASE_ADDR+0x00a00000)"
#SCRATCH_ADDR := "(BASE_ADDR+0x04000000)"
SCRATCH_ADDR := "(BASE_ADDR+0x01400000)"
#BASE_ADDR + 0x04000000
@ -70,5 +59,6 @@ OBJS += \
OBJS += \
$(LOCAL_DIR)/htcleo_boot.o \
$(LOCAL_DIR)/htcleo_boot_s.o\
$(LOCAL_DIR)/platform.o
$(LOCAL_DIR)/platform.o \
$(LOCAL_DIR)/oem_cmd.o

47
oem_filter.c Normal file
View File

@ -0,0 +1,47 @@
#include <stdio.h>
#include <string.h>
unsigned char hexVal(char c)
{
switch(c)
{
case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':
return c-'0';
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
return c - 'a' + 10;
case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
return c - 'A' + 10;
}
return 0;
}
int main() {
char buff[0x40000];
while(!feof(stdin) && fgetc(stdin)!='\n' );
while(!feof(stdin))
{
size_t len = fread(buff, 1, 5, stdin);
int hLen = -1;
if(strncmp(buff, "INFO", 4)==0) hLen = buff[4];
if(strncmp(buff, "(boot", 5)==0)
{
len += fread(buff+5, 1, 9, stdin);
if(strncmp(buff, "(bootloader) ", 13)==0) hLen = buff[13];
}
if(hLen!=-1)
{
for(;hLen>0;hLen--) fputc(hexVal(fgetc(stdin))<<4 | hexVal(fgetc(stdin)), stdout);
fgetc(stdin);// read \n appended by fastboot
continue;
}
fwrite(buff, 1, len, stdout);
break;
}
while(!feof(stdin))
{
size_t len = fread(buff, 1, sizeof(buff), stdin);
fwrite(buff, 1, len, stdout);
}
}

View File

@ -0,0 +1,41 @@
diff --git a/extendedcommands.c b/extendedcommands.c
index 1ce3bf1..2562e6c 100644
--- a/extendedcommands.c
+++ b/extendedcommands.c
@@ -1110,21 +1110,25 @@ int volume_main(int argc, char **argv) {
}
void handle_chargemode() {
+ // old code to read /proc/cmdline was broken because file size is always 0 so file_data was always empty string
const char* filename = "/proc/cmdline";
- struct stat file_info;
- if (0 != stat(filename, &file_info))
- return;
-
- int file_len = file_info.st_size;
- char* file_data = (char*)malloc(file_len + 1);
FILE *file = fopen(filename, "rb");
if (file == NULL)
return;
- fread(file_data, file_len, 1, file);
- // supposedly not necessary, but let's be safe.
+ char file_data[1024];
+ int file_len=fread(file_data, 1, 1023, file);
file_data[file_len] = '\0';
fclose(file);
-
+
if (strstr(file_data, "androidboot.mode=offmode_charging") != NULL)
- reboot(RB_POWER_OFF);
+ {
+ // let recovery kernel charge the battery, reboot on any key press so Android will start as user would expect
+ ev_init();
+ struct input_event ev;
+ do
+ {
+ ev_get(&ev, 0);
+ } while (ev.type != EV_KEY || ev.code > KEY_MAX);
+ reboot(RB_AUTOBOOT);
+ }
}
\ No newline at end of file

View File

@ -0,0 +1,32 @@
diff --git a/arch/arm/mach-msm/board-htcleo.c b/arch/arm/mach-msm/board-htcleo.c
index e13205b..ee7680e 100644
--- a/arch/arm/mach-msm/board-htcleo.c
+++ b/arch/arm/mach-msm/board-htcleo.c
@@ -87,6 +87,7 @@ static int __init parse_tag_nand_boot(const struct tag *tag)
{
struct tag_magldr_entry *mentry = (struct tag_magldr_entry *)(&tag->u);
nand_boot = !(unsigned int)mentry->fNoNandBoot;
+ if(*((unsigned*)&tag->u)==0x004b4c63) nand_boot = 2; // cLK signature
pr_info("Nand Boot: %d\n", nand_boot);
return 0;
}
diff --git a/arch/arm/mach-msm/pm.c b/arch/arm/mach-msm/pm.c
index 8766174..56ccb2a 100644
--- a/arch/arm/mach-msm/pm.c
+++ b/arch/arm/mach-msm/pm.c
@@ -892,6 +892,15 @@ static int __init msm_pm_init(void)
register_reboot_notifier(&msm_reboot_notifier);
msm_pm_reset_vector = ioremap(0x0, PAGE_SIZE);
+#if defined(CONFIG_MACH_HTCLEO)
+ // if cLK is bootloader 0x0 is protected and not writtable but cLK changed reset vecotr to jump at address stored at 0x11800004
+ if(htcleo_is_nand_boot()==2){
+ pr_info("msm_pm: 0x00000000: %x\n", msm_pm_reset_vector[0]);
+ pr_info("msm_pm: 0x00000004: %x\n", msm_pm_reset_vector[1]);
+ msm_pm_reset_vector = ioremap(0x11800000, PAGE_SIZE);
+ }
+#endif
+
if (msm_pm_reset_vector == NULL) {
printk(KERN_ERR "msm_pm_init: failed to map reset vector\n");
return -ENODEV;

View File

@ -0,0 +1,39 @@
diff --git a/arch/arm/mach-msm/board-htcleo-panel.c b/arch/arm/mach-msm/board-htcleo-panel.c
index a7a701d..1b98611 100644
--- a/arch/arm/mach-msm/board-htcleo-panel.c
+++ b/arch/arm/mach-msm/board-htcleo-panel.c
@@ -861,9 +861,17 @@ static void detect_panel_type(void)
}
else
{
- printk(" UNKNOWN, stop system now\n");
htcleo_panel_type = PANELTYPE_UNKNOWN;
- BUG();
+ extern int board_mfg_mode(void);
+ if(board_mfg_mode()==5)
+ {
+ printk(" offmode charging, panel is off\n");
+ }
+ else
+ {
+ printk(" UNKNOWN, stop system now\n");
+ BUG();
+ }
}
}
diff --git a/arch/arm/mach-msm/devices_htc.c b/arch/arm/mach-msm/devices_htc.c
index e5f65e7..6839c0d 100644
--- a/arch/arm/mach-msm/devices_htc.c
+++ b/arch/arm/mach-msm/devices_htc.c
@@ -457,6 +457,10 @@ int __init board_mfg_mode_init(char *s)
mfg_mode = 2;
else if (!strcmp(s, "charge"))
mfg_mode = 3;
+ else if (!strcmp(s, "power_test"))
+ mfg_mode = 4;
+ else if (!strcmp(s, "offmode_charging"))
+ mfg_mode = 5;
return 1;
}

View File

@ -0,0 +1,33 @@
diff --git a/arch/arm/mach-msm/pm.c b/arch/arm/mach-msm/pm.c
index 56ccb2a..f3b17f2 100644
--- a/arch/arm/mach-msm/pm.c
+++ b/arch/arm/mach-msm/pm.c
@@ -714,10 +714,28 @@ void msm_pm_flush_console(void)
release_console_sem();
}
+#if defined(CONFIG_MACH_HTCLEO)
+static void htcleo_save_reset_reason()
+{
+ /* save restart_reason to be accesible in bootloader @ ramconsole - 0x1000*/
+ uint32_t *bootloader_reset_reason = ioremap(0x2FFB0000, PAGE_SIZE);
+ if(bootloader_reset_reason!=NULL)
+ {
+ printk(KERN_INFO "msm_restart saving reason %x @ 0x2FFB0000 \n", restart_reason);
+ bootloader_reset_reason[0]=restart_reason;
+ bootloader_reset_reason[1]=restart_reason^0x004b4c63; //XOR with cLK signature so we know is not trash
+ }
+}
+#endif
+
static void msm_pm_restart(char str)
{
msm_pm_flush_console();
+#if defined(CONFIG_MACH_HTCLEO)
+ htcleo_save_reset_reason();
+#endif
+
/* always reboot device through proc comm */
if (restart_reason == 0x6f656d99)
msm_proc_comm(PCOM_RESET_CHIP_IMM, &restart_reason, 0);

View File

@ -1,6 +1,7 @@
#compile kernel and make boot.img/recovery.img
#make ARCH=arm CROSS_COMPILE=arm-none-eabi-
mkbootimg --kernel zImage --ramdisk initrd.gz --cmdline "" --base 0x11800000 -o android_boot.img
mkbootimg --cmdline "" --base 0x11800000 --kernel zImage --ramdisk initrd.gz -o boot.img
mkbootimg --base 0x11800000 --cmdline "no_console_suspend=0" --kernel zImage --ramdisk initrd.gz -o android_boot.img
#create initrd.gz