写一个bare metal程序,使用uboot go执行:
start.S
1 2 3 4 5 6  |     .text    .global _start_start:    b mainloop:    b loop | 
led.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102  | struct ipq_timer_platdata {    unsigned int gcnt_cntcv_lo;    unsigned int gcnt_cntcv_hi;    unsigned int gpt_freq_hz;    unsigned long long timer_load_val;} ipq_timer = {};#define readl(addr) *(volatile unsigned long *)(addr)#define writel(val, addr) *(volatile unsigned long *)(addr) = (val)unsigned usec2tick(unsigned usec){    return ipq_timer.gpt_freq_hz / 1000 / 1000 * usec;}static unsigned long long read_counter(void){    unsigned long vect_hi1, vect_hi2;    unsigned long vect_low;repeat:    vect_hi1 = readl(ipq_timer.gcnt_cntcv_hi);    vect_low = readl(ipq_timer.gcnt_cntcv_lo);    vect_hi2 = readl(ipq_timer.gcnt_cntcv_hi);    if (vect_hi1 != vect_hi2)        goto repeat;    return ((unsigned long long)vect_hi1 << 32 | vect_low);}void timer_init(){    ipq_timer.gcnt_cntcv_lo = 0x4a2000;    ipq_timer.gcnt_cntcv_hi = 0x4a2004;    ipq_timer.gpt_freq_hz = 24000000;    ipq_timer.timer_load_val = 0x00FFFFFFFFFFFFFF;}void udelay(unsigned usec){    unsigned long long val;    unsigned long long now;    unsigned long long last;    unsigned long long runcount;    val = usec2tick(usec);    last = read_counter();    do {        now = read_counter();        if (last > now)            runcount = (ipq_timer.timer_load_val - last) + now;        else            runcount = now - last;    } while (runcount < val);}#define TLMM_BASE              0x01000000#define GPIO_CONFIG_ADDR(x)            (TLMM_BASE + (x)*0x1000)#define GPIO_IN_OUT_ADDR(x)            (TLMM_BASE + 0x4 + (x)*0x1000)#define GPIO_INPUT              0#define GPIO_OUTPUT             1#define BUTTON_PRESSED 0#define BUTTON_RELEASED 1#define BUTTON_RESET 25#define BLUE_LED     19#define YELLOW_LED   17void gpio_set_value(unsigned int gpio, unsigned int out){    unsigned int *addr = (unsigned int *)GPIO_IN_OUT_ADDR(gpio);    unsigned int val = 0;    val = readl(addr);    val &= ~(0x2);    val |= out << 1;    writel(val, addr);}int gpio_get_value(unsigned int gpio){    unsigned int *addr = (unsigned int *)GPIO_IN_OUT_ADDR(gpio);    unsigned int val = readl(addr);    return (val & 1);}void main(){    timer_init();    while (1) {        udelay(1000*1000);        gpio_set_value(BLUE_LED, 0);        udelay(1000*1000);        gpio_set_value(BLUE_LED, 1);    }} | 
链接脚本 led.lds
1 2 3 4 5 6  | SECTIONS{    . = 0x44000000;    .text : { *(.text) }    .data : { *(.data) }} | 
Makefile
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16  | CROSS_COMPILE := /work/ax3000/staging_dir/toolchain-arm_cortex-a7_gcc-5.5.0_musl_eabi/bin/arm-openwrt-linux-CC := $(CROSS_COMPILE)gccAS := $(CROSS_COMPILE)asLD := $(CROSS_COMPILE)ldOBJCOPY := $(CROSS_COMPILE)objcopyOBJDUMP := $(CROSS_COMPILE)objdumpall:    $(AS) -o start.o start.S    $(CC) -c -g -o led.o led.c    $(LD) -o led.elf -T bare.lds start.o led.o    $(OBJCOPY) -O binary -S led.elf led.bin    $(OBJDUMP) -S led.elf > led.elf.dis    $(OBJDUMP) -b binary --adjust-vma=0x44000000 -m arm -D led.bin > led.bin.dis    cp led.bin /work/tftproot/ | 
将led.elf上传。使用go执行,可以看到可以闪灯。