* AT91: How copy kernel code to SRAM and execute?
@ 2012-02-26 17:37 ARM Linux
2012-02-26 17:50 ` Russell King - ARM Linux
2012-02-26 18:44 ` Jean-Christophe PLAGNIOL-VILLARD
0 siblings, 2 replies; 8+ messages in thread
From: ARM Linux @ 2012-02-26 17:37 UTC (permalink / raw)
To: linux-arm-kernel
I am looking for some examples on how to copy a small piece of kernel code
to internal SRAM and then execute it.
Why?
If you want to restart, you execute the "/sbin/reboot" command
which will eventually call the "arch_reset" function, which in the AT91
case will write to a "user reset" register.
The problem is that the chip may reset in the middle of an SDRAM read
transfer.
The SDRAM will see it's clock stopped and will continue to drive the bus.
When the ROM bootloader tries to access any boot memory (Parallel flash
or NAND flash)
on the parallel bus, there will be a bus conflict between the boot
memory and the SDRAM,
and the bootROM will not properly detect the boot program, and will enter
an In System Programming mode.
This is described in the SAM9G20 datasheet, but is probably valid
for all older generation AT91 devices as well.
The workaround seems to be to turn off the SDRAM and then do the reset.
Obviously you cannot read instructions from SDRAM after it has been
turned off.
One possible workaround is to copy the code to SRAM and then execute.
Looking for some hints on how first copy the code to the internal SRAM
located at 0x300000,
and then jump and execute the code at this address.
Note that when arch_reset is called, the CPU is no longer executing
in its normal state.
It is called from arm_machine_restart in "arch/arm/kernel/process.c"
which has turned off the caches and setup some direct mapping at lower
addresses
--
Best Regards
Ulf Samuelsson
ulf at emagii.com
+46 722 427437
^ permalink raw reply [flat|nested] 8+ messages in thread
* AT91: How copy kernel code to SRAM and execute?
2012-02-26 17:37 AT91: How copy kernel code to SRAM and execute? ARM Linux
@ 2012-02-26 17:50 ` Russell King - ARM Linux
2012-02-26 20:48 ` Ulf Samuelsson
2012-02-26 18:44 ` Jean-Christophe PLAGNIOL-VILLARD
1 sibling, 1 reply; 8+ messages in thread
From: Russell King - ARM Linux @ 2012-02-26 17:50 UTC (permalink / raw)
To: linux-arm-kernel
On Sun, Feb 26, 2012 at 06:37:25PM +0100, ARM Linux wrote:
> I am looking for some examples on how to copy a small piece of kernel code
> to internal SRAM and then execute it.
See fncpy.h
> Note that when arch_reset is called, the CPU is no longer executing
> in its normal state.
> It is called from arm_machine_restart in "arch/arm/kernel/process.c"
> which has turned off the caches and setup some direct mapping at lower
> addresses
You're looking at old kernel code. Stuff has substantially changed in
this area, and CPU caches are no longer turned off if we're going to do
a hardware based reset.
However, that doesn't negate what you're trying to do, and you'll need
to use fncpy() for portability.
The code which you want to copy must be written carefully in assembly
language, and must be written to be relocatable.
^ permalink raw reply [flat|nested] 8+ messages in thread
* AT91: How copy kernel code to SRAM and execute?
2012-02-26 17:37 AT91: How copy kernel code to SRAM and execute? ARM Linux
2012-02-26 17:50 ` Russell King - ARM Linux
@ 2012-02-26 18:44 ` Jean-Christophe PLAGNIOL-VILLARD
2012-02-26 20:52 ` ARM Linux
1 sibling, 1 reply; 8+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2012-02-26 18:44 UTC (permalink / raw)
To: linux-arm-kernel
On 18:37 Sun 26 Feb , ARM Linux wrote:
> I am looking for some examples on how to copy a small piece of kernel code
> to internal SRAM and then execute it.
>
> Why?
> If you want to restart, you execute the "/sbin/reboot" command
> which will eventually call the "arch_reset" function, which in the AT91
> case will write to a "user reset" register.
>
> The problem is that the chip may reset in the middle of an SDRAM
> read transfer.
> The SDRAM will see it's clock stopped and will continue to drive the bus.
>
> When the ROM bootloader tries to access any boot memory (Parallel
> flash or NAND flash)
> on the parallel bus, there will be a bus conflict between the boot
> memory and the SDRAM,
> and the bootROM will not properly detect the boot program, and will enter
> an In System Programming mode.
>
> This is described in the SAM9G20 datasheet, but is probably valid
> for all older generation AT91 devices as well.
>
> The workaround seems to be to turn off the SDRAM and then do the reset.
> Obviously you cannot read instructions from SDRAM after it has been
> turned off.
>
Which version of the kernel do you use?
There is no need to put the code in the sram, you just need to put the
code in cached before shutdown the SDRAM/DDR
Best Regards,
J.
^ permalink raw reply [flat|nested] 8+ messages in thread
* AT91: How copy kernel code to SRAM and execute?
2012-02-26 17:50 ` Russell King - ARM Linux
@ 2012-02-26 20:48 ` Ulf Samuelsson
2012-02-26 21:05 ` Russell King - ARM Linux
0 siblings, 1 reply; 8+ messages in thread
From: Ulf Samuelsson @ 2012-02-26 20:48 UTC (permalink / raw)
To: linux-arm-kernel
On 2012-02-26 18:50, Russell King - ARM Linux wrote:
> On Sun, Feb 26, 2012 at 06:37:25PM +0100, ARM Linux wrote:
>> I am looking for some examples on how to copy a small piece of kernel code
>> to internal SRAM and then execute it.
> See fncpy.h
>
Thanks, this does the copy.
My problem is in making the SRAM executable.
I have already copied to SRAM (I think), but when I jump there
I get a trap and a stackdump.
The "mmap" system call, seems to do what I want, but is this callable
from within the kernel, or is there a better way?
I can see that is has been split upo into "old_mmap" (obsolete) and the
newer
"sys_mmap2" which turns off the MAP_EXECUTABLE.
"mprotect" maybe can be used to fix that.
Googling for how to call a system call from within the kernel gave:
mm_segment_t oldfs = get_fs();
set_fs(KERNEL_DS);
/* Do SysCalls */
sys_mprotect(sram_shutdown, PAGE_SIZE, ... );
set_fs(old_fs);
which is yet to be tried.
PSEUDO CODE for what I think I need
SETUP PAGE TABLE FOR SRAM
SETUP SRAM PAGE PROTECTION AS (READ/WRITE)
sram_shutdown = phys_to_virt(0x300000); /* Get transation for
SRAM */
target = (unsigned int *) sram_shutdown;
memcpy((unsigned int *) sdram_shutdown, "target", size)
SETUP SRAM PAGE PROTECTION AS (EXEC)
(*sram_shutdown)();
>> Note that when arch_reset is called, the CPU is no longer executing
>> in its normal state.
>> It is called from arm_machine_restart in "arch/arm/kernel/process.c"
>> which has turned off the caches and setup some direct mapping at lower
>> addresses
> You're looking at old kernel code. Stuff has substantially changed in
> this area, and CPU caches are no longer turned off if we're going to do
> a hardware based reset.
Yes, It is the std 2.6.30 kernel with Atmel patches from www.linux4sam.org
with some additions made by the customer,
> However, that doesn't negate what you're trying to do, and you'll need
> to use fncpy() for portability.
>
I have made a copy from SDRAM to 0x300000 "manually".
I enclose the piece of code, with a magic key, and check
that is exists in the beginning, and will copy until it is again found.
If the last key is not found, within 100 words, it is an error.
When I jump to the code, I get a trap, a stackdump and the part will reboot
properly, so it actually accomplish what it is supposed to...
An alternative solution to the problem, is to find out what the CPU
is doing after this trap.
If the user reset is replaced with this code, then this might be OK.
> The code which you want to copy must be written carefully in assembly
> language, and must be written to be relocatable.
It a piece of straight code, without jumps, so I do not expect problems
here.
--
Best Regards
Ulf Samuelsson
ulf at emagii.com
+46 722 427437
^ permalink raw reply [flat|nested] 8+ messages in thread
* AT91: How copy kernel code to SRAM and execute?
2012-02-26 18:44 ` Jean-Christophe PLAGNIOL-VILLARD
@ 2012-02-26 20:52 ` ARM Linux
2012-02-27 3:40 ` Jean-Christophe PLAGNIOL-VILLARD
0 siblings, 1 reply; 8+ messages in thread
From: ARM Linux @ 2012-02-26 20:52 UTC (permalink / raw)
To: linux-arm-kernel
On 2012-02-26 19:44, Jean-Christophe PLAGNIOL-VILLARD wrote:
> On 18:37 Sun 26 Feb , ARM Linux wrote:
>> I am looking for some examples on how to copy a small piece of kernel code
>> to internal SRAM and then execute it.
>>
>> Why?
>> If you want to restart, you execute the "/sbin/reboot" command
>> which will eventually call the "arch_reset" function, which in the AT91
>> case will write to a "user reset" register.
>>
>> The problem is that the chip may reset in the middle of an SDRAM
>> read transfer.
>> The SDRAM will see it's clock stopped and will continue to drive the bus.
>>
>> When the ROM bootloader tries to access any boot memory (Parallel
>> flash or NAND flash)
>> on the parallel bus, there will be a bus conflict between the boot
>> memory and the SDRAM,
>> and the bootROM will not properly detect the boot program, and will enter
>> an In System Programming mode.
>>
>> This is described in the SAM9G20 datasheet, but is probably valid
>> for all older generation AT91 devices as well.
>>
>> The workaround seems to be to turn off the SDRAM and then do the reset.
>> Obviously you cannot read instructions from SDRAM after it has been
>> turned off.
>>
> Which version of the kernel do you use?
>
On 2012-02-26 19:44, Jean-Christophe PLAGNIOL-VILLARD wrote:
> On 18:37 Sun 26 Feb , ARM Linux wrote:
>> I am looking for some examples on how to copy a small piece of kernel code
>> to internal SRAM and then execute it.
>>
>> Why?
>> If you want to restart, you execute the "/sbin/reboot" command
>> which will eventually call the "arch_reset" function, which in the AT91
>> case will write to a "user reset" register.
>>
>> The problem is that the chip may reset in the middle of an SDRAM
>> read transfer.
>> The SDRAM will see it's clock stopped and will continue to drive the bus.
>>
>> When the ROM bootloader tries to access any boot memory (Parallel
>> flash or NAND flash)
>> on the parallel bus, there will be a bus conflict between the boot
>> memory and the SDRAM,
>> and the bootROM will not properly detect the boot program, and will enter
>> an In System Programming mode.
>>
>> This is described in the SAM9G20 datasheet, but is probably valid
>> for all older generation AT91 devices as well.
>>
>> The workaround seems to be to turn off the SDRAM and then do the reset.
>> Obviously you cannot read instructions from SDRAM after it has been
>> turned off.
>>
> Which version of the kernel do you use?
>
> There is no need to put the code in the sram, you just need to put the
> code in cached before shutdown the SDRAM/DDR
>
The vanilla 2.6.30 from linux4sam, but it is using a patchset from a
customer.
I don't think it is an option to change kernel version right now.
Cache is turned off in this version.
> Best Regards,
> J.
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> There is no need to put the code in the sram, you just need to put the
> code in cached before shutdown the SDRAM/DDR
>
> Best Regards,
> J.
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
--
Best Regards
Ulf Samuelsson
ulf at emagii.com
+46 722 427437
^ permalink raw reply [flat|nested] 8+ messages in thread
* AT91: How copy kernel code to SRAM and execute?
2012-02-26 20:48 ` Ulf Samuelsson
@ 2012-02-26 21:05 ` Russell King - ARM Linux
2012-02-27 3:42 ` Jean-Christophe PLAGNIOL-VILLARD
0 siblings, 1 reply; 8+ messages in thread
From: Russell King - ARM Linux @ 2012-02-26 21:05 UTC (permalink / raw)
To: linux-arm-kernel
On Sun, Feb 26, 2012 at 09:48:04PM +0100, Ulf Samuelsson wrote:
> On 2012-02-26 18:50, Russell King - ARM Linux wrote:
>> On Sun, Feb 26, 2012 at 06:37:25PM +0100, ARM Linux wrote:
>>> I am looking for some examples on how to copy a small piece of kernel code
>>> to internal SRAM and then execute it.
>> See fncpy.h
>>
> Thanks, this does the copy.
> My problem is in making the SRAM executable.
> I have already copied to SRAM (I think), but when I jump there
> I get a trap and a stackdump.
> The "mmap" system call, seems to do what I want, but is this callable
> from within the kernel, or is there a better way?
>
> I can see that is has been split upo into "old_mmap" (obsolete) and the
> newer
> "sys_mmap2" which turns off the MAP_EXECUTABLE.
> "mprotect" maybe can be used to fix that.
>
> Googling for how to call a system call from within the kernel gave:
>
> mm_segment_t oldfs = get_fs();
> set_fs(KERNEL_DS);
> /* Do SysCalls */
> sys_mprotect(sram_shutdown, PAGE_SIZE, ... );
> set_fs(old_fs);
Don't even think about that. Google doesn't always answer the correct
question. In this case, it's completely the wrong thing because all
the userspace APIs are _only_ designed to work with userspace addresses.
Moreover, this will fail because it won't find a VMA for the address
(which is a good thing - as it will attempt to modify the pages in
ways which could end up exposing them to userspace.)
In general, if you're coding inside the kernel, calling kernel syscalls
is 99.999% of the time totally the wrong thing to do.
The way to do this is to use __arm_ioremap_exec() to map the SRAM.
^ permalink raw reply [flat|nested] 8+ messages in thread
* AT91: How copy kernel code to SRAM and execute?
2012-02-26 20:52 ` ARM Linux
@ 2012-02-27 3:40 ` Jean-Christophe PLAGNIOL-VILLARD
0 siblings, 0 replies; 8+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2012-02-27 3:40 UTC (permalink / raw)
To: linux-arm-kernel
On 21:52 Sun 26 Feb , ARM Linux wrote:
> On 2012-02-26 19:44, Jean-Christophe PLAGNIOL-VILLARD wrote:
> >On 18:37 Sun 26 Feb , ARM Linux wrote:
> >>I am looking for some examples on how to copy a small piece of kernel code
> >>to internal SRAM and then execute it.
> >>
> >>Why?
> >>If you want to restart, you execute the "/sbin/reboot" command
> >>which will eventually call the "arch_reset" function, which in the AT91
> >>case will write to a "user reset" register.
> >>
> >>The problem is that the chip may reset in the middle of an SDRAM
> >>read transfer.
> >>The SDRAM will see it's clock stopped and will continue to drive the bus.
> >>
> >>When the ROM bootloader tries to access any boot memory (Parallel
> >>flash or NAND flash)
> >>on the parallel bus, there will be a bus conflict between the boot
> >>memory and the SDRAM,
> >>and the bootROM will not properly detect the boot program, and will enter
> >>an In System Programming mode.
> >>
> >>This is described in the SAM9G20 datasheet, but is probably valid
> >>for all older generation AT91 devices as well.
> >>
> >>The workaround seems to be to turn off the SDRAM and then do the reset.
> >>Obviously you cannot read instructions from SDRAM after it has been
> >>turned off.
> >>
> > Which version of the kernel do you use?
> >
> On 2012-02-26 19:44, Jean-Christophe PLAGNIOL-VILLARD wrote:
> >On 18:37 Sun 26 Feb , ARM Linux wrote:
> >>I am looking for some examples on how to copy a small piece of kernel code
> >>to internal SRAM and then execute it.
> >>
> >>Why?
> >>If you want to restart, you execute the "/sbin/reboot" command
> >>which will eventually call the "arch_reset" function, which in the AT91
> >>case will write to a "user reset" register.
> >>
> >>The problem is that the chip may reset in the middle of an SDRAM
> >>read transfer.
> >>The SDRAM will see it's clock stopped and will continue to drive the bus.
> >>
> >>When the ROM bootloader tries to access any boot memory (Parallel
> >>flash or NAND flash)
> >>on the parallel bus, there will be a bus conflict between the boot
> >>memory and the SDRAM,
> >>and the bootROM will not properly detect the boot program, and will enter
> >>an In System Programming mode.
> >>
> >>This is described in the SAM9G20 datasheet, but is probably valid
> >>for all older generation AT91 devices as well.
> >>
> >>The workaround seems to be to turn off the SDRAM and then do the reset.
> >>Obviously you cannot read instructions from SDRAM after it has been
> >>turned off.
> >>
> > Which version of the kernel do you use?
> >
> > There is no need to put the code in the sram, you just need to put the
> > code in cached before shutdown the SDRAM/DDR
> >
>
> The vanilla 2.6.30 from linux4sam, but it is using a patchset from a
> customer.
> I don't think it is an option to change kernel version right now.
> Cache is turned off in this version.
so turn it on run the code from sram is wrong solution here
I do not do this on mainline
just use the fix we use here
Best Regards,
J.
^ permalink raw reply [flat|nested] 8+ messages in thread
* AT91: How copy kernel code to SRAM and execute?
2012-02-26 21:05 ` Russell King - ARM Linux
@ 2012-02-27 3:42 ` Jean-Christophe PLAGNIOL-VILLARD
0 siblings, 0 replies; 8+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2012-02-27 3:42 UTC (permalink / raw)
To: linux-arm-kernel
On 21:05 Sun 26 Feb , Russell King - ARM Linux wrote:
> On Sun, Feb 26, 2012 at 09:48:04PM +0100, Ulf Samuelsson wrote:
> > On 2012-02-26 18:50, Russell King - ARM Linux wrote:
> >> On Sun, Feb 26, 2012 at 06:37:25PM +0100, ARM Linux wrote:
> >>> I am looking for some examples on how to copy a small piece of kernel code
> >>> to internal SRAM and then execute it.
> >> See fncpy.h
> >>
> > Thanks, this does the copy.
> > My problem is in making the SRAM executable.
> > I have already copied to SRAM (I think), but when I jump there
> > I get a trap and a stackdump.
>
>
>
> > The "mmap" system call, seems to do what I want, but is this callable
> > from within the kernel, or is there a better way?
> >
> > I can see that is has been split upo into "old_mmap" (obsolete) and the
> > newer
> > "sys_mmap2" which turns off the MAP_EXECUTABLE.
> > "mprotect" maybe can be used to fix that.
> >
> > Googling for how to call a system call from within the kernel gave:
> >
> > mm_segment_t oldfs = get_fs();
> > set_fs(KERNEL_DS);
> > /* Do SysCalls */
> > sys_mprotect(sram_shutdown, PAGE_SIZE, ... );
> > set_fs(old_fs);
>
> Don't even think about that. Google doesn't always answer the correct
> question. In this case, it's completely the wrong thing because all
> the userspace APIs are _only_ designed to work with userspace addresses.
>
> Moreover, this will fail because it won't find a VMA for the address
> (which is a good thing - as it will attempt to modify the pages in
> ways which could end up exposing them to userspace.)
>
> In general, if you're coding inside the kernel, calling kernel syscalls
> is 99.999% of the time totally the wrong thing to do.
>
> The way to do this is to use __arm_ioremap_exec() to map the SRAM.
Ulf try to fix something the wrong way, this probelem is known for longtime on
at91 and fixed at the mainline on all SoC
Best Regards,
J.
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2012-02-27 3:42 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-02-26 17:37 AT91: How copy kernel code to SRAM and execute? ARM Linux
2012-02-26 17:50 ` Russell King - ARM Linux
2012-02-26 20:48 ` Ulf Samuelsson
2012-02-26 21:05 ` Russell King - ARM Linux
2012-02-27 3:42 ` Jean-Christophe PLAGNIOL-VILLARD
2012-02-26 18:44 ` Jean-Christophe PLAGNIOL-VILLARD
2012-02-26 20:52 ` ARM Linux
2012-02-27 3:40 ` Jean-Christophe PLAGNIOL-VILLARD
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).