
Hi Simon,
2014-10-02 0:31 GMT+09:00 Simon Glass sjg@chromium.org:
Hi Masahiro,
On 1 October 2014 05:23, Masahiro Yamada yamada.m@jp.panasonic.com wrote:
Hi Simon,
I am looking at the driver-model serial code.
I notice driver-model serial code uses ".data" section for storing the current device even before relocation.
This code in drivers/serial/serial-uclass.c:
/* The currently-selected console serial device */ struct udevice *cur_dev __attribute__ ((section(".data")));
In my understanding, we should not write any data to .data section before relocation.
Let's say we are booting U-Boot from NOR flash.
Before relocation, everything (including .data section) is placed on NOR flash which is read-only. (Please point out if I am wrong.)
We are only allowed to write data to the stack, gd_t, bd_t and malloc area (if CONFIG_SYS_MALLOC_F_LEN is defined) before relocation, I think.
I think that is why pre-driver-model serial uses a hard-coded default serial port before relocation.
This code in driver/serial/serial.c:
if (!(gd->flags & GD_FLG_RELOC)) dev = default_serial_console(); else if (!serial_current) dev = default_serial_console(); else dev = serial_current;
My question is, does printf() work with driver-model UART and XIP device such NOR flash?
The global_data structure needs to go somewhere, even before relocation. On ARM this is general SRAM I suppose. In your case I think you have some cache RAM to use. Do you use SPL?
UniPhier SoCs support various boot-modes.
I use SPL for NAND and MMC card boot, but I don't for NOR boot.
For NAND boot or MMC card boot, yes, .data section is on some cache RAM, i.e. it is writable.
For NOR boot, the program is running eXecutable-In-Place; therefore before relocation, .data section is remaining on NOR flash and it is read-only.
The pre-reloc malloc() area goes below global_data so uses the same mechanism.
Yes it is true that strictly speaking we should not use data before relocation. I suppose we could move cur_dev to global_data instead for this particular case. It doesn't really scale to other drivers, but then I expect that only serial needs to keep a 'current' pointer before relocation, and even that will eventually go away once the serial stuff is cleaned up.
So let me know if that solution works.
I think it will work.
Moving cur_dev to struct global_data is easy. My concern is only that struct global_data is already too cluttered.
Some other options I have come up with are:
[1] Before relocation, cur_dev is set to a fixed-device by a board file. This is the same solution as pre-driver-model UART does.
This would be unfortunate. We are using Device-Tree more and more these days. Run-time choosing would be more flexible.
[2] Make .data section writable even before relocation.
The boot sequence would be:
1. Copy .data to the temporary SRAM and clear .bss section 2. board_init_f() 3. Relocate all sections to SDRAM 4. board_init_r()