虚拟机环境:Oracle VM VirtualBox
Linux系统:ubuntu_14.04.6
交叉编译工具:[100ask分享的所有文件](https://eyun.baidu.com/s/3b1UtLc)
100ask分享的所有文件 > 002_JZ2440资料光盘_20180516(免费) > 资料光盘 > A盘 > tools.zip > arm-linux-gcc-4.3.2.tar.bz2
gcc-3.4.5-glibc-2.3.6/bin
第一步:查看原理图
left | middle | right |
---|---|---|
nLED4 | nLED2 | nLED1 |
GPF6 | GPF5 | GPF4 |
输出低电平点亮LED灯
输出高电平熄灭LED灯
第二步:查看芯片手册
寄存器 | 地址 | 配置 |
---|---|---|
BWSCON | 0x48000000 | 0x22011110 |
BANKCON0 | 0x48000004 | 0x00000700 |
BANKCON1 | 0x48000008 | 0x00000700 |
BANKCON2 | 0x4800000C | 0x00000700 |
BANKCON3 | 0x48000010 | 0x00000700 |
BANKCON4 | 0x48000014 | 0x00000700 |
BANKCON5 | 0x48000018 | 0x00000700 |
BANKCON6 | 0x4800001C | 0x00018005 |
BANKCON7 | 0x48000020 | 0x00018005 |
REFRESH | 0x48000024 | 0x008C07A3 |
BANKSIZE | 0x48000028 | 0x000000B1 |
MRSRB6 | 0x4800002C | 0x00000030 |
MRSRB7 | 0x48000030 | 0x00000030 |
第三步:编写程序
head.S:
.text
.global _start
_start:
ldr sp,=4096
bl disable_watch_dog
bl memsetup
bl copy_2th_to_sdram
bl create_page_table
bl mmu_init
ldr sp,=0xB4000000
ldr pc,=0xB0004000
halt_loop:
b halt_loop
init.c:
#define WTCON (*(volatile unsigned long *)0x53000000)
#define MEM_CTL_BASE 0x48000000
void disable_watch_dog(void)
{
WTCON = 0;
}
void memsetup(void)
{
unsigned long const mem_cfg_val[] = {
0x22011110,
0x00000700,
0x00000700,
0x00000700,
0x00000700,
0x00000700,
0x00000700,
0x00018005,
0x00018005,
0x008C07A3,
0x000000B1,
0x00000030,
0x00000030,
};
int i = 0;
volatile unsigned long *p = (volatile unsigned long *)MEM_CTL_BASE;
for (; i < 13; i ++)
p[i] = mem_cfg_val[i];
}
void copy_2th_to_sdram(void)
{
unsigned int *pdwSrc = (unsigned int *)2048;
unsigned int *pdwDest = (unsigned int *)0x30004000;
while (pdwSrc < (unsigned int *)4096) {
*pdwDest = *pdwSrc;
pdwDest ++;
pdwSrc ++;
}
}
void create_page_table(void)
{
#define MMU_FULL_ACCESS (3<<10)
#define MMU_DOMAIN (0<<5)
#define MMU_SPECIAL (1<<4)
#define MMU_CACHEABLE (1<<3)
#define MMU_BUFFERABLE (1<<2)
#define MMU_SECTION (2)
#define MMU_SECDESC (MMU_FULL_ACCESS|MMU_DOMAIN|MMU_SPECIAL|MMU_SECTION)
#define MMU_SECDESC_WB (MMU_FULL_ACCESS|MMU_DOMAIN|MMU_SPECIAL|MMU_CACHEABLE|MMU_BUFFERABLE|MMU_SECTION)
#define MMU_SECTION_SIZE 0x00100000
unsigned long virtual_addr, physical_addr;
unsigned long *mmu_tlb_base = (unsigned long *)0x30000000;
virtual_addr = 0;
physical_addr = 0;
*(mmu_tlb_base + (virtual_addr >> 20)) = (physical_addr & 0xFFF00000) | MMU_SECDESC_WB;
virtual_addr = 0xA0000000;
physical_addr = 0x56000000;
*(mmu_tlb_base + (virtual_addr >> 20)) = (physical_addr & 0xFFF00000) | MMU_SECDESC;
virtual_addr = 0xB0000000;
physical_addr = 0x30000000;
while (virtual_addr < 0xB4000000) {
*(mmu_tlb_base + (virtual_addr >> 20)) = (physical_addr & 0xFFF00000) | MMU_SECDESC_WB;
virtual_addr += 0x100000;
physical_addr += 0x100000;
}
}
void mmu_init(void)
{
unsigned long ttb = 0x30000000;
__asm__(
"mov r0, #0\n"
"mcr p15, 0, r0, c7, c7, 0\n"
"mcr p15, 0, r0, c7, c10, 4\n"
"mcr p15, 0, r0, c8, c7, 0\n"
"mov r4, %0\n"
"mcr p15, 0, r4, c2, c0, 0\n"
"mvn r0, #0\n"
"mcr p15, 0, r0, c3, c0, 0\n"
"mrc p15, 0, r0, c1, c0, 0\n"
"bic r0, r0, #0x3000\n"
"bic r0, r0, #0x0300\n"
"bic r0, r0, #0x0087\n"
"orr r0, r0, #0x0002\n"
"orr r0, r0, #0x0004\n"
"orr r0, r0, #0x1000\n"
"orr r0, r0, #0x0001\n"
"mcr p15, 0, r0, c1, c0, 0\n"
:
: "r" (ttb));
}
leds.c:
#define GPFCON (*(volatile unsigned long *)0xA0000050)
#define GPFDAT (*(volatile unsigned long *)0xA0000054)
static inline void wait(unsigned long dly)
{
for (; dly > 0; dly --);
}
int main(void)
{
unsigned long i = 0;
GPFCON = 0x00001500;
GPFDAT = 0x00000070;
while (1) {
wait(300000);
GPFDAT = (~(i<<4));
if (++ i == 8)
i = 0;
}
return 0;
}
第四步:编写链接脚本和makefile
mmu.lds:
SECTIONS {
first 0x00000000 : { head.o init.o }
second 0xB0004000 : AT(2048) { leds.o }
}
makefile:
ARM_LINUX_XXX=/home/xlbtlmy/Desktop/ARM_Linux/gcc-3.4.5-glibc-2.3.6/bin
CC=$(ARM_LINUX_XXX)/arm-linux-gcc
LD=$(ARM_LINUX_XXX)/arm-linux-ld
OBJCOPY=$(ARM_LINUX_XXX)/arm-linux-objcopy
OBJDUMP=$(ARM_LINUX_XXX)/arm-linux-objdump
TARGET=$(OPT)
LDS=$(shell ls *.lds)
src_c=$(shell ls *.c)
objs_c=$(patsubst %.c,%.o,$(src_c))
src_s=$(shell ls *.S)
objs_s=$(patsubst %.S,%.o,$(src_s))
objs=$(objs_c) $(objs_s)
BIN=$(TARGET).bin
ELF=$(TARGET).elf
DIS=$(TARGET).dis
$(BIN):$(objs)
$(LD) -T$(LDS) $^ -o $(ELF)
$(OBJCOPY) -O binary -S $(ELF) $(BIN)
$(OBJDUMP) -D -m arm $(ELF) > $(DIS)
%.o:%.c
$(CC) -Wall -O2 -c -o $@ $<
%.o:%.S
$(CC) -Wall -O2 -c -o $@ $<
.PHONY:clean
clean:
rm -f *.o *.bin *.elf *.dis
make OPT=leds
第五步:烧录运行
eop.bat:
@echo off
:JTAG(0:OpenJTAG 1:DongleJTAG 2:Wiggler)
SET JTAG=0
:CPU(0:S3C2410 1:S3C2440 2:S3C6410)
SET CPU=1
:Flash(0:Nand 1:Nor)
SET Flash=0
:Access(0:Write 1:Read)
SET Access=0
:Offset()
SET Offset=0
:File()
SET File=leds.bin
oflash %JTAG% %CPU% %Flash% %Access% %Offset% %File%
pause
第五步:观察实验现象
流水灯,速度较快