eMMC Flash Layout

Hi Gouwa,

Preamble:

I have built the system based on U-Boot and Linux taken from ubuntu branches of your Git repository and created bootable SD card (16G size).

Then I have erased eMMC flash including the partition table and do the following procedure:

1) Boot the boart and enter into U-Boot console by pressing Esc or Enter or Ctrl+C key.

2) initialize SD Card:

kvim# mmcinfo
Device: SDIO Port B
Manufacturer ID: 41
OEM: 3432
Name: SD16G 
Tran Speed: 50000000
Rd Block Len: 512
SD version 3.0
High Capacity: Yes
Capacity: 14.5 GiB
mmc clock: 40000000
Bus Width: 4-bit

3) read DTB from SD Card:

kvim# ext4load mmc 0:1 0x01080000 /boot/kvim.dtb
37054 bytes read in 42 ms (861.3 KiB/s)

4) write DTB to eMMC (and init partition table):

kvim# store dtb write 1080000
[store]To run cmd[emmc dtb_write 1080000 0x40000]
write emmc dtb
mmc read lba=0x14000, blocks=0x400
start dts,buffer=0000000073eeb850,dt_addr=0000000073eeb850
parts: 3
00:      logo   0000000002000000 1
01:      boot   0000000002000000 1
02:    rootfs   ffffffffffffffff 4
get_dtb_struct: Get emmc dtb OK!
Partition table get from SPL is : 
        name                        offset              size              flag
===================================================================================
   0: bootloader                         0            400000                  0
   1: reserved                     2400000           4000000                  0
   2: cache                        6c00000                 0                  0
   3: env                          7400000            800000                  0
   4: logo                         8400000           2000000                  1
   5: boot                         ac00000           2000000                  1
   6: rootfs                       d400000         1c4c00000                  4
mmc read lba=0x12000, blocks=0x2
mmc read lba=0x12002, blocks=0x2
mmc_read_partition_tbl: mmc read partition ERROR!
mmc write lba=0x12000, blocks=0x2
mmc write lba=0x12002, blocks=0x2
mmc_write_partition_tbl: mmc write partition OK!
 partition table success

5) Store U-Boot Environmets to the env partition:

kvim# 
kvim#defenv
## defenv_reserve

kvim#saveenv
Saving Environment to aml-storage...
mmc env offset: 0x7400000 
Writing to MMC(1)... done

6) reboot the system:

kvim# reboot

Now I have following

Questions:

1) On the Linux userspace after system start in the dev file system I have following inodes:

/dev/mmcblk1
/dev/mmcblk1boot0
/dev/mmcblk1boot1

How these devices corresponded with U-Boot partition table present in the Preamble?

2) When I create following partitions on the /dev/mmcblk1 device:

boot:
  start sector: 352256
   end sector: 417791

rootfs:
  start sector: 417892
   end sector: (last sector of eMMC)

I see the new inodes:

/dev/mmcblk1p1
/dev/mmcblk1p2

and I create the filesystems boot - 32M, rootfs size of rest of eMMC.

But after reboot the new file systems ar lost I think because U-Boot re-initializes partitions during start.

How to use the boot and rootfs partitions on user-space?
May be we have to do some patch for kernel and U-Boot to be able keep the partitions for a long time?

3) Could you please prepare the documentation which consider:

  • eMMC initialisation from scrutch
  • U-Boot partition table format (from U-Boot vision, kernel vision, user-space vision)

4) Could you please write a guidance about LOGO and publish at Khadas Docs.

Best Regards.
Andrey K.

P.S.
I have upload my first build to the FTP.

If you interest then you can create bootable SD by following commands:

# cat khadas-vim.boot-records khadas-vim.ext4fs > SDHC.img
# dd if=SDHC.img of=/dev/<your mounted device, for example, mmcblk0>

Will reply your questions in many posts/comments.

Question1:

/dev/mmcblk1boot0
/dev/mmcblk1boot1

I’m not quite sure, but I guess these two device nodes are u-boot/bootlader itself. And I research on Google and found following topic for your reference:

mmcblk0boot0 is a hardware-defined partition in the eMMC distinct from the mmcblk0pN partitions that are defined by the MBR partition table in the “user area”. U-Boot (if you’re using a version that supports it) could be configured to to access the environment from mmcblk0boot0 instead of the mmcblk0 “user area” by defining #define CONFIG_SYS_MMC_ENV_PART 1 You will also have to define CONFIG_ENV_OFFSET to skip over the u-boot.bin image

Qeustion2:

  • How do you load boot.img ?
  • And how do you create boot.img?

For me, I create boot.img for Ubuntu using:

