diff --git a/board/100ask-d1-h/CMakeLists.txt b/board/100ask-d1-h/CMakeLists.txt index 6861501a..827245f4 100644 --- a/board/100ask-d1-h/CMakeLists.txt +++ b/board/100ask-d1-h/CMakeLists.txt @@ -2,6 +2,7 @@ set(APP_COMMON_SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/start.S ${CMAKE_CURRENT_SOURCE_DIR}/board.c ${CMAKE_CURRENT_SOURCE_DIR}/eabi_compat.c + ${CMAKE_CURRENT_SOURCE_DIR}/head.c ) add_subdirectory(hello_world) diff --git a/board/100ask-d1-h/head.c b/board/100ask-d1-h/head.c new file mode 100644 index 00000000..80c77b37 --- /dev/null +++ b/board/100ask-d1-h/head.c @@ -0,0 +1,70 @@ +#include +#include +#include +#include + +typedef struct boot_file_head { + uint32_t jump_instruction; /* one intruction jumping to real code */ + uint8_t magic[8]; /* ="eGON.BT0" */ + uint32_t check_sum; /* generated by PC */ + uint32_t *length; /* generated by LD */ + uint32_t pub_head_size; /* the size of boot_file_head_t */ + uint8_t pub_head_vsn[4]; /* the version of boot_file_head_t */ + uint32_t *ret_addr; /* the return value */ + uint32_t *run_addr; /* run addr */ + uint32_t boot_cpu; /* eGON version */ + uint8_t platform[8]; /* platform information */ +} boot_file_head_t; + +/* +* This code is used to calculate some values related to the size of a file header +* and combine these values to form a jump instruction: +* +* * BROM_FILE_HEAD_SIZE: Defines a mask for the size of the file header +* and uses the bitwise & operator with 0x00FFFFF to truncate and obtain the size of the file header. +* +* * BROM_FILE_HEAD_BIT_10_1, BROM_FILE_HEAD_BIT_11, BROM_FILE_HEAD_BIT_19_12, BROM_FILE_HEAD_BIT_20: +* These macros define the values of various bit segments of the file header size. +* +* * BROM_FILE_HEAD_SIZE_OFFSET: This macro combines the bit segments of the file header size +* calculated above to form an offset. +* +* * JUMP_INSTRUCTION: This macro uses the calculated offset from above and performs a bitwise +* OR operation with 0x6f to create a jump instruction. +* +* This code calculates an offset corresponding to the size of the file header through a series of +* bitwise operations and utilizes it to construct a jump instruction. +*/ + +#define BROM_FILE_HEAD_SIZE (sizeof(boot_file_head_t) & 0x00FFFFF) +#define BROM_FILE_HEAD_BIT_10_1 ((BROM_FILE_HEAD_SIZE & 0x7FE) >> 1) +#define BROM_FILE_HEAD_BIT_11 ((BROM_FILE_HEAD_SIZE & 0x800) >> 11) +#define BROM_FILE_HEAD_BIT_19_12 ((BROM_FILE_HEAD_SIZE & 0xFF000) >> 12) +#define BROM_FILE_HEAD_BIT_20 ((BROM_FILE_HEAD_SIZE & 0x100000) >> 20) + +#define BROM_FILE_HEAD_SIZE_OFFSET ((BROM_FILE_HEAD_BIT_20 << 31) | \ + (BROM_FILE_HEAD_BIT_10_1 << 21) | \ + (BROM_FILE_HEAD_BIT_11 << 20) | \ + (BROM_FILE_HEAD_BIT_19_12 << 12)) + +#define JUMP_INSTRUCTION (BROM_FILE_HEAD_SIZE_OFFSET | 0x6f) + +#define BOOT0_MAGIC "eGON.BT0" +#define STAMP_VALUE (0x12345678) +#define BOOT_PUB_HEAD_VERSION "3000" + +extern uint32_t __spl_size[]; +extern uint32_t __code_start_address[]; + +const __attribute__((section(".boot0_head"))) boot_file_head_t boot_head = { + .jump_instruction = JUMP_INSTRUCTION, + .magic = BOOT0_MAGIC, + .check_sum = STAMP_VALUE, + .length = __spl_size, + .pub_head_size = sizeof(boot_file_head_t), + .pub_head_vsn = BOOT_PUB_HEAD_VERSION, + .ret_addr = __code_start_address, + .run_addr = __code_start_address, + .boot_cpu = 0, + .platform = {0, 0, '3', '.', '0', '.', '0', 0}, +}; diff --git a/board/100ask-d1-h/start.S b/board/100ask-d1-h/start.S index 2d2c4ef2..d5bdcf66 100644 --- a/board/100ask-d1-h/start.S +++ b/board/100ask-d1-h/start.S @@ -4,24 +4,9 @@ #include .text + .align 4 .globl _start _start: - /* Boot head information for BROM */ - .long 0x0300006f - .byte 'e', 'G', 'O', 'N', '.', 'B', 'T', '0' - .long 0x12345678 /* checksum */ - .long __spl_size /* spl size */ - .long 0x30 /* boot header size */ - .long 0x30303033 /* boot header version */ - .long 0x00020000 /* return value */ - .long 0x00028000 /* run address */ - .long 0x0 /* eGON version */ - .byte 0x00, 0x00, 0x00, 0x00 /* platform information - 8byte */ - .byte 0x34, 0x2e, 0x30, 0x00 - - .align 4 - .globl reset -reset: /* disable interrupt */ csrw mie, zero @@ -76,7 +61,6 @@ clbss_1: blt t0, t1, clbss_1 ret - /* * Exception vectors. */ diff --git a/board/100ask-ros/CMakeLists.txt b/board/100ask-ros/CMakeLists.txt index 5ae84d96..0e35e750 100644 --- a/board/100ask-ros/CMakeLists.txt +++ b/board/100ask-ros/CMakeLists.txt @@ -4,6 +4,7 @@ set(APP_COMMON_SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/eabi_compat.c ${CMAKE_CURRENT_SOURCE_DIR}/payloads/init_dram_bin.c ${CMAKE_CURRENT_SOURCE_DIR}/payloads/ar100s.c + ${CMAKE_CURRENT_SOURCE_DIR}/head.c ) add_subdirectory(hello_world) diff --git a/board/100ask-ros/head.c b/board/100ask-ros/head.c new file mode 100644 index 00000000..05d101a7 --- /dev/null +++ b/board/100ask-ros/head.c @@ -0,0 +1,40 @@ +#include +#include +#include +#include + +typedef struct boot_file_head { + uint32_t jump_instruction; /* one intruction jumping to real code */ + uint8_t magic[8]; /* ="eGON.BT0" */ + uint32_t check_sum; /* generated by PC */ + uint32_t *length; /* generated by LD */ + uint32_t pub_head_size; /* the size of boot_file_head_t */ + uint8_t pub_head_vsn[4]; /* the version of boot_file_head_t */ + uint32_t *ret_addr; /* the return value */ + uint32_t *run_addr; /* run addr */ + uint32_t boot_cpu; /* eGON version */ + uint8_t platform[8]; /* platform information */ +} boot_file_head_t; + +#define BROM_FILE_HEAD_SIZE_OFFSET (((sizeof(boot_file_head_t) + sizeof(int)) / sizeof(int) + 1)) +#define JUMP_INSTRUCTION (BROM_FILE_HEAD_SIZE_OFFSET | 0xEA000000) + +#define BOOT0_MAGIC "eGON.BT0" +#define STAMP_VALUE (0x12345678) +#define BOOT_PUB_HEAD_VERSION "3000" + +extern uint32_t __spl_size[]; +extern uint32_t __code_start_address[]; + +const __attribute__((section(".boot0_head"))) boot_file_head_t boot_head = { + .jump_instruction = JUMP_INSTRUCTION, + .magic = BOOT0_MAGIC, + .check_sum = STAMP_VALUE, + .length = __spl_size, + .pub_head_size = sizeof(boot_file_head_t), + .pub_head_vsn = BOOT_PUB_HEAD_VERSION, + .ret_addr = __code_start_address, + .run_addr = __code_start_address, + .boot_cpu = 0, + .platform = {0, 0, '3', '.', '0', '.', '0', 0}, +}; \ No newline at end of file diff --git a/board/100ask-ros/start.S b/board/100ask-ros/start.S index ca4fc451..3a4bc8ab 100644 --- a/board/100ask-ros/start.S +++ b/board/100ask-ros/start.S @@ -68,22 +68,10 @@ .text _start: - /* Boot head information for BROM */ - .long 0xea000016 - .byte 'e', 'G', 'O', 'N', '.', 'B', 'T', '0' - .long 0x12345678 /* checksum */ - .long __spl_size /* spl size */ - .long 0x30 /* boot header size */ - .long 0x30303033 /* boot header version */ - .long 0x00020000 /* return value */ - .long 0x00028000 /* run address */ - .long 0x0 /* eGON version */ - .byte 0x00, 0x00, 0x00, 0x00 /* platform information - 8byte */ - .byte 0x34, 0x2e, 0x30, 0x00 - + b reset + .align 5 _vector: - b reset ldr pc, _undefined_instruction ldr pc, _software_interrupt ldr pc, _prefetch_abort diff --git a/board/100ask-t113i/CMakeLists.txt b/board/100ask-t113i/CMakeLists.txt index fd14d03f..2e490425 100644 --- a/board/100ask-t113i/CMakeLists.txt +++ b/board/100ask-t113i/CMakeLists.txt @@ -2,6 +2,7 @@ set(APP_COMMON_SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/start.S ${CMAKE_CURRENT_SOURCE_DIR}/board.c ${CMAKE_CURRENT_SOURCE_DIR}/eabi_compat.c + ${CMAKE_CURRENT_SOURCE_DIR}/head.c ) add_subdirectory(hello_world) diff --git a/board/100ask-t113i/head.c b/board/100ask-t113i/head.c new file mode 100644 index 00000000..05d101a7 --- /dev/null +++ b/board/100ask-t113i/head.c @@ -0,0 +1,40 @@ +#include +#include +#include +#include + +typedef struct boot_file_head { + uint32_t jump_instruction; /* one intruction jumping to real code */ + uint8_t magic[8]; /* ="eGON.BT0" */ + uint32_t check_sum; /* generated by PC */ + uint32_t *length; /* generated by LD */ + uint32_t pub_head_size; /* the size of boot_file_head_t */ + uint8_t pub_head_vsn[4]; /* the version of boot_file_head_t */ + uint32_t *ret_addr; /* the return value */ + uint32_t *run_addr; /* run addr */ + uint32_t boot_cpu; /* eGON version */ + uint8_t platform[8]; /* platform information */ +} boot_file_head_t; + +#define BROM_FILE_HEAD_SIZE_OFFSET (((sizeof(boot_file_head_t) + sizeof(int)) / sizeof(int) + 1)) +#define JUMP_INSTRUCTION (BROM_FILE_HEAD_SIZE_OFFSET | 0xEA000000) + +#define BOOT0_MAGIC "eGON.BT0" +#define STAMP_VALUE (0x12345678) +#define BOOT_PUB_HEAD_VERSION "3000" + +extern uint32_t __spl_size[]; +extern uint32_t __code_start_address[]; + +const __attribute__((section(".boot0_head"))) boot_file_head_t boot_head = { + .jump_instruction = JUMP_INSTRUCTION, + .magic = BOOT0_MAGIC, + .check_sum = STAMP_VALUE, + .length = __spl_size, + .pub_head_size = sizeof(boot_file_head_t), + .pub_head_vsn = BOOT_PUB_HEAD_VERSION, + .ret_addr = __code_start_address, + .run_addr = __code_start_address, + .boot_cpu = 0, + .platform = {0, 0, '3', '.', '0', '.', '0', 0}, +}; \ No newline at end of file diff --git a/board/100ask-t113i/start.S b/board/100ask-t113i/start.S index 6b32a13f..045e9c97 100644 --- a/board/100ask-t113i/start.S +++ b/board/100ask-t113i/start.S @@ -68,22 +68,10 @@ .text _start: - /* Boot head information for BROM */ - .long 0xea000016 - .byte 'e', 'G', 'O', 'N', '.', 'B', 'T', '0' - .long 0x12345678 /* checksum */ - .long __spl_size /* spl size */ - .long 0x30 /* boot header size */ - .long 0x30303033 /* boot header version */ - .long 0x00020000 /* return value */ - .long 0x00028000 /* run address */ - .long 0x0 /* eGON version */ - .byte 0x00, 0x00, 0x00, 0x00 /* platform information - 8byte */ - .byte 0x34, 0x2e, 0x30, 0x00 - + b reset + .align 5 _vector: - b reset ldr pc, _undefined_instruction ldr pc, _software_interrupt ldr pc, _prefetch_abort diff --git a/board/100ask-t113s3/CMakeLists.txt b/board/100ask-t113s3/CMakeLists.txt index 97425536..e8746e67 100644 --- a/board/100ask-t113s3/CMakeLists.txt +++ b/board/100ask-t113s3/CMakeLists.txt @@ -2,6 +2,7 @@ set(APP_COMMON_SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/start.S ${CMAKE_CURRENT_SOURCE_DIR}/board.c ${CMAKE_CURRENT_SOURCE_DIR}/eabi_compat.c + ${CMAKE_CURRENT_SOURCE_DIR}/head.c ) add_subdirectory(hello_world) diff --git a/board/100ask-t113s3/head.c b/board/100ask-t113s3/head.c new file mode 100644 index 00000000..05d101a7 --- /dev/null +++ b/board/100ask-t113s3/head.c @@ -0,0 +1,40 @@ +#include +#include +#include +#include + +typedef struct boot_file_head { + uint32_t jump_instruction; /* one intruction jumping to real code */ + uint8_t magic[8]; /* ="eGON.BT0" */ + uint32_t check_sum; /* generated by PC */ + uint32_t *length; /* generated by LD */ + uint32_t pub_head_size; /* the size of boot_file_head_t */ + uint8_t pub_head_vsn[4]; /* the version of boot_file_head_t */ + uint32_t *ret_addr; /* the return value */ + uint32_t *run_addr; /* run addr */ + uint32_t boot_cpu; /* eGON version */ + uint8_t platform[8]; /* platform information */ +} boot_file_head_t; + +#define BROM_FILE_HEAD_SIZE_OFFSET (((sizeof(boot_file_head_t) + sizeof(int)) / sizeof(int) + 1)) +#define JUMP_INSTRUCTION (BROM_FILE_HEAD_SIZE_OFFSET | 0xEA000000) + +#define BOOT0_MAGIC "eGON.BT0" +#define STAMP_VALUE (0x12345678) +#define BOOT_PUB_HEAD_VERSION "3000" + +extern uint32_t __spl_size[]; +extern uint32_t __code_start_address[]; + +const __attribute__((section(".boot0_head"))) boot_file_head_t boot_head = { + .jump_instruction = JUMP_INSTRUCTION, + .magic = BOOT0_MAGIC, + .check_sum = STAMP_VALUE, + .length = __spl_size, + .pub_head_size = sizeof(boot_file_head_t), + .pub_head_vsn = BOOT_PUB_HEAD_VERSION, + .ret_addr = __code_start_address, + .run_addr = __code_start_address, + .boot_cpu = 0, + .platform = {0, 0, '3', '.', '0', '.', '0', 0}, +}; \ No newline at end of file diff --git a/board/100ask-t113s3/load_hifi4/main.c b/board/100ask-t113s3/load_hifi4/main.c index 253244e8..52f5878c 100644 --- a/board/100ask-t113s3/load_hifi4/main.c +++ b/board/100ask-t113s3/load_hifi4/main.c @@ -27,7 +27,7 @@ #include #include -#define CONFIG_HIFI4_ELF_FILENAME "t113_i_dsp0_evb1.elf" +#define CONFIG_HIFI4_ELF_FILENAME "dsp.elf" #define CONFIG_HIFI4_ELF_LOADADDR (0x45000000) #define CONFIG_SDMMC_SPEED_TEST_SIZE 1024// (unit: 512B sectors) @@ -138,6 +138,8 @@ msh_declare_command(boot); msh_define_help(boot, "boot to linux", "Usage: boot\n"); int cmd_boot(int argc, const char **argv) { sunxi_hifi4_start(); + + abort(); return 0; } @@ -153,8 +155,7 @@ int main(void) { sunxi_clk_init();// Initialize clock configurations - uint64_t dram_size = sunxi_dram_init(&dram_para); - arm32_mmu_enable(SDRAM_BASE, dram_size); + sunxi_dram_init(&dram_para); sunxi_clk_dump();// Dump clock information @@ -186,7 +187,7 @@ int main(void) { return 0; } - // sunxi_hifi4_clock_reset(); + sunxi_hifi4_clock_reset(); /* HIFI4 need to remap addresses for some addr. */ vaddr_range_t hifi4_addr_mapping_range[] = { @@ -210,8 +211,12 @@ int main(void) { printk(LOG_LEVEL_ERROR, "HIFI4 ELF load FAIL\n"); } + dump_c906_clock(); + printk(LOG_LEVEL_INFO, "HIFI4 Core now Running... \n"); + cmd_boot(0, NULL); + syterkit_shell_attach(commands); jmp_to_fel();// Jump to FEL mode diff --git a/board/100ask-t113s3/start.S b/board/100ask-t113s3/start.S index 6b32a13f..045e9c97 100644 --- a/board/100ask-t113s3/start.S +++ b/board/100ask-t113s3/start.S @@ -68,22 +68,10 @@ .text _start: - /* Boot head information for BROM */ - .long 0xea000016 - .byte 'e', 'G', 'O', 'N', '.', 'B', 'T', '0' - .long 0x12345678 /* checksum */ - .long __spl_size /* spl size */ - .long 0x30 /* boot header size */ - .long 0x30303033 /* boot header version */ - .long 0x00020000 /* return value */ - .long 0x00028000 /* run address */ - .long 0x0 /* eGON version */ - .byte 0x00, 0x00, 0x00, 0x00 /* platform information - 8byte */ - .byte 0x34, 0x2e, 0x30, 0x00 - + b reset + .align 5 _vector: - b reset ldr pc, _undefined_instruction ldr pc, _software_interrupt ldr pc, _prefetch_abort diff --git a/board/bingpi-m1/CMakeLists.txt b/board/bingpi-m1/CMakeLists.txt index 27e2805d..489b00ec 100644 --- a/board/bingpi-m1/CMakeLists.txt +++ b/board/bingpi-m1/CMakeLists.txt @@ -2,6 +2,7 @@ set(APP_COMMON_SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/start.S ${CMAKE_CURRENT_SOURCE_DIR}/board.c ${CMAKE_CURRENT_SOURCE_DIR}/eabi_compat.c + ${CMAKE_CURRENT_SOURCE_DIR}/head.c ) add_subdirectory(hello_world) diff --git a/board/bingpi-m1/head.c b/board/bingpi-m1/head.c new file mode 100644 index 00000000..05d101a7 --- /dev/null +++ b/board/bingpi-m1/head.c @@ -0,0 +1,40 @@ +#include +#include +#include +#include + +typedef struct boot_file_head { + uint32_t jump_instruction; /* one intruction jumping to real code */ + uint8_t magic[8]; /* ="eGON.BT0" */ + uint32_t check_sum; /* generated by PC */ + uint32_t *length; /* generated by LD */ + uint32_t pub_head_size; /* the size of boot_file_head_t */ + uint8_t pub_head_vsn[4]; /* the version of boot_file_head_t */ + uint32_t *ret_addr; /* the return value */ + uint32_t *run_addr; /* run addr */ + uint32_t boot_cpu; /* eGON version */ + uint8_t platform[8]; /* platform information */ +} boot_file_head_t; + +#define BROM_FILE_HEAD_SIZE_OFFSET (((sizeof(boot_file_head_t) + sizeof(int)) / sizeof(int) + 1)) +#define JUMP_INSTRUCTION (BROM_FILE_HEAD_SIZE_OFFSET | 0xEA000000) + +#define BOOT0_MAGIC "eGON.BT0" +#define STAMP_VALUE (0x12345678) +#define BOOT_PUB_HEAD_VERSION "3000" + +extern uint32_t __spl_size[]; +extern uint32_t __code_start_address[]; + +const __attribute__((section(".boot0_head"))) boot_file_head_t boot_head = { + .jump_instruction = JUMP_INSTRUCTION, + .magic = BOOT0_MAGIC, + .check_sum = STAMP_VALUE, + .length = __spl_size, + .pub_head_size = sizeof(boot_file_head_t), + .pub_head_vsn = BOOT_PUB_HEAD_VERSION, + .ret_addr = __code_start_address, + .run_addr = __code_start_address, + .boot_cpu = 0, + .platform = {0, 0, '3', '.', '0', '.', '0', 0}, +}; \ No newline at end of file diff --git a/board/bingpi-m1/start.S b/board/bingpi-m1/start.S index 6b32a13f..045e9c97 100644 --- a/board/bingpi-m1/start.S +++ b/board/bingpi-m1/start.S @@ -68,22 +68,10 @@ .text _start: - /* Boot head information for BROM */ - .long 0xea000016 - .byte 'e', 'G', 'O', 'N', '.', 'B', 'T', '0' - .long 0x12345678 /* checksum */ - .long __spl_size /* spl size */ - .long 0x30 /* boot header size */ - .long 0x30303033 /* boot header version */ - .long 0x00020000 /* return value */ - .long 0x00028000 /* run address */ - .long 0x0 /* eGON version */ - .byte 0x00, 0x00, 0x00, 0x00 /* platform information - 8byte */ - .byte 0x34, 0x2e, 0x30, 0x00 - + b reset + .align 5 _vector: - b reset ldr pc, _undefined_instruction ldr pc, _software_interrupt ldr pc, _prefetch_abort diff --git a/board/dongshanpi-aict/CMakeLists.txt b/board/dongshanpi-aict/CMakeLists.txt index d589023a..cdffeffb 100644 --- a/board/dongshanpi-aict/CMakeLists.txt +++ b/board/dongshanpi-aict/CMakeLists.txt @@ -2,6 +2,7 @@ set(APP_COMMON_SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/start.S ${CMAKE_CURRENT_SOURCE_DIR}/board.c ${CMAKE_CURRENT_SOURCE_DIR}/eabi_compat.c + ${CMAKE_CURRENT_SOURCE_DIR}/head.c ) add_subdirectory(hello_world) diff --git a/board/dongshanpi-aict/head.c b/board/dongshanpi-aict/head.c new file mode 100644 index 00000000..05d101a7 --- /dev/null +++ b/board/dongshanpi-aict/head.c @@ -0,0 +1,40 @@ +#include +#include +#include +#include + +typedef struct boot_file_head { + uint32_t jump_instruction; /* one intruction jumping to real code */ + uint8_t magic[8]; /* ="eGON.BT0" */ + uint32_t check_sum; /* generated by PC */ + uint32_t *length; /* generated by LD */ + uint32_t pub_head_size; /* the size of boot_file_head_t */ + uint8_t pub_head_vsn[4]; /* the version of boot_file_head_t */ + uint32_t *ret_addr; /* the return value */ + uint32_t *run_addr; /* run addr */ + uint32_t boot_cpu; /* eGON version */ + uint8_t platform[8]; /* platform information */ +} boot_file_head_t; + +#define BROM_FILE_HEAD_SIZE_OFFSET (((sizeof(boot_file_head_t) + sizeof(int)) / sizeof(int) + 1)) +#define JUMP_INSTRUCTION (BROM_FILE_HEAD_SIZE_OFFSET | 0xEA000000) + +#define BOOT0_MAGIC "eGON.BT0" +#define STAMP_VALUE (0x12345678) +#define BOOT_PUB_HEAD_VERSION "3000" + +extern uint32_t __spl_size[]; +extern uint32_t __code_start_address[]; + +const __attribute__((section(".boot0_head"))) boot_file_head_t boot_head = { + .jump_instruction = JUMP_INSTRUCTION, + .magic = BOOT0_MAGIC, + .check_sum = STAMP_VALUE, + .length = __spl_size, + .pub_head_size = sizeof(boot_file_head_t), + .pub_head_vsn = BOOT_PUB_HEAD_VERSION, + .ret_addr = __code_start_address, + .run_addr = __code_start_address, + .boot_cpu = 0, + .platform = {0, 0, '3', '.', '0', '.', '0', 0}, +}; \ No newline at end of file diff --git a/board/dongshanpi-aict/start.S b/board/dongshanpi-aict/start.S index 6b32a13f..045e9c97 100644 --- a/board/dongshanpi-aict/start.S +++ b/board/dongshanpi-aict/start.S @@ -68,22 +68,10 @@ .text _start: - /* Boot head information for BROM */ - .long 0xea000016 - .byte 'e', 'G', 'O', 'N', '.', 'B', 'T', '0' - .long 0x12345678 /* checksum */ - .long __spl_size /* spl size */ - .long 0x30 /* boot header size */ - .long 0x30303033 /* boot header version */ - .long 0x00020000 /* return value */ - .long 0x00028000 /* run address */ - .long 0x0 /* eGON version */ - .byte 0x00, 0x00, 0x00, 0x00 /* platform information - 8byte */ - .byte 0x34, 0x2e, 0x30, 0x00 - + b reset + .align 5 _vector: - b reset ldr pc, _undefined_instruction ldr pc, _software_interrupt ldr pc, _prefetch_abort diff --git a/board/longanpi-3h/CMakeLists.txt b/board/longanpi-3h/CMakeLists.txt index 5192231f..2be3c54f 100644 --- a/board/longanpi-3h/CMakeLists.txt +++ b/board/longanpi-3h/CMakeLists.txt @@ -3,6 +3,7 @@ set(APP_COMMON_SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/board.c ${CMAKE_CURRENT_SOURCE_DIR}/eabi_compat.c ${CMAKE_CURRENT_SOURCE_DIR}/payloads/init_dram_bin.c + ${CMAKE_CURRENT_SOURCE_DIR}/head.c ) add_subdirectory(hello_world) diff --git a/board/longanpi-3h/head.c b/board/longanpi-3h/head.c new file mode 100644 index 00000000..05d101a7 --- /dev/null +++ b/board/longanpi-3h/head.c @@ -0,0 +1,40 @@ +#include +#include +#include +#include + +typedef struct boot_file_head { + uint32_t jump_instruction; /* one intruction jumping to real code */ + uint8_t magic[8]; /* ="eGON.BT0" */ + uint32_t check_sum; /* generated by PC */ + uint32_t *length; /* generated by LD */ + uint32_t pub_head_size; /* the size of boot_file_head_t */ + uint8_t pub_head_vsn[4]; /* the version of boot_file_head_t */ + uint32_t *ret_addr; /* the return value */ + uint32_t *run_addr; /* run addr */ + uint32_t boot_cpu; /* eGON version */ + uint8_t platform[8]; /* platform information */ +} boot_file_head_t; + +#define BROM_FILE_HEAD_SIZE_OFFSET (((sizeof(boot_file_head_t) + sizeof(int)) / sizeof(int) + 1)) +#define JUMP_INSTRUCTION (BROM_FILE_HEAD_SIZE_OFFSET | 0xEA000000) + +#define BOOT0_MAGIC "eGON.BT0" +#define STAMP_VALUE (0x12345678) +#define BOOT_PUB_HEAD_VERSION "3000" + +extern uint32_t __spl_size[]; +extern uint32_t __code_start_address[]; + +const __attribute__((section(".boot0_head"))) boot_file_head_t boot_head = { + .jump_instruction = JUMP_INSTRUCTION, + .magic = BOOT0_MAGIC, + .check_sum = STAMP_VALUE, + .length = __spl_size, + .pub_head_size = sizeof(boot_file_head_t), + .pub_head_vsn = BOOT_PUB_HEAD_VERSION, + .ret_addr = __code_start_address, + .run_addr = __code_start_address, + .boot_cpu = 0, + .platform = {0, 0, '3', '.', '0', '.', '0', 0}, +}; \ No newline at end of file diff --git a/board/longanpi-3h/start.S b/board/longanpi-3h/start.S index ca4fc451..3a4bc8ab 100644 --- a/board/longanpi-3h/start.S +++ b/board/longanpi-3h/start.S @@ -68,22 +68,10 @@ .text _start: - /* Boot head information for BROM */ - .long 0xea000016 - .byte 'e', 'G', 'O', 'N', '.', 'B', 'T', '0' - .long 0x12345678 /* checksum */ - .long __spl_size /* spl size */ - .long 0x30 /* boot header size */ - .long 0x30303033 /* boot header version */ - .long 0x00020000 /* return value */ - .long 0x00028000 /* run address */ - .long 0x0 /* eGON version */ - .byte 0x00, 0x00, 0x00, 0x00 /* platform information - 8byte */ - .byte 0x34, 0x2e, 0x30, 0x00 - + b reset + .align 5 _vector: - b reset ldr pc, _undefined_instruction ldr pc, _software_interrupt ldr pc, _prefetch_abort diff --git a/board/longanpi-3h/syter_boot/main.c b/board/longanpi-3h/syter_boot/main.c index 49535f0e..61306eff 100644 --- a/board/longanpi-3h/syter_boot/main.c +++ b/board/longanpi-3h/syter_boot/main.c @@ -51,32 +51,11 @@ #define FILENAME_MAX_LEN 64 typedef struct { uint8_t *dest; - uint8_t *of_dest; - - uint8_t *config_dest; - uint8_t is_config; - char filename[FILENAME_MAX_LEN]; - char of_filename[FILENAME_MAX_LEN]; - - char config_filename[FILENAME_MAX_LEN]; } image_info_t; -#define MAX_SECTION_LEN 16 -#define MAX_KEY_LEN 16 -#define MAX_VALUE_LEN 512 -#define CONFIG_MAX_ENTRY 3 - -typedef struct { - char section[MAX_SECTION_LEN]; - char key[MAX_KEY_LEN]; - char value[MAX_VALUE_LEN]; -} IniEntry; - -IniEntry entries[CONFIG_MAX_ENTRY]; - extern sunxi_serial_t uart_dbg; extern sunxi_i2c_t i2c_pmu; @@ -167,16 +146,6 @@ static int load_sdcard(image_info_t *image) { if (ret) return ret; - /* load config */ - printk(LOG_LEVEL_INFO, "FATFS: read %s addr=%x\n", image->config_filename, (uint32_t) image->config_dest); - ret = fatfs_loadimage(image->config_filename, image->config_dest); - if (ret) { - printk(LOG_LEVEL_INFO, "CONFIG: Cannot find config file, Using default config.\n"); - image->is_config = 0; - } else { - image->is_config = 1; - } - /* umount fs */ fret = f_mount(0, "", 0); if (fret != FR_OK) { @@ -190,175 +159,6 @@ static int load_sdcard(image_info_t *image) { return 0; } -static void trim(char *str) { - int len = strlen(str); - while (len > 0 && (str[len - 1] == ' ' || str[len - 1] == '\n' || str[len - 1] == '\r')) { - str[--len] = '\0'; - } - while (*str && (*str == ' ' || *str == '\n' || *str == '\r')) { - ++str; - --len; - } -} - -static int parse_ini_data(const char *data, size_t size, IniEntry *entries, int max_entries) { - char line[MAX_VALUE_LEN]; - char current_section[MAX_SECTION_LEN] = ""; - int entry_count = 0; - - const char *p = data; - const char *end = data + size; - - while (p < end) { - /* Read a line of data */ - size_t len = 0; - while (p + len < end && *(p + len) != '\n') { - ++len; - } - if (p + len < end && *(p + len) == '\n') { - ++len; - } - if (len > 0) { - strncpy(line, p, len); - line[len] = '\0'; - p += len; - - trim(line); - - /* Ignore empty lines and comments */ - if (line[0] == '\0' || line[0] == ';' || line[0] == '#') { - continue; - } - - /* Parse the section name */ - if (line[0] == '[' && line[strlen(line) - 1] == ']') { - strncpy(current_section, &line[1], strlen(line) - 2); - current_section[strlen(line) - 2] = '\0'; - continue; - } - - /* Parse key-value pairs */ - char *pos = strchr(line, '='); - if (pos != NULL) { - char *key_start = line; - char *value_start = pos + 1; - *pos = '\0'; - trim(key_start); - trim(value_start); - - if (strlen(current_section) > 0 && strlen(key_start) > 0 && strlen(value_start) > 0) { - if (entry_count >= max_entries) { - printk(LOG_LEVEL_ERROR, "INI: Too many entries!\n"); - break; - } - strncpy(entries[entry_count].section, current_section, MAX_SECTION_LEN - 1); - strncpy(entries[entry_count].key, key_start, MAX_KEY_LEN - 1); - strncpy(entries[entry_count].value, value_start, MAX_VALUE_LEN - 1); - ++entry_count; - } - } - } - } - - return entry_count; -} - -static const char *find_entry_value(const IniEntry *entries, int entry_count, const char *section, const char *key) { - for (int i = 0; i < entry_count; ++i) { - if (strcmp(entries[i].section, section) == 0 && strcmp(entries[i].key, key) == 0) { - return entries[i].value; - } - } - return NULL; -} - -static int update_bootargs_from_config(uint64_t dram_size) { - int ret = 0; - char *bootargs_str_config = NULL; - char *mac_addr = NULL; - - /* Check if using config file, get bootargs in the config file */ - if (image.is_config) { - size_t size_a = strlen(image.config_dest); - int entry_count = parse_ini_data(image.config_dest, size_a, entries, CONFIG_MAX_ENTRY); - for (int i = 0; i < entry_count; ++i) { - /* Print parsed INI entries */ - printk(LOG_LEVEL_DEBUG, "INI: [%s] %s = %s\n", entries[i].section, entries[i].key, entries[i].value); - } - bootargs_str_config = find_entry_value(entries, entry_count, "configs", "bootargs"); - mac_addr = find_entry_value(entries, entry_count, "configs", "mac_addr"); - } - - /* Force image.dest to be a pointer to fdt_header structure */ - struct fdt_header *dtb_header = (struct fdt_header *) image.of_dest; - - /* Check if DTB header is valid */ - if ((ret = fdt_check_header(dtb_header)) != 0) { - printk(LOG_LEVEL_ERROR, "Invalid device tree blob: %s\n", fdt_strerror(ret)); - return -1; - } - - /* Get the total size of DTB */ - uint32_t size = fdt_totalsize(image.of_dest); - printk(LOG_LEVEL_DEBUG, "%s: FDT Size = %d\n", image.of_filename, size); - - int len = 0; - /* Get the offset of "/chosen" node */ - uint32_t bootargs_node = fdt_path_offset(image.of_dest, "/chosen"); - - /* Get bootargs string */ - char *bootargs_str = (void *) fdt_getprop(image.of_dest, bootargs_node, "bootargs", &len); - - /* If config file read fail or not using */ - if (bootargs_str_config == NULL) { - printk(LOG_LEVEL_WARNING, "INI: Cannot parse bootargs, using default bootargs in DTB.\n"); - bootargs_str_config = bootargs_str; - } - - /* update mac address of board */ - if (mac_addr != NULL) { - strcat(bootargs_str_config, " mac_addr="); - strcat(bootargs_str_config, mac_addr); - } - - /* Add dram size to dtb */ - char dram_size_str[8]; - strcat(bootargs_str_config, " mem="); - strcat(bootargs_str_config, ltoa(dram_size, dram_size_str, 10)); - strcat(bootargs_str_config, "M"); - - /* Set bootargs based on the configuration file */ - printk(LOG_LEVEL_DEBUG, "INI: Set bootargs to %s\n", bootargs_str_config); - -_add_dts_size: - /* Modify bootargs string */ - ret = fdt_setprop(image.of_dest, bootargs_node, "bootargs", bootargs_str_config, strlen(bootargs_str_config) + 1); - if (ret == -FDT_ERR_NOSPACE) { - printk(LOG_LEVEL_DEBUG, "FDT: FDT_ERR_NOSPACE, Size = %d, Increase Size = %d\n", size, 512); - ret = fdt_increase_size(image.of_dest, 512); - if (!ret) - goto _add_dts_size; - else - goto _err_size; - } else if (ret < 0) { - printk(LOG_LEVEL_ERROR, "Can't change bootargs node: %s\n", fdt_strerror(ret)); - return -1; - } - - /* Get the total size of DTB */ - printk(LOG_LEVEL_DEBUG, "Modify FDT Size = %d\n", fdt_totalsize(image.of_dest)); - - if (ret < 0) { - printk(LOG_LEVEL_ERROR, "libfdt fdt_setprop() error: %s\n", fdt_strerror(ret)); - return -1; - } - - return 0; -_err_size: - printk(LOG_LEVEL_ERROR, "DTB: Can't increase blob size: %s\n", fdt_strerror(ret)); - return -1; -} - static int abortboot_single_key(int bootdelay) { int abort = 0; unsigned long ts; @@ -389,91 +189,6 @@ static int abortboot_single_key(int bootdelay) { return abort; } -msh_declare_command(bootargs); -msh_define_help(bootargs, "get/set bootargs for kernel", - "Usage: bootargs set \"bootargs\" - set new bootargs for zImage\n" - " bootargs get - get current bootargs\n"); -int cmd_bootargs(int argc, const char **argv) { - int err = 0; - - if (argc < 2) { - uart_puts(cmd_bootargs_usage); - return 0; - } - - if (strncmp(argv[1], "set", 3) == 0) { - if (argc != 3) { - uart_puts(cmd_bootargs_usage); - return 0; - } - /* Force image.of_dest to be a pointer to fdt_header structure */ - struct fdt_header *dtb_header = (struct fdt_header *) image.of_dest; - - /* Check if DTB header is valid */ - if ((err = fdt_check_header(dtb_header)) != 0) { - printk(LOG_LEVEL_ERROR, "Invalid device tree blob: %s\n", fdt_strerror(err)); - return 0; - } - - int len = 0; - /* Get the offset of "/chosen" node */ - uint32_t bootargs_node = fdt_path_offset(image.of_dest, "/chosen"); - - /* Get bootargs string */ - char *bootargs_str = (void *) fdt_getprop(image.of_dest, bootargs_node, "bootargs", &len); - printk(LOG_LEVEL_MUTE, "DTB OLD bootargs = \"%s\"\n", bootargs_str); - - /* New bootargs string */ - char *new_bootargs_str = argv[2]; - printk(LOG_LEVEL_MUTE, "Now set bootargs to \"%s\"\n", new_bootargs_str); - - _add_dts_size: - /* Modify bootargs string */ - err = fdt_setprop(image.of_dest, bootargs_node, "bootargs", new_bootargs_str, strlen(new_bootargs_str) + 1); - if (err == -FDT_ERR_NOSPACE) { - printk(LOG_LEVEL_DEBUG, "FDT: FDT_ERR_NOSPACE, Increase Size = %d\n", 512); - err = fdt_increase_size(image.of_dest, 512); - if (!err) - goto _add_dts_size; - else - goto _err_size; - } else if (err < 0) { - printk(LOG_LEVEL_ERROR, "Can't change bootargs node: %s\n", fdt_strerror(err)); - abort(); - } - - /* Get updated bootargs string */ - char *updated_bootargs_str = (void *) fdt_getprop(image.of_dest, bootargs_node, "bootargs", &len); - printk(LOG_LEVEL_MUTE, "DTB NEW bootargs = \"%s\"\n", updated_bootargs_str); - } else if (strncmp(argv[1], "get", 3) == 0) { - /* Force image.of_dest to be a pointer to fdt_header structure */ - struct fdt_header *dtb_header = (struct fdt_header *) image.of_dest; - - int err = 0; - - /* Check if DTB header is valid */ - if ((err = fdt_check_header(dtb_header)) != 0) { - printk(LOG_LEVEL_ERROR, "Invalid device tree blob: %s\n", fdt_strerror(err)); - return 0; - } - - int len = 0; - /* Get the offset of "/chosen" node */ - uint32_t bootargs_node = fdt_path_offset(image.of_dest, "/chosen"); - - /* Get bootargs string */ - char *bootargs_str = (void *) fdt_getprop(image.of_dest, bootargs_node, "bootargs", &len); - printk(LOG_LEVEL_MUTE, "DTB bootargs = \"%s\"\n", bootargs_str); - } else { - uart_puts(cmd_bootargs_usage); - } - return 0; - -_err_size: - printk(LOG_LEVEL_ERROR, "DTB: Can't increase blob size: %s\n", fdt_strerror(err)); - abort(); -} - static void set_pmu_fin_voltage(char *power_name, uint32_t voltage) { int set_vol = voltage; int temp_vol, src_vol = pmu_axp1530_get_vol(&i2c_pmu, power_name); @@ -504,22 +219,6 @@ int cmd_reload(int argc, const char **argv) { return 0; } -msh_declare_command(print); -msh_define_help(print, "print out env config", "Usage: print\n"); -int cmd_print(int argc, const char **argv) { - if (image.is_config) { - size_t size_a = strlen(image.config_dest); - int entry_count = parse_ini_data(image.config_dest, size_a, entries, CONFIG_MAX_ENTRY); - for (int i = 0; i < entry_count; ++i) { - /* Print parsed INI entries */ - printk(LOG_LEVEL_MUTE, "ENV: [%s] %s = %s\n", entries[i].section, entries[i].key, entries[i].value); - } - } else { - printk(LOG_LEVEL_WARNING, "ENV: Can not find env file\n"); - } - return 0; -} - msh_declare_command(boot); msh_define_help(boot, "boot to linux", "Usage: boot\n"); int cmd_boot(int argc, const char **argv) { @@ -545,10 +244,8 @@ int cmd_boot(int argc, const char **argv) { } const msh_command_entry commands[] = { - msh_define_command(bootargs), msh_define_command(reload), msh_define_command(boot), - msh_define_command(print), msh_command_end, }; @@ -595,13 +292,10 @@ int main(void) { /* Set the destination address for the device tree binary (DTB), kernel image, and configuration data. */ image.of_dest = (uint8_t *) CONFIG_DTB_LOAD_ADDR; image.dest = (uint8_t *) CONFIG_KERNEL_LOAD_ADDR; - image.config_dest = (uint8_t *) CONFIG_CONFIG_LOAD_ADDR; - image.is_config = 0; /* Copy the filenames for the DTB, kernel image, and configuration data. */ strcpy(image.filename, CONFIG_KERNEL_FILENAME); strcpy(image.of_filename, CONFIG_DTB_FILENAME); - strcpy(image.config_filename, CONFIG_CONFIG_FILENAME); /* Initialize the SD host controller. */ if (sunxi_sdhci_init(&sdhci0) != 0) { @@ -623,26 +317,8 @@ int main(void) { goto _shell; } - /* Update boot arguments based on configuration file. */ - if (update_bootargs_from_config(dram_size)) { - goto _shell; - } - int bootdelay = CONFIG_DEFAULT_BOOTDELAY; - if (image.is_config) { - size_t size_a = strlen(image.config_dest); - int entry_count = parse_ini_data(image.config_dest, size_a, entries, CONFIG_MAX_ENTRY); - for (int i = 0; i < entry_count; ++i) { - /* Print parsed INI entries */ - printk(LOG_LEVEL_DEBUG, "INI: [%s] %s = %s\n", entries[i].section, entries[i].key, entries[i].value); - } - char *bootdelay_str = find_entry_value(entries, entry_count, "configs", "bootdelay"); - if (bootdelay_str != NULL) { - bootdelay = simple_atoi(bootdelay_str); - } - } - /* Showing boot delays */ if (abortboot_single_key(bootdelay)) { goto _shell; diff --git a/board/longanpi-4b/CMakeLists.txt b/board/longanpi-4b/CMakeLists.txt index 5a9e7620..9b813c25 100644 --- a/board/longanpi-4b/CMakeLists.txt +++ b/board/longanpi-4b/CMakeLists.txt @@ -3,6 +3,7 @@ set(APP_COMMON_SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/board.c ${CMAKE_CURRENT_SOURCE_DIR}/eabi_compat.c ${CMAKE_CURRENT_SOURCE_DIR}/payloads/init_dram_bin.c + ${CMAKE_CURRENT_SOURCE_DIR}/head.c ) add_subdirectory(hello_world) diff --git a/board/longanpi-4b/head.c b/board/longanpi-4b/head.c new file mode 100644 index 00000000..05d101a7 --- /dev/null +++ b/board/longanpi-4b/head.c @@ -0,0 +1,40 @@ +#include +#include +#include +#include + +typedef struct boot_file_head { + uint32_t jump_instruction; /* one intruction jumping to real code */ + uint8_t magic[8]; /* ="eGON.BT0" */ + uint32_t check_sum; /* generated by PC */ + uint32_t *length; /* generated by LD */ + uint32_t pub_head_size; /* the size of boot_file_head_t */ + uint8_t pub_head_vsn[4]; /* the version of boot_file_head_t */ + uint32_t *ret_addr; /* the return value */ + uint32_t *run_addr; /* run addr */ + uint32_t boot_cpu; /* eGON version */ + uint8_t platform[8]; /* platform information */ +} boot_file_head_t; + +#define BROM_FILE_HEAD_SIZE_OFFSET (((sizeof(boot_file_head_t) + sizeof(int)) / sizeof(int) + 1)) +#define JUMP_INSTRUCTION (BROM_FILE_HEAD_SIZE_OFFSET | 0xEA000000) + +#define BOOT0_MAGIC "eGON.BT0" +#define STAMP_VALUE (0x12345678) +#define BOOT_PUB_HEAD_VERSION "3000" + +extern uint32_t __spl_size[]; +extern uint32_t __code_start_address[]; + +const __attribute__((section(".boot0_head"))) boot_file_head_t boot_head = { + .jump_instruction = JUMP_INSTRUCTION, + .magic = BOOT0_MAGIC, + .check_sum = STAMP_VALUE, + .length = __spl_size, + .pub_head_size = sizeof(boot_file_head_t), + .pub_head_vsn = BOOT_PUB_HEAD_VERSION, + .ret_addr = __code_start_address, + .run_addr = __code_start_address, + .boot_cpu = 0, + .platform = {0, 0, '3', '.', '0', '.', '0', 0}, +}; \ No newline at end of file diff --git a/board/longanpi-4b/start.S b/board/longanpi-4b/start.S index fd5bfc1e..adf8ef5d 100644 --- a/board/longanpi-4b/start.S +++ b/board/longanpi-4b/start.S @@ -70,22 +70,10 @@ .text _start: - /* Boot head information for BROM */ - .long 0xea000016 - .byte 'e', 'G', 'O', 'N', '.', 'B', 'T', '0' - .long 0x12345678 /* checksum */ - .long __spl_size /* spl size */ - .long 0x30 /* boot header size */ - .long 0x30303033 /* boot header version */ - .long 0x00044000 /* return value */ - .long 0x00044000 /* run address */ - .long 0x0 /* eGON version */ - .byte 0x00, 0x00, 0x00, 0x00 /* platform information - 8byte */ - .byte 0x34, 0x2e, 0x30, 0x00 - + b reset + .align 5 _vector: - b reset ldr pc, _undefined_instruction ldr pc, _software_interrupt ldr pc, _prefetch_abort diff --git a/board/lt527x/CMakeLists.txt b/board/lt527x/CMakeLists.txt index 15d4697a..6365ab52 100644 --- a/board/lt527x/CMakeLists.txt +++ b/board/lt527x/CMakeLists.txt @@ -3,6 +3,7 @@ set(APP_COMMON_SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/board.c ${CMAKE_CURRENT_SOURCE_DIR}/eabi_compat.c ${CMAKE_CURRENT_SOURCE_DIR}/payloads/init_dram_bin.c + ${CMAKE_CURRENT_SOURCE_DIR}/head.c ) add_subdirectory(hello_world) diff --git a/board/lt527x/head.c b/board/lt527x/head.c new file mode 100644 index 00000000..05d101a7 --- /dev/null +++ b/board/lt527x/head.c @@ -0,0 +1,40 @@ +#include +#include +#include +#include + +typedef struct boot_file_head { + uint32_t jump_instruction; /* one intruction jumping to real code */ + uint8_t magic[8]; /* ="eGON.BT0" */ + uint32_t check_sum; /* generated by PC */ + uint32_t *length; /* generated by LD */ + uint32_t pub_head_size; /* the size of boot_file_head_t */ + uint8_t pub_head_vsn[4]; /* the version of boot_file_head_t */ + uint32_t *ret_addr; /* the return value */ + uint32_t *run_addr; /* run addr */ + uint32_t boot_cpu; /* eGON version */ + uint8_t platform[8]; /* platform information */ +} boot_file_head_t; + +#define BROM_FILE_HEAD_SIZE_OFFSET (((sizeof(boot_file_head_t) + sizeof(int)) / sizeof(int) + 1)) +#define JUMP_INSTRUCTION (BROM_FILE_HEAD_SIZE_OFFSET | 0xEA000000) + +#define BOOT0_MAGIC "eGON.BT0" +#define STAMP_VALUE (0x12345678) +#define BOOT_PUB_HEAD_VERSION "3000" + +extern uint32_t __spl_size[]; +extern uint32_t __code_start_address[]; + +const __attribute__((section(".boot0_head"))) boot_file_head_t boot_head = { + .jump_instruction = JUMP_INSTRUCTION, + .magic = BOOT0_MAGIC, + .check_sum = STAMP_VALUE, + .length = __spl_size, + .pub_head_size = sizeof(boot_file_head_t), + .pub_head_vsn = BOOT_PUB_HEAD_VERSION, + .ret_addr = __code_start_address, + .run_addr = __code_start_address, + .boot_cpu = 0, + .platform = {0, 0, '3', '.', '0', '.', '0', 0}, +}; \ No newline at end of file diff --git a/board/lt527x/start.S b/board/lt527x/start.S index fd5bfc1e..598f0a8a 100644 --- a/board/lt527x/start.S +++ b/board/lt527x/start.S @@ -70,19 +70,8 @@ .text _start: - /* Boot head information for BROM */ - .long 0xea000016 - .byte 'e', 'G', 'O', 'N', '.', 'B', 'T', '0' - .long 0x12345678 /* checksum */ - .long __spl_size /* spl size */ - .long 0x30 /* boot header size */ - .long 0x30303033 /* boot header version */ - .long 0x00044000 /* return value */ - .long 0x00044000 /* run address */ - .long 0x0 /* eGON version */ - .byte 0x00, 0x00, 0x00, 0x00 /* platform information - 8byte */ - .byte 0x34, 0x2e, 0x30, 0x00 - + b reset + .align 5 _vector: b reset diff --git a/board/project-yosemite/CMakeLists.txt b/board/project-yosemite/CMakeLists.txt index d589023a..cdffeffb 100644 --- a/board/project-yosemite/CMakeLists.txt +++ b/board/project-yosemite/CMakeLists.txt @@ -2,6 +2,7 @@ set(APP_COMMON_SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/start.S ${CMAKE_CURRENT_SOURCE_DIR}/board.c ${CMAKE_CURRENT_SOURCE_DIR}/eabi_compat.c + ${CMAKE_CURRENT_SOURCE_DIR}/head.c ) add_subdirectory(hello_world) diff --git a/board/project-yosemite/head.c b/board/project-yosemite/head.c new file mode 100644 index 00000000..05d101a7 --- /dev/null +++ b/board/project-yosemite/head.c @@ -0,0 +1,40 @@ +#include +#include +#include +#include + +typedef struct boot_file_head { + uint32_t jump_instruction; /* one intruction jumping to real code */ + uint8_t magic[8]; /* ="eGON.BT0" */ + uint32_t check_sum; /* generated by PC */ + uint32_t *length; /* generated by LD */ + uint32_t pub_head_size; /* the size of boot_file_head_t */ + uint8_t pub_head_vsn[4]; /* the version of boot_file_head_t */ + uint32_t *ret_addr; /* the return value */ + uint32_t *run_addr; /* run addr */ + uint32_t boot_cpu; /* eGON version */ + uint8_t platform[8]; /* platform information */ +} boot_file_head_t; + +#define BROM_FILE_HEAD_SIZE_OFFSET (((sizeof(boot_file_head_t) + sizeof(int)) / sizeof(int) + 1)) +#define JUMP_INSTRUCTION (BROM_FILE_HEAD_SIZE_OFFSET | 0xEA000000) + +#define BOOT0_MAGIC "eGON.BT0" +#define STAMP_VALUE (0x12345678) +#define BOOT_PUB_HEAD_VERSION "3000" + +extern uint32_t __spl_size[]; +extern uint32_t __code_start_address[]; + +const __attribute__((section(".boot0_head"))) boot_file_head_t boot_head = { + .jump_instruction = JUMP_INSTRUCTION, + .magic = BOOT0_MAGIC, + .check_sum = STAMP_VALUE, + .length = __spl_size, + .pub_head_size = sizeof(boot_file_head_t), + .pub_head_vsn = BOOT_PUB_HEAD_VERSION, + .ret_addr = __code_start_address, + .run_addr = __code_start_address, + .boot_cpu = 0, + .platform = {0, 0, '3', '.', '0', '.', '0', 0}, +}; \ No newline at end of file diff --git a/board/project-yosemite/start.S b/board/project-yosemite/start.S index 6b32a13f..045e9c97 100644 --- a/board/project-yosemite/start.S +++ b/board/project-yosemite/start.S @@ -68,22 +68,10 @@ .text _start: - /* Boot head information for BROM */ - .long 0xea000016 - .byte 'e', 'G', 'O', 'N', '.', 'B', 'T', '0' - .long 0x12345678 /* checksum */ - .long __spl_size /* spl size */ - .long 0x30 /* boot header size */ - .long 0x30303033 /* boot header version */ - .long 0x00020000 /* return value */ - .long 0x00028000 /* run address */ - .long 0x0 /* eGON version */ - .byte 0x00, 0x00, 0x00, 0x00 /* platform information - 8byte */ - .byte 0x34, 0x2e, 0x30, 0x00 - + b reset + .align 5 _vector: - b reset ldr pc, _undefined_instruction ldr pc, _software_interrupt ldr pc, _prefetch_abort diff --git a/board/tinyvision/CMakeLists.txt b/board/tinyvision/CMakeLists.txt index 91c622c6..bfa6594d 100644 --- a/board/tinyvision/CMakeLists.txt +++ b/board/tinyvision/CMakeLists.txt @@ -2,6 +2,7 @@ set(APP_COMMON_SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/start.S ${CMAKE_CURRENT_SOURCE_DIR}/board.c ${CMAKE_CURRENT_SOURCE_DIR}/eabi_compat.c + ${CMAKE_CURRENT_SOURCE_DIR}/head.c ) add_subdirectory(hello_world) diff --git a/board/tinyvision/head.c b/board/tinyvision/head.c new file mode 100644 index 00000000..05d101a7 --- /dev/null +++ b/board/tinyvision/head.c @@ -0,0 +1,40 @@ +#include +#include +#include +#include + +typedef struct boot_file_head { + uint32_t jump_instruction; /* one intruction jumping to real code */ + uint8_t magic[8]; /* ="eGON.BT0" */ + uint32_t check_sum; /* generated by PC */ + uint32_t *length; /* generated by LD */ + uint32_t pub_head_size; /* the size of boot_file_head_t */ + uint8_t pub_head_vsn[4]; /* the version of boot_file_head_t */ + uint32_t *ret_addr; /* the return value */ + uint32_t *run_addr; /* run addr */ + uint32_t boot_cpu; /* eGON version */ + uint8_t platform[8]; /* platform information */ +} boot_file_head_t; + +#define BROM_FILE_HEAD_SIZE_OFFSET (((sizeof(boot_file_head_t) + sizeof(int)) / sizeof(int) + 1)) +#define JUMP_INSTRUCTION (BROM_FILE_HEAD_SIZE_OFFSET | 0xEA000000) + +#define BOOT0_MAGIC "eGON.BT0" +#define STAMP_VALUE (0x12345678) +#define BOOT_PUB_HEAD_VERSION "3000" + +extern uint32_t __spl_size[]; +extern uint32_t __code_start_address[]; + +const __attribute__((section(".boot0_head"))) boot_file_head_t boot_head = { + .jump_instruction = JUMP_INSTRUCTION, + .magic = BOOT0_MAGIC, + .check_sum = STAMP_VALUE, + .length = __spl_size, + .pub_head_size = sizeof(boot_file_head_t), + .pub_head_vsn = BOOT_PUB_HEAD_VERSION, + .ret_addr = __code_start_address, + .run_addr = __code_start_address, + .boot_cpu = 0, + .platform = {0, 0, '3', '.', '0', '.', '0', 0}, +}; \ No newline at end of file diff --git a/board/tinyvision/start.S b/board/tinyvision/start.S index 22e56936..045e9c97 100644 --- a/board/tinyvision/start.S +++ b/board/tinyvision/start.S @@ -68,23 +68,10 @@ .text _start: - /* Boot head information for BROM */ - .long 0xea00000e - .byte 'e', 'G', 'O', 'N', '.', 'B', 'T', '0' - .long 0x12345678 /* checksum */ - .long __spl_size /* spl size */ - .long 0x30 /* boot header size */ - .long 0x30303033 /* boot header version */ - .long 0x00020000 /* return value */ - .long 0x00028000 /* run address */ - .long 0x0 /* eGON version */ - .byte 0x00, 0x00, 0x00, 0x00 /* platform information - 8byte */ - .byte 0x34, 0x2e, 0x30, 0x00 - .long 0, 0, 0, 0 /* reserve */ - + b reset + .align 5 _vector: - b reset ldr pc, _undefined_instruction ldr pc, _software_interrupt ldr pc, _prefetch_abort diff --git a/board/yuzukilizard/CMakeLists.txt b/board/yuzukilizard/CMakeLists.txt index d589023a..cdffeffb 100644 --- a/board/yuzukilizard/CMakeLists.txt +++ b/board/yuzukilizard/CMakeLists.txt @@ -2,6 +2,7 @@ set(APP_COMMON_SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/start.S ${CMAKE_CURRENT_SOURCE_DIR}/board.c ${CMAKE_CURRENT_SOURCE_DIR}/eabi_compat.c + ${CMAKE_CURRENT_SOURCE_DIR}/head.c ) add_subdirectory(hello_world) diff --git a/board/yuzukilizard/head.c b/board/yuzukilizard/head.c new file mode 100644 index 00000000..05d101a7 --- /dev/null +++ b/board/yuzukilizard/head.c @@ -0,0 +1,40 @@ +#include +#include +#include +#include + +typedef struct boot_file_head { + uint32_t jump_instruction; /* one intruction jumping to real code */ + uint8_t magic[8]; /* ="eGON.BT0" */ + uint32_t check_sum; /* generated by PC */ + uint32_t *length; /* generated by LD */ + uint32_t pub_head_size; /* the size of boot_file_head_t */ + uint8_t pub_head_vsn[4]; /* the version of boot_file_head_t */ + uint32_t *ret_addr; /* the return value */ + uint32_t *run_addr; /* run addr */ + uint32_t boot_cpu; /* eGON version */ + uint8_t platform[8]; /* platform information */ +} boot_file_head_t; + +#define BROM_FILE_HEAD_SIZE_OFFSET (((sizeof(boot_file_head_t) + sizeof(int)) / sizeof(int) + 1)) +#define JUMP_INSTRUCTION (BROM_FILE_HEAD_SIZE_OFFSET | 0xEA000000) + +#define BOOT0_MAGIC "eGON.BT0" +#define STAMP_VALUE (0x12345678) +#define BOOT_PUB_HEAD_VERSION "3000" + +extern uint32_t __spl_size[]; +extern uint32_t __code_start_address[]; + +const __attribute__((section(".boot0_head"))) boot_file_head_t boot_head = { + .jump_instruction = JUMP_INSTRUCTION, + .magic = BOOT0_MAGIC, + .check_sum = STAMP_VALUE, + .length = __spl_size, + .pub_head_size = sizeof(boot_file_head_t), + .pub_head_vsn = BOOT_PUB_HEAD_VERSION, + .ret_addr = __code_start_address, + .run_addr = __code_start_address, + .boot_cpu = 0, + .platform = {0, 0, '3', '.', '0', '.', '0', 0}, +}; \ No newline at end of file diff --git a/board/yuzukilizard/start.S b/board/yuzukilizard/start.S index 22e56936..045e9c97 100644 --- a/board/yuzukilizard/start.S +++ b/board/yuzukilizard/start.S @@ -68,23 +68,10 @@ .text _start: - /* Boot head information for BROM */ - .long 0xea00000e - .byte 'e', 'G', 'O', 'N', '.', 'B', 'T', '0' - .long 0x12345678 /* checksum */ - .long __spl_size /* spl size */ - .long 0x30 /* boot header size */ - .long 0x30303033 /* boot header version */ - .long 0x00020000 /* return value */ - .long 0x00028000 /* run address */ - .long 0x0 /* eGON version */ - .byte 0x00, 0x00, 0x00, 0x00 /* platform information - 8byte */ - .byte 0x34, 0x2e, 0x30, 0x00 - .long 0, 0, 0, 0 /* reserve */ - + b reset + .align 5 _vector: - b reset ldr pc, _undefined_instruction ldr pc, _software_interrupt ldr pc, _prefetch_abort diff --git a/cmake/board/longanpi-3h.cmake b/cmake/board/longanpi-3h.cmake index 807fb3d6..f303398d 100644 --- a/cmake/board/longanpi-3h.cmake +++ b/cmake/board/longanpi-3h.cmake @@ -17,7 +17,7 @@ set(CONFIG_USE_DRAM_PAYLOAD_FILE_PATH "${CMAKE_SOURCE_DIR}/board/longanpi-3h/pay set(CONFIG_USE_DRAM_PAYLOAD_SECTION "init_dram_bin") # Set the cross-compile toolchain -set(CROSS_COMPILE "arm-linux-gnueabi-") +set(CROSS_COMPILE "arm-none-eabi-") set(CROSS_COMPILE ${CROSS_COMPILE} CACHE STRING "CROSS_COMPILE Toolchain") # Set the C and C++ compilers diff --git a/docs/README.md b/docs/README.md index 7b79d121..f16a0832 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,10 +1,10 @@ -# SyterKit +# SyterKit Intro ![SyterKit LOGO_Thin](https://github.com/YuzukiHD/SyterKit/assets/12003087/e6135860-1a6a-4cb4-b0f6-71af8eca1509) SyterKit is a bare-metal framework designed for Allwinner platform. SyterKit utilizes CMake as its build system and supports various applications and peripheral drivers. Additionally, SyterKit also has bootloader functionality, which enables it to replace U-Boot for fast booting (standard Linux 6.7 mainline boot time of 1.02s, significantly faster than traditional U-Boot's 3s boot time). -## Support list +# Support list | Board | Manufacturer | Platform | Spec | Details | Config | | ------------------------------------------------------------ | ------------ | -------- | --------------------------------- | ---------------------------------------------- | ----------------------- | @@ -12,6 +12,7 @@ SyterKit is a bare-metal framework designed for Allwinner platform. SyterKit uti | [TinyVision](https://github.com/YuzukiHD/TinyVision) | YuzukiHD | V851se | Cortex A7 | [board/tinyvision](board/tinyvision) | `tinyvision.cmake` | | 100ask-t113s3 | 100ask | T113-S3 | Dual-Core Cortex A7 | [board/100ask-t113s3](board/100ask-t113s3) | `100ask-t113s3.cmake` | | 100ask-t113i | 100ask | T113-I | Dual-Core Cortex A7 + C906 RISC-V | [board/100ask-t113i](board/100ask-t113i) | `100ask-t113i.cmake` | +| 100ask-d1-h | 100ask | D1-H | C906 RISC-V | [board/100ask-d1-h](board/100ask-d1-h) | `100ask-d1-h.cmake` | | dongshanpi-aict | 100ask | V853 | Cortex A7 | [board/dongshanpi-aict](board/dongshanpi-aict) | `dongshanpi-aict.cmake` | | project-yosemite | YuzukiHD | V853 | Cortex A7 | [board/project-yosemite](board/project-yosemite) | `project-yosemite.cmake` | | 100ask ROS | 100ask | R818 | Quad-Core Cortex A53 | [board/100ask-ros](board/100ask-ros) | `100ask-ros.cmake` | @@ -20,9 +21,9 @@ SyterKit is a bare-metal framework designed for Allwinner platform. SyterKit uti | [LT527X](https://www.myir.cn/shows/134/70.html) | myir-tech | T527 | Octa-Core Cortex A55 | [board/lt527x](board/lt527x) | `lt527x.cmake` | | BingPi-M1 | BingPi | V3s | Cortex A7 | [board/bingpi-m1](board/bingpi-m1) | `bingpi-m1.cmake` | -## Getting Started +# Getting Started -### Building SyterKit From Scratch +## Building SyterKit From Scratch Building SyterKit is a straightforward process that only requires setting up the environment for compilation on a Linux operating system. The software packages required by SyterKit include: @@ -64,7 +65,7 @@ The SyterKit project will compile two versions: firmware ending with `.elf` is f - For SD Card, You need to flash the `xxx_card.bin` - For SPI NAND/SPI NOR, You need to flash the `xxx_spi.bin` -### Creating TF Card Boot Firmware +## Creating TF Card Boot Firmware After build the firmware, you can flash it into the TF card. For the V851s platform, you can write it to either an 8K offset or a 128K offset. Generally, if the TF card uses MBR format, write it with an 8K offset. If it uses GPT format, write it with a 128K offset. Assuming `/dev/sdb` is the target TF card, you can use the following command to write it with an 8K offset: @@ -78,7 +79,7 @@ If it is a GPT partition table, you need to write it with a 128K offset: sudo dd if=syter_boot_bin_card.bin of=/dev/sdb bs=1024 seek=128 ``` -#### Creating the Firmware for SPI NAND +### Creating the Firmware for SPI NAND For SPI NAND, we need to create the firmware for SPI NAND by writing SyterKit to the corresponding positions: @@ -101,7 +102,7 @@ Use the xfel tool to flash the created firmware into SPI NAND: xfel spinand write 0x0 spi.img ``` -#### Creating the Firmware for SPI NOR +### Creating the Firmware for SPI NOR For SPI NOR, we need to create the firmware for SPI NOR by writing SyterKit to the corresponding positions: @@ -123,3 +124,236 @@ Use the xfel tool to flash the created firmware into SPI NOR: ```shell xfel spinor write 0x0 spi.img ``` + +# Development + +## How Hell the device boot up + +The device boot as noted over several places, BROM is the first step in booting and is baked into chip itself. Moving from the BROM, Allwinner boots something called boot0 from a storage device such as TF Card, SPI NAND, SPI NOR and so on. The magicvalue for the AllWinner bootloader in various places is 'eGON' and thus the bootloader shall be known as such. The chip will read the valided code from storage device to SRAM and execute the code in SRAM, the load lenth and start address in SRAM are defined in `boot_file_head`. + +### Boot Head + +#### boot_file_head + +The define of `boot_file_head` used to detect as follow: + +```c +typedef struct boot_file_head { + uint32_t jump_instruction; /* one intruction jumping to real code */ + uint8_t magic[8]; /* ="eGON.BT0" */ + uint32_t check_sum; /* generated by PC */ + uint32_t *length; /* generated by LD */ + uint32_t pub_head_size; /* the size of boot_file_head_t */ + uint8_t pub_head_vsn[4]; /* the version of boot_file_head_t */ + uint32_t *ret_addr; /* the return value */ + uint32_t *run_addr; /* run addr */ + uint32_t boot_cpu; /* eGON version */ + uint8_t platform[8]; /* platform information */ +} boot_file_head_t; +``` + +#### disassemble of boot_file_head + +If you disassemble a compiled SyterKit binary, you will find that the head of the program is not the startup code but a startup header. This startup header is used by BROM to identify the size and length of the code that needs to be started and to verify it. + +Here is a disassembly part of helloworld_bin, we focous on the boot_file_head part: + +```asm +helloworld_bin: file format elf32-littlearm +Disassembly of section .text: + +00044000 : + 44000: ea00000e b 44040 <_start> # jump_instruction, jump to the actrucl code 0x44040 + 44004: 4e4f4765 # magic 'e' 'G' 'O' 'N' + 44008: 3054422e # magic '.' 'B' 'T' '0' + 4400c: 12345678 # check sum, need reset after padding, now use 0x12345678 to hold the place + 44010: 0000c0c8 # length of the code + 44014: 00000030 # the size of boot_file_head_t + 44018: 30303033 # the version of boot_file_head_t + 4401c: 00044000 # the return value, not used in SyterKit, set same as start address + 44020: 00044000 # start address + 44024: 00000000 # eGON version, set to 0x0 + 44028: 2e330000 # platform 0 0 '3' '.' + 4402c: 00302e30 # platform '0' '.' '0' 0 + ... + +00044040 <_start>: + 44040: ea000014 b 44098 # the actrucl start code + 44044: e320f000 nop {0} + 44048: e320f000 nop {0} + 4404c: e320f000 nop {0} + 44050: e320f000 nop {0} + 44054: e320f000 nop {0} + 44058: e320f000 nop {0} + 4405c: e320f000 nop {0} + ... + ... + ... +``` + +From the above, it is known that the first instruction at the program entry point is a jump instruction, which skips the boot_head to execute the actual startup code. BROM then performs verification of SyterKit by reading boot_head and retrieves the corresponding code to the corresponding address. + +### eGON.BT0 + +In SyterKit supported platform, The BROM will seek the `eGON.BT0` magic from device storage. + +#### MMC Device + +For the MMC Device, Such as TF Card, SD NAND, eMMC, UFS, the mapping as follows: + +``` ++--------+----------+------------------------------+ +| 0K--8K | 8K----END | ++--------+----------+------------------------------+ +| MBR | SyterKit | Other Code | ++--------+----------+------------------------------+ +``` + +But for the GPT partition table, Due to 8K can't fit the GPT partition table and backup table, the chip support to check the header in 128K + +``` ++----------+-----------------------------------------+ +| 0K--128K | 128K----END | ++----------+-----------------------------------------+ +| GPT | SyterKit | Other Code | ++----------+----------+------------------------------+ +``` + +The 8KB offset is dictated by the BROM, it will check for a valid eGON header at this location. if no valid eGON signature is found at 8KB, BROM can also check the header from sector 256 (128KB) of an SD card or eMMC. + +#### MTD Device + +For the MTD Device, Such as SPI NAND, SPI NOR, the mapping as follows: + +``` ++--------------------------------------------------+ +| 0K------END | ++-------------------+------------------------------+ +| SyterKit | Other Code | ++-------------------+------------------------------+ +``` + +MTD Device is sample, check a valid eGON header and weeeeeee it run! + +#### RAW Device + +SyterKit does not Support NFTL Raw NAND. + +#### About the jump_instruction for ARM + +The jump_instruction field stores a jump instruction: (B BACK_OF_boot_file_head_address). When this jump instruction is executed, the program will jump to the first instruction after the boot_file_head. + +The B instruction encoding in ARM instructions is as follows: + +``` ++--------+---------+------------------------------+ +| 31--28 | 27--24 | 23--0 | ++--------+---------+------------------------------+ +| cond | 1 0 1 0 | signed_immed_24 | ++--------+---------+------------------------------+ +``` + +The "ARM Architecture Reference Manual" explains this instruction as follows: + +``` +Syntax: +B{} + Is the condition under which the instruction is executed. If the + is omitted, the AL (always, its code is 0b1110) is used. + + Specifies the address to branch to. The branch target address is + calculated by: + 1. Sign-extending the 24-bit signed (two's complement) immediate + to 32 bits. + 2. Shifting the result left two bits. + 3. Adding to the contents of the PC, which contains the address + of the branch instruction plus 8. +``` + +Based on this explanation, the highest 8 bits of the instruction encoding are: 0b11101010, and the lower 24 bits are generated dynamically based on the size of boot_file_head. Therefore, the assembly process of the instruction is as follows: + +```c +((((((sizeof(boot_file_head_t) + sizeof(int)) / sizeof(int)) + 1)) & 0x00FFFFFF) | 0xEA000000) + +((sizeof(boot_file_head_t) + sizeof(int)) / sizeof(int)) -> Obtain the number of "words" occupied by the file header +(((sizeof(boot_file_head_t) + sizeof(int)) / sizeof(int)) + 1) -> Set the offset to the real start code +(((((sizeof(boot_file_head_t) + sizeof(int)) / sizeof(int)) + 1)) & 0x00FFFFFF) -> Obtain the signed-immed-24 +((((((sizeof(boot_file_head_t) + sizeof(int)) / sizeof(int)) + 1)) & 0x00FFFFFF) | 0xEA000000) -> Assemble into a B instruction +``` + +#### About the jump_instruction for RISC-V + +The jump_instruction field stores a jump instruction: (B BACK_OF_boot_file_head). When this jump instruction is executed, the program will jump to the first instruction after the boot_file_head. + +The B instruction encoding in ARM instructions is as follows: + +```c +#define BROM_FILE_HEAD_SIZE (sizeof(boot_file_head_t) & 0x00FFFFF) +#define BROM_FILE_HEAD_BIT_10_1 ((BROM_FILE_HEAD_SIZE & 0x7FE) >> 1) +#define BROM_FILE_HEAD_BIT_11 ((BROM_FILE_HEAD_SIZE & 0x800) >> 11) +#define BROM_FILE_HEAD_BIT_19_12 ((BROM_FILE_HEAD_SIZE & 0xFF000) >> 12) +#define BROM_FILE_HEAD_BIT_20 ((BROM_FILE_HEAD_SIZE & 0x100000) >> 20) + +#define BROM_FILE_HEAD_SIZE_OFFSET ((BROM_FILE_HEAD_BIT_20 << 31) | \ + (BROM_FILE_HEAD_BIT_10_1 << 21) | \ + (BROM_FILE_HEAD_BIT_11 << 20) | \ + (BROM_FILE_HEAD_BIT_19_12 << 12)) + +#define JUMP_INSTRUCTION (BROM_FILE_HEAD_SIZE_OFFSET | 0x6f) +``` + +This code appears to be a series of preprocessor macro definitions that manipulate the value of `BROM_FILE_HEAD_SIZE` to derive different bit positions and create a final constant `JUMP_INSTRUCTION`. + +Unconditional Jumps + +> The jump and link (JAL) instruction uses the J-type format, where the J-immediate encodes a signed offset in multiples of 2 bytes. The offset is sign-extended and added to the pc to form the jump target address. Jumps can therefore target a ±1 MiB range. JAL stores the address of the instruction following the jump (pc+4) into register rd. The standard software calling convention uses x1 as the return address register and x5 as an alternate link register. + +Plain unconditional jumps (assembler pseudo-op J) are encoded as a JAL with rd=x0. we use it here. + +The Plain unconditional jumps instruction in the RV (RISC-V) instruction set is a type of instruction that allows for unconditional branching in the program flow. It is represented by the assembler pseudo-op J. This instruction is used to unconditionally change the program's control flow and jump to a specified target address. + +The encoding of the J instruction in the RV instruction set is as follows: +``` ++------------------------------------------------+ +| imm[20] | imm[10:1] | imm[11] | ++------------------------------------------------+ +| jump_offset[19:12] | rd (destination) | ++------------------------------------------------+ +| opcode (6 bits) | imm[19:12] | rd | ++------------------------------------------------+ +``` + +The J instruction takes a 20-bit signed immediate value and a target register (rd) as operands, where the target register stores the return address after the jump. The calculation of the target address for the jump is as follows: + +1. Sign-extend the 20-bit immediate value to 32 bits. +2. Left-shift the immediate value by one bit (multiply by 2) to align it with the instruction boundary. The RV instruction set has a fixed instruction length of 4 bytes (32 bits), so the target address needs to be left-shifted by 1 bit for alignment. +3. Clear the lower bits of the PC register (current instruction address + 4) to align it with the instruction boundary. +4. Add the aligned PC address and the left-shifted immediate value to obtain the final jump target address. + +Therefore, the J instruction in the RV instruction set is used for implementing unconditional jumps, allowing the program flow to be redirected to a specified target address, thereby altering the program's execution path. + +Here's a brief description of each macro: +1. `BROM_FILE_HEAD_SIZE`: Calculates the size of `boot0_file_head_t` and masks it with `0x00FFFFF`. +2. `BROM_FILE_HEAD_BIT_10_1`: Extracts specific bits from `BROM_FILE_HEAD_SIZE` and shifts them. +3. `BROM_FILE_HEAD_BIT_11`: Extracts a specific bit from `BROM_FILE_HEAD_SIZE`. +4. `BROM_FILE_HEAD_BIT_19_12`: Extracts specific bits from `BROM_FILE_HEAD_SIZE` and shifts them. +5. `BROM_FILE_HEAD_BIT_20`: Extracts a specific bit from `BROM_FILE_HEAD_SIZE`. +6. `BROM_FILE_HEAD_SIZE_OFFSET`: Combines the extracted bits from previous macros to form a final offset value. +7. `JUMP_INSTRUCTION`: Creates a jump instruction using the calculated `BROM_FILE_HEAD_SIZE_OFFSET` and a constant value `0x6f` means `j #offset` which is `jal x0 #offset` in RV asm. + +#### About the check_sum and length + +In the block device, need to padding the binary file, and that will need to reset the checksum and length, we provide a tool `mksunxi.c` to adjusting bootloader files by correcting header information and ensuring correct formatting. + +Specific operations include: +1. Reading command-line arguments, such as the bootloader file name and padding size. +2. Opening the bootloader file and obtaining its size. +3. Ensuring that the file size is greater than the size of the bootloader header. +4. Allocating memory and reading the contents of the bootloader file into memory. +5. Calculating the length of the bootloader and aligning it based on the padding size. +6. Computing the checksum and updating the checksum field in the header information. +7. Writing the corrected bootloader back to the file. +8. Displaying information about the corrected bootloader header and the bootloader size. + +You can find this tool in `tools/mksunxi.c` + diff --git a/link/arm32/link.ld b/link/arm32/link.ld index 314b53f1..0bee783e 100644 --- a/link/arm32/link.ld +++ b/link/arm32/link.ld @@ -16,20 +16,29 @@ STACK_SIZE = 0x1000; /* 4KB */ /* Section Definitions */ SECTIONS { - + . = ALIGN(4); .text : { - . = ALIGN(4); PROVIDE(__spl_start = .); + KEEP(*(.boot0_head)) *(.text .text.*) PROVIDE(__ddr_bin_start = .); KEEP(*(.init_dram_bin)) PROVIDE(__ddr_bin_end = .); KEEP(*(.note.gnu.build-id)) - . = ALIGN(4); } > ram - . = ALIGN(4); + . = ALIGN(16); + .rodata : + { + *(.rodata) + } > ram + + . = ALIGN(16); + .data : + { + *(.data) + } > ram .ARM.exidx : { __exidx_start = .; @@ -39,6 +48,7 @@ SECTIONS PROVIDE(__spl_end = .); PROVIDE(__spl_size = __spl_end - __spl_start); + PROVIDE(__code_start_address = @ARCH_START_ADDRESS@); /* .bss section which is used for uninitialized data */ .bss (NOLOAD) : diff --git a/link/riscv64/link.ld b/link/riscv64/link.ld index c792edf4..02a056d4 100644 --- a/link/riscv64/link.ld +++ b/link/riscv64/link.ld @@ -16,12 +16,12 @@ STACK_SIZE = 0x1000; /* 4KB */ /* Section Definitions */ SECTIONS { - .text : { . = ALIGN(4); PROVIDE(__image_start = .); PROVIDE(__spl_start = .); + KEEP(*(.boot0_head)) *(.text .text.*) PROVIDE(__ddr_bin_start = .); KEEP(*(.init_dram_bin)) @@ -40,6 +40,7 @@ SECTIONS PROVIDE(__spl_end = .); PROVIDE(__spl_size = __spl_end - __spl_start); + PROVIDE(__code_start_address = @ARCH_START_ADDRESS@); /* .bss section which is used for uninitialized data */ .bss (NOLOAD) : diff --git a/src/drivers/sun8iw20/sys-clk.c b/src/drivers/sun8iw20/sys-clk.c index f343d175..bd344c3f 100644 --- a/src/drivers/sun8iw20/sys-clk.c +++ b/src/drivers/sun8iw20/sys-clk.c @@ -31,11 +31,11 @@ void set_pll_cpux_axi(void) { write32(CCU_BASE + CCU_PLL_CPU_CTRL_REG, val); sdelay(5); - /* Set clk to 1008mhz (default) or CONFIG_CPU_FREQ */ + /* Set clk to 1200 MHz */ /* PLL_CPUX = 24 MHz*N/P */ val = read32(CCU_BASE + CCU_PLL_CPU_CTRL_REG); val &= ~((0x3 << 16) | (0xff << 8) | (0x3 << 0)); - val |= (41 << 8); + val |= (50 << 8); write32(CCU_BASE + CCU_PLL_CPU_CTRL_REG, val); /* Lock enable */ @@ -165,7 +165,7 @@ void sunxi_clk_init(void) { set_apb(); set_dma(); set_mbus(); - set_module(CCU_BASE + CCU_PLL_PERI0_CTRL_REG); + //set_module(CCU_BASE + CCU_PLL_PERI0_CTRL_REG); set_module(CCU_BASE + CCU_PLL_VIDEO0_CTRL_REG); set_module(CCU_BASE + CCU_PLL_VIDEO1_CTRL_REG); set_module(CCU_BASE + CCU_PLL_VE_CTRL); diff --git a/src/drivers/sun8iw20/sys-rproc.c b/src/drivers/sun8iw20/sys-rproc.c index ed41d467..1ff556ce 100644 --- a/src/drivers/sun8iw20/sys-rproc.c +++ b/src/drivers/sun8iw20/sys-rproc.c @@ -73,6 +73,15 @@ void sunxi_hifi4_clock_init(uint32_t addr) { reg_val = readl(CCU_BASE + CCU_DSP_BGR_REG); reg_val |= (1 << CCU_BIT_DSP0_RST); writel(reg_val, CCU_BASE + CCU_DSP_BGR_REG); + +/* + reg_val = readl(CCU_BASE + CCU_DSP_CLK_REG); + printk(LOG_LEVEL_INFO, "CCU_DSP_CLK_REG = %x\n", reg_val); + reg_val = readl(CCU_BASE + CCU_DSP_BGR_REG); + printk(LOG_LEVEL_INFO, "CCU_DSP_BGR_REG = %x\n", reg_val); + reg_val = readl(DSP0_CFG_BASE + DSP_CTRL_REG0); + printk(LOG_LEVEL_INFO, "DSP_CTRL_REG0 = %x\n", reg_val); +*/ } void sunxi_hifi4_start(void) { @@ -134,7 +143,7 @@ void sunxi_c906_clock_reset(void) { } void dump_c906_clock(void) { - uint32_t reg_val, pll_perf, factor_m, factor_n, pll_riscv; + uint32_t reg_val, pll_perf, factor_m, factor_n, pll_riscv, pll_dsp; uint32_t plln, pllm; uint8_t p0, p1; @@ -161,4 +170,5 @@ void dump_c906_clock(void) { printk(LOG_LEVEL_INFO, "CLK: RISC-V PLL FREQ=%uMHz\n", pll_riscv); printk(LOG_LEVEL_INFO, "CLK: RISC-V AXI FREQ=%uMHz\n", pll_riscv / factor_n); + printk(LOG_LEVEL_INFO, "CLK: PERI1X = %uMHz\n", sunxi_clk_get_peri1x_rate() / (1000 * 1000)); } \ No newline at end of file