移植u-boot-2010.09到三星SC32442平台(二):nand读写和ax88180以太网支持

本文介绍U-Boot在S3C2442平台上的NAND闪存支持移植过程及AX88180以太网控制器的驱动集成。详细讲述了如何添加NAND闪存读写功能、配置环境变量存储位置,并实现网络功能。

接着上一篇文章:(字体我就不改了)

 

4.添加u-bootnand的读写功能

因为24422440差别不大,现参照2440的移植方法进行操作:

driver/mtd/nand下添加s3c2440_nand.c文件,内容如下:

#include <common.h>

#if 0

#define DEBUGN    printf

#else

#define DEBUGN(x, args ...) {}

#endif

#include <nand.h>

#include <asm/arch/s3c24x0_cpu.h>

#include <asm/io.h>

#define __REGb(x)    (*(volatile unsigned char *)(x))

#define __REGi(x)    (*(volatile unsigned int *)(x))

#define NF_BASE  0x4e000000            

#define NFCONF   __REGi(NF_BASE + 0x0) 

#define NFCONT   __REGi(NF_BASE + 0x4) 

#define NFCMD    __REGb(NF_BASE + 0x8) 

#define NFADDR   __REGb(NF_BASE + 0xc) 

#define NFDATA   __REGb(NF_BASE + 0x10)

#define NFMECCD0 __REGi(NF_BASE + 0x14)

#define NFMECCD1 __REGi(NF_BASE + 0x18)

#define NFSECCD  __REGi(NF_BASE + 0x1C)

#define NFSTAT   __REGb(NF_BASE + 0x20)

#define NFSTAT0  __REGi(NF_BASE + 0x24)

#define NFSTAT1  __REGi(NF_BASE + 0x28)

#define NFMECC0  __REGi(NF_BASE + 0x2C)

#define NFMECC1  __REGi(NF_BASE + 0x30)

#define NFSECC   __REGi(NF_BASE + 0x34)

#define NFSBLK   __REGi(NF_BASE + 0x38)

#define NFEBLK   __REGi(NF_BASE + 0x3c)

#define NFECC0 __REGb(NF_BASE + 0x2c)

#define NFECC1 __REGb(NF_BASE + 0x2d)

#define NFECC2 __REGb(NF_BASE + 0x2e)

#define S3C2440_NFCONT_nCE  (1<<1)

#define S3C2440_ADDR_NALE   0x0c

#define S3C2440_ADDR_NCLE   0x08

#define S3C2440_NFCONT_nFCE     (1<<1)

#define S3C2440_NFCONT_EN         (1<<0)

#define S3C2440_NFCONT_INITECC     (1<<4)

#define S3C2440_NFCONT_MAINECCLOCK (1<<5)

 

#define S3C2440_NFCONF_TACLS(x) ((x)<<12)

#define S3C2440_NFCONF_TWRPH0(x) ((x)<<8)

#define S3C2440_NFCONF_TWRPH1(x) ((x)<<4)

ulong IO_ADDR_W = NF_BASE;

static void s3c2440_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)

{

    struct nand_chip *chip = mtd->priv;

    DEBUGN("hwcontrol(): 0x%02x 0x%02x/n", cmd, ctrl);

    if (ctrl & NAND_CTRL_CHANGE) {

        IO_ADDR_W = NF_BASE;

        if (!(ctrl & NAND_CLE))               

            IO_ADDR_W |= S3C2440_ADDR_NALE;

        if (!(ctrl & NAND_ALE))               

            IO_ADDR_W |= S3C2440_ADDR_NCLE;

        if (ctrl & NAND_NCE)

            NFCONT &= ~S3C2440_NFCONT_nCE;   

        else

            NFCONT |= S3C2440_NFCONT_nCE;    

    }

    if (cmd != NAND_CMD_NONE)

        writeb(cmd,(void *)IO_ADDR_W);

}

static int s3c2440_dev_ready(struct mtd_info *mtd)

{

    DEBUGN("dev_ready/n");

    return (NFSTAT & 0x01);

}

 

#ifdef CONFIG_S3C2440_NAND_HWECC //硬件ECC还没完成,只好用软件ECC

void s3c2440_nand_enable_hwecc(struct mtd_info *mtd, int mode)

{

    DEBUGN("s3c2440_nand_enable_hwecc(%p, %d)/n", mtd, mode);

    struct s3c2410_nand *nand = s3c2410_get_base_nand();

        writel(readl(&nand->NFCONT) | S3C2440_NFCONT_INITECC, &nand->NFCONT);

   

}

 

static int s3c2440_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat,

                 u_char *ecc_code)

{

    ecc_code[0] = NFECC0;

    ecc_code[1] = NFECC1;

    ecc_code[2] = NFECC2;

    DEBUGN("s3c2440_nand_calculate_hwecc(%p,): 0x%02x 0x%02x 0x%02x/n",

        mtd , ecc_code[0], ecc_code[1], ecc_code[2]);

 

    return 0;

}

 

static int s3c2440_nand_correct_data(struct mtd_info *mtd, u_char *dat,

                 u_char *read_ecc, u_char *calc_ecc)

{

    if (read_ecc[0] == calc_ecc[0] &&

     read_ecc[1] == calc_ecc[1] &&

     read_ecc[2] == calc_ecc[2])

        return 0;

 

    printf("s3c2440_nand_correct_data: not implemented/n");

    return -1;

}

#endif

 

int board_nand_init(struct nand_chip *nand)

{

    u_int32_t cfg;

    u_int8_t tacls, twrph0, twrph1;

    struct s3c24x0_clock_power * const clk_power = s3c24x0_get_base_clock_power();

    DEBUGN("board_nand_init()/n");

    clk_power->CLKCON |= (1 << 4);

    twrph0 = 4; twrph1 = 2; tacls = 0;

    cfg = (tacls<<12)|(twrph0<<8)|(twrph1<<4);

    NFCONF = cfg;

    cfg = (1<<6)|(1<<4)|(0<<1)|(1<<0);

    NFCONT = cfg;

    /* initialize nand_chip data structure */

    nand->IO_ADDR_R = nand->IO_ADDR_W = (void *)0x4e000010;

    /* read_buf and write_buf are default */

    /* read_byte and write_byte are default */

    /* hwcontrol always must be implemented */

    nand->cmd_ctrl = s3c2440_hwcontrol;

    nand->dev_ready = s3c2440_dev_ready;

    nand->ecc.mode = NAND_ECC_SOFT;                //采用软件ECC

    return 0;

}

 

 

接下来在board2442.h中添加支持Nand的宏:

/*

 * High Level Configuration Options

 * (easy to change)

 */

#define CONFIG_ARM920T 1     /* This is an ARM920T Core   */

#define CONFIG_S3C24X0  1     /* in a SAMSUNG S3C24x0-type SoC       */

#define CONFIG_S3C2410   1     /* specifically a SAMSUNG S3C2410 SoC       */

#define CONFIG_SMDK2410      1     /* on a SAMSUNG SMDK2410 Board  */

#define CONFIG_S3C2440   1

#define CONFIG_S3C2442b  1

 

/*

 * Command line configuration.

 */

 

#define CONFIG_CMD_NAND

#define CONFIG_CMDLINE_EDITING

#ifdef CONFIG_CMDLINE_EDITING

#undef CONFIG_AUTO_COMPLETE

#else

#define CONFIG_AUTO_COMPLETE

#endif

 

/*Nand flash settings*/

 

#if defined(CONFIG_CMD_NAND)

#define CONFIG_SYS_NAND_BASE            0x4E000000 //Nand配置寄存器基地址

#define CONFIG_SYS_MAX_NAND_DEVICE      1

#define CONFIG_MTD_NAND_VERIFY_WRITE    1 

#define CONFIG_NAND_S3C2440

#endif

 

接下来,在drivers/mtd/nand/Makefile文件中添加s3c2440_nand.c的编译项,如下:

COBJS-y += s3c2440_nand.o

COBJS-$(CONFIG_NAND_S3C2440) += s3c2440_nand.o

 

 

这部分与2440的移植相比基本上是一样的,唯一不同的是我参考了网上别人的博客,把ECC错误验证加上去了,这样就不会有烦人的“ECC_SNAND_ECC_NONE selected by board driver. This is not recommended !!”的提示。

 

记得以前看过网上说u-boot nandECCbug,不过目前还没怎么发现,有待进一步观察。

 

现在启动后界面如下:

 

5.其他一些调整

修改board2442.h 注释掉储存环境变量到flash中的宏

//#define       CONFIG_ENV_IS_IN_FLASH   1

//#define CONFIG_ENV_SIZE           0x10000       /* Total Size of Environment Sector */

添加储存到nand中的宏

#define CONFIG_CMD_SAVEENV

 

#define CONFIG_ENV_IS_IN_NAND     1

#define CONFIG_ENV_OFFSET       0x40000

#define CONFIG_ENV_SIZE             0x20000