$ ./utils/mkbootimg --kernel linux/arch/arm64/boot/Image --ramdisk images/initrd.img -o images/boot.img

Check http://docs.khadas.com/social/BuildBootloaderAndRamfs/ for info.

And the u-boot load boot.img using:

imgread kernel boot ${loadaddr}; bootm ${loadaddr}

Check CONFIG_BOOTCOMMAND in u-boot/board/khadas/configs/kvim.h for info.

And using one of follow approaches to burn boot.img into eMMC:

Burnning boot.img using USB-Disk
Copy the boot.img to a USB disk, the plug into your target device:

kvim# usb_update boot boot.img

Burnning boot.img using SD Card
Copy the boot.img to a USB disk, the plug into your target device:

kvim# sdc_update boot boot.img

Hi Gouwa,

Your method related to Android and also needs initrd image. This is not good idea for normal linux system.

I load Linux image and dtb separately:

mmcinfo
ext4load mmc 0:1 0x13000000 /boot/radix-2CPU-224x96-32bpp.bmp
setenv display_bpp 32
setenv display_color_index 32
setenv display_color_fg 0xffffffff
osd open
osd clear
bmp display 0x13000000
bmp scale
ext4load mmc 0:1 0x11000000 /boot/uImage
ext4load mmc 0:1 0x01000000 /boot/kvim.dtb
setenv bootargs 'console=ttyS0,115200n8 ro root=/dev/mmcblk0p1 rootfstype=ext4 no_console_suspend logo=osd1,loaded,0x3d800000,1080p60hz consoleblank=0 hdmimode=1080p60hz'
bootm 0x11000000 - 0x01000000

The uImage I create from Image.gz by following command:

mkimage \
           -A arm64 -O linux -T kernel -C gzip -a 0x01080000 -e 0x01080000 \
           -n 3.14.29 -d Image.gz uImage

I also changed CONFIG_BOOTCOMMAND because I want to use custom boot.scr which placed in the /boot directory on the ext4 rootfs.

Please see the Makefile and PATCHES in this directory.

Yes, It’s indeed not a good idea for normal linux distro, as when upgrading kernel/ramdisk would be also require a non-standard way.

I saw you built image using SD card, it’s quite easier to create two partitions for each boot and rootfs.
And the reasons I used Android mkbootimg to to build Linux Distro image are:

  • Can pack the images to update.img for users to upgrade ROM using USB-C cable on Windows PC.
  • The boot partition just for ramdisk image only, but not for /boot path of linux root
  • When upgrading kernel/ramdisk is needed, the system can load the new files into /boot folder first, then write into boot parttion

Back to your question2:

What do you mean here then?

Question3.1 Pack update.img for eMMC installation:

Will update Khdas Docs then, just paste brief at here for your reference first:

  1. Create upgrade folder and copy all the images and files into it:
gouwa@Server:~/project/khadas/ubuntu$ ls upgrade/
aml_sdc_burn.ini          boot.img  logo.img       rootfs.img  u-boot.bin.sd.bin   u-boot.bin.usb.tpl
aml_upgrade_package.conf  kvim.dtb  platform.conf  u-boot.bin  u-boot.bin.usb.bl2
gouwa@Server:~/project/khadas/ubuntu$ 

2.Pack images:

$ ./utils/aml_image_v2_packer -r upgrade/aml_upgrade_package.conf upgrade/ images/update.img
1 Like

Question3.2 & Question4: will do that in next week.

About partitions, paste some code here first (u-boot/include/emmc_partitions.h):

#ifndef CONFIG_AML_MMC_INHERENT_PART
#define     PARTITION_RESERVED              (8*SZ_1M)  // 8MB
#define     MMC_BOOT_PARTITION_RESERVED     (32*SZ_1M) // 32MB

#define     MMC_BOOT_NAME                   "bootloader"
#define     MMC_BOOT_DEVICE_SIZE            (0x4*SZ_1M)

#define     MMC_RESERVED_NAME               "reserved"
#define     MMC_RESERVED_SIZE               (64*SZ_1M)
#define     MMC_BOTTOM_RSV_SIZE             (0)
#endif      /* CONFIG_AML_MMC_INHERENT_PART */

#define     MMC_CACHE_NAME                  "cache"
// #define     MMC_CACHE_SIZE                  (512*SZ_1M) // this is not used and should be get from spl

#define     MMC_ENV_NAME                    "env"
#define     MMC_ENV_SIZE                    (8*SZ_1M)
1 Like

The same procedure can be done by fill image directly by dd without using android-tools.

Regarding partitions created by fdisk and placed at addresses which we have in the U-Boot partition tables I can say that after next system start this partitions become invisible probably U-Boot erases information during init on boot time.

