ahau 发表于 2019-6-30 13:09:12

start.S点亮LED

大家好,我参考了白菜板和u-boot的启动代码,想在start.S里点亮LED,但是没成功。我用的是智龙开发板V2.1。搞了很长时间,实在不知道什么原因,请大家帮帮我。


这是我的start.S文件:
#include <asm/regdef.h>
#include <asm/mipsregs.h>
#define SR_BOOT_EXC_VEC                0x00400000
#define LS1X_SPI_SFC_PARAM        0x1b

#define SDRAM_DIV_2                0x0
#define PLL_MULT                0x54                /* CPU LCD CAM及外设倍频 */
#define SDRAM_DIV                SDRAM_DIV_2        /* LS1C的SDRAM分频 */
#define CPU_DIV                2                        /* LS1C的CPU分频 */
#define PLL_FREQ                (0x80000008 | (PLL_MULT << 8) | (0x3 << 2) | SDRAM_DIV)
#define PLL_DIV                (0x00008003 | (CPU_DIV << 8))
/* Delay macro */
#define DELAY(count)        \
        li                t2, count;        \
99:                                                \
        nop;                                \
        subu        t2, 0x1;        \
        bnez        t2, 99b;        \
        nop

        .set noreorder

        .globl _start
        .text

_start:
        b        reset
        nop

reset:
        /* Clear watch registers,这一步是否必需? */
        mtc0        zero, CP0_WATCHLO
        mtc0        zero, CP0_WATCHHI

        mtc0        zero, CP0_STATUS// 清零cp0 status寄存器 $12
        mtc0        zero, CP0_CAUSE   // 清零cp0 cause寄存器 $13

        /*
    设置启动异常向量入口地址为ROM地址(0xbfc00000)
    将寄存器cp0 status的BEV置1,使CPU采用ROM(kseg1)空间的异常入口点
    */
        li        t0, SR_BOOT_EXC_VEC        /* Exception to Boostrap Location */
        mtc0        t0, CP0_STATUS

        /* initialize spi */
        lit0, 0xbfe80000      //地址0xbfe80000为SPI0的寄存器基地址
        lit1, 0x1b
        //lit1, 0x17                // div 4, fast_read + burst_en + memory_en double I/O 模式 部分SPI flash可能不支持
        sbt1, 0x4(t0)                // 设置寄存器sfc_param
        lit1, 0x05
        sbt1, 0x6(t0)         // 设置寄存器sfc_timing
       

        /* config pll div for cpu and sdram */
        li        t0, 0xbfe78030
        /* 设置PLL倍频 及SDRAM分频 */
        li        t2, PLL_FREQ
        /* 设置CPU分频 */
        li        t3, PLL_DIV
        /* 注意:首先需要把分频使能位清零 */
        li        t1, 0x2
        sw        t1, 0x4(t0)
        sw        t2, 0x0(t0)
        sw        t3, 0x4(t0)
        DELAY(4096)
       
        // 尝试点亮LED
        // LED5 CMADATA0 GPIO050, 在GPIO1这个组里。这个是我看电路图猜的,不知道对不对?
        li a0, 0xbfd00000
        li t1, 0xffffffff
        sw t1, 0x10c4(a0)    // 配置寄存器,1表示不复用,即普通的GPIO
       
        li t0, 0x0
        sw t0, 0x10d4(a0)    // 使能寄存器 0表示配置为输出



blink:
        li t0, 0xffffffff
        sw t0, 0x10f4(a0)    // 输出寄存器 1表示输出高电平
        DELAY(50000)
       
        li t0, 0x0
        sw t0, 0x10f4(a0)    // 输出寄存器 0表示输出低电平
        DELAY(50000)
        b blink
        nop


编译和链接的指令我是从u-boot里拷贝的,为了方便编译,我写了一个简单的Makefile:

start.o:
        echo "compiling u-boot..."
        mipsel-linux-gcc   -D__ASSEMBLY__ -g-Os   -ffunction-sections -fdata-sections -D__KERNEL__ -DCONFIG_SYS_TEXT_BASE=0xbfc00000 -I/mnt/hgfs/CentOS_Share/trystart -fno-builtin -ffreestanding -nostdinc -isystem /opt/gcc-4.3-ls232/bin/../lib/gcc/mipsel-linux/4.3.0/include -pipe-DCONFIG_MIPS -D__MIPS__ -G 0 -mabicalls -fpic -EL -msoft-float -march=mips32 -mabi=32 -DCONFIG_32BIT   -o start.o start.S -c
        echo "echo "linking u-boot...""
        mipsel-linux-ld-G 0 -static -n -nostdlib -EL -m elf32ltsmip -T u-boot.lds --gc-sections -pie -Bstatic -Ttext 0xbfc00000 start.o -L /opt/gcc-4.3-ls232/bin/../lib/gcc/mipsel-linux/4.3.0 -lgcc -Map u-boot.map -o u-boot
        echo "generating u-boot.bin..."
        mipsel-linux-objcopy --remove-section=.dynsym --gap-fill=0xff -O binary u-boot u-boot.bin
        echo "done!"

