代码编织梦想

分区结构

在img写入后, 会产生两个分区
EMUELEC: 用于启动的文件, 例如dtb文件等, 以及system.img & system.img.md5, EmuELEC的系统文件都在这个img里面
STORAGE: 空

运行中目录结构


  1. /dev/mmcblk1p1 511.7M 373.6M 138.2M 73% /flash
  2. /dev/loop0 357.5M 357.5M 0 100% /
  3. /dev/mmcblk1p2 28.6G 3.5G 25.1G 12% /storage

启动后, EMUELEC分区被挂载为 /flash, STORAGE分区被挂载为 /storage, system.img 通过 /dev/loop0 被挂载为系统根目录 /

所以, 用户能修改的仅仅是 /flash 和 /storage 目录下的内容
root用户的home目录被定位到 /storage, 如果需要添加登录后自动执行的命令(例如添加alias), 可以直接在 /storage 目录下新建 .profile 文件来实现

开机启动顺序

这个是在uboot中进行管理的, 可以通过fw_printenv命令进行查看


  1. EmuELEC:/usr/sbin # fw_printenv
  2. ...
  3. baudrate=115200
  4. boot_count=0
  5. bootcmd=if test ${bootfromnand} = 1; then setenv bootfromnand 0; saveenv; else run bootfromsd; run bootfromusb; fi; run storeboot
  6. bootcount_check=echo bootcounts=${boot_count}; if itest ${boot_count} == 0; then setenv boot_count 1;saveenv;else if itest ${boot_count} == 1; then setenv boot_count 2;saveenv;else if itest ${boot_count} == 2; then setenv boot_count 3;saveenv;else if itest ${boot_count} == 3; then setenv boot_count 4;saveenv;else if itest ${boot_count} == 4; then run recovery_from_flash;fi;fi;fi;fi;fi
  7. bootdelay=0
  8. bootfromnand=0
  9. bootfromsd=mmcinfo; if fatload mmc 0 ${loadaddr} kernel.img; then run sddtb; setenv bootargs ${bootargs} bootfromsd; bootm; fi
  10. bootfromusb=usb start 0; if fatload usb 0 ${loadaddr} kernel.img; then run usbdtb; setenv bootargs ${bootargs} bootfromusb; bootm; fi
  11. bootmode_check=get_rebootmode; echo reboot_mode=${reboot_mode};if test ${reboot_mode} = factory_reset; then defenv_reserv;setenv upgrade_step 2; save;fi;
  12. cmdline_keys=if keyman init 0x1234; then if sec_keyunify read mac ${loadaddr} str; then setenv bootargs ${bootargs} mac=${mac} androidboot.mac=${mac};fi;fi;
  13. ...

可以看到其中的 bootfromnand 变量是用于控制设备的启动顺序, 如果值为1, 那么从nand(设备内部存储, eMMC等), 如果值为0, 那么依次从sd, 从usb启动, 在这个过程中如果某个介质可以启动了, 就把这个方式加到bootargs变量的值当中去, 例如


  1. setenv bootargs ${bootargs} bootfromsd;

.然后调用系统函数bootm启动内核. bootm会调用 ./lib_arm/armlinux.c的do_bootm() 方法, 里面会调用./common/cmd_bootm.c的do_bootm_linux()

如果这些都不成功, 那就调用storeboot


  1. storeboot=if imgread kernel boot ${loadaddr}; then bootm ${loadaddr}; fi;run update;

而update会依次尝试从各个媒介升级


  1. update=run usb_burning; run sdc_burning; if mmcinfo; then run recovery_from_sdcard;fi;if usb start 0; then run recovery_from_udisk;fi;run recovery_from_flash;

中间还会记录启动次数, 如果启动次数达到4, 就会执行 recovery_from_flash


  1. recovery_from_flash=setenv bootargs ${bootargs} aml_dt=${aml_dt} recovery_part={recovery_part} recovery_offset={recovery_offset};if imgread kernel ${recovery_part} ${loadaddr} ${recovery_offset}; then wipeisb; bootm ${loadaddr}; fi

ES的Quit菜单中的Reboot From NAND, 实际执行的就是 /usr/sbin/rebootfromnand 这个命令, 里面将 bootfromnand 值设为了1


  1. EmuELEC:/usr/sbin # more rebootfromnand
  2. #!/bin/sh
  3. # SPDX-License-Identifier: GPL-2.0-or-later
  4. # Copyright (C) 2016-2018 kszaq (kszaquitto@gmail.com)
  5. # Copyright (C) 2018-present Team CoreELEC (https://coreelec.org)
  6. if /usr/sbin/fw_printenv whereToBootFrom > /dev/null 2>&1; then /usr/sbin/fw_setenv whereToBootFrom internal; fi
  7. /usr/sbin/fw_setenv bootfromnand 1

  