Yes, I will give a try to do that without android-tools.

Still not quite understand the contents on your question2:

And here:

Did you say same things?

Yes.

We have the U-Boot partition table entries:

  5: boot                         ac00000           2000000                  1
  6: rootfs                       d400000         1c4c00000                  4

and if we create entries in the MBR () using fdisk utility which has the same addresses and sise:

(the sector size is 512 bites)
boot:
  start sector: 352256
   end sector: 417791

rootfs:
  start sector: 417892
   end sector: (last sector of eMMC)

we will have inodes:

/dev/mmcblk1p1
/dev/mmcblk1p2

and we will can create file systems:

mke2fs -t ext4 -L boot /dev/mmcblk1p1
mke2fs -t ext4 -L rootfs /dev/mmcblk1p2

Also at first time we can to mount these file systems and use its.

But after the system reboot we dowsn’t have inodes:

/dev/mmcblk1p1
/dev/mmcblk1p2

it is strange. It seems like U-Boot erases data or kernel cannot find these partitions on the eMMC.

The question is that how to use boot and rootfs partitions on the userspace?

I haven’t met the issue yet.

You can install the Ubuntu ROM on eMMC installation in this topic and do the comparison.

And you said first time okay, but with wrong nodes when reboot, can you post the whole log from 1st boot and 2nd boot? (u-boot printing & dmesg)

Full logs is the same.

Issue is that when we create partitions by fdisk and make file systems we have inodes /dev/mmcblk1p{1,2}. After reboot we have not inodes /dev/mmcblk1p{1,2} but if we start fdisk and repeat the wtite command:

fdisk /dev/mmcblk1
. . .
Command (m for help): w

then we can see the inodes /dev/mmcblk1p{1,2} again and can mount partitions. All data in that partitions exists and available.

MBR partition table is same and U-Boot doesn’t take this table.

Probably U-Boot rewrite some data in the partition or I have to use another values of start/end sectors?

No idea yet.

As you didn’t provide any further details, i.e. full log or so, so I just can’t locate the issue.

Hi Gouwa,

I found the root cause of this issue.

After reboot the Linux kernel create inodes

/dev/boot
/dev/rootfs

according the names of partitions in the U-Boot partition table. And I can mount /dev/boot partition created before as /dev/mmcblk1p1.

But the partition /dev/rootfs recognised by kernel as read only data:

# file -s /dev/rootfs
/dev/rootfs: data

So it seems like in the ubuntu linux branch we have code from android staff where the last partition recognized as data Android partition.

Please give me point of linux kernel code where Linux kernel initializes partitions???

Hi Gouwa,

As we have following entries:

5: boot ac00000 2000000 1
6: rootfs d400000 1c4c00000 4

in U-Boot partition table and ac00000 + 2000000 = cc00000 I can say that the last partition haw wrong addres d400000 !

So if we create partitions with following addresses by fdisk:

(the sector size is 512 bites)
boot:
  start sector: 352256
   end sector: 434175

rootfs:
  start sector: 434176
   end sector: (last sector of eMMC)

The issue will be fixes.

I think we have to fix partitions addresses in the kvim.dts file and share our experience with other people!

Thank you very much for your attention. We have found a solution thanks to your support.

Best Regards,
Andrey K.

Andrey

Where is that FTP server?

Have you been able to build an image with a corrected partn table? If so I’d love to try it here.

Thanks
Ed

Hi Gouwa,

I think is correct because in the U-Boot declared reserved 8Mb space after each partition

#define PARTITION_RESERVED (8*SZ_1M) // 8MB

so you can use current image and create partitions with offset in my second post:

(the sector size is 512 bites)
boot:
  start sector: 352256
   end sector: 434175

rootfs:
  start sector: 434176
   end sector: (last sector of eMMC)

Probably for the future we can remove cache and reserved partitions and do not declare reserved space after each partition. What do you think about it?

The current images here ftp://ftp.radix.pro/radix/platform/releases/1.1.617/s9xx-glibc/khadas-vim/

Thank you for the best technical support.

Let me known if you need some changed images and I will create for you!

Best Regards,
Andrey K.

For my purpose I think I will remove the /dev/boot partition because it don’t needed and also too small.

Hi Gouwa,

Please note that the RESERVED partition cannot be removed because in this partition the partition table is located for U-Boot an Kernel.

Also if you change the bootloder partition size then you have to do the same in kernel include/linux/mmc/emmc_partitions.h file. The kernel use this size for finding the offset of RESERVED partition where partition table is placed.

Best Regards,
Andrey K.

P.S.
I need more tests before I can share my patches.

1 Like

Will keep research that. Sometimes I just wanna keep everything simple :blush: