【TINY4412】LINUX移植笔记:(4)Ramdisk文件系统
宿主机 : 虚拟机 Ubuntu 16.04 LTS / X64
目标板[底板]: Tiny4412SDK - 1506
目标板[核心板]: Tiny4412 - 1412
LINUX内核: 4.12.0
交叉编译器: gcc-arm-none-eabi-5_4-2016q3
日期: 2017-7-8 22:56:20
作者: SY
简介
Ramdisk
是一个使用内存模拟硬盘的文件系统- 在
硬盘
、eMMC
正常工作之前,由Linux内核使用 - 在最小文件系统的基础上制作
制作
设置
Ramdisk
大小root@ubuntu:/opt/linux-4.12# make menuconfig Device Drivers ---> [*] Block devices ---> (16) Default number of RAM disks (8192) Default RAM disk size (kbytes)
- 设置16个
RAM disk
, 每一个大小为8MBytes
- 设置16个
制作空白的
ramdisk
root@ubuntu:/opt# dd if=/dev/zero of=ramdisk bs=1M count=8 8+0 records in 8+0 records out 8388608 bytes (8.4 MB, 8.0 MiB) copied, 0.00489288 s, 1.7 GB/s
将
ramdisk
挂载为loop
文件系统root@ubuntu:/opt# losetup /dev/loop0 ramdisk root@ubuntu:/opt# mke2fs -m 0 /dev/loop0 mke2fs 1.42.13 (17-May-2015) Discarding device blocks: done Creating filesystem with 8192 1k blocks and 2048 inodes Allocating group tables: done Writing inode tables: done Writing superblocks and filesystem accounting information: done root@ubuntu:/opt# mkdir /mnt/loop root@ubuntu:/opt# mount -t ext2 /dev/loop0 /mnt/loop
将最小文件系统的数据拷贝到
/mnt/loop
,然后卸载root@ubuntu:/opt# cp -arf busybox-1.27.0/rootfs/* /mnt/loop root@ubuntu:/opt# umount /mnt/loop root@ubuntu:/opt# rm -rf /mnt/loop
使用
u-boot
的工具mkimage
压缩为.img
root@ubuntu:/opt# gzip -v9 ramdisk ramdisk: 86.2% -- replaced with ramdisk.gz root@ubuntu:/opt# mkimage -n 'Tiny4412 Ramdisk Image' -A arm -O linux -T ramdisk -C gzip -d ramdisk.gz ramdisk.img Image Name: Tiny4412 Ramdisk Image Created: Sun Jul 9 22:25:32 2017 Image Type: ARM Linux RAMDisk Image (gzip compressed) Data Size: 1161411 Bytes = 1134.19 KiB = 1.11 MiB Load Address: 00000000 Entry Point: 00000000 root@ubuntu:/opt# ls arm busybox-1.27.0 gdb-7.9.1 linux-4.12 ramdisk.img temp u-boot-2017.03 arm-2014.05 gcc-arm-none-eabi-5_4-2016q3 initramfs ramdisk.gz share tftpboot
可以将上述过程制作成脚本
mk_ramdisk.sh
#!/bin/bash # Make Ramdisk img # Author: SY # Date: 2017-7-9 22:39:55 SRC_PATH="./ramdisk" TEMP_FILE="_ramdisk" echo "------------------------------" echo "Delete ramdisk.img" rm -rf ramdisk.img rm -rf ramdisk.gz echo "------------------------------" echo "Create TEMP" dd if=/dev/zero of=$TEMP_FILE bs=1M count=8 echo "------------------------------" echo "mount loop" losetup /dev/loop0 $TEMP_FILE mke2fs -m 0 /dev/loop0 mkdir /mnt/loop mount -t ext2 /dev/loop0 /mnt/loop cp -arf $SRC_PATH/* /mnt/loop echo "------------------------------" echo "umount loop" umount /mnt/loop rm -rf /mnt/loop losetup -d /dev/loop0 echo "------------------------------" echo "gzip ramdisk" gzip -v9 $TEMP_FILE mv $TEMP_FILE.gz ramdisk.gz echo "------------------------------" echo "mkimage" mkimage -n 'Tiny4412 Ramdisk Image' -A arm -O linux -T ramdisk -C gzip -d ramdisk.gz ramdisk.img echo "over" echo "------------------------------"
设置环境变量
TINY4412 # setenv dfu_alt_info uImage ram 0x41000000 0xA00000\;ramdisk.img ram 0x42000000 0x800000\;exynos4412-tiny4412.dtb ram 0x43000000 0x100000 TINY4412 # saveenv
去掉
initramfs
root@ubuntu:/opt/linux-4.12# make menuconfig General setup ---> [*] Initial RAM filesystem and RAM disk (initramfs/initrd) support () Initramfs source file(s)
烧录
U-Boot 2017.03-ge4aa2a4-dirty (Jul 09 2017 - 10:49:03 +0800) for TINY4412 CPU: Exynos4412 @ 1.4 GHz Model: Tiny4412 based on Exynos4412 Board: Tiny4412 based on Exynos4412 DRAM: 1 GiB WARNING: Caches not enabled MMC: SAMSUNG SDHCI: 2, EXYNOS DWMMC: 4 ** First descriptor is NOT a primary desc on 4:1 ** Net: No ethernet found. Hit any key to stop autoboot: 0 USB PHY0 Enable #DOWNLOAD ... OK Ctrl+C to exit ... #DOWNLOAD ... OK Ctrl+C to exit ... #DOWNLOAD ... OK Ctrl+C to exit ... TINY4412 # bootm 41000000 42000000 43000000 ## Booting kernel from Legacy Image at 41000000 ... Image Name: Linux-4.12.0-gd593bff-dirty Image Type: ARM Linux Kernel Image (uncompressed) Data Size: 4827888 Bytes = 4.6 MiB Load Address: 40008000 Entry Point: 40008000 Verifying Checksum ... OK ## Loading init Ramdisk from Legacy Image at 42000000 ... Image Name: Tiny4412 Ramdisk Image Image Type: ARM Linux RAMDisk Image (gzip compressed) Data Size: 1161914 Bytes = 1.1 MiB Load Address: 00000000 Entry Point: 00000000 Verifying Checksum ... OK ## Flattened Device Tree blob at 43000000 Booting using the fdt blob at 0x43000000 Loading Kernel Image ... OK Loading Ramdisk to 4fee4000, end 4ffffaba ... OK Loading Device Tree to 4fed5000, end 4fee356c ... OK Starting kernel ... Uncompressing Linux... done, booting the kernel. [ 0.000000] Booting Linux on physical CPU 0xa00 [ 0.000000] Linux version 4.12.0-gd593bff-dirty (root@ubuntu) (gcc version 5.4.1 20160919 (release) [ARM/embedded-5-branch revision 240496] (GNU Tools for ARM Embedded Processors) ) #13 SMP PREEMPT Mon Jul 10 20:13:51 CST 2017 [ 0.000000] CPU: ARMv7 Processor [413fc090] revision 0 (ARMv7), cr=10c5387d [ 0.000000] CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache [ 0.000000] OF: fdt: Machine model: FriendlyARM TINY4412 board based on Exynos4412 [ 0.000000] bootconsole [earlycon0] enabled [ 0.000000] Memory policy: Data cache writealloc [ 0.000000] cma: Reserved 96 MiB at 0x7a000000 [ 0.000000] Samsung CPU ID: 0xe4412011 ... [ 1.429519] Exception stack(0xef09ff78 to 0xef09ffc0) [ 1.434555] ff60: 00000001 00000000 [ 1.442720] ff80: 00000000 c0115740 ef09e000 c0c054c0 c0c05464 c0b66138 ef09ffd0 00000000 [ 1.450878] ffa0: 00000000 00000000 f081b540 ef09ffc8 c0108fd4 c0108fd8 60000013 ffffffff [ 1.459039] [<c010c78c>] (__irq_svc) from [<c0108fd8>] (arch_cpu_idle+0x38/0x3c) [ 1.466421] [<c0108fd8>] (arch_cpu_idle) from [<c015175c>] (do_idle+0x16c/0x200) [ 1.473797] [<c015175c>] (do_idle) from [<c0151aa8>] (cpu_startup_entry+0x18/0x1c) [ 1.481346] [<c0151aa8>] (cpu_startup_entry) from [<4010158c>] (0x4010158c) [ 1.488297] ---[ end Kernel panic - not syncing: Requested init /linuxrc failed (error -2).
由于
ramdisk.img
在ramdisk.gz
文件的开头增加0x40
字节的头,因此修改环境变量TINY4412 # setenv bootargs initrd=0x42000040,0x800000 root=/dev/ram0 rw rootfstype=ext2 console=ttySAC0,115200 init=/linuxrc TINY4412 # saveenv Saving Environment to MMC... Writing to MMC(4)... done
烧录
Starting kernel ... Uncompressing Linux... done, booting the kernel. [ 0.000000] Booting Linux on physical CPU 0xa00 [ 0.000000] Linux version 4.12.0-gd593bff-dirty (root@ubuntu) (gcc version 5.4.1 20160919 (release) [ARM/embedded-5-branch revision 240496] (GNU Tools for ARM Embedded Processors) ) #15 SMP PREEMPT Mon Jul 10 23:25:00 CST 2017 ... [ 1.444596] NET: Registered protocol family 17 [ 1.448666] NET: Registered protocol family 15 [ 1.453121] Key type dns_resolver registered [ 1.457510] Registering SWP/SWPB emulation handler [ 1.473155] mmc0: new high speed SDHC card at address 0007 [ 1.473538] mmcblk0: mmc0:0007 SD16G 14.5 GiB [ 1.474057] hctosys: unable to open rtc device (rtc0) [ 1.477667] ALSA device list: [ 1.479992] No soundcards found. [ 1.483918] RAMDISK: gzip image found at block 0 [ 1.609180] VFS: Mounted root (ext2 filesystem) on device 1:0. [ 1.609389] devtmpfs: mounted [ 1.610680] Freeing unused kernel memory: 1024K Processing /etc/profile... Done / # / # / # ls bin etc lost+found proc sbin tmp dev linuxrc mnt root sys / #
成功!
总结
使用最小文件系统作为源文件,切记第一个加载的文件是环境变量设置的
linuxrc
,不是init
ramdisk.img
经过mkimage
工具处理后,会在文件头添加64
字节(0x40)
的文件头,因此设置环境变量时,需要将属性initrd
的地址增加0x40
的长度。initrd
属性的值表示ramdisk
的起始地址rootfstype
属性可以不设置,linux
会尝试ext4
、ext2
等,直至找到合适的类型!init=/linuxrc
表示linux
第一个执行的程序为/linuxrc
制作ext4
格式的ramdisk
只需要稍微修改一下脚本即可
root@ubuntu:/opt# mkfs.ext4 Usage: mkfs.ext4 [-c|-l filename] [-b block-size] [-C cluster-size] [-i bytes-per-inode] [-I inode-size] [-J journal-options] [-G flex-group-size] [-N number-of-inodes] [-m reserved-blocks-percentage] [-o creator-os] [-g blocks-per-group] [-L volume-label] [-M last-mounted-directory] [-O feature[,...]] [-r fs-revision] [-E extended-option[,...]] [-t fs-type] [-T usage-type ] [-U UUID] [-jnqvDFKSV] device [blocks-count] root@ubuntu:/opt/ramdisk# cat mkfs_ext4.sh #!/bin/bash # Make Ramdisk img -- ext4 Format # Author: SY # Date: 2017-7-11 21:30:22 SRC_PATH="./ramdisk" TEMP_FILE="_ramdisk" echo "------------------------------" echo "Delete ramdisk.img" rm -rf ramdisk.* echo "------------------------------" echo "Create TEMP" dd if=/dev/zero of=$TEMP_FILE bs=1M count=8 echo "------------------------------" echo "mount loop" losetup /dev/loop0 $TEMP_FILE mkfs.ext4 -m 0 /dev/loop0 mkdir /mnt/loop mount -t ext4 /dev/loop0 /mnt/loop cp -arf $SRC_PATH/* /mnt/loop echo "------------------------------" echo "umount loop" umount /mnt/loop rm -rf /mnt/loop losetup -d /dev/loop0 echo "------------------------------" echo "gzip ramdisk" gzip -v9 $TEMP_FILE mv $TEMP_FILE.gz ramdisk.gz echo "------------------------------" echo "mkimage" mkimage -n 'Tiny4412 Ramdisk Image' -A arm -O linux -T ramdisk -C gzip -d ramdisk.gz ramdisk.img echo "over" echo "------------------------------"
烧录测试
[ 2.015524] CPU3: stopping [ 2.018217] CPU: 3 PID: 0 Comm: swapper/3 Not tainted 4.12.0-gd593bff-dirty #15 [ 2.025505] Hardware name: SAMSUNG EXYNOS (Flattened Device Tree) [ 2.031592] [<c010f268>] (unwind_backtrace) from [<c010bcb0>] (show_stack+0x10/0x14) [ 2.039313] [<c010bcb0>] (show_stack) from [<c034b068>] (dump_stack+0x88/0x9c) [ 2.046516] [<c034b068>] (dump_stack) from [<c010e2b8>] (handle_IPI+0x1a0/0x1b0) [ 2.053893] [<c010e2b8>] (handle_IPI) from [<c01014e8>] (gic_handle_irq+0x94/0x98) [ 2.061444] [<c01014e8>] (gic_handle_irq) from [<c010c78c>] (__irq_svc+0x6c/0xa8) [ 2.068905] Exception stack(0xef0a1f78 to 0xef0a1fc0) [ 2.073941] 1f60: 00000001 00000000 [ 2.082103] 1f80: 00000000 c0115740 ef0a0000 c0c054c0 c0c05464 c0b66138 ef0a1fd0 00000000 [ 2.090262] 1fa0: 00000000 00000000 f081b640 ef0a1fc8 c0108fd4 c0108fd8 60000013 ffffffff [ 2.098422] [<c010c78c>] (__irq_svc) from [<c0108fd8>] (arch_cpu_idle+0x38/0x3c) [ 2.105802] [<c0108fd8>] (arch_cpu_idle) from [<c015175c>] (do_idle+0x16c/0x200) [ 2.113179] [<c015175c>] (do_idle) from [<c0151aa8>] (cpu_startup_entry+0x18/0x1c) [ 2.120729] [<c0151aa8>] (cpu_startup_entry) from [<4010158c>] (0x4010158c) [ 2.127679] ---[ end Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(1,0)
查看当前的环境变量
bootargs=initrd=0x42000040,0x800000 root=/dev/ram0 rw rootfstype=ext2 console=ttySAC0,115200 init=/linuxrc earlyprintk
修改
rootfstype
setenv bootargs initrd=0x42000040,0x800000 root=/dev/ram0 rw rootfstype=ext4 console=ttySAC0,115200 init=/linuxrc earlyprintk
测试
[ 1.473178] Key type dns_resolver registered [ 1.477589] Registering SWP/SWPB emulation handler [ 1.493224] mmc0: new high speed SDHC card at address 0007 [ 1.493598] mmcblk0: mmc0:0007 SD16G 14.5 GiB [ 1.494155] hctosys: unable to open rtc device (rtc0) [ 1.497967] ALSA device list: [ 1.500046] No soundcards found. [ 1.503936] RAMDISK: gzip image found at block 0 [ 1.613510] EXT4-fs (ram0): mounted filesystem with ordered data mode. Opts: (null) [ 1.613625] VFS: Mounted root (ext4 filesystem) on device 1:0. [ 1.613934] devtmpfs: mounted [ 1.614857] Freeing unused kernel memory: 1024K Processing /etc/profile... Done / # / # / #
OK!