* [PATCH 0/3] Support BE8 kernel modules relocation @ 2011-01-17 8:42 Stanley.Miao 2011-01-17 8:42 ` [PATCH 1/3] Support BE8 mode " Stanley.Miao ` (2 more replies) 0 siblings, 3 replies; 19+ messages in thread From: Stanley.Miao @ 2011-01-17 8:42 UTC (permalink / raw) To: linux-arm-kernel The first patch is to solve the BE8 kernel modules relocation problems. The second patch is to support BE8 kernel on a little-endian machine. The third patch is to add some debug macros to help the developer to location the boot problems. In order to test the first patch, I am sure some people will need the other two patches, so I send them together. Stanley. ^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 1/3] Support BE8 mode kernel modules relocation 2011-01-17 8:42 [PATCH 0/3] Support BE8 kernel modules relocation Stanley.Miao @ 2011-01-17 8:42 ` Stanley.Miao 2011-01-17 8:52 ` Russell King - ARM Linux 2011-01-17 9:56 ` Catalin Marinas 2011-01-17 8:42 ` [PATCH 2/3] support ARM BE8 mode on a little endian machine Stanley.Miao 2011-01-17 8:42 ` [PATCH 3/3] Add ARM kernel debug macros for locating the boot problems quickly Stanley.Miao 2 siblings, 2 replies; 19+ messages in thread From: Stanley.Miao @ 2011-01-17 8:42 UTC (permalink / raw) To: linux-arm-kernel The code section in BE8 kernel modules is in little-endian while data section is in big-endian. When reading code from memory in the relocation procedure, these instructions are read according to big-endian, so they need to be inverted before writing to memory and after reading from memory. Signed-off-by: Stanley.Miao <stanley.miao@windriver.com> --- arch/arm/Makefile | 1 + arch/arm/include/asm/io.h | 12 ++++++++++ arch/arm/kernel/module.c | 51 ++++++++++++++++++++++++-------------------- 3 files changed, 41 insertions(+), 23 deletions(-) diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 3eec793..03e7761 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -13,6 +13,7 @@ LDFLAGS_vmlinux :=-p --no-undefined -X ifeq ($(CONFIG_CPU_ENDIAN_BE8),y) LDFLAGS_vmlinux += --be8 +LDFLAGS_MODULE += --be8 endif OBJCOPYFLAGS :=-O binary -R .note -R .note.gnu.build-id -R .comment -S diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h index 815efa2..2f088c5 100644 --- a/arch/arm/include/asm/io.h +++ b/arch/arm/include/asm/io.h @@ -233,6 +233,18 @@ extern void _memset_io(volatile void __iomem *, int, size_t); #endif /* __mem_pci */ +#ifdef CONFIG_CPU_ENDIAN_BE8 +#define read_instr32(c) __swab32(*(u32 *)c) +#define read_instr16(c) __swab16(*(u16 *)c) +#define write_instr32(v,a) (*(u32 *)(a) = __swab32((__force __u32)(v))) +#define write_instr16(v,a) (*(u16 *)(a) = __swab16((__force __u16)(v))) +#else +#define read_instr32(c) (*(u32 *)c) +#define read_instr16(c) (*(u16 *)c) +#define write_instr32(v,a) (*(u32 *)(a) = (v)) +#define write_instr16(v,a) (*(u16 *)(a) = (v)) +#endif + /* * ioremap and friends. * diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c index d9bd786..9c58a0d 100644 --- a/arch/arm/kernel/module.c +++ b/arch/arm/kernel/module.c @@ -14,6 +14,7 @@ #include <linux/moduleloader.h> #include <linux/kernel.h> #include <linux/mm.h> +#include <linux/io.h> #include <linux/elf.h> #include <linux/vmalloc.h> #include <linux/fs.h> @@ -148,7 +149,7 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex, case R_ARM_PC24: case R_ARM_CALL: case R_ARM_JUMP24: - offset = (*(u32 *)loc & 0x00ffffff) << 2; + offset = (read_instr32(loc) & 0x00ffffff) << 2; if (offset & 0x02000000) offset -= 0x04000000; @@ -165,8 +166,8 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex, offset >>= 2; - *(u32 *)loc &= 0xff000000; - *(u32 *)loc |= offset & 0x00ffffff; + write_instr32((read_instr32(loc) & 0xff000000) | + (offset & 0x00ffffff), loc); break; case R_ARM_V4BX: @@ -174,9 +175,9 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex, * other bits to re-code instruction as * MOV PC,Rm. */ - *(u32 *)loc &= 0xf000000f; - *(u32 *)loc |= 0x01a0f000; - break; + write_instr32((read_instr32(loc) & 0xf000000f) | + 0x01a0f000, loc); + break; case R_ARM_PREL31: offset = *(u32 *)loc + sym->st_value - loc; @@ -185,7 +186,7 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex, case R_ARM_MOVW_ABS_NC: case R_ARM_MOVT_ABS: - offset = *(u32 *)loc; + offset = read_instr32(loc); offset = ((offset & 0xf0000) >> 4) | (offset & 0xfff); offset = (offset ^ 0x8000) - 0x8000; @@ -193,16 +194,16 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex, if (ELF32_R_TYPE(rel->r_info) == R_ARM_MOVT_ABS) offset >>= 16; - *(u32 *)loc &= 0xfff0f000; - *(u32 *)loc |= ((offset & 0xf000) << 4) | - (offset & 0x0fff); + write_instr32((read_instr32(loc) & 0xfff0f000) | + ((offset & 0xf000) << 4) | + (offset & 0x0fff), loc); break; #ifdef CONFIG_THUMB2_KERNEL case R_ARM_THM_CALL: case R_ARM_THM_JUMP24: - upper = *(u16 *)loc; - lower = *(u16 *)(loc + 2); + upper = read_instr16(loc); + lower = read_instr16(loc + 2); /* * 25 bit signed address range (Thumb-2 BL and B.W @@ -242,17 +243,19 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex, sign = (offset >> 24) & 1; j1 = sign ^ (~(offset >> 23) & 1); j2 = sign ^ (~(offset >> 22) & 1); - *(u16 *)loc = (u16)((upper & 0xf800) | (sign << 10) | - ((offset >> 12) & 0x03ff)); - *(u16 *)(loc + 2) = (u16)((lower & 0xd000) | - (j1 << 13) | (j2 << 11) | - ((offset >> 1) & 0x07ff)); + write_instr16((u16)((upper & 0xf800) | (sign << 10) | + ((offset >> 12) & 0x03ff)), + loc); + write_instr16((u16)((lower & 0xd000) | + (j1 << 13) | (j2 << 11) | + ((offset >> 1) & 0x07ff)), + loc + 2); break; case R_ARM_THM_MOVW_ABS_NC: case R_ARM_THM_MOVT_ABS: - upper = *(u16 *)loc; - lower = *(u16 *)(loc + 2); + upper = read_instr16(loc); + lower = read_instr16(loc + 2); /* * MOVT/MOVW instructions encoding in Thumb-2: @@ -273,12 +276,14 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex, if (ELF32_R_TYPE(rel->r_info) == R_ARM_THM_MOVT_ABS) offset >>= 16; - *(u16 *)loc = (u16)((upper & 0xfbf0) | + write_instr16((u16)((upper & 0xfbf0) | ((offset & 0xf000) >> 12) | - ((offset & 0x0800) >> 1)); - *(u16 *)(loc + 2) = (u16)((lower & 0x8f00) | + ((offset & 0x0800) >> 1)), + doc); + write_instr16((u16)((lower & 0x8f00) | ((offset & 0x0700) << 4) | - (offset & 0x00ff)); + (offset & 0x00ff)), + doc + 2); break; #endif -- 1.5.4.3 ^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 1/3] Support BE8 mode kernel modules relocation 2011-01-17 8:42 ` [PATCH 1/3] Support BE8 mode " Stanley.Miao @ 2011-01-17 8:52 ` Russell King - ARM Linux 2011-01-17 9:56 ` Catalin Marinas 1 sibling, 0 replies; 19+ messages in thread From: Russell King - ARM Linux @ 2011-01-17 8:52 UTC (permalink / raw) To: linux-arm-kernel On Mon, Jan 17, 2011 at 04:42:07PM +0800, Stanley.Miao wrote: > The code section in BE8 kernel modules is in little-endian while data > section is in big-endian. When reading code from memory in the relocation > procedure, these instructions are read according to big-endian, so they > need to be inverted before writing to memory and after reading from memory. > > Signed-off-by: Stanley.Miao <stanley.miao@windriver.com> > --- > arch/arm/Makefile | 1 + > arch/arm/include/asm/io.h | 12 ++++++++++ > arch/arm/kernel/module.c | 51 ++++++++++++++++++++++++-------------------- > 3 files changed, 41 insertions(+), 23 deletions(-) > > diff --git a/arch/arm/Makefile b/arch/arm/Makefile > index 3eec793..03e7761 100644 > --- a/arch/arm/Makefile > +++ b/arch/arm/Makefile > @@ -13,6 +13,7 @@ > LDFLAGS_vmlinux :=-p --no-undefined -X > ifeq ($(CONFIG_CPU_ENDIAN_BE8),y) > LDFLAGS_vmlinux += --be8 > +LDFLAGS_MODULE += --be8 > endif > > OBJCOPYFLAGS :=-O binary -R .note -R .note.gnu.build-id -R .comment -S > diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h > index 815efa2..2f088c5 100644 > --- a/arch/arm/include/asm/io.h > +++ b/arch/arm/include/asm/io.h > @@ -233,6 +233,18 @@ extern void _memset_io(volatile void __iomem *, int, size_t); > > #endif /* __mem_pci */ > > +#ifdef CONFIG_CPU_ENDIAN_BE8 > +#define read_instr32(c) __swab32(*(u32 *)c) > +#define read_instr16(c) __swab16(*(u16 *)c) > +#define write_instr32(v,a) (*(u32 *)(a) = __swab32((__force __u32)(v))) > +#define write_instr16(v,a) (*(u16 *)(a) = __swab16((__force __u16)(v))) > +#else > +#define read_instr32(c) (*(u32 *)c) > +#define read_instr16(c) (*(u16 *)c) > +#define write_instr32(v,a) (*(u32 *)(a) = (v)) > +#define write_instr16(v,a) (*(u16 *)(a) = (v)) > +#endif > + It makes no sense to put these in asm/io.h ^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 1/3] Support BE8 mode kernel modules relocation 2011-01-17 8:42 ` [PATCH 1/3] Support BE8 mode " Stanley.Miao 2011-01-17 8:52 ` Russell King - ARM Linux @ 2011-01-17 9:56 ` Catalin Marinas 2011-01-18 1:22 ` Stanley.Miao 1 sibling, 1 reply; 19+ messages in thread From: Catalin Marinas @ 2011-01-17 9:56 UTC (permalink / raw) To: linux-arm-kernel On 17 January 2011 08:42, Stanley.Miao <stanley.miao@windriver.com> wrote: > The code section in BE8 kernel modules is in little-endian while data > section is in big-endian. When reading code from memory in the relocation > procedure, these instructions are read according to big-endian, so they > need to be inverted before writing to memory and after reading from memory. [...] > --- a/arch/arm/include/asm/io.h > +++ b/arch/arm/include/asm/io.h > @@ -233,6 +233,18 @@ extern void _memset_io(volatile void __iomem *, int, size_t); > > ?#endif /* __mem_pci */ > > +#ifdef CONFIG_CPU_ENDIAN_BE8 > +#define read_instr32(c) ? ? ? ? ? ? ? ? ? ? ? ?__swab32(*(u32 *)c) > +#define read_instr16(c) ? ? ? ? ? ? ? ? ? ? ? ?__swab16(*(u16 *)c) > +#define write_instr32(v,a) ? ? ? ? ? ? (*(u32 *)(a) = __swab32((__force __u32)(v))) > +#define write_instr16(v,a) ? ? ? ? ? ? (*(u16 *)(a) = __swab16((__force __u16)(v))) > +#else > +#define read_instr32(c) ? ? ? ? ? ? ? ? ? ? ? ?(*(u32 *)c) > +#define read_instr16(c) ? ? ? ? ? ? ? ? ? ? ? ?(*(u16 *)c) > +#define write_instr32(v,a) ? ? ? ? ? ? (*(u32 *)(a) = (v)) > +#define write_instr16(v,a) ? ? ? ? ? ? (*(u16 *)(a) = (v)) > +#endif Can we not use cpu_to_le32 etc in here (and as Russell said, they are not really IO)? -- Catalin ^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 1/3] Support BE8 mode kernel modules relocation 2011-01-17 9:56 ` Catalin Marinas @ 2011-01-18 1:22 ` Stanley.Miao 2011-01-18 15:23 ` Catalin Marinas 0 siblings, 1 reply; 19+ messages in thread From: Stanley.Miao @ 2011-01-18 1:22 UTC (permalink / raw) To: linux-arm-kernel 2011/1/17 Catalin Marinas <catalin.marinas@arm.com>: > On 17 January 2011 08:42, Stanley.Miao <stanley.miao@windriver.com> wrote: >> The code section in BE8 kernel modules is in little-endian while data >> section is in big-endian. When reading code from memory in the relocation >> procedure, these instructions are read according to big-endian, so they >> need to be inverted before writing to memory and after reading from memory. > [...] >> --- a/arch/arm/include/asm/io.h >> +++ b/arch/arm/include/asm/io.h >> @@ -233,6 +233,18 @@ extern void _memset_io(volatile void __iomem *, int, size_t); >> >> ?#endif /* __mem_pci */ >> >> +#ifdef CONFIG_CPU_ENDIAN_BE8 >> +#define read_instr32(c) ? ? ? ? ? ? ? ? ? ? ? ?__swab32(*(u32 *)c) >> +#define read_instr16(c) ? ? ? ? ? ? ? ? ? ? ? ?__swab16(*(u16 *)c) >> +#define write_instr32(v,a) ? ? ? ? ? ? (*(u32 *)(a) = __swab32((__force __u32)(v))) >> +#define write_instr16(v,a) ? ? ? ? ? ? (*(u16 *)(a) = __swab16((__force __u16)(v))) >> +#else >> +#define read_instr32(c) ? ? ? ? ? ? ? ? ? ? ? ?(*(u32 *)c) >> +#define read_instr16(c) ? ? ? ? ? ? ? ? ? ? ? ?(*(u16 *)c) >> +#define write_instr32(v,a) ? ? ? ? ? ? (*(u32 *)(a) = (v)) >> +#define write_instr16(v,a) ? ? ? ? ? ? (*(u16 *)(a) = (v)) >> +#endif > > Can we not use cpu_to_le32 etc in here (and as Russell said, they are > not really IO)? Except moving these definition to arch/arm/kernel/module.c, do I need to do other modifications ? Stanley. > > -- > Catalin > > _______________________________________________ > linux-arm-kernel mailing list > linux-arm-kernel at lists.infradead.org > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel > ^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 1/3] Support BE8 mode kernel modules relocation 2011-01-18 1:22 ` Stanley.Miao @ 2011-01-18 15:23 ` Catalin Marinas 2011-01-19 6:21 ` Stanley.Miao 0 siblings, 1 reply; 19+ messages in thread From: Catalin Marinas @ 2011-01-18 15:23 UTC (permalink / raw) To: linux-arm-kernel On 18 January 2011 01:22, Stanley.Miao <stanleymiao@gmail.com> wrote: > 2011/1/17 Catalin Marinas <catalin.marinas@arm.com>: >> On 17 January 2011 08:42, Stanley.Miao <stanley.miao@windriver.com> wrote: >>> The code section in BE8 kernel modules is in little-endian while data >>> section is in big-endian. When reading code from memory in the relocation >>> procedure, these instructions are read according to big-endian, so they >>> need to be inverted before writing to memory and after reading from memory. >> [...] >>> --- a/arch/arm/include/asm/io.h >>> +++ b/arch/arm/include/asm/io.h >>> @@ -233,6 +233,18 @@ extern void _memset_io(volatile void __iomem *, int, size_t); >>> >>> ?#endif /* __mem_pci */ >>> >>> +#ifdef CONFIG_CPU_ENDIAN_BE8 >>> +#define read_instr32(c) ? ? ? ? ? ? ? ? ? ? ? ?__swab32(*(u32 *)c) >>> +#define read_instr16(c) ? ? ? ? ? ? ? ? ? ? ? ?__swab16(*(u16 *)c) >>> +#define write_instr32(v,a) ? ? ? ? ? ? (*(u32 *)(a) = __swab32((__force __u32)(v))) >>> +#define write_instr16(v,a) ? ? ? ? ? ? (*(u16 *)(a) = __swab16((__force __u16)(v))) >>> +#else >>> +#define read_instr32(c) ? ? ? ? ? ? ? ? ? ? ? ?(*(u32 *)c) >>> +#define read_instr16(c) ? ? ? ? ? ? ? ? ? ? ? ?(*(u16 *)c) >>> +#define write_instr32(v,a) ? ? ? ? ? ? (*(u32 *)(a) = (v)) >>> +#define write_instr16(v,a) ? ? ? ? ? ? (*(u16 *)(a) = (v)) >>> +#endif >> >> Can we not use cpu_to_le32 etc in here (and as Russell said, they are >> not really IO)? > > Except moving these definition to arch/arm/kernel/module.c, do I need > to do other modifications ? Just personal preference (not important), I'd rather have a "u32 instr" variable set by read_instr32() than this kind of functional style (in C code, I'm fine with it otherwise): > + write_instr32((read_instr32(loc) & 0xff000000) | > + (offset & 0x00ffffff), loc); BTW (not related to modules, but since you are looking at this), when we copy the sigreturn_codes to the vectors page in early_trap_init(), do they get there in little endian form (as required by BE8)? -- Catalin ^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 1/3] Support BE8 mode kernel modules relocation 2011-01-18 15:23 ` Catalin Marinas @ 2011-01-19 6:21 ` Stanley.Miao 2011-01-19 17:32 ` Catalin Marinas 0 siblings, 1 reply; 19+ messages in thread From: Stanley.Miao @ 2011-01-19 6:21 UTC (permalink / raw) To: linux-arm-kernel 2011/1/18 Catalin Marinas <catalin.marinas@arm.com>: > On 18 January 2011 01:22, Stanley.Miao <stanleymiao@gmail.com> wrote: >> 2011/1/17 Catalin Marinas <catalin.marinas@arm.com>: >>> On 17 January 2011 08:42, Stanley.Miao <stanley.miao@windriver.com> wrote: >>>> The code section in BE8 kernel modules is in little-endian while data >>>> section is in big-endian. When reading code from memory in the relocation >>>> procedure, these instructions are read according to big-endian, so they >>>> need to be inverted before writing to memory and after reading from memory. >>> [...] >>>> --- a/arch/arm/include/asm/io.h >>>> +++ b/arch/arm/include/asm/io.h >>>> @@ -233,6 +233,18 @@ extern void _memset_io(volatile void __iomem *, int, size_t); >>>> >>>> ?#endif /* __mem_pci */ >>>> >>>> +#ifdef CONFIG_CPU_ENDIAN_BE8 >>>> +#define read_instr32(c) ? ? ? ? ? ? ? ? ? ? ? ?__swab32(*(u32 *)c) >>>> +#define read_instr16(c) ? ? ? ? ? ? ? ? ? ? ? ?__swab16(*(u16 *)c) >>>> +#define write_instr32(v,a) ? ? ? ? ? ? (*(u32 *)(a) = __swab32((__force __u32)(v))) >>>> +#define write_instr16(v,a) ? ? ? ? ? ? (*(u16 *)(a) = __swab16((__force __u16)(v))) >>>> +#else >>>> +#define read_instr32(c) ? ? ? ? ? ? ? ? ? ? ? ?(*(u32 *)c) >>>> +#define read_instr16(c) ? ? ? ? ? ? ? ? ? ? ? ?(*(u16 *)c) >>>> +#define write_instr32(v,a) ? ? ? ? ? ? (*(u32 *)(a) = (v)) >>>> +#define write_instr16(v,a) ? ? ? ? ? ? (*(u16 *)(a) = (v)) >>>> +#endif >>> >>> Can we not use cpu_to_le32 etc in here (and as Russell said, they are >>> not really IO)? >> >> Except moving these definition to arch/arm/kernel/module.c, do I need >> to do other modifications ? > > Just personal preference (not important), I'd rather have a "u32 > instr" variable set by read_instr32() than this kind of functional > style (in C code, I'm fine with it otherwise): upper, lower and offset are used. It looks we don't need another "instr". > >> + ? ? ? ? ? ? ? ? ? ? ? write_instr32((read_instr32(loc) & 0xff000000) | >> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (offset & 0x00ffffff), loc); > > BTW (not related to modules, but since you are looking at this), when > we copy the sigreturn_codes to the vectors page in early_trap_init(), > do they get there in little endian form (as required by BE8)? No, they get there in big endian.They are read as data in the function setup_return(). retcode = KERN_SIGRETURN_CODE + (idx << 2) + thumb; Stanley. > > -- > Catalin > ^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 1/3] Support BE8 mode kernel modules relocation 2011-01-19 6:21 ` Stanley.Miao @ 2011-01-19 17:32 ` Catalin Marinas 2011-01-21 9:39 ` stanley.miao 0 siblings, 1 reply; 19+ messages in thread From: Catalin Marinas @ 2011-01-19 17:32 UTC (permalink / raw) To: linux-arm-kernel On Wed, 2011-01-19 at 06:21 +0000, Stanley.Miao wrote: > 2011/1/18 Catalin Marinas <catalin.marinas@arm.com>: > > BTW (not related to modules, but since you are looking at this), when > > we copy the sigreturn_codes to the vectors page in early_trap_init(), > > do they get there in little endian form (as required by BE8)? > > No, they get there in big endian.They are read as data in the function > setup_return(). > > retcode = KERN_SIGRETURN_CODE + (idx << 2) + thumb; This retcode here is an address in the vectors page which is set to LR when invoking the signal handler. All fine here. But the sigreturn_codes array contains instructions which get copied to the vectors page in the early_trap_init() function. This array has this instructions in big endian format but they should be converted to little endian when copied to the vectors page. -- Catalin ^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 1/3] Support BE8 mode kernel modules relocation 2011-01-19 17:32 ` Catalin Marinas @ 2011-01-21 9:39 ` stanley.miao 0 siblings, 0 replies; 19+ messages in thread From: stanley.miao @ 2011-01-21 9:39 UTC (permalink / raw) To: linux-arm-kernel Catalin Marinas wrote: > On Wed, 2011-01-19 at 06:21 +0000, Stanley.Miao wrote: > >> 2011/1/18 Catalin Marinas <catalin.marinas@arm.com>: >> >>> BTW (not related to modules, but since you are looking at this), when >>> we copy the sigreturn_codes to the vectors page in early_trap_init(), >>> do they get there in little endian form (as required by BE8)? >>> >> No, they get there in big endian.They are read as data in the function >> setup_return(). >> >> retcode = KERN_SIGRETURN_CODE + (idx << 2) + thumb; >> > > This retcode here is an address in the vectors page which is set to LR > when invoking the signal handler. All fine here. > > But the sigreturn_codes array contains instructions which get copied to > the vectors page in the early_trap_init() function. This array has this > instructions in big endian format but they should be converted to little > endian when copied to the vectors page. > > I don't have a board in hand for now. When I get a board, I will test it. Stanley. -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20110121/c05712b2/attachment-0001.html> ^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 2/3] support ARM BE8 mode on a little endian machine 2011-01-17 8:42 [PATCH 0/3] Support BE8 kernel modules relocation Stanley.Miao 2011-01-17 8:42 ` [PATCH 1/3] Support BE8 mode " Stanley.Miao @ 2011-01-17 8:42 ` Stanley.Miao 2011-01-17 10:01 ` Catalin Marinas 2011-01-17 8:42 ` [PATCH 3/3] Add ARM kernel debug macros for locating the boot problems quickly Stanley.Miao 2 siblings, 1 reply; 19+ messages in thread From: Stanley.Miao @ 2011-01-17 8:42 UTC (permalink / raw) To: linux-arm-kernel When BE8 kernel is running on a little endian machine, the kernel endian mode need to be converted at the begining of the startup procedure with the instruction "setend be". Besides, the tags that the bootloader passed to the kernel are in little-endian mode and they need to be inverted. Signed-off-by: Stanley.Miao <stanley.miao@windriver.com> --- arch/arm/boot/compressed/head.S | 3 +++ arch/arm/include/asm/setup.h | 13 +++++++++---- arch/arm/kernel/head-common.S | 6 ++++++ arch/arm/kernel/setup.c | 22 +++++++++++----------- arch/arm/mm/Kconfig | 7 +++++++ 5 files changed, 36 insertions(+), 15 deletions(-) diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S index a00055d..a33075b 100644 --- a/arch/arm/boot/compressed/head.S +++ b/arch/arm/boot/compressed/head.S @@ -131,6 +131,9 @@ start: mov r0, r0 .endr +#ifdef CONFIG_BE8_ON_LE + setend be +#endif b 1f .word 0x016f2818 @ Magic numbers to help the loader .word start @ absolute load/run zImage address diff --git a/arch/arm/include/asm/setup.h b/arch/arm/include/asm/setup.h index f1e5a9b..1504d09 100644 --- a/arch/arm/include/asm/setup.h +++ b/arch/arm/include/asm/setup.h @@ -173,15 +173,20 @@ struct tagtable { int (*parse)(const struct tag *); }; +#ifdef CONFIG_BE8_ON_LE +#define read_tag(a) le32_to_cpu(a) +#else +#define read_tag(a) a +#endif + #define tag_member_present(tag,member) \ ((unsigned long)(&((struct tag *)0L)->member + 1) \ - <= (tag)->hdr.size * 4) - -#define tag_next(t) ((struct tag *)((__u32 *)(t) + (t)->hdr.size)) + <= read_tag((tag)->hdr.size) * 4) +#define tag_next(t) ((struct tag *)((__u32 *)(t) + read_tag((t)->hdr.size))) #define tag_size(type) ((sizeof(struct tag_header) + sizeof(struct type)) >> 2) #define for_each_tag(t,base) \ - for (t = base; t->hdr.size; t = tag_next(t)) + for (t = base; read_tag((t)->hdr.size); t = tag_next(t)) #ifdef __KERNEL__ diff --git a/arch/arm/kernel/head-common.S b/arch/arm/kernel/head-common.S index bbecaac..37cfa88 100644 --- a/arch/arm/kernel/head-common.S +++ b/arch/arm/kernel/head-common.S @@ -118,10 +118,16 @@ __vet_atags: bne 1f ldr r5, [r2, #0] @ is first tag ATAG_CORE? +#ifdef CONFIG_BE8_ON_LE + rev r5, r5 +#endif cmp r5, #ATAG_CORE_SIZE cmpne r5, #ATAG_CORE_SIZE_EMPTY bne 1f ldr r5, [r2, #4] +#ifdef CONFIG_BE8_ON_LE + rev r5, r5 +#endif ldr r6, =ATAG_CORE cmp r5, r6 bne 1f diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index 3cadb46..9098aa5 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -578,10 +578,10 @@ request_standard_resources(struct meminfo *mi, struct machine_desc *mdesc) */ static int __init parse_tag_core(const struct tag *tag) { - if (tag->hdr.size > 2) { - if ((tag->u.core.flags & 1) == 0) + if (read_tag(tag->hdr.size) > 2) { + if ((read_tag(tag->u.core.flags) & 1) == 0) root_mountflags &= ~MS_RDONLY; - ROOT_DEV = old_decode_dev(tag->u.core.rootdev); + ROOT_DEV = old_decode_dev(read_tag(tag->u.core.rootdev)); } return 0; } @@ -590,7 +590,7 @@ __tagtable(ATAG_CORE, parse_tag_core); static int __init parse_tag_mem32(const struct tag *tag) { - return arm_add_memory(tag->u.mem.start, tag->u.mem.size); + return arm_add_memory(read_tag(tag->u.mem.start), read_tag(tag->u.mem.size)); } __tagtable(ATAG_MEM, parse_tag_mem32); @@ -643,7 +643,7 @@ __tagtable(ATAG_SERIAL, parse_tag_serialnr); static int __init parse_tag_revision(const struct tag *tag) { - system_rev = tag->u.revision.rev; + system_rev = read_tag(tag->u.revision.rev); return 0; } @@ -670,7 +670,7 @@ static int __init parse_tag(const struct tag *tag) struct tagtable *t; for (t = &__tagtable_begin; t < &__tagtable_end; t++) - if (tag->hdr.tag == t->tag) { + if ((read_tag(tag->hdr.tag) == t->tag)) { t->parse(tag); break; } @@ -684,9 +684,9 @@ static int __init parse_tag(const struct tag *tag) */ static void __init parse_tags(const struct tag *t) { - for (; t->hdr.size; t = tag_next(t)) + for (; read_tag(t->hdr.size); t = tag_next(t)) if (!parse_tag(t)) - printk(KERN_WARNING + early_printk(KERN_WARNING "Ignoring unrecognised tag 0x%08x\n", t->hdr.tag); } @@ -824,16 +824,16 @@ void __init setup_arch(char **cmdline_p) * If we have the old style parameters, convert them to * a tag list. */ - if (tags->hdr.tag != ATAG_CORE) + if (read_tag(tags->hdr.tag) != ATAG_CORE) convert_to_tag_list(tags); #endif - if (tags->hdr.tag != ATAG_CORE) + if (read_tag(tags->hdr.tag) != ATAG_CORE) tags = (struct tag *)&init_tags; if (mdesc->fixup) mdesc->fixup(mdesc, tags, &from, &meminfo); - if (tags->hdr.tag == ATAG_CORE) { + if (read_tag(tags->hdr.tag) == ATAG_CORE) { if (meminfo.nr_banks != 0) squash_mem_tags(tags); save_atags(tags); diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index c16ae86..eb74e6b 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig @@ -686,6 +686,13 @@ config CPU_ENDIAN_BE32 help Support for the BE-32 (big-endian) mode on pre-ARMv6 processors. +config BE8_ON_LE + bool "Run BE8 kernel on a little endian machine" + depends on CPU_V6 || CPU_V7 + select CPU_BIG_ENDIAN + help + Run BE8 kernel on a little endian machine. + config CPU_HIGH_VECTOR depends on !MMU && CPU_CP15 && !CPU_ARM740T bool "Select the High exception vector" -- 1.5.4.3 ^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 2/3] support ARM BE8 mode on a little endian machine 2011-01-17 8:42 ` [PATCH 2/3] support ARM BE8 mode on a little endian machine Stanley.Miao @ 2011-01-17 10:01 ` Catalin Marinas 2011-01-17 10:23 ` stanley.miao 2011-01-18 1:24 ` Stanley.Miao 0 siblings, 2 replies; 19+ messages in thread From: Catalin Marinas @ 2011-01-17 10:01 UTC (permalink / raw) To: linux-arm-kernel On 17 January 2011 08:42, Stanley.Miao <stanley.miao@windriver.com> wrote: > When BE8 kernel is running on a little endian machine, the kernel endian > mode need to be converted at the begining of the startup procedure with > the instruction "setend be". Can we not let the boot loader do this? It could also prepare the tags as big endian. -- Catalin ^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 2/3] support ARM BE8 mode on a little endian machine 2011-01-17 10:01 ` Catalin Marinas @ 2011-01-17 10:23 ` stanley.miao 2011-01-18 1:24 ` Stanley.Miao 1 sibling, 0 replies; 19+ messages in thread From: stanley.miao @ 2011-01-17 10:23 UTC (permalink / raw) To: linux-arm-kernel Catalin Marinas wrote: > On 17 January 2011 08:42, Stanley.Miao <stanley.miao@windriver.com> wrote: > >> When BE8 kernel is running on a little endian machine, the kernel endian >> mode need to be converted at the begining of the startup procedure with >> the instruction "setend be". >> > > Can we not let the boot loader do this? It could also prepare the tags > as big endian. > > Yes, the bootloader can also do this. However, it is dangerous to modify the bootloader. If the new boot loader can't work, it is difficult to update the bootloader again. So, I choose to modify Linux kernel. Stanley. -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20110117/ce66b171/attachment-0001.html> ^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 2/3] support ARM BE8 mode on a little endian machine 2011-01-17 10:01 ` Catalin Marinas 2011-01-17 10:23 ` stanley.miao @ 2011-01-18 1:24 ` Stanley.Miao 1 sibling, 0 replies; 19+ messages in thread From: Stanley.Miao @ 2011-01-18 1:24 UTC (permalink / raw) To: linux-arm-kernel Yes, the bootloader can also do this. However, it is dangerous to modify the bootloader. If the new boot loader can't work, it is difficult to update the bootloader again. So, I choose to modify Linux kernel. Stanley. 2011/1/17 Catalin Marinas <catalin.marinas@arm.com>: > On 17 January 2011 08:42, Stanley.Miao <stanley.miao@windriver.com> wrote: >> When BE8 kernel is running on a little endian machine, the kernel endian >> mode need to be converted at the begining of the startup procedure with >> the instruction "setend be". > > Can we not let the boot loader do this? It could also prepare the tags > as big endian. > > -- > Catalin > > _______________________________________________ > linux-arm-kernel mailing list > linux-arm-kernel at lists.infradead.org > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel > ^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 3/3] Add ARM kernel debug macros for locating the boot problems quickly 2011-01-17 8:42 [PATCH 0/3] Support BE8 kernel modules relocation Stanley.Miao 2011-01-17 8:42 ` [PATCH 1/3] Support BE8 mode " Stanley.Miao 2011-01-17 8:42 ` [PATCH 2/3] support ARM BE8 mode on a little endian machine Stanley.Miao @ 2011-01-17 8:42 ` Stanley.Miao 2 siblings, 0 replies; 19+ messages in thread From: Stanley.Miao @ 2011-01-17 8:42 UTC (permalink / raw) To: linux-arm-kernel When we are porting Linux to a new board, we ofter encounter the problems that the board can't boot up and there is no any messages output in console. These debug macros can help the developers print registers' value or messages easily and locate the root cause quickly. All these debug macros are under CONFIG_DEBUG_LL. When CONFIG_DEBUG_LL is enabled, the following messages will be printed in the boot procedure. Uncompressing Linux... done, booting the kernel. r13:005454ec stext enter. __lookup_processor_type enter. __lookup_machine_type enter. __vet_atags enter. __create_page_tables enter. __enable_mmu enter. __mmap_switched enter. __lookup_processor_type enter. __lookup_machine_type enter. secondary_startup enter. __lookup_processor_type enter. __enable_mmu enter. __secondary_switched enter. Linux version 2.6.38.rc1 ... Signed-off-by: Stanley.Miao <stanley.miao@windriver.com> --- arch/arm/kernel/debug_macro.S | 88 +++++++++++++++++++++++++++++++++++++++++ arch/arm/kernel/head-common.S | 8 ++++ arch/arm/kernel/head.S | 19 +++++++-- arch/arm/kernel/vmlinux.lds.S | 7 +++ 4 files changed, 118 insertions(+), 4 deletions(-) create mode 100644 arch/arm/kernel/debug_macro.S diff --git a/arch/arm/kernel/debug_macro.S b/arch/arm/kernel/debug_macro.S new file mode 100644 index 0000000..033acf3 --- /dev/null +++ b/arch/arm/kernel/debug_macro.S @@ -0,0 +1,88 @@ +/* + * linux/arch/arm/kernel/debug_macro.S + * + * Copyright (c) 2011 Wind River Systems, Inc. + * Stanley.Miao <stanley.miao@windriver.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 32-bit debugging code + */ + +#ifdef CONFIG_DEBUG_LL + + .macro kputc,val + mov r0, \val + bl printch + .endm + + .macro dbgmsg, str + stmfd sp!, {r0-r3, lr} + adr r0, \str + bl printascii + ldmfd sp!, {r0-r3, lr} + .endm + + .macro read_reg reg, num + stmfd sp!, {r0-r4, lr} + kputc #'r' + mov r4, #\num + cmp r4, #10 + blt 901f + sub r4, r4, #10 + kputc #'1' +901: add r0, r4, #'0' + bl printch + kputc #':' + ldmfd sp, {r0-r4, lr} + mov r0, \reg + bl printhex8 + kputc #'\n' + ldmfd sp!, {r0-r4, lr} + .endm + + .macro PRINT_SCTLR + stmfd sp!, {r0-r4, lr} + kputc #'S' + kputc #'C' + kputc #'T' + kputc #'L' + kputc #'R' + kputc #':' + mrc p15, 0, r0, c1, c0, 0 + bl printhex8 + kputc #'\n' + ldmfd sp!, {r0-r4, lr} + .endm + + .macro PRINT_CPSR + stmfd sp!, {r0-r4, lr} + kputc #'C' + kputc #'P' + kputc #'S' + kputc #'R' + kputc #':' + mrs r0, cpsr + bl printhex8 + kputc #'\n' + ldmfd sp!, {r0-r4, lr} + .endm + +#define DBG_MSG(x) dbgmsg dbg_##x +#define PRINT_REG(x) read_reg r##x, x + +#undef ENDPROC +#define ENDPROC(name) \ + .type name, %function; \ + END(name); \ + dbg_##name:; \ + .ascii #name; \ + .asciz " enter.\n"; \ + .align 2 + +#else +#define DBG_MSG(x) +#define PRINT_REG(x) +#endif diff --git a/arch/arm/kernel/head-common.S b/arch/arm/kernel/head-common.S index 37cfa88..f916bb8 100644 --- a/arch/arm/kernel/head-common.S +++ b/arch/arm/kernel/head-common.S @@ -74,6 +74,7 @@ str_a3: .asciz "\nPlease check your kernel config and/or bootloader.\n" * r5 = mach_info pointer in physical address space */ __lookup_machine_type: + DBG_MSG(__lookup_machine_type) adr r3, __lookup_machine_type_data ldmia r3, {r4, r5, r6} sub r3, r3, r4 @ get offset between virt&phys @@ -114,6 +115,7 @@ __lookup_machine_type_data: * r5, r6 corrupted */ __vet_atags: + DBG_MSG(__vet_atags) tst r2, #0x3 @ aligned? bne 1f @@ -149,6 +151,7 @@ ENDPROC(__vet_atags) */ __INIT __mmap_switched: + DBG_MSG(__mmap_switched) adr r3, __mmap_switched_data ldmia r3!, {r4, r5, r6, r7} @@ -225,6 +228,7 @@ ENDPROC(lookup_processor_type) */ __CPUINIT __lookup_processor_type: + DBG_MSG(__lookup_processor_type) adr r3, __lookup_processor_type_data ldmia r3, {r4 - r6} sub r3, r3, r4 @ get offset between virt&phys @@ -284,3 +288,7 @@ __error: 1: mov r0, r0 b 1b ENDPROC(__error) + + .align + .section ".boot.stack", "aw" +boot_stack: .space 512 diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S index dd6b369..bde50cd 100644 --- a/arch/arm/kernel/head.S +++ b/arch/arm/kernel/head.S @@ -33,6 +33,7 @@ #define KERNEL_RAM_VADDR (PAGE_OFFSET + TEXT_OFFSET) #define KERNEL_RAM_PADDR (PHYS_OFFSET + TEXT_OFFSET) +#include "debug_macro.S" /* * swapper_pg_dir is the virtual address of the initial page table. @@ -82,6 +83,9 @@ ENTRY(stext) setmode PSR_F_BIT | PSR_I_BIT | SVC_MODE, r9 @ ensure svc mode @ and irqs disabled + ldr r13, =(__stack_end - PAGE_OFFSET + PHYS_OFFSET) + PRINT_REG(13) + DBG_MSG(stext) mrc p15, 0, r9, c0, c0 @ get processor id bl __lookup_processor_type @ r5=procinfo r9=cpuid movs r10, r5 @ invalid processor (r5=0)? @@ -102,8 +106,8 @@ ENTRY(stext) * above. On return, the CPU will be ready for the MMU to be * turned on, and r0 will hold the CPU control register value. */ - ldr r13, =__mmap_switched @ address to jump to after - @ mmu has been enabled + ldr r0, =__mmap_switched @ address to jump to after + str r0, [r13, #-4]! @ mmu has been enabled adr lr, BSYM(1f) @ return (PIC) address ARM( add pc, r10, #PROCINFO_INITFUNC ) THUMB( add r12, r10, #PROCINFO_INITFUNC ) @@ -126,6 +130,7 @@ ENDPROC(stext) * r4 = physical page table address */ __create_page_tables: + DBG_MSG(__create_page_tables) pgtbl r4 @ page table address /* @@ -278,6 +283,8 @@ ENTRY(secondary_startup) * as it has already been validated by the primary processor. */ setmode PSR_F_BIT | PSR_I_BIT | SVC_MODE, r9 + ldr r13, =(__stack_end - PAGE_OFFSET + PHYS_OFFSET) + DBG_MSG(secondary_startup) mrc p15, 0, r9, c0, c0 @ get processor id bl __lookup_processor_type movs r10, r5 @ invalid processor? @@ -292,7 +299,7 @@ ENTRY(secondary_startup) sub r4, r4, r5 @ mmu has been enabled ldr r4, [r7, r4] @ get secondary_data.pgdir adr lr, BSYM(__enable_mmu) @ return address - mov r13, r12 @ __secondary_switched address + str r12, [r13, #-4]! @ __secondary_switched address ARM( add pc, r10, #PROCINFO_INITFUNC ) @ initialise processor @ (return control reg) THUMB( add r12, r10, #PROCINFO_INITFUNC ) @@ -303,6 +310,7 @@ ENDPROC(secondary_startup) * r6 = &secondary_data */ ENTRY(__secondary_switched) + DBG_MSG(__secondary_switched) ldr sp, [r7, #4] @ get secondary_data.stack mov fp, #0 b secondary_start_kernel @@ -330,6 +338,7 @@ __secondary_data: * r13 = *virtual* address to jump to upon completion */ __enable_mmu: + DBG_MSG(__enable_mmu) #ifdef CONFIG_ALIGNMENT_TRAP orr r0, r0, #CR_A #else @@ -373,7 +382,9 @@ __turn_mmu_on: mcr p15, 0, r0, c1, c0, 0 @ write control reg mrc p15, 0, r3, c0, c0, 0 @ read id reg mov r3, r3 - mov r3, r13 + sub r13, r13, #PHYS_OFFSET + add r13, r13, #PAGE_OFFSET + ldr r3, [r13], #4 mov pc, r3 __enable_mmu_end: ENDPROC(__turn_mmu_on) diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S index cead889..5030bc0 100644 --- a/arch/arm/kernel/vmlinux.lds.S +++ b/arch/arm/kernel/vmlinux.lds.S @@ -246,6 +246,13 @@ SECTIONS #endif BSS_SECTION(0, 0, 0) + .stack : { + . = ALIGN(4); + __stack_start = .; + *(.boot.stack) + . = ALIGN(4); + __stack_end = .; + } _end = .; STABS_DEBUG -- 1.5.4.3 ^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH V2 0/3] Support BE8 kernel modules relocation @ 2011-01-19 6:44 Stanley.Miao 2011-01-19 6:44 ` [PATCH 1/3] Support BE8 mode " Stanley.Miao 0 siblings, 1 reply; 19+ messages in thread From: Stanley.Miao @ 2011-01-19 6:44 UTC (permalink / raw) To: linux-arm-kernel Changes from V1: 1, move the defintion of read_instr32/write_instr32 from arm/include/asm/io.h to arm/kernel/module.c The first patch is to solve the BE8 kernel modules relocation problems. The second patch is to support BE8 kernel on a little-endian machine. The third patch is to add some debug macros to help the developer to location the boot problems. In order to test the first patch, I am sure some people will need the other two patches, so I send them together. Stanley. ^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 1/3] Support BE8 mode kernel modules relocation 2011-01-19 6:44 [PATCH V2 0/3] Support BE8 kernel modules relocation Stanley.Miao @ 2011-01-19 6:44 ` Stanley.Miao 2011-01-21 9:40 ` Stanley.Miao 2011-01-21 9:44 ` Russell King - ARM Linux 0 siblings, 2 replies; 19+ messages in thread From: Stanley.Miao @ 2011-01-19 6:44 UTC (permalink / raw) To: linux-arm-kernel The code section in BE8 kernel modules is in little-endian while data section is in big-endian. When reading code from memory in the relocation procedure, these instructions are read according to big-endian, so they are needed to be inverted. Signed-off-by: Stanley.Miao <stanley.miao@windriver.com> --- arch/arm/Makefile | 1 + arch/arm/kernel/module.c | 62 +++++++++++++++++++++++++++++----------------- 2 files changed, 40 insertions(+), 23 deletions(-) diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 3eec793..03e7761 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -13,6 +13,7 @@ LDFLAGS_vmlinux :=-p --no-undefined -X ifeq ($(CONFIG_CPU_ENDIAN_BE8),y) LDFLAGS_vmlinux += --be8 +LDFLAGS_MODULE += --be8 endif OBJCOPYFLAGS :=-O binary -R .note -R .note.gnu.build-id -R .comment -S diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c index d9bd786..c5e5bb1 100644 --- a/arch/arm/kernel/module.c +++ b/arch/arm/kernel/module.c @@ -99,6 +99,18 @@ int module_frob_arch_sections(Elf_Ehdr *hdr, return 0; } +#ifdef CONFIG_CPU_ENDIAN_BE8 +#define read_instr32(c) __swab32(*(u32 *)c) +#define read_instr16(c) __swab16(*(u16 *)c) +#define write_instr32(v,a) (*(u32 *)(a) = __swab32((__force __u32)(v))) +#define write_instr16(v,a) (*(u16 *)(a) = __swab16((__force __u16)(v))) +#else +#define read_instr32(c) (*(u32 *)c) +#define read_instr16(c) (*(u16 *)c) +#define write_instr32(v,a) (*(u32 *)(a) = (v)) +#define write_instr16(v,a) (*(u16 *)(a) = (v)) +#endif + int apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex, unsigned int relindex, struct module *module) @@ -148,7 +160,7 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex, case R_ARM_PC24: case R_ARM_CALL: case R_ARM_JUMP24: - offset = (*(u32 *)loc & 0x00ffffff) << 2; + offset = (read_instr32(loc) & 0x00ffffff) << 2; if (offset & 0x02000000) offset -= 0x04000000; @@ -165,8 +177,8 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex, offset >>= 2; - *(u32 *)loc &= 0xff000000; - *(u32 *)loc |= offset & 0x00ffffff; + write_instr32((read_instr32(loc) & 0xff000000) | + (offset & 0x00ffffff), loc); break; case R_ARM_V4BX: @@ -174,9 +186,9 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex, * other bits to re-code instruction as * MOV PC,Rm. */ - *(u32 *)loc &= 0xf000000f; - *(u32 *)loc |= 0x01a0f000; - break; + write_instr32((read_instr32(loc) & 0xf000000f) | + 0x01a0f000, loc); + break; case R_ARM_PREL31: offset = *(u32 *)loc + sym->st_value - loc; @@ -185,7 +197,7 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex, case R_ARM_MOVW_ABS_NC: case R_ARM_MOVT_ABS: - offset = *(u32 *)loc; + offset = read_instr32(loc); offset = ((offset & 0xf0000) >> 4) | (offset & 0xfff); offset = (offset ^ 0x8000) - 0x8000; @@ -193,16 +205,16 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex, if (ELF32_R_TYPE(rel->r_info) == R_ARM_MOVT_ABS) offset >>= 16; - *(u32 *)loc &= 0xfff0f000; - *(u32 *)loc |= ((offset & 0xf000) << 4) | - (offset & 0x0fff); + write_instr32((read_instr32(loc) & 0xfff0f000) | + ((offset & 0xf000) << 4) | + (offset & 0x0fff), loc); break; #ifdef CONFIG_THUMB2_KERNEL case R_ARM_THM_CALL: case R_ARM_THM_JUMP24: - upper = *(u16 *)loc; - lower = *(u16 *)(loc + 2); + upper = read_instr16(loc); + lower = read_instr16(loc + 2); /* * 25 bit signed address range (Thumb-2 BL and B.W @@ -242,17 +254,19 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex, sign = (offset >> 24) & 1; j1 = sign ^ (~(offset >> 23) & 1); j2 = sign ^ (~(offset >> 22) & 1); - *(u16 *)loc = (u16)((upper & 0xf800) | (sign << 10) | - ((offset >> 12) & 0x03ff)); - *(u16 *)(loc + 2) = (u16)((lower & 0xd000) | - (j1 << 13) | (j2 << 11) | - ((offset >> 1) & 0x07ff)); + write_instr16((u16)((upper & 0xf800) | (sign << 10) | + ((offset >> 12) & 0x03ff)), + loc); + write_instr16((u16)((lower & 0xd000) | + (j1 << 13) | (j2 << 11) | + ((offset >> 1) & 0x07ff)), + loc + 2); break; case R_ARM_THM_MOVW_ABS_NC: case R_ARM_THM_MOVT_ABS: - upper = *(u16 *)loc; - lower = *(u16 *)(loc + 2); + upper = read_instr16(loc); + lower = read_instr16(loc + 2); /* * MOVT/MOVW instructions encoding in Thumb-2: @@ -273,12 +287,14 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex, if (ELF32_R_TYPE(rel->r_info) == R_ARM_THM_MOVT_ABS) offset >>= 16; - *(u16 *)loc = (u16)((upper & 0xfbf0) | + write_instr16((u16)((upper & 0xfbf0) | ((offset & 0xf000) >> 12) | - ((offset & 0x0800) >> 1)); - *(u16 *)(loc + 2) = (u16)((lower & 0x8f00) | + ((offset & 0x0800) >> 1)), + doc); + write_instr16((u16)((lower & 0x8f00) | ((offset & 0x0700) << 4) | - (offset & 0x00ff)); + (offset & 0x00ff)), + doc + 2); break; #endif -- 1.5.4.3 ^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 1/3] Support BE8 mode kernel modules relocation 2011-01-19 6:44 ` [PATCH 1/3] Support BE8 mode " Stanley.Miao @ 2011-01-21 9:40 ` Stanley.Miao 2011-01-21 9:44 ` Russell King - ARM Linux 1 sibling, 0 replies; 19+ messages in thread From: Stanley.Miao @ 2011-01-21 9:40 UTC (permalink / raw) To: linux-arm-kernel Hi, Russell, It looks no other comments. I uploaded these patches to you patches tracking system. Stanley. 2011/1/19, Stanley.Miao <stanley.miao@windriver.com>: > The code section in BE8 kernel modules is in little-endian while data > section is in big-endian. When reading code from memory in the relocation > procedure, these instructions are read according to big-endian, so they are > needed to be inverted. > > Signed-off-by: Stanley.Miao <stanley.miao@windriver.com> > --- > arch/arm/Makefile | 1 + > arch/arm/kernel/module.c | 62 > +++++++++++++++++++++++++++++----------------- > 2 files changed, 40 insertions(+), 23 deletions(-) > > diff --git a/arch/arm/Makefile b/arch/arm/Makefile > index 3eec793..03e7761 100644 > --- a/arch/arm/Makefile > +++ b/arch/arm/Makefile > @@ -13,6 +13,7 @@ > LDFLAGS_vmlinux :=-p --no-undefined -X > ifeq ($(CONFIG_CPU_ENDIAN_BE8),y) > LDFLAGS_vmlinux += --be8 > +LDFLAGS_MODULE += --be8 > endif > > OBJCOPYFLAGS :=-O binary -R .note -R .note.gnu.build-id -R .comment -S > diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c > index d9bd786..c5e5bb1 100644 > --- a/arch/arm/kernel/module.c > +++ b/arch/arm/kernel/module.c > @@ -99,6 +99,18 @@ int module_frob_arch_sections(Elf_Ehdr *hdr, > return 0; > } > > +#ifdef CONFIG_CPU_ENDIAN_BE8 > +#define read_instr32(c) __swab32(*(u32 *)c) > +#define read_instr16(c) __swab16(*(u16 *)c) > +#define write_instr32(v,a) (*(u32 *)(a) = __swab32((__force __u32)(v))) > +#define write_instr16(v,a) (*(u16 *)(a) = __swab16((__force __u16)(v))) > +#else > +#define read_instr32(c) (*(u32 *)c) > +#define read_instr16(c) (*(u16 *)c) > +#define write_instr32(v,a) (*(u32 *)(a) = (v)) > +#define write_instr16(v,a) (*(u16 *)(a) = (v)) > +#endif > + > int > apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int > symindex, > unsigned int relindex, struct module *module) > @@ -148,7 +160,7 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, > unsigned int symindex, > case R_ARM_PC24: > case R_ARM_CALL: > case R_ARM_JUMP24: > - offset = (*(u32 *)loc & 0x00ffffff) << 2; > + offset = (read_instr32(loc) & 0x00ffffff) << 2; > if (offset & 0x02000000) > offset -= 0x04000000; > > @@ -165,8 +177,8 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, > unsigned int symindex, > > offset >>= 2; > > - *(u32 *)loc &= 0xff000000; > - *(u32 *)loc |= offset & 0x00ffffff; > + write_instr32((read_instr32(loc) & 0xff000000) | > + (offset & 0x00ffffff), loc); > break; > > case R_ARM_V4BX: > @@ -174,9 +186,9 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, > unsigned int symindex, > * other bits to re-code instruction as > * MOV PC,Rm. > */ > - *(u32 *)loc &= 0xf000000f; > - *(u32 *)loc |= 0x01a0f000; > - break; > + write_instr32((read_instr32(loc) & 0xf000000f) | > + 0x01a0f000, loc); > + break; > > case R_ARM_PREL31: > offset = *(u32 *)loc + sym->st_value - loc; > @@ -185,7 +197,7 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, > unsigned int symindex, > > case R_ARM_MOVW_ABS_NC: > case R_ARM_MOVT_ABS: > - offset = *(u32 *)loc; > + offset = read_instr32(loc); > offset = ((offset & 0xf0000) >> 4) | (offset & 0xfff); > offset = (offset ^ 0x8000) - 0x8000; > > @@ -193,16 +205,16 @@ apply_relocate(Elf32_Shdr *sechdrs, const char > *strtab, unsigned int symindex, > if (ELF32_R_TYPE(rel->r_info) == R_ARM_MOVT_ABS) > offset >>= 16; > > - *(u32 *)loc &= 0xfff0f000; > - *(u32 *)loc |= ((offset & 0xf000) << 4) | > - (offset & 0x0fff); > + write_instr32((read_instr32(loc) & 0xfff0f000) | > + ((offset & 0xf000) << 4) | > + (offset & 0x0fff), loc); > break; > > #ifdef CONFIG_THUMB2_KERNEL > case R_ARM_THM_CALL: > case R_ARM_THM_JUMP24: > - upper = *(u16 *)loc; > - lower = *(u16 *)(loc + 2); > + upper = read_instr16(loc); > + lower = read_instr16(loc + 2); > > /* > * 25 bit signed address range (Thumb-2 BL and B.W > @@ -242,17 +254,19 @@ apply_relocate(Elf32_Shdr *sechdrs, const char > *strtab, unsigned int symindex, > sign = (offset >> 24) & 1; > j1 = sign ^ (~(offset >> 23) & 1); > j2 = sign ^ (~(offset >> 22) & 1); > - *(u16 *)loc = (u16)((upper & 0xf800) | (sign << 10) | > - ((offset >> 12) & 0x03ff)); > - *(u16 *)(loc + 2) = (u16)((lower & 0xd000) | > - (j1 << 13) | (j2 << 11) | > - ((offset >> 1) & 0x07ff)); > + write_instr16((u16)((upper & 0xf800) | (sign << 10) | > + ((offset >> 12) & 0x03ff)), > + loc); > + write_instr16((u16)((lower & 0xd000) | > + (j1 << 13) | (j2 << 11) | > + ((offset >> 1) & 0x07ff)), > + loc + 2); > break; > > case R_ARM_THM_MOVW_ABS_NC: > case R_ARM_THM_MOVT_ABS: > - upper = *(u16 *)loc; > - lower = *(u16 *)(loc + 2); > + upper = read_instr16(loc); > + lower = read_instr16(loc + 2); > > /* > * MOVT/MOVW instructions encoding in Thumb-2: > @@ -273,12 +287,14 @@ apply_relocate(Elf32_Shdr *sechdrs, const char > *strtab, unsigned int symindex, > if (ELF32_R_TYPE(rel->r_info) == R_ARM_THM_MOVT_ABS) > offset >>= 16; > > - *(u16 *)loc = (u16)((upper & 0xfbf0) | > + write_instr16((u16)((upper & 0xfbf0) | > ((offset & 0xf000) >> 12) | > - ((offset & 0x0800) >> 1)); > - *(u16 *)(loc + 2) = (u16)((lower & 0x8f00) | > + ((offset & 0x0800) >> 1)), > + doc); > + write_instr16((u16)((lower & 0x8f00) | > ((offset & 0x0700) << 4) | > - (offset & 0x00ff)); > + (offset & 0x00ff)), > + doc + 2); > break; > #endif > > -- > 1.5.4.3 > > > _______________________________________________ > linux-arm-kernel mailing list > linux-arm-kernel at lists.infradead.org > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel > ^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 1/3] Support BE8 mode kernel modules relocation 2011-01-19 6:44 ` [PATCH 1/3] Support BE8 mode " Stanley.Miao 2011-01-21 9:40 ` Stanley.Miao @ 2011-01-21 9:44 ` Russell King - ARM Linux 2011-01-21 10:11 ` stanley.miao 1 sibling, 1 reply; 19+ messages in thread From: Russell King - ARM Linux @ 2011-01-21 9:44 UTC (permalink / raw) To: linux-arm-kernel On Wed, Jan 19, 2011 at 02:44:45PM +0800, Stanley.Miao wrote: > @@ -174,9 +186,9 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex, > * other bits to re-code instruction as > * MOV PC,Rm. > */ > - *(u32 *)loc &= 0xf000000f; > - *(u32 *)loc |= 0x01a0f000; > - break; > + write_instr32((read_instr32(loc) & 0xf000000f) | > + 0x01a0f000, loc); > + break; Indentation error. ^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 1/3] Support BE8 mode kernel modules relocation 2011-01-21 9:44 ` Russell King - ARM Linux @ 2011-01-21 10:11 ` stanley.miao 2011-01-22 17:00 ` Russell King - ARM Linux 0 siblings, 1 reply; 19+ messages in thread From: stanley.miao @ 2011-01-21 10:11 UTC (permalink / raw) To: linux-arm-kernel Russell King - ARM Linux wrote: > On Wed, Jan 19, 2011 at 02:44:45PM +0800, Stanley.Miao wrote: > >> @@ -174,9 +186,9 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex, >> * other bits to re-code instruction as >> * MOV PC,Rm. >> */ >> - *(u32 *)loc &= 0xf000000f; >> - *(u32 *)loc |= 0x01a0f000; >> - break; >> + write_instr32((read_instr32(loc) & 0xf000000f) | >> + 0x01a0f000, loc); >> + break; >> > > Indentation error. > > Actually, The indentation of my code is right, and the original code is wrong. Stanley. -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20110121/aaf41cba/attachment-0001.html> ^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 1/3] Support BE8 mode kernel modules relocation 2011-01-21 10:11 ` stanley.miao @ 2011-01-22 17:00 ` Russell King - ARM Linux 0 siblings, 0 replies; 19+ messages in thread From: Russell King - ARM Linux @ 2011-01-22 17:00 UTC (permalink / raw) To: linux-arm-kernel On Fri, Jan 21, 2011 at 06:11:45PM +0800, stanley.miao wrote: > Russell King - ARM Linux wrote: >> On Wed, Jan 19, 2011 at 02:44:45PM +0800, Stanley.Miao wrote: >> >>> @@ -174,9 +186,9 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex, >>> * other bits to re-code instruction as >>> * MOV PC,Rm. >>> */ >>> - *(u32 *)loc &= 0xf000000f; >>> - *(u32 *)loc |= 0x01a0f000; >>> - break; >>> + write_instr32((read_instr32(loc) & 0xf000000f) | >>> + 0x01a0f000, loc); >>> + break; >>> >> >> Indentation error. >> >> > Actually, The indentation of my code is right, and the original code is > wrong. Yes, you're right. Please precede your patch which a patch which _just_ corrects the formatting of the old code. ^ permalink raw reply [flat|nested] 19+ messages in thread
end of thread, other threads:[~2011-01-22 17:00 UTC | newest] Thread overview: 19+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2011-01-17 8:42 [PATCH 0/3] Support BE8 kernel modules relocation Stanley.Miao 2011-01-17 8:42 ` [PATCH 1/3] Support BE8 mode " Stanley.Miao 2011-01-17 8:52 ` Russell King - ARM Linux 2011-01-17 9:56 ` Catalin Marinas 2011-01-18 1:22 ` Stanley.Miao 2011-01-18 15:23 ` Catalin Marinas 2011-01-19 6:21 ` Stanley.Miao 2011-01-19 17:32 ` Catalin Marinas 2011-01-21 9:39 ` stanley.miao 2011-01-17 8:42 ` [PATCH 2/3] support ARM BE8 mode on a little endian machine Stanley.Miao 2011-01-17 10:01 ` Catalin Marinas 2011-01-17 10:23 ` stanley.miao 2011-01-18 1:24 ` Stanley.Miao 2011-01-17 8:42 ` [PATCH 3/3] Add ARM kernel debug macros for locating the boot problems quickly Stanley.Miao -- strict thread matches above, loose matches on Subject: below -- 2011-01-19 6:44 [PATCH V2 0/3] Support BE8 kernel modules relocation Stanley.Miao 2011-01-19 6:44 ` [PATCH 1/3] Support BE8 mode " Stanley.Miao 2011-01-21 9:40 ` Stanley.Miao 2011-01-21 9:44 ` Russell King - ARM Linux 2011-01-21 10:11 ` stanley.miao 2011-01-22 17:00 ` Russell King - ARM Linux
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).