diff options
author | Max Filippov <jcmvbkbc@gmail.com> | 2017-01-03 17:57:51 -0800 |
---|---|---|
committer | Max Filippov <jcmvbkbc@gmail.com> | 2019-11-26 11:33:38 -0800 |
commit | 7af710d988775aadf440222ecbe0c10eecf3eb54 (patch) | |
tree | f499a51c705441d0aa2019ef88f13e8598627b92 /arch/xtensa/kernel | |
parent | 76743c0e0915af6ae1d960c14e8c1dcb3e238f23 (diff) | |
download | linux-7af710d988775aadf440222ecbe0c10eecf3eb54.tar.bz2 |
xtensa: add XIP kernel support
XIP (eXecute In Place) kernel image is the image that can be run
directly from ROM, using RAM only for writable data.
XIP xtensa kernel differs from regular xtensa kernel in the following
ways:
- it has exception/IRQ vectors merged into text section. No vectors
relocation takes place at kernel startup.
- .data/.bss location must be specified in the kernel configuration,
its content is copied there in the _startup function.
- .init.text is merged with the rest of text and is executed from ROM.
- when MMU is used the virtual address where the kernel will be mapped
must be specified in the kernel configuration. It may be in the KSEG
or in the KIO, __pa macro is adjusted to be able to handle both.
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
Diffstat (limited to 'arch/xtensa/kernel')
-rw-r--r-- | arch/xtensa/kernel/head.S | 7 | ||||
-rw-r--r-- | arch/xtensa/kernel/setup.c | 7 | ||||
-rw-r--r-- | arch/xtensa/kernel/vmlinux.lds.S | 52 |
3 files changed, 64 insertions, 2 deletions
diff --git a/arch/xtensa/kernel/head.S b/arch/xtensa/kernel/head.S index 2cec13a457d7..e0c1fac0910f 100644 --- a/arch/xtensa/kernel/head.S +++ b/arch/xtensa/kernel/head.S @@ -260,6 +260,13 @@ ENTRY(_startup) ___invalidate_icache_all a2 a3 isync +#ifdef CONFIG_XIP_KERNEL + /* Setup bootstrap CPU stack in XIP kernel */ + + movi a1, start_info + l32i a1, a1, 0 +#endif + movi a6, 0 xsr a6, excsave1 diff --git a/arch/xtensa/kernel/setup.c b/arch/xtensa/kernel/setup.c index e0e1e1892b86..0f93b67c7a5a 100644 --- a/arch/xtensa/kernel/setup.c +++ b/arch/xtensa/kernel/setup.c @@ -308,6 +308,10 @@ extern char _Level6InterruptVector_text_end; extern char _SecondaryResetVector_text_start; extern char _SecondaryResetVector_text_end; #endif +#ifdef CONFIG_XIP_KERNEL +extern char _xip_start[]; +extern char _xip_end[]; +#endif static inline int __init_memblock mem_reserve(unsigned long start, unsigned long end) @@ -339,6 +343,9 @@ void __init setup_arch(char **cmdline_p) #endif mem_reserve(__pa(_stext), __pa(_end)); +#ifdef CONFIG_XIP_KERNEL + mem_reserve(__pa(_xip_start), __pa(_xip_end)); +#endif #ifdef CONFIG_VECTORS_OFFSET mem_reserve(__pa(&_WindowVectors_text_start), diff --git a/arch/xtensa/kernel/vmlinux.lds.S b/arch/xtensa/kernel/vmlinux.lds.S index 943f10639a93..01e3112cdb27 100644 --- a/arch/xtensa/kernel/vmlinux.lds.S +++ b/arch/xtensa/kernel/vmlinux.lds.S @@ -134,6 +134,9 @@ SECTIONS NOTES /* Data section */ +#ifdef CONFIG_XIP_KERNEL + INIT_TEXT_SECTION(PAGE_SIZE) +#else _sdata = .; RW_DATA_SECTION(XCHAL_ICACHE_LINESIZE, PAGE_SIZE, THREAD_SIZE) _edata = .; @@ -147,6 +150,11 @@ SECTIONS .init.data : { INIT_DATA + } +#endif + + .init.rodata : + { . = ALIGN(0x4); __tagtable_begin = .; *(.taglist) @@ -187,12 +195,16 @@ SECTIONS RELOCATE_ENTRY(_DebugInterruptVector_text, .DebugInterruptVector.text); #endif +#ifdef CONFIG_XIP_KERNEL + RELOCATE_ENTRY(_xip_data, .data); + RELOCATE_ENTRY(_xip_init_data, .init.data); +#else #if defined(CONFIG_SMP) RELOCATE_ENTRY(_SecondaryResetVector_text, .SecondaryResetVector.text); #endif +#endif - __boot_reloc_table_end = ABSOLUTE(.) ; INIT_SETUP(XCHAL_ICACHE_LINESIZE) @@ -278,7 +290,7 @@ SECTIONS . = (LOADADDR( .DoubleExceptionVector.text ) + SIZEOF( .DoubleExceptionVector.text ) + 3) & ~ 3; #endif -#if defined(CONFIG_SMP) +#if !defined(CONFIG_XIP_KERNEL) && defined(CONFIG_SMP) SECTION_VECTOR (_SecondaryResetVector_text, .SecondaryResetVector.text, @@ -291,12 +303,48 @@ SECTIONS . = ALIGN(PAGE_SIZE); +#ifndef CONFIG_XIP_KERNEL __init_end = .; BSS_SECTION(0, 8192, 0) +#endif _end = .; +#ifdef CONFIG_XIP_KERNEL + . = CONFIG_XIP_DATA_ADDR; + + _xip_start = .; + +#undef LOAD_OFFSET +#define LOAD_OFFSET \ + (CONFIG_XIP_DATA_ADDR - (LOADADDR(.dummy) + SIZEOF(.dummy) + 3) & ~ 3) + + _xip_data_start = .; + _sdata = .; + RW_DATA_SECTION(XCHAL_ICACHE_LINESIZE, PAGE_SIZE, THREAD_SIZE) + _edata = .; + _xip_data_end = .; + + /* Initialization data: */ + + STRUCT_ALIGN(); + + _xip_init_data_start = .; + __init_begin = .; + .init.data : + { + INIT_DATA + } + _xip_init_data_end = .; + __init_end = .; + BSS_SECTION(0, 8192, 0) + + _xip_end = .; + +#undef LOAD_OFFSET +#endif + DWARF_DEBUG .xt.prop 0 : { KEEP(*(.xt.prop .xt.prop.* .gnu.linkonce.prop.*)) } |