Not much to write home about. mostly tidying, some debug, and XIP support.
just keeping arm26 up to date really.
directly from ROM or flash. If unsure, say N.
config ZBOOT_ROM_TEXT
+ depends on ZBOOT_ROM
hex "Compressed ROM boot loader base address"
default "0"
help
should not change this value.
config ZBOOT_ROM_BSS
+ depends on ZBOOT_ROM
hex "Compressed ROM boot loader BSS address"
default "0"
help
while the decompressor is running. Unless you have special requirements,
you should not change this value.
+config XIP_KERNEL
+ bool "Execute In Place (XIP) kernel image"
+ help
+ Select this option to create a kernel that can be programed into
+ the OS ROMs.
+
config HOTPLUG
bool "Support for hot-pluggable devices"
---help---
AFLAGS_vmlinux.lds.o = -DTEXTADDR=$(TEXTADDR) -DDATAADDR=$(DATAADDR)
OBJCOPYFLAGS :=-O binary -R .note -R .comment -S
GZFLAGS :=-9
-#CFLAGS +=-pipe
-CFLAGS :=$(CFLAGS:-O2=-Os)
ifeq ($(CONFIG_FRAME_POINTER),y)
CFLAGS +=-fno-omit-frame-pointer -mno-sched-prolog
CFLAGS +=-mapcs-26 -mcpu=arm3 -mshort-load-bytes -msoft-float -Wa,-mno-fpu -Uarm
AFLAGS +=-mapcs-26 -mcpu=arm3 -mno-fpu -msoft-float -Wa,-mno-fpu
-#Default value
-DATAADDR := .
-
-ifeq ($(CONFIG_CPU_26),y)
head-y := arch/arm26/machine/head.o arch/arm26/kernel/init_task.o
LDFLAGS_BLOB += --oformat elf32-littlearm
- ifeq ($(CONFIG_ROM_KERNEL),y)
- DATAADDR := 0x02080000
- textaddr-y := 0x03800000
- else
- textaddr-y := 0x02080000
- endif
+
+ifeq ($(CONFIG_XIP_KERNEL),y)
+ TEXTADDR := 0x03880000
+ DATAADDR := 0x02080000
+else
+ TEXTADDR := 0x02080000
+ DATAADDR := .
endif
-TEXTADDR := $(textaddr-y)
ifeq ($(incdir-y),)
incdir-y :=
endif
bzImage: vmlinux
$(Q)$(MAKE) $(build)=$(boot) $(boot)/zImage
-zImage Image bootpImage: vmlinux
+zImage Image bootpImage xipImage: vmlinux
$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
zinstall install: vmlinux
export ZTEXTADDR ZBSSADDR ZRELADDR INITRD_PHYS PARAMS_PHYS
-targets := Image zImage bootpImage
+targets := Image zImage bootpImage xipImage
$(obj)/Image: vmlinux FORCE
$(call if_changed,objcopy)
$(obj)/compressed/vmlinux: vmlinux FORCE
$(Q)$(MAKE) $(build)=$(obj)/compressed $@
+ifeq ($(CONFIG_XIP_KERNEL),y)
+$(obj)/xipImage: vmlinux FORCE
+ $(OBJCOPY) -S -O binary -R .data -R .comment vmlinux vmlinux-text.bin
+ $(OBJCOPY) -S -O binary -R .init -R .text -R .comment -R __ex_table -R __ksymtab vmlinux vmlinux-data.bin
+ cat vmlinux-text.bin vmlinux-data.bin > $@
+ $(RM) -f vmlinux-text.bin vmlinux-data.bin
+ @echo ' Kernel: $@ is ready'
+endif
+
.PHONY: initrd
initrd:
@test "$(INITRD_PHYS)" != "" || \
#define ec_set_resource(ec,nr,st,sz,flg) \
do { \
- (ec)->resource[nr].name = ec->dev.name; \
+ (ec)->resource[nr].name = ec->dev.bus_id; \
(ec)->resource[nr].start = st; \
(ec)->resource[nr].end = (st) + (sz) - 1; \
(ec)->resource[nr].flags = flg; \
return sprintf(buf, "%u\n", ec->irq);
}
-static DEVICE_ATTR(irq, S_IRUGO, ecard_show_irq, NULL);
+static ssize_t ecard_show_vendor(struct device *dev, char *buf)
+{
+ struct expansion_card *ec = ECARD_DEV(dev);
+ return sprintf(buf, "%u\n", ec->cid.manufacturer);
+}
+
+static ssize_t ecard_show_device(struct device *dev, char *buf)
+{
+ struct expansion_card *ec = ECARD_DEV(dev);
+ return sprintf(buf, "%u\n", ec->cid.product);
+}
static ssize_t ecard_show_dma(struct device *dev, char *buf)
{
return sprintf(buf, "%u\n", ec->dma);
}
-static DEVICE_ATTR(dma, S_IRUGO, ecard_show_dma, NULL);
-
static ssize_t ecard_show_resources(struct device *dev, char *buf)
{
struct expansion_card *ec = ECARD_DEV(dev);
return str - buf;
}
+static DEVICE_ATTR(irq, S_IRUGO, ecard_show_irq, NULL);
+static DEVICE_ATTR(vendor, S_IRUGO, ecard_show_vendor, NULL);
+static DEVICE_ATTR(device, S_IRUGO, ecard_show_device, NULL);
+static DEVICE_ATTR(dma, S_IRUGO, ecard_show_dma, NULL);
static DEVICE_ATTR(resource, S_IRUGO, ecard_show_resources, NULL);
/*
}
snprintf(ec->dev.bus_id, sizeof(ec->dev.bus_id), "ecard%d", slot);
- snprintf(ec->dev.name, sizeof(ec->dev.name), "ecard %04x:%04x",
- ec->cid.manufacturer, ec->cid.product);
ec->dev.parent = NULL;
ec->dev.bus = &ecard_bus_type;
ec->dev.dma_mask = &ec->dma_mask;
device_create_file(&ec->dev, &dev_attr_dma);
device_create_file(&ec->dev, &dev_attr_irq);
device_create_file(&ec->dev, &dev_attr_resource);
+ device_create_file(&ec->dev, &dev_attr_vendor);
+ device_create_file(&ec->dev, &dev_attr_device);
return 0;
@
@ Stack format (ensured by USER_* and SVC_*)
@
-#define S_FRAME_SIZE 72
+#define S_FRAME_SIZE 72 @ FIXME: Really?
#define S_OLD_R0 64
#define S_PSR 60
#define S_PC 60
.endm
.macro slow_restore_user_regs
- ldmia sp, {r0 - lr}^
- mov r0, r0
- ldr lr, [sp, #15*4]
- add sp, sp, #15*4+8
- movs pc, lr
+ ldmia sp, {r0 - lr}^ @ restore the user regs
+ mov r0, r0 @ no-op
+ ldr lr, [sp, #15*4] @ get user PC
+ add sp, sp, #15*4+8 @ free stack
+ movs pc, lr @ return
.endm
.macro fast_restore_user_regs
* Handles floating point instructions
*/
vector_undefinstr:
- tst lr,#3
- bne __und_svc
+ tst lr, #MODE_SVC26 @ did we come from a non-user mode?
+ bne __und_svc @ yes - deal with it.
+/* Otherwise, fall through for the user-space (common) case. */
save_user_regs
- zero_fp
- teqp pc, #PSR_I_BIT | MODE_SVC26
+ zero_fp @ zero frame pointer
+ teqp pc, #PSR_I_BIT | MODE_SVC26 @ disable IRQs
.Lbug_undef:
ldr r4, .LC2
- ldr pc, [r4] @ Call FP module USR entry point
-
- .globl fpundefinstr
-fpundefinstr: @ Called by FP module on undefined instr
+ ldr pc, [r4] @ Call FP module entry point
+/* FIXME - should we trap for a null pointer here? */
+
+/* The SVC mode case */
+__und_svc: SVC_SAVE_ALL @ Non-user mode
+ mask_pc r0, lr
+ and r2, lr, #3
+ sub r0, r0, #4
+ mov r1, sp
+ bl do_undefinstr
+ SVC_RESTORE_ALL
+
+/* We get here if the FP emulator doesnt handle the undef instr.
+ * If the insn WAS handled, the emulator jumps to ret_from_exception by itself/
+ */
+ .globl fpundefinstr
+fpundefinstr:
mov r0, lr
mov r1, sp
teqp pc, #MODE_SVC26
bl do_undefinstr
b ret_from_exception @ Normal FP exit
-__und_svc: SVC_SAVE_ALL @ Non-user mode
- mask_pc r0, lr
- and r2, lr, #3
- sub r0, r0, #4
- mov r1, sp
- bl do_undefinstr
- SVC_RESTORE_ALL
-
#if defined CONFIG_FPE_NWFPE || defined CONFIG_FPE_FASTFPE
/* The FPE is always present */
.equ fpe_not_present, 0
* a WFS, we just perform a normal return as if we had emulated the
* operation. This is a hack to allow some basic userland binaries
* to run so that the emulator module proper can be loaded. --philb
+ * FIXME - probably a broken useless hack...
*/
fpe_not_present:
adr r10, wfs_mask_data
* Prefetch abort handler
*-----------------------------------------------------------------------------
*/
-
+#define DEBUG_UNDEF
/* remember: lr = USR pc */
vector_prefetch:
sub lr, lr, #4
- tst lr, #3
+ tst lr, #MODE_SVC26
bne __pabt_invalid
save_user_regs
- teqp pc, #MODE_SVC26
+ teqp pc, #MODE_SVC26 @ Enable IRQs...
mask_pc r0, lr @ Address of abort
mov r1, sp @ Tasks registers
bl do_PrefetchAbort
adr r0, t
bl printk
#endif
- ldr lr, [sp,#S_PC] @ program to test this on. I think its
+ ldr lr, [sp,#S_PC] @ FIXME program to test this on. I think its
b .Lbug_undef @ broken at the moment though!)
__pabt_invalid: SVC_SAVE_ALL
bne asm_do_IRQ
mov why, #0
- get_thread_info r5
+ get_thread_info tsk @ FIXME - was r5, but seemed wrong.
b ret_to_user
irq_prio_table
#include <asm/system.h>
#include <asm/irqchip.h>
+//FIXME - this ought to be in a header IMO
+void __init arc_init_irq(void);
+
/*
* Maximum IRQ count. Currently, this is arbitary. However, it should
* not be set too low to prevent false triggering. Conversely, if it
extern void bootmem_init(struct meminfo *);
extern int root_mountflags;
extern int _stext, _text, _etext, _edata, _end;
+#ifdef CONFIG_XIP_KERNEL
+extern int _endtext, _sdata;
+#endif
+
unsigned int processor_id;
unsigned int __machine_arch_type;
for (list = &__proc_info_begin; list < &__proc_info_end ; list++)
if ((processor_id & list->cpu_mask) == list->cpu_val)
break;
+
/*
* If processor type is unrecognised, then we
* can do nothing...
kernel_code.start = init_mm.start_code;
kernel_code.end = init_mm.end_code - 1;
+#ifdef CONFIG_XIP_KERNEL
+ kernel_data.start = init_mm.start_data;
+#else
kernel_data.start = init_mm.end_code;
+#endif
kernel_data.end = init_mm.brk - 1;
for (i = 0; i < mi->nr_banks; i++) {
else
machine_name = "UNKNOWN";
- //FIXME - this may need altering when we get ROM images working
+ //FIXME - the tag struct is always copied here but this is a block
+ // of RAM that is accidentally reserved along with video RAM. perhaps
+ // it would be a good idea to explicitly reserve this?
+
tags = (struct tag *)0x0207c000;
/*
}
init_mm.start_code = (unsigned long) &_text;
+#ifndef CONFIG_XIP_KERNEL
init_mm.end_code = (unsigned long) &_etext;
+#else
+ init_mm.end_code = (unsigned long) &_endtext;
+ init_mm.start_data = (unsigned long) &_sdata;
+#endif
init_mm.end_data = (unsigned long) &_edata;
init_mm.brk = (unsigned long) &_end;
--- /dev/null
+/* ld script to make ARM Linux kernel
+ * taken from the i386 version by Russell King
+ * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>
+ * borrowed from Russels ARM port by Ian Molton
+ */
+
+#include <asm-generic/vmlinux.lds.h>
+
+OUTPUT_ARCH(arm)
+ENTRY(stext)
+jiffies = jiffies_64;
+SECTIONS
+{
+ . = TEXTADDR;
+ .init : { /* Init code and data */
+ _stext = .;
+ __init_begin = .;
+ _sinittext = .;
+ *(.init.text)
+ _einittext = .;
+ __proc_info_begin = .;
+ *(.proc.info)
+ __proc_info_end = .;
+ __arch_info_begin = .;
+ *(.arch.info)
+ __arch_info_end = .;
+ __tagtable_begin = .;
+ *(.taglist)
+ __tagtable_end = .;
+ . = ALIGN(16);
+ __setup_start = .;
+ *(.init.setup)
+ __setup_end = .;
+ __early_begin = .;
+ *(__early_param)
+ __early_end = .;
+ __start___param = .;
+ *(__param)
+ __stop___param = .;
+ __initcall_start = .;
+ *(.initcall1.init)
+ *(.initcall2.init)
+ *(.initcall3.init)
+ *(.initcall4.init)
+ *(.initcall5.init)
+ *(.initcall6.init)
+ *(.initcall7.init)
+ __initcall_end = .;
+ __con_initcall_start = .;
+ *(.con_initcall.init)
+ __con_initcall_end = .;
+ . = ALIGN(32);
+ __initramfs_start = .;
+ usr/built-in.o(.init.ramfs)
+ __initramfs_end = .;
+ . = ALIGN(32768);
+ __init_end = .;
+ }
+
+ /DISCARD/ : { /* Exit code and data */
+ *(.exit.text)
+ *(.exit.data)
+ *(.exitcall.exit)
+ }
+
+ .text : { /* Real text segment */
+ _text = .; /* Text and read-only data */
+ *(.text)
+ *(.fixup)
+ *(.gnu.warning)
+ *(.rodata)
+ *(.rodata.*)
+ *(.glue_7)
+ *(.glue_7t)
+ *(.got) /* Global offset table */
+
+ _etext = .; /* End of text section */
+ }
+
+ . = ALIGN(16);
+ __ex_table : { /* Exception table */
+ __start___ex_table = .;
+ *(__ex_table)
+ __stop___ex_table = .;
+ }
+
+ RODATA
+
+ _endtext = .;
+
+ . = DATAADDR;
+
+ _sdata = .;
+
+ .data : {
+ /*
+ * first, the init thread union, aligned
+ * to an 8192 byte boundary.
+ */
+ *(.init.task)
+
+ /*
+ * The cacheline aligned data
+ */
+ . = ALIGN(32);
+ *(.data.cacheline_aligned)
+
+ /*
+ * and the usual data section
+ */
+ *(.data)
+ CONSTRUCTORS
+
+ *(.init.data)
+
+ _edata = .;
+ }
+
+ .bss : {
+ __bss_start = .; /* BSS */
+ *(.bss)
+ *(COMMON)
+ _end = . ;
+ }
+ /* Stabs debugging sections. */
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+ .stab.excl 0 : { *(.stab.excl) }
+ .stab.exclstr 0 : { *(.stab.exclstr) }
+ .stab.index 0 : { *(.stab.index) }
+ .stab.indexstr 0 : { *(.stab.indexstr) }
+ .comment 0 : { *(.comment) }
+}
--- /dev/null
+/* ld script to make ARM Linux kernel
+ * taken from the i386 version by Russell King
+ * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>
+ * borrowed from Russels ARM port by Ian Molton and subsequently modified.
+ */
+
+#include <asm-generic/vmlinux.lds.h>
+
+OUTPUT_ARCH(arm)
+ENTRY(stext)
+jiffies = jiffies_64;
+SECTIONS
+{
+ . = TEXTADDR;
+ .init : { /* Init code and data */
+ _stext = .;
+ __init_begin = .;
+ _sinittext = .;
+ *(.init.text)
+ _einittext = .;
+ __proc_info_begin = .;
+ *(.proc.info)
+ __proc_info_end = .;
+ __arch_info_begin = .;
+ *(.arch.info)
+ __arch_info_end = .;
+ __tagtable_begin = .;
+ *(.taglist)
+ __tagtable_end = .;
+ *(.init.data)
+ . = ALIGN(16);
+ __setup_start = .;
+ *(.init.setup)
+ __setup_end = .;
+ __early_begin = .;
+ *(__early_param)
+ __early_end = .;
+ __start___param = .;
+ *(__param)
+ __stop___param = .;
+ __initcall_start = .;
+ *(.initcall1.init)
+ *(.initcall2.init)
+ *(.initcall3.init)
+ *(.initcall4.init)
+ *(.initcall5.init)
+ *(.initcall6.init)
+ *(.initcall7.init)
+ __initcall_end = .;
+ __con_initcall_start = .;
+ *(.con_initcall.init)
+ __con_initcall_end = .;
+ . = ALIGN(32);
+ __initramfs_start = .;
+ usr/built-in.o(.init.ramfs)
+ __initramfs_end = .;
+ . = ALIGN(32768);
+ __init_end = .;
+ }
+
+ /DISCARD/ : { /* Exit code and data */
+ *(.exit.text)
+ *(.exit.data)
+ *(.exitcall.exit)
+ }
+
+ .text : { /* Real text segment */
+ _text = .; /* Text and read-only data */
+ *(.text)
+ *(.fixup)
+ *(.gnu.warning)
+ *(.rodata)
+ *(.rodata.*)
+ *(.glue_7)
+ *(.glue_7t)
+ *(.got) /* Global offset table */
+
+ _etext = .; /* End of text section */
+ }
+
+ . = ALIGN(16);
+ __ex_table : { /* Exception table */
+ __start___ex_table = .;
+ *(__ex_table)
+ __stop___ex_table = .;
+ }
+
+ RODATA
+
+ . = ALIGN(8192);
+
+ .data : {
+ /*
+ * first, the init task union, aligned
+ * to an 8192 byte boundary.
+ */
+ *(.init.task)
+
+ /*
+ * The cacheline aligned data
+ */
+ . = ALIGN(32);
+ *(.data.cacheline_aligned)
+
+ /*
+ * and the usual data section
+ */
+ *(.data)
+ CONSTRUCTORS
+
+ _edata = .;
+ }
+
+ .bss : {
+ __bss_start = .; /* BSS */
+ *(.bss)
+ *(COMMON)
+ _end = . ;
+ }
+ /* Stabs debugging sections. */
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+ .stab.excl 0 : { *(.stab.excl) }
+ .stab.exclstr 0 : { *(.stab.exclstr) }
+ .stab.index 0 : { *(.stab.index) }
+ .stab.indexstr 0 : { *(.stab.indexstr) }
+ .comment 0 : { *(.comment) }
+}
#include <linux/config.h>
-#ifdef CONFIG_ROM_KERNEL
+#ifdef CONFIG_XIP_KERNEL
-#include "vmlinux-armo-rom.lds.in"
+#include "vmlinux-arm26-xip.lds.in"
#else
-#include "vmlinux-armo.lds.in"
+#include "vmlinux-arm26.lds.in"
#endif
ENTRY(stext)
__entry: cmp pc, #0x02000000
ldrlt pc, LC0 @ if 0x01800000, call at 0x02080000
- teq r0, #0 @ Check for old calling method
+ teq r0, #0 @ Check for old calling method
blne oldparams @ Move page if old
adr r0, LC0
- ldmib r0, {r2-r5, sp} @ Setup stack
- mov r0, #0
-1: cmp r2, r3 @ Clear BSS
+ ldmib r0, {r2-r5, sp} @ Setup stack (and fetch other values)
+
+ mov r0, #0 @ Clear BSS
+1: cmp r2, r3
strcc r0, [r2], #4
bcc 1b
bl detect_arch_type
str r0, [r5]
+#ifdef CONFIG_XIP_KERNEL
+ ldr r3, ETEXT @ data section copy
+ ldr r4, SDATA
+ ldr r5, EDATA
+1:
+ ldr r6, [r3], #4
+ str r6, [r4], #4
+ cmp r4, r5
+ blt 1b
+#endif
+
mov fp, #0
b start_kernel
.word processor_id @ r4
.word __machine_arch_type @ r5
.word init_thread_union+8192 @ sp
-arm2_id: .long 0x41560200
-arm250_id: .long 0x41560250
+#ifdef CONFIG_XIP_KERNEL
+ETEXT: .word _endtext
+SDATA: .word _sdata
+EDATA: .word __bss_start
+#endif
+
+arm2_id: .long 0x41560200 @ ARM2 and 250 dont have a CPUID
+arm250_id: .long 0x41560250 @ So we create some after probing for them
.align
oldparams: mov r4, #0x02000000
show_pte(tsk->mm, addr);
show_regs(regs);
//dump_backtrace(regs, tsk); // FIXME ARM32 dropped this - why?
- while(1);
+ while(1); //FIXME - hack to stop debug going nutso
#endif
tsk->thread.address = addr;
tsk = current;
mm = tsk->mm;
- printk("do_page_fault: pid: %d\n", tsk->pid);
+ printk("do_page_fault: pid: %d %08x\n", tsk->pid, addr);
/*
* If we're in an interrupt or have no user
* context, we must not take the fault..
/*
* If we are in kernel mode at this point, we
* have no context to handle this fault with.
+ * FIXME - is this test right?
*/
if (!user_mode(regs)){
goto no_context;
#include <asm/setup.h>
#include <asm/tlb.h>
-//#include <asm/arch.h>
#include <asm/map.h>
+
#define TABLE_SIZE PTRS_PER_PTE * sizeof(pte_t))
struct mmu_gather mmu_gathers[NR_CPUS];
extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
extern char _stext, _text, _etext, _end, __init_begin, __init_end;
+#ifdef CONFIG_XIP_KERNEL
+extern char _endtext, _sdata;
+#endif
extern unsigned long phys_initrd_start;
extern unsigned long phys_initrd_size;
find_memend_and_nodes(struct meminfo *mi, struct node_info *np)
{
unsigned int memend_pfn = 0;
+
numnodes = 1;
np->bootmap_pages = 0;
}
-/*
- * Reserve the various regions of node 0
- */
-static __init void reserve_node_zero(unsigned int bootmap_pfn, unsigned int bootmap_pages)
-{
- pg_data_t *pgdat = NODE_DATA(0);
-
- /*
- * Register the kernel text and data with bootmem.
- * Note that this can only be in node 0.
- */
- reserve_bootmem_node(pgdat, __pa(&_stext), &_end - &_stext);
-
- /*
- * And don't forget to reserve the allocator bitmap,
- * which will be freed later.
- */
- reserve_bootmem_node(pgdat, bootmap_pfn << PAGE_SHIFT,
- bootmap_pages << PAGE_SHIFT);
-
- /*
- * These should likewise go elsewhere. They pre-reserve
- * the screen memory region at the start of main system
- * memory.
- */
- reserve_bootmem_node(pgdat, 0x02000000, 0x00080000);
-
-#ifdef CONFIG_BLK_DEV_INITRD
- initrd_start = phys_initrd_start;
- initrd_end = initrd_start + phys_initrd_size;
-
- /* Achimedes machines only have one node, so initrd is in node 0 */
- reserve_bootmem_node(pgdat, __pa(initrd_start),
- initrd_end - initrd_start);
-#endif
-
-}
-
-
/*
* Initialise the bootmem allocator for all nodes. This is called
* early during the architecture specific initialisation.
{
struct node_info node_info;
unsigned int bootmap_pfn;
+ pg_data_t *pgdat = NODE_DATA(0);
find_memend_and_nodes(mi, &node_info);
/*
* Initialise the bootmem allocator.
*/
- init_bootmem_node(NODE_DATA(node), bootmap_pfn, node_info.start, node_info.end);
+ init_bootmem_node(pgdat, bootmap_pfn, node_info.start, node_info.end);
/*
* Register all available RAM in this node with the bootmem allocator.
*/
- free_bootmem_node(NODE_DATA(node), mi->bank->start, mi->bank->size);
+ free_bootmem_node(pgdat, mi->bank->start, mi->bank->size);
+
+ /*
+ * Register the kernel text and data with bootmem.
+ * Note: with XIP we dont register .text since
+ * its in ROM.
+ */
+#ifdef CONFIG_XIP_KERNEL
+ reserve_bootmem_node(pgdat, __pa(&_sdata), &_end - &_sdata);
+#else
+ reserve_bootmem_node(pgdat, __pa(&_stext), &_end - &_stext);
+#endif
- /*
- * Reserve ram for stuff like initrd, video, kernel, etc.
- */
+ /*
+ * And don't forget to reserve the allocator bitmap,
+ * which will be freed later.
+ */
+ reserve_bootmem_node(pgdat, bootmap_pfn << PAGE_SHIFT,
+ node_info.bootmap_pages << PAGE_SHIFT);
+
+ /*
+ * These should likewise go elsewhere. They pre-reserve
+ * the screen memory region at the start of main system
+ * memory. FIXME - screen RAM is not 512K!
+ */
+ reserve_bootmem_node(pgdat, 0x02000000, 0x00080000);
+
+#ifdef CONFIG_BLK_DEV_INITRD
+ initrd_start = phys_initrd_start;
+ initrd_end = initrd_start + phys_initrd_size;
+
+ /* Achimedes machines only have one node, so initrd is in node 0 */
+#ifdef CONFIG_XIP_KERNEL
+ /* Only reserve initrd space if it is in RAM */
+ if(initrd_start && initrd_start < 0x03000000){
+#else
+ if(initrd_start){
+#endif
+ reserve_bootmem_node(pgdat, __pa(initrd_start),
+ initrd_end - initrd_start);
+ }
+#endif /* CONFIG_BLK_DEV_INITRD */
- reserve_node_zero(bootmap_pfn, node_info.bootmap_pages);
}
pgdat = NODE_DATA(0);
bdata = pgdat->bdata;
-
zone_size[0] = bdata->node_low_pfn -
(bdata->node_boot_start >> PAGE_SHIFT);
if (!zone_size[0])
BUG();
free_area_init_node(0, pgdat, 0, zone_size,
- bdata->node_boot_start >> PAGE_SHIFT, 0);
+ bdata->node_boot_start >> PAGE_SHIFT, zhole_size);
- mem_map = contig_page_data.node_mem_map;
+ mem_map = NODE_DATA(0)->node_mem_map;
/*
* finish off the bad pages once
pg_data_t *pgdat = NODE_DATA(0);
extern int sysctl_overcommit_memory;
- datapages = &_end - &_etext;
+
+ /* Note: data pages includes BSS */
+#ifdef CONFIG_XIP_KERNEL
+ codepages = &_endtext - &_text;
+ datapages = &_end - &_sdata;
+#else
codepages = &_etext - &_text;
+ datapages = &_end - &_etext;
+#endif
initpages = &__init_end - &__init_begin;
high_memory = (void *)__va(meminfo.end);
if (pgdat->node_spanned_pages != 0)
totalram_pages += free_all_bootmem_node(pgdat);
- printk(KERN_INFO "Memory:");
-
num_physpages = meminfo.bank[0].size >> PAGE_SHIFT;
- printk(" = %luMB total\n", num_physpages >> (20 - PAGE_SHIFT));
+ printk(KERN_INFO "Memory: %luMB total\n", num_physpages >> (20 - PAGE_SHIFT));
printk(KERN_NOTICE "Memory: %luKB available (%dK code, "
"%dK data, %dK init)\n",
(unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
codepages >> 10, datapages >> 10, initpages >> 10);
+
/*
* Turn on overcommit on tiny machines
*/
}
}
-void free_initmem(void)
-{
+void free_initmem(void){
+#ifndef CONFIG_XIP_KERNEL
free_area((unsigned long)(&__init_begin),
(unsigned long)(&__init_end),
"init");
+#endif
}
#ifdef CONFIG_BLK_DEV_INITRD
void free_initrd_mem(unsigned long start, unsigned long end)
{
+#ifdef CONFIG_XIP_KERNEL
+ /* Only bin initrd if it is in RAM... */
+ if(!keep_initrd && start < 0x03000000)
+#else
if (!keep_initrd)
+#endif
free_area(start, end, "initrd");
}
+++ /dev/null
-/* ld script to make ARM Linux kernel
- * taken from the i386 version by Russell King
- * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>
- * borrowed from Russels ARM port by Ian Molton
- */
-
-#include <asm-generic/vmlinux.lds.h>
-
-OUTPUT_ARCH(arm)
-ENTRY(stext)
-jiffies = jiffies_64;
-SECTIONS
-{
- . = TEXTADDR;
- .init : { /* Init code and data */
- _stext = .;
- __init_begin = .;
- _sinittext = .;
- *(.init.text)
- _einittext = .;
- __proc_info_begin = .;
- *(.proc.info)
- __proc_info_end = .;
- __arch_info_begin = .;
- *(.arch.info)
- __arch_info_end = .;
- __tagtable_begin = .;
- *(.taglist)
- __tagtable_end = .;
- *(.init.data)
- . = ALIGN(16);
- __setup_start = .;
- *(.init.setup)
- __setup_end = .;
- __early_begin = .;
- *(__early_param)
- __early_end = .;
- __start___param = .;
- *(__param)
- __stop___param = .;
- __initcall_start = .;
- *(.initcall1.init)
- *(.initcall2.init)
- *(.initcall3.init)
- *(.initcall4.init)
- *(.initcall5.init)
- *(.initcall6.init)
- *(.initcall7.init)
- __initcall_end = .;
- __con_initcall_start = .;
- *(.con_initcall.init)
- __con_initcall_end = .;
- . = ALIGN(32);
- __initramfs_start = .;
- usr/built-in.o(.init.ramfs)
- __initramfs_end = .;
- . = ALIGN(32768);
- __init_end = .;
- }
-
- /DISCARD/ : { /* Exit code and data */
- *(.exit.text)
- *(.exit.data)
- *(.exitcall.exit)
- }
-
- .text : { /* Real text segment */
- _text = .; /* Text and read-only data */
- *(.text)
- *(.fixup)
- *(.gnu.warning)
- *(.rodata)
- *(.rodata.*)
- *(.glue_7)
- *(.glue_7t)
- *(.got) /* Global offset table */
-
- _etext = .; /* End of text section */
- }
-
- . = ALIGN(16);
- __ex_table : { /* Exception table */
- __start___ex_table = .;
- *(__ex_table)
- __stop___ex_table = .;
- }
-
- RODATA
-
- . = ALIGN(8192);
-
- .data : {
- /*
- * first, the init task union, aligned
- * to an 8192 byte boundary.
- */
- *(.init.task)
-
- /*
- * The cacheline aligned data
- */
- . = ALIGN(32);
- *(.data.cacheline_aligned)
-
- /*
- * and the usual data section
- */
- *(.data)
- CONSTRUCTORS
-
- _edata = .;
- }
-
- .bss : {
- __bss_start = .; /* BSS */
- *(.bss)
- *(COMMON)
- _end = . ;
- }
- /* Stabs debugging sections. */
- .stab 0 : { *(.stab) }
- .stabstr 0 : { *(.stabstr) }
- .stab.excl 0 : { *(.stab.excl) }
- .stab.exclstr 0 : { *(.stab.exclstr) }
- .stab.index 0 : { *(.stab.index) }
- .stab.indexstr 0 : { *(.stab.indexstr) }
- .comment 0 : { *(.comment) }
-}
struct resource resource[ECARD_NUM_RESOURCES];
/* Public data */
- volatile unsigned char *irqaddr; /* address of IRQ register */
- volatile unsigned char *fiqaddr; /* address of FIQ register */
- unsigned char irqmask; /* IRQ mask */
- unsigned char fiqmask; /* FIQ mask */
- unsigned char claimed; /* Card claimed? */
-
- void *irq_data; /* Data for use for IRQ by card */
- void *fiq_data; /* Data for use for FIQ by card */
- const expansioncard_ops_t *ops; /* Enable/Disable Ops for card */
-
- CONST unsigned int slot_no; /* Slot number */
- CONST unsigned int dma; /* DMA number (for request_dma) */
- CONST unsigned int irq; /* IRQ number (for request_irq) */
- CONST unsigned int fiq; /* FIQ number (for request_irq) */
- CONST card_type_t type; /* Type of card */
- CONST struct in_ecid cid; /* Card Identification */
+ volatile unsigned char *irqaddr; /* address of IRQ register */
+ volatile unsigned char *fiqaddr; /* address of FIQ register */
+ unsigned char irqmask; /* IRQ mask */
+ unsigned char fiqmask; /* FIQ mask */
+ unsigned char claimed; /* Card claimed? */
+
+ void *irq_data; /* Data for use for IRQ by card */
+ void *fiq_data; /* Data for use for FIQ by card */
+ const expansioncard_ops_t *ops; /* Enable/Disable Ops for card */
+
+ CONST unsigned int slot_no; /* Slot number */
+ CONST unsigned int dma; /* DMA number (for request_dma) */
+ CONST unsigned int irq; /* IRQ number (for request_irq) */
+ CONST unsigned int fiq; /* FIQ number (for request_irq) */
+ CONST card_type_t type; /* Type of card */
+ CONST struct in_ecid cid; /* Card Identification */
/* Private internal data */
- const char *card_desc; /* Card description */
- CONST unsigned int podaddr; /* Base Linux address for card */
- CONST loader_t loader; /* loader program */
+ const char *card_desc; /* Card description */
+ CONST unsigned int podaddr; /* Base Linux address for card */
+ CONST loader_t loader; /* loader program */
u64 dma_mask;
};
--- /dev/null
+//FIXME - nicked from arm32 - check it is correct...
+#include <asm-generic/local.h>
--- /dev/null
+//FIXME - nicked from arm32 - check its correct.
+#include <asm-generic/sections.h>
/*
* These are the values used to represent the user `fs' and the kernel `ds'
+ * FIXME - the KERNEL_DS should end at 0x03000000 but we want to access ROM at
+ * 0x03400000. ideally we want to forbid access to the IO space inbetween.
*/
-#define KERNEL_DS 0x03000000
+#define KERNEL_DS 0x03FFFFFF
#define USER_DS 0x02000000
extern uaccess_t uaccess_user, uaccess_kernel;
static inline void set_fs (mm_segment_t fs)
{
current_thread_info()->addr_limit = fs;
- current->thread.uaccess = fs == USER_DS ? &uaccess_user : &uaccess_kernel;
+ current->thread.uaccess = (fs == USER_DS ? &uaccess_user : &uaccess_kernel);
}
#define __range_ok(addr,size) ({ \