当前位置:首页 > 工具 > 正文内容

NBOOT - 串口与NAND FLASH功能实现

访客 工具 2026年5月27日 3
为了增强NBOOT的功能,本文将介绍如何添加串口调试和NAND FLASH支持。以下是具体步骤:

一、串口功能配置

在调试过程中,通过串口输出信息可以有效帮助定位问题。以下是实现方法:

  1. 修改默认的UART设置:打开 \SRC\INC\bsp_cfg.h 文件,调整为使用UART0。
#define BSP_UART0_ULCON         0x03    // 配置数据位、停止位和校验
#define BSP_UART0_UCON          0x0005  // 池模式,PCLK作为UART时钟源
#define BSP_UART0_UFCON         0x00    // 禁用FIFO
#define BSP_UART0_UMCON         0x00    // 禁用自动流控
#define BSP_UART0_UBRDIV        (S3C2410X_PCLK/(115200*16) - 1) // 波特率分频器
  1. 创建并实现串口初始化及字符串输出功能:在nboot目录下新建 debug.c 文件,并将其加入工程中。
#include <bsp.h>

VOID UART_Init() {
    volatile S3C2410X_IOPORT_REG *ioPort = (S3C2410X_IOPORT_REG*)(S3C2410X_BASE_REG_PA_IOPORT);
    volatile S3C2410X_UART_REG *uartReg = (S3C2410X_UART_REG *)(S3C2410X_BASE_REG_PA_UART0);

    ioPort->GPHCON &= ~((3 << 4)|(3 << 6));   // 清除原有配置
    ioPort->GPHCON |= (2 << 4)|(2 << 6);      // 设置GPH2/GHP3为UART0 Tx/Rx

    ioPort->GPHUP |= (1 << 2)|(1 << 3);       // 禁用TXD0和RXD0的上拉电阻

    uartReg->UFCON = BSP_UART0_UFCON;        // 禁用FIFO
    uartReg->UMCON = BSP_UART0_UMCON;        // 禁用自动流控
    uartReg->ULCON = BSP_UART0_ULCON;        // 数据格式配置
    uartReg->UCON = BSP_UART0_UCON;          // UART控制寄存器配置
    uartReg->UBRDIV = BSP_UART0_UBRDIV;      // 波特率分频器设置
}

static VOID Send_Char(UINT8 ch) {
    volatile S3C2410X_UART_REG *uartReg = (S3C2410X_UART_REG *)(S3C2410X_BASE_REG_PA_UART0);

    while (!(uartReg->UTRSTAT & 0x02));       // 等待发送缓冲区为空
    uartReg->UTXH = ch;                      // 发送字符
}

VOID Print_String(LPWSTR str) {
    while (*str != L'\0') {
        Send_Char((UINT8)*str++);
    }
}

完成上述步骤后,可以通过调用 Print_String(TEXT("Hello World!\\r\\n")) 来测试串口输出。

二、NAND FLASH功能配置

NAND FLASH读取代码较为复杂,但通常BSP中已有现成代码可供参考。以下是实现步骤:

  1. 在nboot目录下新建 flash.c 文件,并加入工程;同时复制相关文件:nand.snand.h
void Init_NAND_Controller() {
    s2410NAND = (S3C2410X_NAND_REG *)NAND_BASE;

    s2410NAND->NFCONF = 
        (1 << 15) | // 启用控制器
        (1 << 14) | // 页面大小:512字节
        (1 << 13) | // 地址步数:4步
        (1 << 12) | // 初始化ECC
        (1 << 11) | // nFCE控制:高电平
        (TACLS << 0) | // CLE/ALE延迟
        (TWRPH0 << 3) | // 写周期第一阶段延迟
        (TWRPH1 << 0);  // 写周期第二阶段延迟

    NF_nFCE_L(); // 选中芯片
    NF_CMD(CMD_RESET); // 发送复位命令
    NF_WAITRB(); // 等待操作完成
    NF_nFCE_H(); // 取消选中芯片
}