服务启动顺序

系统启动的服务是通过systemd管理的, 启动脚本位于 /usr/lib/systemd/system/ 下, 因为是过loop设备挂载的, 所以这里面的文件都不可修改. 默认的启动target为


  1. EmuELEC:/usr/lib/systemd/system # systemctl get-default
  2. emuelec.target
  3. EmuELEC:/usr/lib/systemd/system # ll def*.*
  4. lrwxrwxrwx 1 root root 14 Nov 19 00:42 default.target -> emuelec.target

服务依赖关系为


  1. EmuELEC:/usr/lib/systemd/system # systemctl list-dependencies emuelec.target
  2. emuelec.target
  3. ● ├─emuelec-autostart.service
  4. ● ├─emustation.service
  5. ● ├─retroarch.service
  6. ● ├─tmp-assets.mount
  7. ● ├─tmp-cores.mount
  8. ● ├─tmp-database.mount
  9. ● ├─tmp-joypads.mount
  10. ● ├─tmp-overlays.mount
  11. ● ├─tmp-shaders.mount
  12. ● ├─graphical.target
  13. ● │ ├─unbind-console.service
  14. ● │ └─multi-user.target
  15. ● │ ├─avahi-daemon.service
  16. ● │ ├─connman.service
  17. ● │ ├─dbus.service
  18. ● │ ├─entware.service
  19. ● │ ├─iptables.service
  20. ● │ ├─nmbd.service
  21. ● │ ├─pulseaudio.service
  22. ● │ ├─rpcbind.service
  23. ● │ ├─sixaxis@multi-user.service
  24. ● │ ├─smbd.service
  25. ● │ ├─sshd.service
  26. ● │ ├─systemd-ask-password-wall.path
  27. ● │ ├─systemd-logind.service
  28. ● │ └─basic.target
  29. ● │ ├─add-entropy.service
  30. ● │ ├─amlogic-dvb.service
  31. ● │ ├─fstrim.service
  32. ● │ ├─hwdb.service
  33. ● │ ├─kvimfan.service
  34. ● │ ├─openvfd.service
  35. ● │ ├─show-version.service
  36. ● │ ├─swap.service
  37. ● │ ├─tmp.mount
  38. ● │ ├─var.mount
  39. ● │ ├─wetekdvb.service
  40. ● │ ├─paths.target
  41. ● │ ├─slices.target
  42. ● │ │ ├─-.slice
  43. ● │ │ └─system.slice
  44. ● │ ├─sockets.target
  45. ● │ │ ├─dbus.socket
  46. ● │ │ ├─systemd-initctl.socket
  47. ● │ │ ├─systemd-journald-audit.socket
  48. ● │ │ ├─systemd-journald-dev-log.socket
  49. ● │ │ ├─systemd-journald.socket
  50. ● │ │ ├─systemd-udevd-control.socket
  51. ● │ │ └─systemd-udevd-kernel.socket
  52. ● │ ├─sysinit.target
  53. ● │ │ ├─debug-shell.service
  54. ● │ │ ├─debugconfig.service
  55. ● │ │ ├─dev-hugepages.mount
  56. ● │ │ ├─dev-mqueue.mount
  57. ● │ │ ├─kmod-static-nodes.service
  58. ● │ │ ├─machine-id.service
  59. ● │ │ ├─openssl-config.service
  60. ● │ │ ├─sys-fs-fuse-connections.mount
  61. ● │ │ ├─sys-kernel-config.mount
  62. ● │ │ ├─sys-kernel-debug.mount
  63. ● │ │ ├─systemd-ask-password-console.path
  64. ● │ │ ├─systemd-hwdb-update.service
  65. ● │ │ ├─systemd-journal-catalog-update.service
  66. ● │ │ ├─systemd-journal-flush.service
  67. ● │ │ ├─systemd-journald.service
  68. ● │ │ ├─systemd-modules-load.service
  69. ● │ │ ├─systemd-sysctl.service
  70. ● │ │ ├─systemd-tmpfiles-setup-dev.service
  71. ● │ │ ├─systemd-tmpfiles-setup.service
  72. ● │ │ ├─systemd-udev-trigger.service
  73. ● │ │ ├─systemd-udevd.service
  74. ● │ │ ├─tz-data.service
  75. ● │ │ ├─usercache.service
  76. ● │ │ ├─userconfig.service
  77. ● │ │ ├─local-fs.target
  78. ● │ │ │ ├─kernel-overlays.service
  79. ● │ │ │ ├─libmali.service
  80. ● │ │ │ ├─tmp.mount
  81. ● │ │ │ └─var.mount
  82. ● │ │ └─swap.target
  83. ● │ └─timers.target
  84. ● │ └─systemd-tmpfiles-clean.timer
  85. ● └─multi-user.target
  86. ● ├─avahi-daemon.service
  87. ● ├─connman.service
  88. ● ├─dbus.service
  89. ● ├─entware.service
  90. ● ├─iptables.service
  91. ● ├─nmbd.service
  92. ● ├─pulseaudio.service
  93. ● ├─rpcbind.service
  94. ● ├─sixaxis@multi-user.service
  95. ● ├─smbd.service
  96. ● ├─sshd.service
  97. ● ├─systemd-ask-password-wall.path
  98. ● ├─systemd-logind.service
  99. ● └─basic.target

