817e629743
For this code before __ld_kernel_begin should not be modifier (e.g. crt0.S and static_tools.c). Inspired/Taken by/from https://github.com/nicolasmesa/PiOS
45 lines
1.1 KiB
C
45 lines
1.1 KiB
C
#define IO_BASE 0x3f000000
|
|
#define UART0_BASE (IO_BASE + 0x201000)
|
|
#define UART0_DR (*(volatile unsigned *)(UART0_BASE + 0x0))
|
|
#define UART0_FR (*(volatile unsigned *)(UART0_BASE + 0x18))
|
|
|
|
extern unsigned long int __ld_kernel_begin;
|
|
|
|
static __attribute__((section("static_tools"))) char uart_recv(void)
|
|
{
|
|
while (UART0_FR & (1 << 4)) {
|
|
}
|
|
return UART0_DR & 0xFF;
|
|
}
|
|
|
|
static int __attribute__((section("static_tools"))) uart_read_int() {
|
|
int num = 0;
|
|
for (int i = 0; i < 4; i++) {
|
|
char c = uart_recv();
|
|
num = num << 8;
|
|
num += (int)c;
|
|
}
|
|
return num;
|
|
}
|
|
|
|
int __attribute__((section("static_tools"))) copy_kernel()
|
|
{
|
|
unsigned int kernel_size = uart_read_int();
|
|
int expected_checksum = uart_read_int();
|
|
int debug = uart_read_int();
|
|
char *kernel = (char *)&__ld_kernel_begin;
|
|
int checksum = 0;
|
|
(void)debug;
|
|
|
|
for (unsigned int i = 0; i < kernel_size; i++) {
|
|
char c = uart_recv();
|
|
checksum += c;
|
|
kernel[i] = c;
|
|
}
|
|
|
|
if(checksum != expected_checksum)
|
|
return -1;
|
|
|
|
return 0;
|
|
}
|