uboot: failsafe: support boot into initramfs

sort uri handlers while at it.

Signed-off-by: Tianling Shen <cnsztl@immortalwrt.org>
This commit is contained in:
Tianling Shen
2024-09-08 17:15:26 +08:00
committed by hanwckf
parent 24ca421ac3
commit 15ac366e7d
8 changed files with 255 additions and 42 deletions

View File

@@ -19,6 +19,7 @@
#include <dm/ofnode.h>
#include <version_string.h>
#include "../board/mediatek/common/boot_helper.h"
#include "fs.h"
void led_control(const char *cmd, const char *name, const char *arg);
@@ -27,7 +28,8 @@ enum {
FW_TYPE_GPT,
FW_TYPE_BL2,
FW_TYPE_FIP,
FW_TYPE_FW
FW_TYPE_FW,
FW_TYPE_INITRD
};
typedef struct fip_toc_header {
@@ -276,6 +278,14 @@ static void upload_handler(enum httpd_uri_handler_status status,
goto done;
}
fw = httpd_request_find_value(request, "initramfs");
if (fw) {
fw_type = FW_TYPE_INITRD;
if (fdt_check_header(fw->data))
goto fail;
goto done;
}
fw = httpd_request_find_value(request, "firmware");
if (fw) {
fw_type = FW_TYPE_FW;
@@ -377,8 +387,11 @@ static void result_handler(enum httpd_uri_handler_status status,
env_save();
}
#endif
st->ret = write_firmware_failsafe((size_t) upload_data,
upload_size);
if (fw_type == FW_TYPE_INITRD)
st->ret = 0;
else
st->ret = write_firmware_failsafe((size_t) upload_data,
upload_size);
}
/* invalidate upload identifier */
@@ -444,21 +457,23 @@ int start_web_failsafe(void)
}
httpd_register_uri_handler(inst, "/", &index_handler, NULL);
httpd_register_uri_handler(inst, "/bl2.html", &html_handler, NULL);
httpd_register_uri_handler(inst, "/booting.html", &html_handler, NULL);
httpd_register_uri_handler(inst, "/cgi-bin/luci", &index_handler, NULL);
httpd_register_uri_handler(inst, "/cgi-bin/luci/", &index_handler, NULL);
httpd_register_uri_handler(inst, "/fail.html", &html_handler, NULL);
httpd_register_uri_handler(inst, "/flashing.html", &html_handler, NULL);
httpd_register_uri_handler(inst, "/getmtdlayout", &mtd_layout_handler, NULL);
#if defined(CONFIG_MT7981_BOOTMENU_EMMC) || defined(CONFIG_MT7986_BOOTMENU_EMMC)
httpd_register_uri_handler(inst, "/gpt.html", &html_handler, NULL);
#endif
httpd_register_uri_handler(inst, "/bl2.html", &html_handler, NULL);
httpd_register_uri_handler(inst, "/uboot.html", &html_handler, NULL);
httpd_register_uri_handler(inst, "/fail.html", &html_handler, NULL);
httpd_register_uri_handler(inst, "/flashing.html", &html_handler, NULL);
httpd_register_uri_handler(inst, "/version", &version_handler, NULL);
httpd_register_uri_handler(inst, "/getmtdlayout", &mtd_layout_handler, NULL);
httpd_register_uri_handler(inst, "/upload", &upload_handler, NULL);
httpd_register_uri_handler(inst, "/index.js", &js_handler, NULL);
httpd_register_uri_handler(inst, "/initramfs.html", &html_handler, NULL);
httpd_register_uri_handler(inst, "/result", &result_handler, NULL);
httpd_register_uri_handler(inst, "/style.css", &style_handler, NULL);
httpd_register_uri_handler(inst, "/index.js", &js_handler, NULL);
httpd_register_uri_handler(inst, "/uboot.html", &html_handler, NULL);
httpd_register_uri_handler(inst, "/upload", &upload_handler, NULL);
httpd_register_uri_handler(inst, "/version", &version_handler, NULL);
httpd_register_uri_handler(inst, "", &not_found_handler, NULL);
net_loop(TCP);
@@ -486,8 +501,12 @@ static int do_httpd(struct cmd_tbl *cmdtp, int flag, int argc,
ret = start_web_failsafe();
if (upgrade_success)
do_reset(NULL, 0, 0, NULL);
if (upgrade_success) {
if (fw_type == FW_TYPE_INITRD)
boot_from_mem((ulong)upload_data);
else
do_reset(NULL, 0, 0, NULL);
}
return ret;
}

View File