.PHONY : clean

clean:
        rm -f start.o u-boot u-boot.map u-boot.bin

本来不准备使用链接脚本的,但是不使用链接脚本,会填充很多无用的数据,导致.bin文件非常大。链接脚本就是移植好的原生的u-boot.lds。
这个移植好的u-boot我试过,烧到板子里是可以跑起来的。

u-boot.lds:
/*
* (C) Copyright 2003
* Wolfgang Denk Engineering, <wd@denx.de>
*
* SPDX-License-Identifier:        GPL-2.0+
*/



OUTPUT_ARCH(mips)
ENTRY(_start)
SECTIONS
{
        . = 0x00000000;

        . = ALIGN(4);
        .text : {
                *(.text*)
        }

        . = ALIGN(4);
        .rodata : {
                *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*)))
        }

        . = ALIGN(4);
        .data : {
                *(.data*)
        }

        . = .;
        _gp = ALIGN(16) + 0x7ff0;

        .got : {
                *(.got)
        }

        num_got_entries = SIZEOF(.got) >> 2;

        . = ALIGN(4);
        .sdata : {
                *(.sdata*)
        }

        . = ALIGN(4);
        .u_boot_list : {
                KEEP(*(SORT(.u_boot_list*)));
        }

        . = ALIGN(4);
        __image_copy_end = .;

        .rel.dyn : {
                __rel_dyn_start = .;
                *(.rel.dyn)
                __rel_dyn_end = .;
        }

        .deadcode : {
                /*
               * Workaround for a binutils feature (or bug?).
               *
               * The GNU ld from binutils puts the dynamic relocation
               * entries into the .rel.dyn section. Sometimes it
               * allocates more dynamic relocation entries than it needs
               * and the unused slots are set to R_MIPS_NONE entries.
               *
               * However the size of the .rel.dyn section in the ELF
               * section header does not cover the unused entries, so
               * objcopy removes those during stripping.
               *
               * Create a small section here to avoid that.
               */
                LONG(0xffffffff);
        }

        .dynsym : {
                *(.dynsym)
        }

        .bss __rel_dyn_start (OVERLAY) : {
                __bss_start = .;
                *(.sbss.*)
                *(.bss.*)
                *(COMMON)
                . = ALIGN(4);
                __bss_end = .;
        }

        /DISCARD/ : {
                *(.dynbss)
                *(.dynstr)
                *(.dynamic)
                *(.interp)
                *(.hash)
                *(.gnu.*)
                *(.plt)
                *(.got.plt)
                *(.rel.plt)
        }
}



ahau 发表于 2019-6-30 13:27:19

不知道是我GPIO没找对,还是哪地方写错了。上电后没反应。项目文件我放在附件里了,实在不知道哪里错了,请大牛指点一下。


cyberhero 发表于 2019-6-30 21:05:43

可以先串口連接智龍試一下gpio是否找對了。
#!/bin/sh
echo "test"
echo 52 > /sys/class/gpio/export
echo out > /sys/class/gpio/gpio52/direction
while true
do
    echo 0 > /sys/class/gpio/gpio52/value
    sleep 0.1
    echo 1 > /sys/class/gpio/gpio52/value
    sleep 0.1
done

ahau 发表于 2019-6-30 21:22:10

cyberhero 发表于 2019-6-30 21:05
可以先串口連接智龍試一下gpio是否找對了。
#!/bin/sh
echo "test"


我是看电路图找的。CAMDATA0,110管脚,查了用户手册是GPIO050。

我已经把pmon擦除了,没办法用串口试了。

ahau 发表于 2019-7-2 22:21:54

找到原因了,低电平是点亮。还要注意li和lw的区别。。

cyberhero 发表于 2019-7-3 20:44:48

有時間可以寫個詳細的教程

ahau 发表于 2019-7-3 23:12:17

cyberhero 发表于 2019-7-3 20:44
有時間可以寫個詳細的教程

正在做了:)

sn2015ol 发表于 2019-7-10 17:01:42

ahau 发表于 2019-7-3 23:12
正在做了

发些图片吧

ahau 发表于 2019-7-15 19:35:37

sn2015ol 发表于 2019-7-10 17:01
发些图片吧

:)写了一个分享的帖子
http://www.openloongson.org/forum.php?mod=viewthread&tid=23506&page=1&extra=#pid26011
页: [1]
查看完整版本: start.S点亮LED