BOOL Read_Sector(DWORD addr, LPBYTE buffer, DWORD count) {
    ULONG sectorAddr = (ULONG)addr;
    ULONG blockPage;

    NF_RSTECC(); // 初始化ECC
    NF_nFCE_L(); // 选中芯片
    NF_CMD(CMD_RESET); // 发送复位命令

    while (count--) {
        blockPage = (((sectorAddr / NAND_PAGE_CNT) * NAND_PAGE_CNT) | (sectorAddr % NAND_PAGE_CNT));

        NF_WAITRB(); // 等待命令完成

        if (buffer) {
            NF_CMD(CMD_READ); // 发送读命令
            NF_ADDR(0); // 列地址
            NF_ADDR(blockPage & 0xff); // 页地址低位
            NF_ADDR((blockPage >> 8) & 0xff); // 中间位
            NF_ADDR((blockPage >> 16) & 0xff); // 高位
            NF_WAITRB(); // 等待命令完成

            RdPage512(buffer); // 读取页面数据
            NF_RDDATA(); // 读取状态
            NF_RDDATA();

            buffer += NAND_PAGE_SIZE;
        }

        ++sectorAddr;
    }

    NF_nFCE_H(); // 取消选中芯片
    return TRUE;
}
  1. 确保NAND控制器寄存器地址正确,例如 #define NAND_BASE 0x4e000000,并在 nand.s 文件中同步更新。

三、主程序整合

在main函数中按顺序调用以下函数:

UART_Init();
Init_NAND_Controller();
Read_Sector(0x30021000, buffer, 0x00040000 / 512); // 加载EBOOT到RAM
Launch(0x30021000); // 启动EBOOT
标签: S3C2410XUART

相关文章

Trojan服务器搭建与配置

一、整体架构(先对齐认知)Clash Meta (PC / iOS / Android)        ↓ TLS   Trojan Server (443)        ↓     InternetTrojan 的核心是: TLS + HTTPS 流量伪装 看起来像正常网站 非常适合...

Tailscale 的详细用法

Tailscale 是一种基于 WireGuard 协议 的 零配置 VPN(虚拟私有网络)服务,让设备之间能够 安全、加密地直接连接,就像它们在同一个本地网络一样。它的核心特点是 简单、安全、跨平台。Tailscale 非常适合 没有公网 IP、两台电脑不在同一局域网 的场景。 简单来说,Tailscale 是什么?Tailscale 是一款让你的各种设备(电脑、服务器、手机...

Clash Tun 模式 导致 爱快(iKuai SD-Wan)内网域名无法访问

一、Clash  DNS 配置dns:  enable: true  listen: 0.0.0.0:53  ipv6: true  enhanced-mode: redir-host  nameserver:    - 223.5.5.5    - 223.6.6.6iKuai 内网域名 ...

深入解析Node.js运行环境与异步I/O架构

深入解析Node.js运行环境与异步I/O架构

核心定义与价值Node.js本质上是一个JavaScript运行环境,而非编程语言或应用框架。它赋予了JavaScript脱离浏览器在服务端、命令行工具及网络应用中执行的能力。其核心意义在于:用单一语言打通前后端开发壁垒。基于事件驱动与非阻塞I/O的架构特性,Node.js在处理API网关、实时通信及微服务等I/O密集型场景时表现卓越,已成为现代后端工程的主流选择。浏览器沙箱限制1995年Java...

ADO.NET SQL参数化查询的最佳实践

在 ADO.NET 中执行 SQL 查询时,参数化查询是一种关键的安全措施和性能优化手段。它通过将 SQL 命令和用户提供的数据分开处理,有效防止了 SQL 注入攻击,并有助于数据库缓存执行计划。下面总结了几种常用的参数化查询方式。 1. 使用 SqlParameter 对象(推荐) 这是最推荐的参数化查询方式。通过显式创建 SqlParameter 对象,您可以精确控制参数的类...

基于ELK的日志集中化分析系统搭建

构建统一日志管理平台的必要性 在分布式架构中,各服务节点独立运行,日志分散存储于不同主机。传统通过命令行工具如grep、awk逐个检索日志的方式,在数据量庞大时效率极低,难以实现快速定位问题。为提升运维效率,需建立集中式日志处理体系,具备日志采集、传输、存储、分析与告警能力。 ELK技术栈核心组件解析 Elasticsearch:分布式搜索引擎,支持全文检索、实时数据分析和高可用集群部署,...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。