@@ -0,0 +1,49 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Booting initramfs</title>
<link rel="stylesheet" href="/style.css">
<script src="/index.js"></script>
<script>
function init() {
getversion();
ajax({
url: '/result',
done: function(response) {
if (response == 'failed') {
location = '/fail.html'
return
}
document.getElementById('title').innerHTML = 'BOOT SUCCESS'
document.getElementById('info').innerHTML = 'Your device was successfully booted into initramfs!'
},
timeout: 30000
})
ajax('/result', function(response) {
if (response == 'failed') {
location = '/fail.html'
return
}
document.getElementById('title').innerHTML = 'BOOT SUCCESS'
document.getElementById('info').innerHTML = 'Your device was successfully booted into initramfs!'
}, 30000)
}
</script>
</head>
<body onload="init()">
<div id="m">
<h1 id="title">BOOTING INITRAMFS</h1>
<p id="info">
Your file was successfully uploaded! Booting is in progress, please wait...<br>
This page may be in not responding status for a short time.
</p>
<div id="l"></div>
</div>
<div id="version"></div>
</body>
</html>

View File

@@ -0,0 +1,39 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Load initramfs</title>
<link rel="stylesheet" href="/style.css">
<script src="/index.js"></script>
</head>
<body onload="startup()">
<div id="m">
<h1>LOAD INITRAMFS</h1>
<p id="hint">
You are going to load <strong>initramfs</strong> on the device.<br>
Please, choose file from your local hard drive and click <strong>Upload</strong> button.
</p>
<form id="form">
<input id="file" type="file" name="initramfs">
<input type="button" value="Upload" onclick="upload('initramfs')">
</form>
<div>
<div class="bar" id="bar" style="display: none; --percent: 0;"></div>
</div>
<div id="size" style="display: none;">Size: xxxx</div>
<div id="md5" style="display: none;">MD5: xxxx</div>
<div id="upgrade" style="display: none;">
<p>If all information above is correct, click "Boot".</p>
<button class="button" onclick="location = '/booting.html'">Boot</button>
</div>
<div class="i w">
<strong>WARNINGS</strong>
<ul>
<li>if everything goes well, the device will boot into the initramfs</li>
<li>you can upload whatever you want, so be sure that you choose proper initramfs image for your device</li>
</ul>
</div>
</div>
<div id="version"></div>
</body>
</html>

View File

@@ -20,6 +20,8 @@
#include <vsprintf.h>
#include <version_string.h>
#include <failsafe/fw_type.h>
#include "../board/mediatek/common/boot_helper.h"
#include "fs.h"
static u32 upload_data_id;
@@ -154,6 +156,14 @@ static void upload_handler(enum httpd_uri_handler_status status,
goto done;
}
fw = httpd_request_find_value(request, "initramfs");
if (fw) {
fw_type = FW_TYPE_INITRD;
if (fdt_check_header(fw->data))
goto fail;
goto done;
}
fail:
response->data = "fail";
response->size = strlen(response->data);
@@ -248,8 +258,11 @@ static void result_handler(enum httpd_uri_handler_status status,
env_save();
}
#endif
st->ret = failsafe_write_image(upload_data,
upload_size, fw_type);
if (fw_type == FW_TYPE_INITRD)
st->ret = 0;
else
st->ret = failsafe_write_image(upload_data,
upload_size, fw_type);
}
/* invalidate upload identifier */
@@ -377,21 +390,23 @@ int start_web_failsafe(void)
}
httpd_register_uri_handler(inst, "/", &index_handler, NULL);
httpd_register_uri_handler(inst, "/bl2.html", &html_handler, NULL);
httpd_register_uri_handler(inst, "/booting.html", &html_handler, NULL);
httpd_register_uri_handler(inst, "/cgi-bin/luci", &index_handler, NULL);
httpd_register_uri_handler(inst, "/cgi-bin/luci/", &index_handler, NULL);
httpd_register_uri_handler(inst, "/upload", &upload_handler, NULL);
httpd_register_uri_handler(inst, "/fail.html", &html_handler, NULL);
httpd_register_uri_handler(inst, "/flashing.html", &html_handler, NULL);
httpd_register_uri_handler(inst, "/uboot.html", &html_handler, NULL);
httpd_register_uri_handler(inst, "/bl2.html", &html_handler, NULL);
httpd_register_uri_handler(inst, "/getmtdlayout", &mtd_layout_handler, NULL);
#ifdef CONFIG_MTK_BOOTMENU_MMC
httpd_register_uri_handler(inst, "/gpt.html", &html_handler, NULL);
#endif
httpd_register_uri_handler(inst, "/version", &version_handler, NULL);
httpd_register_uri_handler(inst, "/initramfs.html", &html_handler, NULL);
httpd_register_uri_handler(inst, "/main.js", &js_handler, NULL);
httpd_register_uri_handler(inst, "/result", &result_handler, NULL);
httpd_register_uri_handler(inst, "/style.css", &style_handler, NULL);
httpd_register_uri_handler(inst, "/main.js", &js_handler, NULL);
httpd_register_uri_handler(inst, "/uboot.html", &html_handler, NULL);
httpd_register_uri_handler(inst, "/upload", &upload_handler, NULL);
httpd_register_uri_handler(inst, "/version", &version_handler, NULL);
httpd_register_uri_handler(inst, "", &not_found_handler, NULL);
net_loop(MTK_TCP);
@@ -419,8 +434,12 @@ static int do_httpd(struct cmd_tbl *cmdtp, int flag, int argc,
ret = start_web_failsafe();
if (upgrade_success)
do_reset(NULL, 0, 0, NULL);
if (upgrade_success) {
if (fw_type == FW_TYPE_INITRD)
boot_from_mem((ulong)upload_data);
else
do_reset(NULL, 0, 0, NULL);
}
return ret;
}

