谷动谷力

 找回密码
 立即注册
查看: 609|回复: 0
打印 上一主题 下一主题
收起左侧

【openwrt】使用qemu模拟mt7628 并成功运行uboot、OpenWrt、NetBSD

[复制链接]
跳转到指定楼层
楼主
发表于 2023-7-1 15:58:53 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 sunsili 于 2024-1-30 15:54 编辑

【openwrt】使用qemu模拟mt7628 并成功运行uboot、OpenWrt、NetBSD



前言:

    代码实现不一定正确, 因为MTK不公开SOC内部的实现细节,这个模拟器的实现依据是我的对此芯片的了解程度以及Linux/Uboot/NetBSD里面的驱动代码.
项目地址: https://github.com/newluhux/qemu-mt7628

下载QEMU 应用PATCH 然后构建

  1. git clone https://gitlab.com/qemu-project/qemu
  2. git clone https://github.com/newluhux/qemu-mt7628
  3. cd ./qemu/
  4. git branch mt7628
  5. git switch mt7628
  6. for i in ../qemu-mt7628/000*.patch
  7. do
  8.     git am < $i
  9. done
  10. ./configure --cc=gcc --cxx=g++ --target-list=mipsel-softmmu
  11. make -j$(nproc)
  12. make check
复制代码

启动主线uboot
  1. wget http://musl.cc/mipsel-linux-muslsf-cross.tgz
  2. tar xf mipsel-linux-muslsf-cross.tgz
  3. cd mipsel-linux-muslsf-cross/bin/
  4. export PATH=$PATH:$(pwd)
  5. cd -
  6. git clone https://github.com/u-boot/u-boot
  7. cd u-boot
  8. cp ./configs/linkit-smart-7688_defconfig ./.config
  9. make ARCH=mips CROSS_COMPILE=mipsel-linux-musl- menuconfig
  10. # you need select:
  11. # CONFIG_REMAKE_ELF=y
  12. make ARCH=mips CROSS_COMPILE=mipsel-linux-musl- -j$(nproc)
  13. # create a blank flash image
  14. dd if=/dev/zero of=flash_16M.bin count=16 bs=1M
  15. ../qemu/qemu-system-mipsel -M mt7628 \
  16.   -serial telnet:localhost:4000,server \
  17.   -serial telnet:localhost:4001,server \
  18.   -serial telnet:localhost:4002,server \
  19.   -drive if=mtd,file=flash_16M.bin,type=raw \
  20.   -usb \
  21.   -kernel ./u-boot.elf
复制代码

使用telnet连接串口:

  1. $ telnet localhost 4002
  2. Trying 127.0.0.1...
  3. Connected to 127.0.0.1.
  4. Escape character is '^]'.


  5. U-Boot 2022.04 (Feb 14 2023 - 15:32:34 +0000)

  6. CPU:   MediaTek MT7628A ver:1 eco:2
  7. Boot:  DDR2, SPI-NOR 3-Byte Addr, CPU clock from XTAL
  8. Clock: CPU: 575MHz, Bus: 191MHz, XTAL: 25MHz
  9. Model: LinkIt-Smart-7688
  10. DRAM:  256 MiB
  11. Core:  54 devices, 15 uclasses, devicetree: separate
  12. Loading Environment from SPIFlash... SF: Detected w25q128 with page
  13. size 256 Bytes, erase size 4 KiB, total 16 MiB

  14. Net:
  15. Warning: eth@10110000 (eth0) using random MAC address - 96:0d:9e:0d:3f:ea
  16. eth0: eth@10110000
  17. =>
复制代码

现在你可以使用tftp或者fatload命令来加载固件到内存,然后使用sf写入到 spi flash
最后使用bootm来启动固件

启动OpenWRT固件

在此之前你需要构建一个主线的uboot用于启动uImage,然后执行:
  1. cp /path/to/uboot/uboot.elf ./uboot.elf
  2. wget https://downloads.openwrt.org/re ... shfs-sysupgrade.bin
  3. dd if=/path/to/uboot/uboot-with-spl.bin of=flash.bin
  4. dd if=/dev/zero bs=1M count=1 >> flash.bin
  5. truncate -s 327680 flash.bin
  6. dd if=./openwrt-22.03.3-ramips-mt76x8-vocore_vocore2-squashfs-sysupgrade.bin
  7. >> flash.bin
  8. dd if=/dev/zero bs=1M count=16 >> flash.bin
  9. truncate -s 16M flash.bin
  10. /path/to/qemu-build/qemu-system-mipsel -M mt7628 \
  11.   -serial telnet:localhost:4000,server,nowait \
  12.   -serial telnet:localhost:4001,server,nowait \
  13.   -serial telnet:localhost:4002,server \
  14.   -kernel ./uboot.elf \
  15.   -drive if=mtd,file=flash_16M.bin,type=raw \
  16.   -usb
复制代码

使用telnet 连接串口
  1. $ telnet localhost 4002
  2. Trying 127.0.0.1...
  3. Connected to 127.0.0.1.
  4. Escape character is '^]'.


  5. U-Boot 2022.04 (Feb 14 2023 - 15:32:34 +0000)

  6. CPU:   MediaTek MT7628A ver:1 eco:2
  7. Boot:  DDR2, SPI-NOR 3-Byte Addr, CPU clock from XTAL
  8. Clock: CPU: 575MHz, Bus: 191MHz, XTAL: 25MHz
  9. Model: LinkIt-Smart-7688
  10. DRAM:  256 MiB
  11. Core:  54 devices, 15 uclasses, devicetree: separate
  12. Loading Environment from SPIFlash... SF: Detected w25q128 with page
  13. size 256 Bytes, erase size 4 KiB, total 16 MiB

  14. Net:
  15. Warning: eth@10110000 (eth0) using random MAC address - 96:0d:9e:0d:3f:ea
  16. eth0: eth@10110000
复制代码

使用 `bootm 0x1c050000` 来启动 openwrt

启动主线NetBSD
ref: https://www.netbsd.org/docs/guide/en/chap-build.html
NetBSD在8.0以及之后的版本加入了mt7628支持,你可以使用Linux/NetBSD/Other UNIX 来交叉编译 NetBSD,构建NetBSD内核是十分容易的(在我的Slackware Linux 机器上):
  1. mkdir ./netbsd/
  2. cd ./netbsd/
  3. wget https://ftp.NetBSD.org/pub/NetBS ... ar_files/src.tar.gz
  4. tar -zxf src.tar.gz
  5. cd ./src/
  6. ./build.sh -U -O ~/obj -j$(nproc) -m evbmips -a mipsel tools
  7. cd sys/arch/evbmips/conf/
  8. ~/obj/tooldir.HOST/bin/nbconfig LINKITSMART7688
  9. cd ../compile/LINKITSMART7688/
  10. ~/obj/tooldir.HOST/bin/nbmake-evbmips depend
  11. ~/obj/tooldir.HOST/bin/nbmake-evbmips
复制代码

构建成功后你会获得一个 './netbsd' 的文件
  1. file ./netbsd
  2. netbsd: ELF 32-bit LSB executable, MIPS, MIPS32 rel2 version 1 (SYSV),
  3. statically linked, for NetBSD 9.3, with debug_info, not stripped
复制代码

运行它:
  1. /path/to/qemu-build/qemu-system-mipsel -M mt7628 \
  2.    -serial telnet:localhost:4000,server,nowait \
  3.    -serial telnet:localhost:4001,server,nowait \
  4.    -serial telnet:localhost:4002,server \
  5.    -kernel ./netbsd
复制代码

连接串口,你可以看到netbsd内核的启动日志:
  1. telnet localhost 4002
  2. Trying ::1...
  3. telnet: connect to address ::1: Connection refused
  4. Trying 127.0.0.1...
  5. Connected to localhost.
  6. Escape character is '^]'.
  7. [   1.0000000] MIPS32/64 params: cpu arch: 128
  8. [   1.0000000] MIPS32/64 params: TLB entries: 16
  9. [   1.0000000] MIPS32/64 params: Icache: line=16, total=2048, ways=2,
  10. sets=64, colors=0
  11. [   1.0000000] MIPS32/64 params: Dcache: line=16, total=2048, ways=2,
  12. sets=64, colors=0
  13. [   1.0000000] phys segment: 0x8000000 @ 0
  14. [   1.0000000] adding 0xe000 @ 0x2000 to freelist 0
  15. [   1.0000000] adding 0x797e000 @ 0x682000 to freelist 0
  16. [   1.0000000] Enabled early console
  17. [   1.0000000] Copyright (c) 1996, 1997, 1998, 1999, 2000, 2001, 2002,
  18. 2003, 2004, 2005,
  19. [   1.0000000]     2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013,
  20. 2014, 2015, 2016, 2017,
  21. [   1.0000000]     2018, 2019, 2020, 2021, 2022
  22. [   1.0000000]     The NetBSD Foundation, Inc.  All rights reserved.
  23. [   1.0000000] Copyright (c) 1982, 1986, 1989, 1991, 1993
  24. [   1.0000000]     The Regents of the University of California.  All
  25. rights reserved.
  26. [   1.0000000] NetBSD 9.3 (LINKITSMART7688) #0: Wed Mar 15 20:37:27 HKT 2023
  27. [   1.0000000]
  28. luhui@x230.luhui:/home/luhui/pub/netbsd/src/sys/arch/evbmips/compile/LINKITSMART7688
  29. [   1.0000000] MT7628
  30. [   1.0000000] total memory = 128 MB
  31. [   1.0000000] avail memory = 120 MB
  32. [   1.0000000] mainbus0 (root): Mediatek MT7628 System Bus
  33. [   1.0000000] cpu0 at mainbus0: 580.00MHz (hz cycles = 2900000, delay
  34. divisor = 290)
  35. [   1.0000000] cpu0: MIPS 24KE (0x19600) Rev. 0 with software emulated
  36. floating point
复制代码

从flash镜像启动

我了解了一下mt7628的启动流程,发现从flash启动的流程很简单,但是会遇到一些问题:

取指令太慢, 因为QEMU没有实现cache, 所以启动时的指令是从flash反复读取的,延迟很大.
导致DRAM test和 LZMA解压会很慢, 建议使用hexedit修改镜像来跳过这些指令,或者直接拷贝他们到DRAM上,设置pc寄存器跳过去执行.

你需要从真实的板子上dump flash镜像,然后执行:
  1. ./qemu/qemu-system-mipsel -M mt7628 \
  2.   -serial telnet:localhost:4000,server \
  3.   -serial telnet:localhost:4001,server \
  4.   -serial telnet:localhost:4002,server \
  5.   -drive if=mtd,file=flash_16M.bin,type=raw \
  6.   -usb
复制代码


本文为项目原作者投稿,原文: https://newluhux.github.io/2023-02-14-qemu-emulate-mt7628.html


+10
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|深圳市光明谷科技有限公司|光明谷商城|Sunshine Silicon Corpporation ( 粤ICP备14060730号|Sitemap

GMT+8, 2024-4-28 22:54 , Processed in 0.086528 second(s), 41 queries .

Powered by Discuz! X3.2 Licensed

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表