On Tue, 2011-09-27 at 17:54 +0530, Suzuki Poulose wrote: > Hi, > > I am working on enabling CONFIG_RELOCATABLE for PPC44x Embedded PowerPC > boards as a foundation to enable CONFIG_CRASH_DUMP. After a discussion > on the linux-ppcdev we decided that we will follow the 'processing > relocation entries' approach for running the kernel from a different > address.
I think the best approach is to not touch KERNELBASE and PAGE_OFFSET, and just process relocations, that way __va() and __pa() are unoutched and plenty of other stuff won't break. Ben. > > On PPC44x we pin the kernel text/data sections using 256M sized TLB > entries. Since the embedded boards have limited amount of RAM, we cannot > enforce the kernel load address to be aligned to 256M. This prevents us > from mapping the 'loaded physical address' of the kernel to 'KERNELBASE' > (virtual address of the kernel start). So we are forced to generate > relocation entries and process them before we start using the virtual > address(s) at the kernel boot time. > > Please note that the KERNELBASE doesn't have to be 256M aligned. > > > I have adopted the following method for finding the relocation offset. > > 1) Find the physical address of _start (start of kernel text) > 2) Calculate the relocation offset as : > > reloc_offset = (Phy_Addr(_stext) % 256M) - (KERNELBASE % 256M) > > And then map ALIGN_DOWN(KERNELBASE,256M) to > ALIGN_DOWN(Phys_Addr(_stext),256M). > > > > > > | Phys. Addr | Virt. Addr | > PageBoundary (256M) |-------------------------------| > | | | > | | | > | | | > (Phys. Start)%256M-> |_______________|_ _ _ _ _ _ _ _|<- Act. Kernel > | | ^ | Virtual Address > | | | | > | | | | > | | reloc_offset | > | | | | > | | | | > | |_______v_______|<-(KERNELBASE)% > | | | 256M > | | | > | | | > | | | > | | | > PageBoundary (256M) |---------------|---------------| > | | | > | | | > > > So the conversion of the addresses from virtual to physical and vice versa, > needs to take care of the actual kernel virtual address taking into account > of the relocation offset. > > Currently __va() & __pa() has been defined as follows : > > #define __va(x) ((void *)(unsigned long)((phys_addr_t)(x) - PHYSICAL_START + > KERNELBASE)) > #define __pa(x) ((unsigned long)(x) + PHYSICAL_START - KERNELBASE) > > Where: > > * PHYSICAL_START (defined to variable, kernstart_addr) which holds > the physical address where the kernel is loaded. This variable is > initialized at the boot time. > > * KERNELBASE is the (compiled) kernel virtual start address. > > These definitions would hold only if the load address is Page aligned, > which is not feasible onf PPC44x(as mentioned in the beginning). > > So we need new definitions for them in CONFIG_RELOCATABLE case. > > Here are the solutions that I could think of : > > 1) Update kernstart_addr(PHSYICAL_START) to match the Physical address of > KERNELBASE. > > i.e, kernstart_addr = Phys.Addr(_stext) + Reloc Offset > > This may not sound good, however, the kernstart_addr is only used for the > __va()/__pa() calculation. So we are OK to use that. > > 2) Redefine __va() & __pa() > i.e, > > #if defined(CONFIG_RELOCATABLE) && defined(CONFIG_44x) > #define __va(x) ((void *)(unsigned long)((phys_addr_t)(x) - PHYSICAL_START + > (KERNELBASE + RELOC_OFFSET))) > #define __pa(x) ((unsigned long)(x) + PHYSICAL_START - (KERNELBASE + > RELOC_OFFSET)) > #endif > > where, RELOC_OFFSET could be > > a) Either stored in a variable, say relocation_offset (like kernstart_addr) > at boot time. > > OR > > b) #define RELOC_OFFSET ((PHYSICAL_START & PPC_PIN_SIZE_OFFSET_MASK) - \ > (KERNELBASE & PPC_PIN_SIZE_OFFSET_MASK)) > > > I am more tempted to adopt 2(a). Could you please let me know your > suggestions / thoughts / comments. > > OR > > Do should we support CONFIG_RELOCATABLE & CONFIG_KERNEL_START in the same > time ? > > > Thanks > Suzuki > > > > > > > > > > _______________________________________________ Linuxppc-dev mailing list [email protected] https://lists.ozlabs.org/listinfo/linuxppc-dev