View File

@@ -5,42 +5,50 @@
# FILE_XXXX.o := YYYY.html <- actual html file to be embedded
# FSPATH_XXXX.o := ZZZ/WWW.EXT <- virtual fs path to be used inside u-boot
obj-y += index.o
FILE_index.o := index.html
FSPATH_index.o := index.html
obj-y += main.o
FILE_main.o := main.js
FSPATH_main.o := main.js
obj-y += flashing.o
FILE_flashing.o := flashing.html
FSPATH_flashing.o := flashing.html
obj-y += fail.o
FILE_fail.o := fail.html
FSPATH_fail.o := fail.html
obj-y += 404.o
FILE_404.o := 404.html
FSPATH_404.o := 404.html
obj-y += uboot.o
FILE_uboot.o := uboot.html
FSPATH_uboot.o := uboot.html
obj-y += bl2.o
FILE_bl2.o := bl2.html
FSPATH_bl2.o := bl2.html
obj-y += booting.o
FILE_booting.o := booting.html
FSPATH_booting.o := booting.html
obj-y += fail.o
FILE_fail.o := fail.html
FSPATH_fail.o := fail.html
obj-y += flashing.o
FILE_flashing.o := flashing.html
FSPATH_flashing.o := flashing.html
obj-y += gpt.o
FILE_gpt.o := gpt.html
FSPATH_gpt.o := gpt.html
obj-y += index.o
FILE_index.o := index.html
FSPATH_index.o := index.html
obj-y += initramfs.o
FILE_initramfs.o := initramfs.html
FSPATH_initramfs.o := initramfs.html
obj-y += main.o
FILE_main.o := main.js
FSPATH_main.o := main.js
obj-y += style.o
FILE_style.o := style.css
FSPATH_style.o := style.css
obj-y += uboot.o
FILE_uboot.o := uboot.html
FSPATH_uboot.o := uboot.html
# customized build rules
strip_path = $(subst /,_,$(subst -,_,$(subst .,_,$(1))))

View File

@@ -0,0 +1,39 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Booting initramfs</title>
<link rel="stylesheet" href="/style.css">
<script src="/main.js"></script>
<script>
function init() {
getversion();
ajax({
url: '/result',
done: function(response) {
if (response == 'failed') {
location = '/fail.html'
return
}
document.getElementById('title').innerHTML = 'BOOT SUCCESS'
document.getElementById('info').innerHTML = 'Your device was successfully booted into initramfs!'
},
timeout: 30000
})
}
</script>
</head>
<body onload="init()">
<div id="m">
<h1 id="title">BOOTING INITRAMFS</h1>
<p id="info">
Your file was successfully uploaded! Booting is in progress, please wait...<br>
This page may be in not responding status for a short time.
</p>
<div id="l"></div>
</div>
<div id="version"></div>
</body>
</html>

View File

@@ -0,0 +1,39 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Load initramfs</title>
<link rel="stylesheet" href="/style.css">
<script src="/main.js"></script>
</head>
<body onload="startup()">
<div id="m">
<h1>LOAD INITRAMFS</h1>
<p id="hint">
You are going to load <strong>initramfs</strong> on the device.<br>
Please, choose file from your local hard drive and click <strong>Upload</strong> button.
</p>
<form id="form">
<input id="file" type="file" name="initramfs">
<input type="button" value="Upload" onclick="upload('initramfs')">
</form>
<div>
<div class="bar" id="bar" style="display: none; --percent: 0;"></div>
</div>
<div id="size" style="display: none;">Size: xxxx</div>
<div id="md5" style="display: none;">MD5: xxxx</div>
<div id="upgrade" style="display: none;">
<p>If all information above is correct, click "Boot".</p>
<button class="button" onclick="location = '/booting.html'">Boot</button>
</div>
<div class="i w">
<strong>WARNINGS</strong>
<ul>
<li>if everything goes well, the device will boot into the initramfs</li>
<li>you can upload whatever you want, so be sure that you choose proper initramfs image for your device</li>
</ul>
</div>
</div>
<div id="version"></div>
</body>
</html>

View File

@@ -8,6 +8,7 @@ typedef enum {
FW_TYPE_BL2,
FW_TYPE_FIP,
FW_TYPE_FW,
FW_TYPE_INITRD,
} failsafe_fw_t;
#endif