ARM: 8518/1: Use correct symbols for XIP_KERNEL
For an XIP build, _etext does not represent the end of the binary image that needs to stay mapped into the MODULES_VADDR area. Years ago, data came before text in the memory map. However, now that the order is text/init/data, an XIP_KERNEL needs to map up to the data location in order to keep from cutting off parts of the kernel that are needed. We only map up to the beginning of data because data has already been copied, so there's no reason to keep it around anymore. A new symbol is created to make it clear what it is we are referring to. This fixes the bug where you might lose the end of your kernel area after page table setup is complete. Signed-off-by: Chris Brandt <chris.brandt@renesas.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
This commit is contained in:
Родитель
31b96cae5c
Коммит
02afa9a87b
|
@ -23,7 +23,6 @@ generic-y += preempt.h
|
||||||
generic-y += resource.h
|
generic-y += resource.h
|
||||||
generic-y += rwsem.h
|
generic-y += rwsem.h
|
||||||
generic-y += seccomp.h
|
generic-y += seccomp.h
|
||||||
generic-y += sections.h
|
|
||||||
generic-y += segment.h
|
generic-y += segment.h
|
||||||
generic-y += sembuf.h
|
generic-y += sembuf.h
|
||||||
generic-y += serial.h
|
generic-y += serial.h
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
#ifndef _ASM_ARM_SECTIONS_H
|
||||||
|
#define _ASM_ARM_SECTIONS_H
|
||||||
|
|
||||||
|
#include <asm-generic/sections.h>
|
||||||
|
|
||||||
|
extern char _exiprom[];
|
||||||
|
|
||||||
|
#endif /* _ASM_ARM_SECTIONS_H */
|
|
@ -34,7 +34,7 @@
|
||||||
* recompiling the whole kernel when CONFIG_XIP_KERNEL is turned on/off.
|
* recompiling the whole kernel when CONFIG_XIP_KERNEL is turned on/off.
|
||||||
*/
|
*/
|
||||||
#undef MODULES_VADDR
|
#undef MODULES_VADDR
|
||||||
#define MODULES_VADDR (((unsigned long)_etext + ~PMD_MASK) & PMD_MASK)
|
#define MODULES_VADDR (((unsigned long)_exiprom + ~PMD_MASK) & PMD_MASK)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_MMU
|
#ifdef CONFIG_MMU
|
||||||
|
|
|
@ -85,6 +85,7 @@ SECTIONS
|
||||||
}
|
}
|
||||||
|
|
||||||
. = XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR);
|
. = XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR);
|
||||||
|
_xiprom = .; /* XIP ROM area to be mapped */
|
||||||
|
|
||||||
.head.text : {
|
.head.text : {
|
||||||
_text = .;
|
_text = .;
|
||||||
|
@ -210,6 +211,7 @@ SECTIONS
|
||||||
PERCPU_SECTION(L1_CACHE_BYTES)
|
PERCPU_SECTION(L1_CACHE_BYTES)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
_exiprom = .; /* End of XIP ROM area */
|
||||||
__data_loc = ALIGN(4); /* location in binary */
|
__data_loc = ALIGN(4); /* location in binary */
|
||||||
. = PAGE_OFFSET + TEXT_OFFSET;
|
. = PAGE_OFFSET + TEXT_OFFSET;
|
||||||
|
|
||||||
|
|
|
@ -1253,7 +1253,7 @@ static inline void prepare_page_table(void)
|
||||||
|
|
||||||
#ifdef CONFIG_XIP_KERNEL
|
#ifdef CONFIG_XIP_KERNEL
|
||||||
/* The XIP kernel is mapped in the module area -- skip over it */
|
/* The XIP kernel is mapped in the module area -- skip over it */
|
||||||
addr = ((unsigned long)_etext + PMD_SIZE - 1) & PMD_MASK;
|
addr = ((unsigned long)_exiprom + PMD_SIZE - 1) & PMD_MASK;
|
||||||
#endif
|
#endif
|
||||||
for ( ; addr < PAGE_OFFSET; addr += PMD_SIZE)
|
for ( ; addr < PAGE_OFFSET; addr += PMD_SIZE)
|
||||||
pmd_clear(pmd_off_k(addr));
|
pmd_clear(pmd_off_k(addr));
|
||||||
|
@ -1335,7 +1335,7 @@ static void __init devicemaps_init(const struct machine_desc *mdesc)
|
||||||
#ifdef CONFIG_XIP_KERNEL
|
#ifdef CONFIG_XIP_KERNEL
|
||||||
map.pfn = __phys_to_pfn(CONFIG_XIP_PHYS_ADDR & SECTION_MASK);
|
map.pfn = __phys_to_pfn(CONFIG_XIP_PHYS_ADDR & SECTION_MASK);
|
||||||
map.virtual = MODULES_VADDR;
|
map.virtual = MODULES_VADDR;
|
||||||
map.length = ((unsigned long)_etext - map.virtual + ~SECTION_MASK) & SECTION_MASK;
|
map.length = ((unsigned long)_exiprom - map.virtual + ~SECTION_MASK) & SECTION_MASK;
|
||||||
map.type = MT_ROM;
|
map.type = MT_ROM;
|
||||||
create_mapping(&map);
|
create_mapping(&map);
|
||||||
#endif
|
#endif
|
||||||
|
@ -1426,7 +1426,11 @@ static void __init kmap_init(void)
|
||||||
static void __init map_lowmem(void)
|
static void __init map_lowmem(void)
|
||||||
{
|
{
|
||||||
struct memblock_region *reg;
|
struct memblock_region *reg;
|
||||||
|
#ifdef CONFIG_XIP_KERNEL
|
||||||
|
phys_addr_t kernel_x_start = round_down(__pa(_sdata), SECTION_SIZE);
|
||||||
|
#else
|
||||||
phys_addr_t kernel_x_start = round_down(__pa(_stext), SECTION_SIZE);
|
phys_addr_t kernel_x_start = round_down(__pa(_stext), SECTION_SIZE);
|
||||||
|
#endif
|
||||||
phys_addr_t kernel_x_end = round_up(__pa(__init_end), SECTION_SIZE);
|
phys_addr_t kernel_x_end = round_up(__pa(__init_end), SECTION_SIZE);
|
||||||
|
|
||||||
/* Map all the lowmem memory banks. */
|
/* Map all the lowmem memory banks. */
|
||||||
|
|
Загрузка…
Ссылка в новой задаче