From 894d49cd62c8adeac929ad9f376d4f0be061d9a9 Mon Sep 17 00:00:00 2001 From: Piotr Dymacz Date: Wed, 12 Apr 2017 23:05:13 +0200 Subject: [PATCH] Fix loading kernel from official vendor firmware As it turned out, some old kernel versions from Atheros LSDK expect different arguments passed from bootloader: RAM size (in bytes) in 3rd parameter and FLASH size (in MB) in 4th. Most of TP-Link firmware also contains kernel which follows this 'broken' approach. To make fix more universal, load kernel with different parameters and their values based on 'lsdk_kernel' environment variable. If it's > 0, RAM and FLASH size will be passed to satisfy LSDK based kernel requirements. --- u-boot/lib_mips/mips_linux.c | 43 ++++++++++++++++++++++++++---------- 1 file changed, 31 insertions(+), 12 deletions(-) diff --git a/u-boot/lib_mips/mips_linux.c b/u-boot/lib_mips/mips_linux.c index 4f16126..bf35cbc 100644 --- a/u-boot/lib_mips/mips_linux.c +++ b/u-boot/lib_mips/mips_linux.c @@ -146,20 +146,18 @@ static void linux_env_set(char *env_name, char *env_val) void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { - char buf[16]; - char *cmdline; - unsigned int flash_mb; + int lsdk_kernel; + char *cmdline, *s, buf[16]; image_header_t *hdr = &header; - void(*theKernel)(int, char **, char **, int); + void(*Kernel)(int, char **, char **); + void(*LSDKKernel)(int, char **, ulong, ulong); cmdline = getenv("bootargs"); - theKernel = (void (*)(int, char **, char **, int))ntohl(hdr->ih_ep); - #if defined(DEBUG) - printf("## Bootargs: %s\n", cmdline); - printf("## Transferring control to Linux (at address %08lx) ...\n", - (ulong)theKernel); + printf("## Bootargs: '%s'\n", cmdline); + printf("## Transferring control to Linux (at address 0x%08lx) ...\n", + (ulong)(ntohl(hdr->ih_ep))); #endif linux_params_init(UNCACHED_SDRAM(gd->bd->bi_boot_params), cmdline); @@ -190,7 +188,28 @@ void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) (ar7240_reg_rd(AR7240_GPIO_FUNC) | 0x88)); #endif - /* Pass the flash size as expected by current Linux kernel for AR7100 */ - flash_mb = gd->bd->bi_flashsize >> 20; - theKernel(linux_argc, linux_argv, linux_env, flash_mb); + /* + * In some of old Atheros LSDK based firmware versions (kernel 2.6.x), + * kernel expects RAM size (in bytes) in 3rd parameter and FLASH + * size (in MB) in 4th. Also, most of old TP-Link firmwares follow + * this 'broken' approach. + * + * To make it somehow universal, we will use here a dedicated env + * flag 'lsdk_kernel' - if it's set to > 0, RAM and FLASH sizes + * will be passed as 3rd and 4th parameters. + */ + s = getenv("lsdk_kernel"); + lsdk_kernel = s ? simple_strtol(s, NULL, 10) : 0; + + if (lsdk_kernel > 0) { + LSDKKernel = (void (*)(int, char **, + ulong, ulong))ntohl(hdr->ih_ep); + + LSDKKernel(linux_argc, linux_argv, gd->ram_size, + gd->bd->bi_flashsize >> 20); + } else { + Kernel = (void (*)(int, char **, char **))ntohl(hdr->ih_ep); + + Kernel(linux_argc, linux_argv, linux_env); + } } -- 2.25.1