之后重新编译前需要make clean一下,不然最后链接时还会链接到env_flash.o文件,会使修改没有效果。

 

定义以下宏,才能让u-boot传递内核启动参数(如果编译出错就去掉这两个定义)

#define CONFIG_CMDLINE_TAG    
#define CONFIG_SETUP_MEMORY_TAGS

修改arch/arm/lib board.c文件注释掉flash语句:

//     display_flash_config (flash_init ());

 

board.c文件中,u-boot是通过init_sequence[]结构体数组中调用env_init函数来进行环境变量的初始化。之后转到common/env_XXX.c文件执行。env_XXX.c文件中也包含了读取,存储环境变量的函数。XXX可以是flashdataflasheeprommmcnand。由不同的存储介质编译相应的env_XXX文件。打开该目录下的Makefile,发现:

COBJS-$(CONFIG_ENV_IS_IN_DATAFLASH) += env_dataflash.o

COBJS-$(CONFIG_ENV_IS_IN_EEPROM) += env_eeprom.o

COBJS-$(CONFIG_ENV_IS_EMBEDDED) += env_embedded.o

COBJS-$(CONFIG_ENV_IS_IN_EEPROM) += env_embedded.o

COBJS-$(CONFIG_ENV_IS_IN_FLASH) += env_embedded.o

COBJS-$(CONFIG_ENV_IS_IN_NVRAM) += env_embedded.o

COBJS-$(CONFIG_ENV_IS_IN_FLASH) += env_flash.o

COBJS-$(CONFIG_ENV_IS_IN_MG_DISK) += env_mgdisk.o

COBJS-$(CONFIG_ENV_IS_IN_MMC) += env_mmc.o

COBJS-$(CONFIG_ENV_IS_IN_NAND) += env_nand.o

COBJS-$(CONFIG_ENV_IS_IN_NVRAM) += env_nvram.o

COBJS-$(CONFIG_ENV_IS_IN_ONENAND) += env_onenand.o

COBJS-$(CONFIG_ENV_IS_IN_SPI_FLASH) += env_sf.o

COBJS-$(CONFIG_ENV_IS_NOWHERE) += env_nowhere.o

由此可见,通过定义不同的宏,就能选择操作环境变量的不同存储介质。

common/env_common.c文件中有所有默认环境变量的设置。

 

 

6.ax88180以太网芯片的移植:

打开board/samsung/board2442/board2442.c

修改:

#ifdef CONFIG_CMD_NET

int board_eth_init(bd_t *bis)

{

       int rc = 0;

#if 0

       rc = cs8900_initialize(0, CONFIG_CS8900_BASE);

#endif

       rc = ax88180_initialize(bis);

       return rc;

}

#endif

 

修改board2442.h, 注释掉cs8900的宏,添加ax88180的宏

/*

 * Hardware drivers

 */

#define CONFIG_NET_MULTI

//#define CONFIG_CS8900          /* we have a CS8900 on-board */

//#define CONFIG_CS8900_BASE     0x19000300

//#define CONFIG_CS8900_BUS16   /* the Linux driver does accesses as shorts */

#define CONFIG_DRIVER_AX88180

#define AX88180_BASE 0x28000000 //ax88180bank5,所以地址是28000000

 

添加网络命令:

/*

 * Command line configuration.

 */

#include <config_cmd_default.h>

 

#define CONFIG_CMD_CACHE

#define CONFIG_CMD_DATE

#define CONFIG_CMD_ELF

#define CONFIG_CMD_SAVEENV

#define CONFIG_CMD_NAND

#define CONFIG_CMD_PING

#define CONFIG_CMD_NET

 

设置ip,网关,掩码,mac地址:

#define CONFIG_NETMASK          255.255.255.0

#define CONFIG_IPADDR          192.168.1.5                      //开发板ip

#define CONFIG_SERVERIP             192.168.1.100     //主机ip

#define CONFIG_ETHADDR             08:00:3e:26:0a:5c //由于mac芯片没有接储存mac地址的eeprom,所以需要我们手动指定一个mac地址

 

除了修改这里,还要修改ax88180.c文件里,给相应变量赋值:

static void ax88180_read_mac_addr (struct eth_device *dev)