在 emuelec-autostart.service 里, 执行了/storage/.config/autostart.sh

在autostart.sh的结尾, 又执行了 /storage/.config/custom_start.sh

X96 Max Plus sd卡 刷Emuelec-爱代码爱编程

准备刷机工具 对应设备的固件型号1镜像写入工具(rufus)2开始刷机 1 选择 镜像 国产 外贸盒子 选第一个通用的就行了, 您还可以查看此处是否列出了您的设备:https://pastebin.com/MzcGntYB区别如下 2 下载好 对应的固件镜像 用镜像写入工具 写入到sd 卡 3 进入device_trees目录,找到适合自己

android双系统切换软件,双系统如何进行切换?-爱代码爱编程

02双系统如何进行切换? ■双系统怎么切换使用? 台电X98 Air 3G(双系统版)在开机后进入选择系统界面,我们选择其中一个系统,点击确认,就能进入自己所需的系统。在选系统界面里,左上角有一个选项,这选项是用户根据自己爱好选择是否每次开机都要进入选系统界面。如果不勾上这选项,那么下次开机将会直接进入之前的系统。如果想再进入选系统界面,那我们可以

x96max+ 电视盒子如何刷入EmuELEC游戏系统-爱代码爱编程

一. 了解相关概念 1. Kodi是什么? Kodi(以前称为XBMC)是一个免费的开放源代码媒体播放器软件应用程序,它可以运行在Linux、OSX、Windows、Android等多种操作系统和硬件平台。它是一个优秀的开源的(GPL)媒体中心软件。最初为Xbox而开发,叫XBMC(全称是XBOX Media Center),也就是XBOX平台的媒

emuelec 设置frpc开机自启动-爱代码爱编程

下载frp,并且解压到:/storage/frp_0.37.1_linux_arm64/ vi /storage/.config/system.d/frpc.service [Unit] Description=frpc service After=network-online.service Requires=network-online.servic

EmuELEC初体验(源码下载)-爱代码爱编程

       接触这个EmuELEC复古系统有几个月,从了解到深度定制开发,也花了不少时间。记得当时开始接触emuelec的时候,也是各种查阅资料,发现这块开发的资料在国内的确非常少,所以走了很多弯路,目前对此系统源码也还算了解。希望写一些东西给新来想研究对同学,避免绕弯。      其实,这个系统还是很有意思的,很多怀旧游戏,比如街机的拳皇,马里奥,ps

关于EmuELEC下如何精简模块(packages目录理解)-爱代码爱编程

今天有一朋友遇到关于EmuELEC4.3下emuelec-ports模拟器VVVVVV 模块异常报错,然后怎么都解决不掉。最后发现其实是第三方的源已经失效,然后自己又找不到这个源了,这个模块又不是很重要。 基于这个思路,我们可以把这个模块删除掉,不参加编译。有了这个方法,那么我们就可以做精简裁剪版了,说不定速度会更快哦?(PS:有兴趣的可以试试) 我们

emuelec 镜像太大无法写入u盘解决方法_iamlsz的博客-爱代码爱编程

    经常遇到一种情况,比如镜像标明32G,但是实际占用空间已经超过了我们U盘的大小,比如镜像28G,但是我们U盘只有27.5G。此时,想要写入U盘,我们只能够删除镜像里面的游戏rom,然后占用小了,自然可以写入了。     我们需要以下4个步骤: 用DG(专业版的磁盘精灵),分别打开U盘跟虚拟磁盘镜像(游戏镜像)。删除U盘的所有分区,然后为U盘新建