Freescale IMX6 Android (3): 手动制作Android启动用SD卡 省去MFGTOOLS烧写

最后更新于:2022-04-01 11:41:36

Freescale IMX6的烧写方式在Windows下面一般使用MFGTools,但是TQ提供的MFGTools在Windows 10下面无法工作,USB的驱动不正常。于是想到Linux下面的烧写方式,结果一样出现问题,且因为TQ没有提供一些烧写程序的源码,因此无法更改与调试。因此TQ提供的两种烧写Android的方式都无法使用了,加之前面博文中,我也尝试使用NFS来启动,也没有达到需要的效果,因此这篇文章说一下自己原创的直接制作SD卡来启动Android。 本文默认大家很熟悉Linux与Android的启动流程,如果不是很熟悉可以先看看我的分享:[Linux启动流程 关于initrd与initramfs的区分及其发展历程](http://blog.csdn.net/sy373466062/article/details/50325047) Linux系统下面使用 SD卡烧写Android的尝试:这个是TQ给出的方法不可行,可以跳过,直接到下面的分区mount开始看 因为这个方案是TQ给出的,所以我尝试的去使用了一下,结果无法使用,因此也写下来,希望其他人不用会去浪费时间,或者帮忙指出我的操作哪里不对。 按照官方的说法制作好了烧写用的SD卡,并且从SD卡启动之后,rcS中会自动去mount SD卡,然后解析EmbedSky.ini配置文件,但是解析的结果似乎不正确,以下是启动之后看到了rcS内容: ~~~ # cat /etc/init.d/rcS #!/bin/sh PATH=/sbin:/bin:/usr/sbin:/usr/bin runlevel=S prevlevel=N umask 022 export PATH runlevel prevlevel # # Trap CTRL-C &c only in this shell so we can interrupt subprocesses. # mount -a mkdir -p /dev/pts mount -t devpts devpts /dev/pts mount -n -t usbfs none /proc/bus/usb echo /sbin/mdev > /proc/sys/kernel/hotplug mdev -s mkdir -p /var/lock #modprobe s5pv210_wm8960 #modprobe ds18b20 #modprobe rt5370sta hwclock -s EmbedSky_wdg & ifconfig lo 127.0.0.1 net_set & /etc/rc.d/init.d/netd start /etc/rc.d/init.d/httpd start #InputAdapter #pda & /bin/hostname -F /etc/sysconfig/HOSTNAME autoDownload [root@EmbedSky /]# ~~~ 步骤非常直接,配置好各种需要的材料之后,直接调用一个可执行的ELF程序autoDownload,然后就没有反应了,使用ps命令也无法看到有此进程在工作。 ## 分区mount 前面的博客([Freescale IMX6 Android NFS启动问题汇总](http://blog.csdn.net/sy373466062/article/details/50208247))中提到了Android的启动过程,其中有一个步骤是mount各个分区,这个分区的mount list有一个和Linux 发行版类似的配置文件,IMX6的这个文件是fstab.freescale,其内容如下: ~~~ # Android fstab file. #<src> <mnt_point> <type> <mnt_flags and options> <fs_mgr_flags> # The filesystem that contains the filesystem checker binary (typically /system) cannot # specify MF_CHECK, and must come before any filesystems that do specify MF_CHECK /devices/platform/sdhci-esdhc-imx.1/mmc_host/mmc1 /mnt/extsd vfat defaults voldmanaged=sdcard:auto /devices/platform/fsl-ehci /mnt/udisk vfat defaults voldmanaged=sdcard:auto /dev/block/mmcblk0p5 /system ext4 rw wait /dev/block/mmcblk0p4 /data ext4 nosuid,nodev,nodiratime,noatime,nomblk_io_submit,noauto_da_alloc,errors=panic wait,encryptable=footer /dev/block/mmcblk0p6 /cache ext4 nosuid,nodev,nomblk_io_submit wait /dev/block/mmcblk0p7 /device ext4 rw,nosuid,nodev wait /dev/block/mmcblk0p1 /boot emmc defaults defaults /dev/block/mmcblk0p2 /recovery emmc defaults defaults /dev/block/mmcblk0p8 /misc emmc defaults defaults ~~~ 其中各个分区的信息可以参考这篇文章:[安卓系统分区介绍](http://cn.club.vmall.com/thread-985489-1-1.html),下面是我给出自己的理解,不保证准确: - /system是system.img对应的partition - /boot存放的应该是boot.img文件 - /recovery放recovery.img文件,手机进入recovery模式的时候使用 - /data分区,存放的是用户配置信息,以及安装的用户程序 - /cache分区,就是我们平常刷手机的时候双清中的一个分区,放一些程序运行过程中的cache - /device分区,一些设备特有文件的配置或者资源文件,例如可能是fireware,这个在标准的Android中没有 对于我们而已,要制作一个启动用的SD卡,我们需要创建所有Android系统必须的分区,同时将对应的文件放进去,以上分区只有recovery分区可以不需要,因为我们不会进入到recovery模式中去,因此,我们第一步就是对SD卡分区。 ## 对SD卡分区 可以使用Gparted GUI图形化软件来进行分区,我使用的是4GB的SD卡,分区如下: ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-05-05_572afc992274f.jpg) 注意后面的扩展分区,在新建分区的时候需要选择扩展分区类型而不是主分区,因为MBR格式的分区表只能有4ge主分区,但是我们需要的分区数目远大于4个。注意第一个分区(label为init的分区)是我额外添加的一个分区,原生中没有。 ## 拷贝文件到分区 文件拷贝如下: - root下面的文件 -->  init分区 - system下面的文件 --> system分区 更改fstab配置文件 因为TQ提供的Android编译出来之后,默认是烧写到eMMC中的,而我们使用的是SD卡,因此mmc的设备号是不一样的,同时根据: - eMMC与SD卡的特性,eMMC的初始化比SD卡快 - 在Makefile中更靠前,因此init段在更前面,因此会更快的运行init 因此,eMMC在TQIMX6Q中是mmc0,而SD卡是mmc1。 另外也可以在启动之后,拔插SD卡来确认,拔掉的时候会有类似下面的提示,也可以确定SD卡的名称: ~~~ mmc1 removed ~~~ 然后我们就可以更改fstab(就是在out/target/XXX/init中的fstab.freescale)了,将里面的mmc0改成mmc1,同时将各个分区变更一下,例如SD卡挂载到了/media/init下面,那么可以使用 gvim /media/init/fstab.freescale命令来修改,如下: ~~~ root@sabresd_6dq:/ # cat /fstab.freescale # Android fstab file. #<src> <mnt_point> <type> <mnt_flags and options> <fs_mgr_flags> # The filesystem that contains the filesystem checker binary (typically /system) cannot # specify MF_CHECK, and must come before any filesystems that do specify MF_CHECK /devices/platform/sdhci-esdhc-imx.1/mmc_host/mmc1 /mnt/extsd vfat defaults voldmanaged=sdcard:auto /devices/platform/fsl-ehci /mnt/udisk vfat defaults voldmanaged=sdcard:auto /dev/block/mmcblk1p2 /system ext4 rw wait /dev/block/mmcblk1p3 /data ext4 nosuid,nodev,nodiratime,noatime,nomblk_io_submit,noauto_da_alloc,errors=panic wait,encryptable=footer /dev/block/mmcblk1p5 /cache ext4 nosuid,nodev,nomblk_io_submit wait /dev/block/mmcblk1p6 /device ext4 rw,nosuid,nodev wait root@sabresd_6dq:/ # ~~~ 注意结合前面的GParted分区图示,根据自己的实际情况填写。这里配置了/system,/data,/chace与/device分区; 这些就够了。 修改完成后,保存并sync,然后将SD卡查到机器上面。 如果没有更改这个fstab,那么将会在下面的log后没有任何输出: ~~~ Freeing init memory: 236K ~~~ 将这些拷贝操作,与fstab文件打包放到了csdn,供参考,下载链接:[imx6 手动制作Android启动用SD卡脚本与fstab](http://download.csdn.net/detail/sy373466062/9343265)   ## 使用SD卡启动Android 我们已经制作好了启动Android的SD卡,还记得前面博客说道的Android启动顺序吗? 由这个顺序,我们可以使用下面这些命令从uboot来启动kenrel与Android: ~~~ set serverip 192.168.2.100;set ipaddr 192.168.2.111; set bootargs 'rootwait console=ttySAC0,115200n8 root=/dev/mmcblk1p1 debug ignore_loglevel init=/init vmalloc=400M androidboot.console=ttySAC0 androidboot.hardware=freescale video=mxcfb0:dev=hdmi,1280x720MM@60,if=RGB24,bpp=32 video=mxcfb1:off video=mxcfb2:off fbmem=48M' tftp 0x10800000 192.168.2.100:imx6/uImage;bootm 0x10800000 ~~~ 其中需要注意的是'root='参数,这个是以前不一样的地方,同时添加了rootwait,等待SD卡Probe。 启动之后,输入mount可以查看mount信息: ~~~ root@sabresd_6dq:/ # mount rootfs / rootfs rw 0 0 /dev/root / ext4 ro,relatime,user_xattr,barrier=1,data=ordered 0 0 tmpfs /dev tmpfs rw,nosuid,relatime,mode=755 0 0 devpts /dev/pts devpts rw,relatime,mode=600 0 0 proc /proc proc rw,relatime 0 0 sysfs /sys sysfs rw,relatime 0 0 none /acct cgroup rw,relatime,cpuacct 0 0 tmpfs /mnt/secure tmpfs rw,relatime,mode=700 0 0 tmpfs /mnt/asec tmpfs rw,relatime,mode=755,gid=1000 0 0 tmpfs /mnt/obb tmpfs rw,relatime,mode=755,gid=1000 0 0 tmpfs /mnt/shm tmpfs rw,relatime,size=1024k,mode=775,uid=1000,gid=1003 0 0 none /dev/cpuctl cgroup rw,relatime,cpu 0 0 /dev/block/mmcblk1p2 /system ext4 ro,relatime,user_xattr,barrier=1,data=ordered 0 0 /dev/block/mmcblk1p3 /data ext4 rw,nosuid,nodev,noatime,nodiratime,errors=panic,user_xattr,barrier=1,nomblk_io_submit,data=ordered,noauto_da_alloc 0 0 /dev/block/mmcblk1p5 /cache ext4 rw,nosuid,nodev,relatime,user_xattr,barrier=1,nomblk_io_submit,data=ordered 0 0 /dev/block/mmcblk1p6 /device ext4 ro,relatime,user_xattr,barrier=1,data=ordered 0 0 none /sys/kernel/debug debugfs rw,relatime 0 0 /dev/fuse /mnt/shell/emulated fuse rw,nosuid,nodev,relatime,user_id=1023,group_id=1023,default_permissions,allow_other 0 0 ~~~ 下面则是这些分区的size信息: ~~~ 1|root@sabresd_6dq:/ # df Filesystem Size Used Free Blksize / 96.8M 6.0M 90.8M 1024 / 96.8M 6.0M 90.8M 1024 /dev 381.6M 48.0K 381.6M 4096 /mnt/secure 381.6M 0.0K 381.6M 4096 /mnt/asec 381.6M 0.0K 381.6M 4096 /mnt/obb 381.6M 0.0K 381.6M 4096 /mnt/shm 1024.0K 0.0K 1024.0K 4096 /system 503.9M 234.5M 269.5M 4096 /data 1007.9M 48.8M 959.1M 4096 /cache 503.9M 16.4M 487.6M 4096 /device 503.9M 16.4M 487.6M 4096 /mnt/shell/emulated 1007.9M 48.8M 959.1M 4096 ~~~ ## APK的测试 和前面一样,我们使用Android Studio编译一个HelloWorld程序,并选择这个设备运行,那么就会自动push apk并安装这个apk到设备中,如果没有出现问题,那么就OK了,如下: ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-05-05_572afc994839a.jpg) 连接完成后,可以在logcat中看到信息: ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-05-05_572afc995b8b8.jpg) 新建Android Project的时候需要注意API版本的匹配,不要用比设备更高的Android版本。 同时需要注意打开开发者模式,使能USB调试。 ## 开发过程中遇到的其他问题 OTG线连接不稳定,会不断的出现如下log: ~~~ <span style="font-family:Microsoft YaHei;font-size:18px;">android_work: did not send uevent (0 0 (null)) android_work: did not send uevent (0 0 (null)) android_work: did not send uevent (0 0 (null))</span> ~~~ 正常连接的应该是这样的log: ~~~ android_work: sent uevent USB_STATE=DISCONNECTED android_work: sent uevent USB_STATE=CONNECTED android_usb gadget: high speed config #1: android android_work: sent uevent USB_STATE=CONFIGURED mtp_open ~~~ 同时也可以在PC中使用下面命令来查看dmesg,从而确定是否打开了调试,并确认OTG adb连接是否有问题: ~~~ dmesg | tail ~~~
';