{

       unsigned short macid0_val, macid1_val, macid2_val;

       unsigned short tmp_regval;

       unsigned short i;

 

       /* Reload MAC address from EEPROM */

       OUTW (dev, RELOAD_EEPROM, PROMCTRL);

 

       /* Waiting for reload eeprom completion */

       for (i = 0; i < 500; i++) {

              tmp_regval = INW (dev, PROMCTRL);

              if ((tmp_regval & RELOAD_EEPROM) == 0)

                     break;

              udelay (1000);

       }

#ifdef CONFIG_ETHADDR

       /* Get MAC addresses */      

              dev->enetaddr[0] = 0x08;

              dev->enetaddr[1] = 0x00;

              dev->enetaddr[2] = 0x3e;

              dev->enetaddr[3] = 0x26;

              dev->enetaddr[4] = 0x0a;

              dev->enetaddr[5] = 0x5c;

      

 

#else

       /* Get MAC addresses */

       macid0_val = INW (dev, MACID0);

       macid1_val = INW (dev, MACID1);

       macid2_val = INW (dev, MACID2);

 

       if (((macid0_val | macid1_val | macid2_val) != 0) &&

           ((macid0_val & 0x01) == 0)) {

              dev->enetaddr[0] = (unsigned char)macid0_val;

              dev->enetaddr[1] = (unsigned char)(macid0_val >> 8);

              dev->enetaddr[2] = (unsigned char)macid1_val;

              dev->enetaddr[3] = (unsigned char)(macid1_val >> 8);

              dev->enetaddr[4] = (unsigned char)macid2_val;

              dev->enetaddr[5] = (unsigned char)(macid2_val >> 8);

       }

#endif

}

再修改board/samsung/board2442/lowlevel_init.s中对内存控制寄存器的设置:

 

#define B1_BWSCON            (DW32)

#define B2_BWSCON            (DW16)

#define B3_BWSCON            (DW16 + WAIT + UBLB)

#define B4_BWSCON            (DW16)

#define B5_BWSCON            (DW32 + WAIT + UBLB) //将对应片选的地址空间设成32

#define B6_BWSCON            (DW32)

#define B7_BWSCON            (DW32)

 

下面这部分是修改时钟周期的,不修改应该也没问题

#define B5_Tacs               0x0 /*  0clk */

#define B5_Tcos               0x3 /*  0clk */

#define B5_Tacc               0x7 /* 14clk */

#define B5_Tcoh                     0x1 /*  0clk */

#define B5_Tah                0x0 /*  0clk */

#define B5_Tacp               0x3    

#define B5_PMC                     0x0 /* normal */

 

修改内存刷新频率这部分要改:

#define REFCNT                  0x4f4     /* period=7.8125us, HCLK=100Mhz, (2048+1-7.8125*100) */

 

另外,为了能使u-boot正常使用nfs协议,需修改net/nfs.c 文件

 

#define NFS_TIMEOUT (30*2000UL)

 //把延迟由2000UL延长成成 30*2000UL,不然会有提示ERROR: Cannot unmount!

 

之后重新编译u-boot这时ax88180网口应该就能用了。

Ax88180现在应该已经可以用了,不过很难ping通,tftp传文件也不行。数据已经能从物理层通过网线发出来了,但是主机经常收不到包,估计是信号质量不高的原因。

 

 

 

内容概要:本文详细记录了对一个Android ARM64静态ELF文件中字符串加密机制的逆向分析过程。该ELF文件的所有字符串均被加密,无法通过常规strings命令或IDA直接识别。作者通过分析发现,加密字符串存储在.rodata段,其解密所需信息(包括密文地址、长度16位密钥)保存在.data.rel.ro段的40字节描述符中。核心解密函数sub_10F408采用自反的双pass流密码算法,结合固定密钥KEY_TERM(由.data段24字节数据计算得出),实现字节级非线性、位置与长度相关的加密。文章还复现了完整的Python解密脚本,并揭示了该保护机制的本质为代码混淆而非强加密,最终成功批量解密全部956条字符串,暴露程序真实行为,如shell命令模板、设备标识篡改、网络重置等操作。此外,文中还提及未启用的自定义壳框架及其反dump设计。; 适合人群:具备逆向工程基础的安全研究人员、进制分析人员及对ELF保护技术感兴趣的开发者。; 使用场景及目标:①学习ELF进制中字符串加密的典型实现方式与逆向突破口;②掌握从结构识别、函数追踪到算法还原的完整逆向流程;③理解“绑定进制”的完整性校验设计及其局限性;④实践编写IDAPython脚本自动化提取与解密敏感数据。; 阅读建议:此资源以实战案例驱动,不仅展示技术细节,更强调逆向思维与验证方法,建议读者结合IDA调试环境,逐步跟随文中步骤进行动态分析与算法验证,深入理解每一步的推理依据。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值