mizi-linux已经根据Linux 2.4内核针对S3C2410A这一芯片进行了有针对性的移植工作,包括:
a.指定目标平台为ARM:
#ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
ARCH := arm
b.指定交叉编译器:
CROSS_COMPILE = arm-linux-
根据本章第一节可知,Linux的arch目录存放硬件相关的内核代码,因此,在Linux内核中增加对S3C2410的支持,最主要就是要修改arch目录中的文件。
a.在arch/arm/Makefile文件中加入:
ifeq ($(CONFIG_ARCH_S3C2410),y)
TEXTADDR = 0xC0008000
MACHINE = s3c2410
Endif
b.在arch\arm\config.in文件中加入:
if [ "$CONFIG_ARCH_S3C2410" = "y" ]; then
comment 'S3C2410 Implementation'
dep_bool ' SMDK (MERI TECH BOARD)' CONFIG_S3C2410_SMDK $CONFIG_ARCH_S3C2410
dep_bool ' change AIJI' CONFIG_SMDK_AIJI
dep_tristate 'S3C2410 USB function support' CONFIG_S3C2410_USB $CONFIG_ARCH_S3C2100
dep_tristate ' Support for S3C2410 USB character device emulation' CONFIG_S3C2410_USB_CHAR $CONFIG_S3C2410_USB
fi # /* CONFIG_ARCH_S3C2410 */
arch\arm\config.in文件还有几处针对S3C2410的修改。
c.在arch/arm/boot/Makefile文件中加入:
ifeq ($(CONFIG_ARCH_S3C2410),y)
ZTEXTADDR = 0x30008000
ZRELADDR = 0x30008000
endif
d.在linux/arch/arm/boot/compressed/Makefile文件中加入:
ifeq ($(CONFIG_ARCH_S3C2410),y)
OBJS += head-s3c2410.o
endif
加入的结果是head-s3c2410.S文件被编译为head-s3c2410.o。
e.加入arch\arm\boot\compressed\ head-s3c2410.S文件
#include
#include
#include
.section ".start", #alloc, #execinstr
__S3C2410_start:
@ Preserve r8/r7 i.e. kernel entry values
@ What is it?
@ Nandy
@ Data cache, Intstruction cache, MMU might be active.
@ Be sure to flush kernel binary out of the cache,
@ whatever state it is, before it is turned off.
@ This is done by fetching through currently executed
@ memory to be sure we hit the same cache
bic r2, pc, #0x1f
add r3, r2, #0x4000 @ 16 kb is quite enough...
1: ldr r0, [r2], #32
teq r2, r3
bne 1b
mcr p15, 0, r0, c7, c10, 4 @ drain WB
mcr p15, 0, r0, c7, c7, 0 @ flush I & D caches
#if 0
@ disabling MMU and caches
mrc p15, 0, r0, c1, c0, 0 @ read control register
bic r0, r0, #0x05 @ disable D cache and MMU
bic r0, r0, #1000 @ disable I cache
mcr p15, 0, r0, c1, c0, 0
#endif
/*
* Pause for a short time so that we give enough time
* for the host to start a terminal up.
*/
mov r0, #0x00200000
1: subs r0, r0, #1
bne 1b
该文件中的汇编代码完成S3C2410特定硬件相关的初始化。
f.在arch\arm\def-configs目录中增加配置文件
g.在arch\arm\kernel\Makefile中增加对S3C2410的支持
no-irq-arch := $(CONFIG_ARCH_INTEGRATOR) $(CONFIG_ARCH_CLPS711X) \
$(CONFIG_FOOTBRIDGE) $(CONFIG_ARCH_EBSA110) \
$(CONFIG_ARCH_SA1100) $(CONFIG_ARCH_CAMELOT) \
$(CONFIG_ARCH_S3C2400) $(CONFIG_ARCH_S3C2410) \
$(CONFIG_ARCH_MX1ADS) $(CONFIG_ARCH_PXA)
obj-$(CONFIG_MIZI) += event.o
obj-$(CONFIG_APM) += apm2.o
h.修改arch/arm/kernel/debug-armv.S文件,在适当的位置增加如下关于S3C2410的代码:
#elif defined(CONFIG_ARCH_S3C2410)
.macro addruart,rx
mrc p15, 0, \rx, c1, c0
tst \rx, #1 @ MMU enabled ?
moveq \rx, #0x50000000 @ physical base address
movne \rx, #0xf0000000 @ virtual address
.endm
.macro senduart,rd,rx
str \rd, [\rx, #0x20] @ UTXH
.endm
.macro waituart,rd,rx
.endm
.macro busyuart,rd,rx
1001: ldr \rd, [\rx, #0x10] @ read UTRSTAT
tst \rd, #1 << 2 @ TX_EMPTY ?
beq 1001b
.endm
i.修改arch/arm/kernel/setup.c文件
此文件中的setup_arch非常关键,用来完成与体系结构相关的初始化:
void __init setup_arch(char **cmdline_p)
{
struct tag *tags = NULL;
struct machine_desc *mdesc;
char *from = default_command_line;
ROOT_DEV = MKDEV(0, 255);
setup_processor();
mdesc = setup_machine(machine_arch_type);
machine_name = mdesc->name;
if (mdesc->soft_reboot)
reboot_setup("s");
if (mdesc->param_offset)
tags = phys_to_virt(mdesc->param_offset);
/*
* Do the machine-specific fixups before we parse the
* parameters or tags.
*/
if (mdesc->fixup)
mdesc->fixup(mdesc, (struct param_struct *)tags,
&from, &meminfo);
/*
* If we have the old style parameters, convert them to
* a tag list before.
*/
if (tags && tags->hdr.tag != ATAG_CORE)
convert_to_tag_list((struct param_struct *)tags,
meminfo.nr_banks == 0);
if (tags && tags->hdr.tag == ATAG_CORE)
parse_tags(tags);
if (meminfo.nr_banks == 0) {
meminfo.nr_banks = 1;
meminfo.bank[0].start = PHYS_OFFSET;
meminfo.bank[0].size = MEM_SIZE;
}
init_mm.start_code = (unsigned long) &_text;
init_mm.end_code = (unsigned long) &_etext;
init_mm.end_data = (unsigned long) &_edata;
init_mm.brk = (unsigned long) &_end;
memcpy(saved_command_line, from, COMMAND_LINE_SIZE);
saved_command_line[COMMAND_LINE_SIZE-1] = '\0';
parse_cmdline(&meminfo, cmdline_p, from);
bootmem_init(&meminfo);
paging_init(&meminfo, mdesc);
request_standard_resources(&meminfo, mdesc);
/*
* Set up various architecture-specific pointers
*/
init_arch_irq = mdesc->init_irq;
#ifdef CONFIG_VT
#if defined(CONFIG_VGA_CONSOLE)
conswitchp = &vga_con;
#elif defined(CONFIG_DUMMY_CONSOLE)
conswitchp = &dummy_con;
#endif
#endif
}
j.修改arch/arm/mm/mm-armv.c文件(arch/arm/mm/目录中的文件完成与ARM相关的MMU处理)
修改
init_maps->bufferable = 0;
为
init_maps->bufferable = 1;