Target device is TMS320DM355 DVEVM.
The linux kernel is android version 2.6.23.
Cross compiled GCC is built by myself, the study source is Cross-Compiled Linux From Scratch - Embedded (Version SVN-0.0.1-20080109-arm).
A good reference document about porting linux kernel is "Porting the Linux Kernel to a New ARM Platform", Wookey and Tak-Shing, Aleph One
The last encountered problem is that the kernel can not boot from DVEVM board, the display information is as following:
2048 MiB
In: serial
Out: serial
Err: serial
ARM Clock :- 216MHz
DDR Clock :- 171MHz
Hit any key to stop autoboot: 0
BOOTP broadcast 1
DHCP client bound to address 192.168.1.101
TFTP from server 192.168.1.12; our IP address is 192.168.1.101
Filename 'uImage-android'.
Load address: 0x80700000
Loading: #################################################################
#################################################################
#################################################################
#################################################################
#################################################################
####################
done
Bytes transferred = 1764160 (1aeb40 hex)
## Booting image at 80700000 ...
Image Name: Linux-2.6.23
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 1764096 Bytes = 1.7 MB
Load Address: 80008000
Entry Point: 80008000
Verifying Checksum ... OK
OK
Starting kernel ...
Uncompressing Linux.................................................................................................................. done, booting the kernel.
After my basic analysis, it seems that it is related to the process of enabling the MMU, the dependent file is arch/arm/kernel/head.S; other possible files are arch/arm/mm/proc-arm926.S and arch/arm/mach-davinci/board-evm.c.
The most files that I have modified are listed as following:
arch/arm/tools/mach-types
arch/arm/Kconfig
arch/arm/Makefile
arch/arm/kernel/head.S
arch/arm/kernel/head-common.S
arch/arm/kernel/debug.S
arch/arm/mm/Kconfig
arch/arm/mach-davinci/Kconfig
arch/arm/mach-davinci/Makefile
arch/arm/mach-davinci/io.c
arch/arm/mach-davinci/irq.c
arch/arm/mach-davinci/time.c
arch/arm/mach-davinci/clock.c
arch/arm/mach-davinci/serial.c
arch/arm/mach-davinci/gpio.c
arch/arm/mach-davinci/psc.c
arch/arm/mach-davinci/board-evm.c
include/asm-arm/arch-davinci/
include/asm-arm/arch-davinci/gpio.h
include/asm-arm/arch-davinci/io.h
include/asm-arm/arch-davinci/dma.h
include/asm-arm/arch-davinci/memory.h
include/asm-arm/arch-davinci/system.h
include/asm-arm/arch-davinci/timex.h
include/asm-arm/arch-davinci/hardware.h
include/asm-arm/arch-davinci/cpu.h
include/asm-arm/arch-davinci/uncompress.h
include/asm-arm/mach/arch.h
include/asm-arm/setup.h
include/asm-arm/procinfo.h
The following context describes the modified source code in each files:
### arch/arm/tools/mach-types ###
# machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number
#
anakin ARCH_ANAKIN ANAKIN 57
davinci_dm355_evm MACH_DAVINCI_DM355_EVM DAVINCI_DM355_EVM 1381
### arch/arm/Kconfig ###
config LEDS
depends on ARCH_CDB89712 || ARCH_CO285 || ARCH_EBSA110 || \
ARCH_EBSA285 || ARCH_IMX || ARCH_INTEGRATOR || \
ARCH_LUBBOCK || MACH_MAINSTONE || ARCH_NETWINDER || \
ARCH_OMAP || ARCH_P720T || ARCH_PXA_IDP || \
ARCH_SA1100 || ARCH_SHARK || ARCH_VERSATILE || \
ARCH_AT91 || MACH_TRIZEPS4 || ARCH_DAVINCI || \
ARCH_KS8695 || MACH_DAVINCI_EVM
config LEDS_TIMER
bool "Timer LED" if (!ARCH_CDB89712 && !ARCH_OMAP) || \
OMAP_OSK_MISTRAL || MACH_OMAP_H2 \
|| MACH_OMAP_PERSEUS2 || MACH_DAVINCI_EVM
depends on LEDS || MACH_DAVINCI_EVM
if PCMCIA || ARCH_CLPS7500 || ARCH_IOP32X || ARCH_IOP33X || ARCH_IXP4XX \
|| ARCH_L7200 || ARCH_LH7A40X || ARCH_PXA || ARCH_RPC \
|| ARCH_S3C2410 || ARCH_SA1100 || ARCH_SHARK || FOOTBRIDGE \
|| ARCH_IXP23XX || ARCH_DAVINCI
source "drivers/ide/Kconfig"
endif
### arch/arm/Makefile ###
CPPFLAGS_vmlinux.lds = -DTEXT_OFFSET=$(TEXT_OFFSET)
machine-$(CONFIG_ARCH_DAVINCI) := davinci
#Default value
head-y := arch/arm/kernel/head$(MMUEXT).o arch/arm/kernel/init_task.o
textofs-y := 0x00008000
### arch/arm/kernel/head.S ###
/* line 81~93 */
.type stext, %function
ENTRY(stext)
msr cpsr_c, #PSR_F_BIT | PSR_I_BIT | SVC_MODE @ ensure svc mode
@ and irqs disabled
mrc p15, 0, r9, c0, c0 @ get processor id
bl __lookup_processor_type @ r5=procinfo r9=cpuid
movs r10, r5 @ invalid processor (r5=0)?
beq __error_p @ yes, error 'p'
bl __lookup_machine_type @ r5=machinfo
movs r8, r5 @ invalid machine (r5=0)?
beq __error_a @ yes, error 'a'
bl __vet_atags
bl __create_page_tables
# comment
__vet_atags:arch/arm/kernel/head-common.S
__create_page_tables
### arch/arm/kernel/head-common.S ###
/* line 80~114 */
.type __error_a, %function
__error_a:
#ifdef CONFIG_DEBUG_LL
mov r4, r1 @ preserve machine ID
adr r0, str_a1
bl printascii
mov r0, r4
bl printhex8
adr r0, str_a2
bl printascii
adr r3, 3f
ldmia r3, {r4, r5, r6} @ get machine desc list
sub r4, r3, r4 @ get offset between virt&phys
add r5, r5, r4 @ convert virt addresses to
add r6, r6, r4 @ physical address space
1: ldr r0, [r5, #MACHINFO_TYPE] @ get machine type
bl printhex8
mov r0, #'\t'
bl printch
ldr r0, [r5, #MACHINFO_NAME] @ get machine name
add r0, r0, r4
bl printascii
mov r0, #'\n'
bl printch
add r5, r5, #SIZEOF_MACHINE_DESC @ next machine_desc
cmp r5, r6
blo 1b
adr r0, str_a3
bl printascii
b __error
str_a1: .asciz "\nError: unrecognized/unsupported machine ID (r1 = 0x"
str_a2: .asciz ").\n\nAvailable machine support:\n\nID (hex)\tNAME\n"
str_a3: .asciz "\nPlease check your kernel config and/or bootloader.\n"
.align
#endif
### arch/arm/kernel/debug.S ###
Debug Serial Output
addruart, rx - Provide UART address in \rx
senduart rd, rx - Send character in \rd (@ address \rx)
busyuart rd, rx - Wait until UART is done sending
waituart rd, rx - Wait for Clear to Send
### arch/arm/mm/Kconfig ###
# ARM926T
config CPU_ARM926T
bool "Support ARM926T processor"
depends on ARCH_GOLDFISH || ARCH_INTEGRATOR || ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || MACH_REALVIEW_EB || ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 || ARCH_AT91SAM9260 || ARCH_AT91SAM9261 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_NS9XXX || ARCH_DAVINCI
default y if ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 || ARCH_AT91SAM9260 || ARCH_AT91SAM9261 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_NS9XXX || ARCH_DAVINCI
select CPU_32v5
select CPU_ABRT_EV5TJ
select CPU_CACHE_VIVT
select CPU_CP15_MMU
select CPU_COPY_V4WB if MMU
select CPU_TLB_V4WBI if MMU
select ARM_THUMB
help
This is a variant of the ARM920. It has slightly different
instruction sequences for cache and TLB operations. Curiously,
there is no documentation on it at the ARM corporate website.
Say Y if you want support for the ARM926T processor.
Otherwise, say N.
### arch/arm/mach-davinci/Kconfig ###
config ARCH_DAVINCI355
default n
bool "DaVinci DM355 based system"
comment "DaVinci Board Type"
config MACH_DAVINCI_EVM
bool "TI DaVinci EVM"
default y
depends on ARCH_DAVINCI644x
help
Configure this option to specify the whether the board used
for development is a DaVinci EVM
config MACH_DAVINCI_DM355_EVM
bool "TI DM355 EVM"
default n
depends on ARCH_DAVINCI355
help
Configure this option to specify the whether the board used
for development is a DM355 EVM
config DAVINCI_I2C_EXPANDER
bool "TI DaVinci I2C Expander"
default y
depends on ARCH_DAVINCI644x
select I2C_DAVINCI
help
Configure this option to specify whether the board used
has I2C exapnder with ATA, USB, CF.
config DAVINCI_MCBSP
bool
prompt "DaVinci McBSP Driver" if SOUND_DAVINCI=n
depends on ARCH_DAVINCI
default SOUND_DAVINCI
---help---
DaVinci McBSP driver. Auto-enabled by DaVinci sound driver.
comment "DaVinci Options"
config DAVINCI_BLK_DEV_CF
bool "TI DaVinci CF Card Support"
default Y
depends on BLK_DEV_DAVINCI
help
Configure this option to enable CF Card support.
config DM355_NAND_256KB_BLOCKS
bool "NAND chip installed on DM355 EVM has 256KB blocks"
default y
depends on MACH_DAVINCI_DM355_EVM
help
The boot firmware on the DM355 EVM assumes a default partition map
for NAND flash based on erase block offsets. Thus, the partition map
varies based on the size of the erase blocks in the particular NAND
flash component installed on the board. Answer Y here if the NAND
chip (e.g a 16 Gigabit Micron MT29F16G08QAA) installed on your board
has 256KB blocks. Answer N here if the NAND chip (e.g. a 4 Gigabit
Micron MT29F4G08AAA) installed on your board has 128KB blocks.
choice
prompt "Low-level debug console UART"
default DAVINCI_LL_DEBUG_UART0
config DAVINCI_LL_DEBUG_UART0
bool "UART0"
config DAVINCI_LL_DEBUG_UART1
bool "UART1"
endchoice
config DM355_SPI
bool "TI DM355 SPI device"
default y
help
Configure this option to specify whether the board used
has SPI device.
### arch/arm/mach-davinci/Makefile ###
# Common objects
obj-y := time.o irq.o clock.o serial.o io.o id.o psc.o gpio.o mux.o
# Board specific
# obj-$(CONFIG_MACH_DAVINCI_EVM) += board-evm.o
obj-$(CONFIG_MACH_DAVINCI_DM355_EVM) += board-evm.o
### arch/arm/mach-davinci/io.c ###
static struct map_desc davinci_io_desc[] __initdata = {
{
.virtual = IO_VIRT,
.pfn = __phys_to_pfn(IO_PHYS),
.length = IO_SIZE,
.type = MT_DEVICE
},
{
.virtual = DAVINCI_IRAM_VIRT,
.pfn = __phys_to_pfn(DAVINCI_IRAM_BASE),
.length = SZ_16K,
.type = MT_DEVICE
},
};
void __init davinci_map_common_io(void)
{
...
davinci_clk_init();
}
### arch/arm/mach-davinci/irq.c ###
### arch/arm/mach-davinci/time.c ###
### arch/arm/mach-davinci/clock.c ###
#include
int __init davinci_clk_init(void)
{
...
if (cpu_is_davinci_dm355()) {
/*
* FIXME
* We're assuming a 24MHz reference, but the DM355 also
* supports a 36MHz reference.
*/
unsigned long postdiv;
/*
* Read the PLL1 POSTDIV register to determine if the post
* divider is /1 or /2
*/
postdiv = (davinci_readl(DAVINCI_PLL_CNTRL0_BASE + 0x128) & 0x1f) + 1;
fixedrate = 24000000;
armrate = (PLL1_PLLM + 1)*(fixedrate/(16*postdiv));
commonrate = armrate/2;
} else {
...
}
...
}
### arch/arm/mach-davinci/serial.c ###
void __init davinci_serial_init(struct platform_device *pdev)
{
struct clk *uart_clk;
struct device *dev = &pdev->dev;
struct plat_serial8250_port *p;
int uart;
char uart_name[6];
memset(uart_name, 0, sizeof(uart_name));
for (p = dev->platform_data; p && p->flags; p++) {
switch (p->mapbase) {
case DAVINCI_UART0_BASE:
uart = 0;
break;
case DAVINCI_UART1_BASE:
uart = 1;
break;
case DM644X_UART2_BASE:
case DM355_UART2_BASE:
uart = 2;
break;
default:
dev_err(dev,
"Unknown UART base address 0x%08lx\n",
p->mapbase);
continue;
}
sprintf(uart_name, "UART%i", uart);
uart_clk = clk_get(dev, uart_name);
if (IS_ERR(uart_clk))
dev_err(dev, "failed to get %s clock\n", uart_name);
else
clk_enable(uart_clk);
davinci_serial_reset(p);
}
}
### arch/arm/mach-davinci/gpio.c ###
int gpio_interrupt_bank_enable(int gpio)
{
void *__iomem ptr1;
u32 temp = 0;
u32 mask = 0;
u32 gpio_bank;
u32 max_gpio = 0;
if (cpu_is_davinci_dm355())
max_gpio = DM355_NUM_GIOS;
else if (cpu_is_davinci_dm6443())
max_gpio = DM644x_NUM_GIOS;
if (gpio >= max_gpio)
return -EINVAL;
gpio_bank = gpio/16;
ptr1 = (void *__iomem) IO_ADDRESS(DAVINCI_GPIO_BASE + 0x8);
mask = (1 << temp =" __raw_readl(ptr1);" g =" gpio2controller(gpio);" mask =" gpio_mask(gpio);">set_rising);
if (trigger & TRIGGER_FALLING_EDGE)
__raw_writel(mask, &g->set_falling);
return 0;
}
EXPORT_SYMBOL(gpio_interrupt_enable);
int gpio_interrupt_disable(unsigned gpio, int trigger)
{
struct gpio_controller *__iomem g = gpio2controller(gpio);
u32 mask;
if (!g)
return -EINVAL;
if (trigger & ~(TRIGGER_RISING_EDGE|TRIGGER_FALLING_EDGE))
return -EINVAL;
mask = gpio_mask(gpio);
if (trigger & TRIGGER_RISING_EDGE)
__raw_writel(mask, &g->clr_rising);
if (trigger & TRIGGER_FALLING_EDGE)
__raw_writel(mask, &g->clr_falling);
return 0;
}
EXPORT_SYMBOL(gpio_interrupt_disable);
### arch/arm/mach-davinci/psc.c ###
void __init davinci_psc_init(void)
{
// board_setup_psc() - in DM355
...
davinci_psc_config(DAVINCI_GPSC_ARMDOMAIN, DAVINCI_LPSC_McBSP1, 1);
davinci_psc_config(DAVINCI_GPSC_ARMDOMAIN, DAVINCI_LPSC_SPI, 1);
/* Turn on WatchDog timer LPSC. Needed for RESET to work */
davinci_psc_config(DAVINCI_GPSC_ARMDOMAIN, DAVINCI_LPSC_TIMER2, 1);
davinci_serial_init(&serial_device);
davinci_writel(0x56837210, DAVINCI_VPSS_REGS_BASE + 0x810);
davinci_writel(0x7b3c0004, DAVINCI_VPSS_REGS_BASE + 0x814);
}
### arch/arm/mach-davinci/board-evm.c ###
MACHINE_START(DAVINCI_EVM, "DaVinci DM355 EVM")
/* Maintainer: MontaVista Software
4 comments:
Hi,I'm very interesting in your work. Can you send me your congress if possiable? Contact me at ouyang.nupt(at)gmail.com. Thanks!
Sorry for my late reply! I have e-mailed to you. :D
hi,I'm very interesting in your work, too. can you send me your congress if possiable? and my platform is dm6441.Contact me at yzq,seen@gmail.com. Thank you!
hi,I'm very interesting in your work, too. can you send me your congress if possiable? and my platform is dm6441.Contact me at yzq.seen@gmail.com. Thank you!
Post a Comment