summaryrefslogtreecommitdiff
path: root/bootloader/x1000/boot.c
diff options
context:
space:
mode:
authorAidan MacDonald <amachronic@protonmail.com>2022-03-05 14:28:57 +0000
committerAidan MacDonald <amachronic@protonmail.com>2022-03-24 23:40:07 +0000
commit90cb0b0ae541303b3efb5ddbdc2ff8adab26cb49 (patch)
tree02e2468f8b5da220aab97664481cd485b7e11b35 /bootloader/x1000/boot.c
parent53a92f0ecce72ec92084a23a4f22679d2c01e22a (diff)
downloadrockbox-90cb0b0ae541303b3efb5ddbdc2ff8adab26cb49.tar.gz
rockbox-90cb0b0ae541303b3efb5ddbdc2ff8adab26cb49.zip
x1000: bootloader: add mainline Linux boot option
This adds a *very basic* Linux loader to the Rockbox bootloader, which allows running a mainline Linux kernel using the following file layout on the SD card: - /uImage - /linux_cmdline.txt The command line arguments are listed in linux_cmdline.txt, all lines are concatenated together and whitespace is converted into spaces. Comments aren't supported however. The loader doesn't support the modern devicetree boot protocol, so it can only pass command line arguments. It would be easy to support an appended dtb though. Change-Id: I373f465dbbdafe94738f619748cbb0278fc2c25f
Diffstat (limited to 'bootloader/x1000/boot.c')
-rw-r--r--bootloader/x1000/boot.c91
1 files changed, 91 insertions, 0 deletions
diff --git a/bootloader/x1000/boot.c b/bootloader/x1000/boot.c
index ca69e2e057..153c2277aa 100644
--- a/bootloader/x1000/boot.c
+++ b/bootloader/x1000/boot.c
@@ -24,8 +24,11 @@
24#include "system.h" 24#include "system.h"
25#include "kernel.h" 25#include "kernel.h"
26#include "power.h" 26#include "power.h"
27#include "file.h"
27#include "linuxboot.h" 28#include "linuxboot.h"
28#include "boot-x1000.h" 29#include "boot-x1000.h"
30#include <ctype.h>
31#include <sys/types.h>
29 32
30void boot_rockbox(void) 33void boot_rockbox(void)
31{ 34{
@@ -53,6 +56,94 @@ void reboot(void)
53} 56}
54 57
55/* 58/*
59 * boot_linux() is intended for mainline kernels, and as such it
60 * should not need any major target-specific modifications.
61 */
62
63static int read_linux_args(const char* filename)
64{
65 if(check_disk(false) != DISK_PRESENT)
66 return -1;
67
68 int ret;
69
70 size_t max_size;
71 int handle = core_alloc_maximum("args", &max_size, &buflib_ops_locked);
72 if(handle <= 0) {
73 splash(5*HZ, "Out of memory");
74 return -2;
75 }
76
77 int fd = open(filename, O_RDONLY);
78 if(fd < 0) {
79 splash2(5*HZ, "Can't open args file", filename);
80 ret = -3;
81 goto err_free;
82 }
83
84 /* this isn't 100% correct but will be good enough */
85 off_t fsize = filesize(fd);
86 if(fsize < 0 || fsize+1 > (off_t)max_size) {
87 splash(5*HZ, "Arguments too long");
88 ret = -4;
89 goto err_close;
90 }
91
92 char* buf = core_get_data(handle);
93 core_shrink(handle, buf, fsize+1);
94
95 ssize_t rdres = read(fd, buf, fsize);
96 close(fd);
97
98 if(rdres != (ssize_t)fsize) {
99 splash(5*HZ, "Can't read args file");
100 ret = -5;
101 goto err_free;
102 }
103
104 /* append a null terminator */
105 char* end = buf + fsize;
106 *end = 0;
107
108 /* change all newlines, etc, to spaces */
109 for(; buf != end; ++buf)
110 if(isspace(*buf))
111 *buf = ' ';
112
113 return handle;
114
115 err_close:
116 close(fd);
117 err_free:
118 core_free(handle);
119 return ret;
120}
121
122/*
123 * Provisional linux loading function: kernel is at "/uImage",
124 * contents of "/linux_cmdline.txt" are used as kernel arguments.
125 */
126void boot_linux(void)
127{
128 struct uimage_header uh;
129 size_t img_length;
130 int handle = load_uimage_file("/uImage", &uh, &img_length);
131 if(handle < 0)
132 return;
133
134 int args_handle = read_linux_args("/linux_cmdline.txt");
135 if(args_handle < 0) {
136 core_free(handle);
137 return;
138 }
139
140 x1000_boot_linux(core_get_data(handle), img_length,
141 (void*)uimage_get_load(&uh),
142 (void*)uimage_get_ep(&uh),
143 core_get_data(args_handle));
144}
145
146/*
56 * WARNING: Original firmware can be finicky. 147 * WARNING: Original firmware can be finicky.
57 * Be careful when modifying this code. 148 * Be careful when modifying this code.
58 */ 149 */