On Fri, Oct 31, 2025 at 8:46 AM Markus Armbruster <[email protected]> wrote: > > Clément Chigot <[email protected]> writes: > > > On Mon, Oct 27, 2025 at 1:09 PM Markus Armbruster <[email protected]> wrote: > >> > >> Clément Chigot <[email protected]> writes: > >> > >> > On Fri, Oct 24, 2025 at 10:35 AM Markus Armbruster <[email protected]> > >> > wrote: > >> >> > >> >> Kevin Wolf <[email protected]> writes: > >> >> > >> >> > Am 03.09.2025 um 09:57 hat Clément Chigot geschrieben: > >> >> >> This allows more flexibility to vvfat backend. The value for "Number > >> >> >> of > >> >> >> Heads" and "Sectors per track" are based on SD specifications Part 2. > >> >> > >> >> This is too terse to remind me of how vvfat picks cylinders, heads, and > >> >> sectors before this patch, so I need to go dig through the source code. > >> >> I figure it depends on configuration parameters @floppy and @fat-type > >> >> like this: > >> >> > >> >> floppy fat-type cyls heads secs cyls*heads*secs*512 > >> >> false 12 64 16 63 31.5 MiB > >> >> false 16 1024 16 63 504 MiB > >> >> false 32 1024 16 63 504 MiB > >> >> true 12 80 2 18 1440 KiB > >> >> true 16 80 2 36 2880 KiB > >> >> true 32 80 2 36 2880 KiB > >> >> > >> >> How exactly does the new parameter @size change this? > >> > > >> > My prime goal was to create a 256 Mib VVFAT disk. As you can see, > >> > today for hard-disks there are only two possibilities: 31.5 Mib or 504 > >> > Mib. Hence, I've introduced the option `size=xxx` to allow more > >> > granular choices. > >> > This option changes how cyls, heads and secs parameters are computed > >> > to be as closed as possible of its value. > >> > > >> > I did try to keep it simple. I could have introduced options to select > >> > cylinders, heads, etc. But I think "size=xxx" would be more intuitive. > >> > There are also approximations made, as not all sizes can be reached. I > >> > didn't add errors or warnings for them. I'm fine adding them. > >> > >> I don't have an opinion on whether we should support more sizes and/or > >> provide full control over CHS geometry. > >> > >> >> >> Some limitations remains, the size parameter is recognized only when > >> >> >> "format=vvfat" is passed. In particular, "format=raw,size=xxx" is > >> >> >> keeping the previously hardcoded value: 504MB for FAT16 and 32 MB for > >> >> >> FAT12. FAT32 has not been adjusted and thus still default to 504MB. > >> >> > >> >> 31.5MiB unless I'm mistaken. > >> > > >> > True, I will fix it. > >> > > >> >> I'm not sure what you're trying to convey in this paragraph. As far as > >> >> I can tell, you're adding a @size parameter to vvfat, so of course it > >> >> doesn't affect raw. > >> > > >> > Yes, but AFAICT, `if=sd,format=raw` will result in vvfat backend being > >> > called. I didn't manage to make the new option work with > >> > `if=sd,format=raw,size=256Mb`. Thus, when the "size" option is not > >> > provided, I keep the previous value (those for your above comment). > >> > Hence this paragraph to mostly warn people about the current > >> > limitation. > >> > >> Are you talking about -drive? > >> > >> Complete examples, please. > >> > >> I'm confused about the connection between SD (from if=sd here, and "SD > >> specification" above) and vvfat. SD is a frontend. vvfat is a backend. > > > > Alright, I'll try to explain how I came up with this patch. And sorry > > if it's a bit blurry, I made it some months ago hence I don't remember > > all the details... > > So, first, my prime goal was to access a local folder in a QNX system > > running on Raspi 4B emulation. > > My usual way to pass such a local folder is through `-drive > > file=fat:rw:<host_folder>,format=raw`. For virt, it's usually > > connected to virtio-blk-device: `-drive id=disk0,if=none,... -device > > virtio-blk-device,drive=disk0`. For the Raspi 4b, adding the > > virtio-blk-device is not possible, hence I have to connect it as a SD > > card: `-drive if=sd,...`. > > > > However, without any `size=` argument, QEMU will complain that the SD > > card has not a valid size: > > | (host) $ qemu-system-aarch64 -M raspi4b -kernel raspi4b-kernel > > -nographic -no-reboot -append "earlycon=pl011,mmio32,0xfe201000 > > console=ttyAMA0 noreboot" -dtb bcm2711-rpi-4-b.dtb -initrd > > rootfs.cpio.gz -drive > > id=sdcard,file=fat:rw:<host_folder>,format=raw,if=sd > > | qemu-system-aarch64: Invalid SD card size: 504 MiB > > | SD card size has to be a power of 2, e.g. 512 MiB. > > | You can resize disk images with 'qemu-img resize <imagefile> <new-size>' > > | (note that this will lose data if you make the image smaller than > > it currently is). > > Fun! > > > ("raspi4b-kernel", the dtb and the rootfs come from > > functional/aarch64/test_raspi4.py) > > > > Hence, I've added `size=256M` to reduce the size of that SD card and > > make QEMU happy. This allows me to mount my host folder on Linux: > > | (host) $ qemu-system-aarch64 -M raspi4b -kernel raspi4b-kernel > > -nographic -no-reboot -append "earlycon=pl011,mmio32,0xfe201000 > > console=ttyAMA0 noreboot" -dtb bcm2711-rpi-4-b.dtb -initrd > > rootfs.cpio.gz -drive > > id=sdcard,file=fat:rw:<host_folder>,format=raw,if=sd,size=256M > > | (QEMU) # fdisk -l /dev/mmcblk1 > > | Disk /dev/mmcblk1: 256 MB, 268435456 bytes, 524288 sectors > > | 520 cylinders, 16 heads, 63 sectors/track > > | Units: sectors of 1 * 512 = 512 bytes > > 520 * 16 * 63 is 524160 sectors, 128 less than the 524288 reported. I > figure that's harmless. Only ancient software should look at CHS, and > losing a few sectors with ancient software is fine. > > > | > > | Device Boot StartCHS EndCHS StartLBA EndLBA > > Sectors Size Id Type > > | /dev/mmcblk1p1 * 0,1,1 1023,15,63 63 1032191 > > 1032129 503M 6 FAT16 > > > > As you can see the "Disk" has the right size (256MB) but the partition > > still has a 503M size. > > The partition table's EndLBA is 1032191 even though the disk has only > 524288 cylinders. Scary! > > Its EndCHS is consistent with its EndLBA: 1024*16*63 = 1032191 + 1. > > > However, Linux doesn't seem to care too much > > about that as I'm able to mount this partition, and perform IO > > operations. > > | (QEMU) # mount /dev/mmcblk1p1 /mnt > > | (QEMU) # ls /mnt > > | file.txt > > | (QEMU) # cat /mnt/file.txt > > | Hello World > > | (QEMU) # echo "OK" > /mnt/test.txt > > | (host) $ cat <host_folder>/test.txt > > | OK > > Have you tried with a host folder containing more than 256MiB? What > happens if you try to read all of it?
The access is crashing: | (host) $ du -sh vvfat-test/huge_file | 251M vvfat-test/huge_file | (host) $ qemu-system ... -drive file=fat:rw:vvfat-test,format=raw,if=sd,size=128M | (QEMU) # tail /mnt/huge_file | [ 29.325885] attempt to access beyond end of device | [ 29.325885] mmcblk1p1: rw=524288, want=510657, limit=262081 | [ 29.337672] attempt to access beyond end of device | [ 29.337672] mmcblk1p1: rw=0, want=510657, limit=262081 | tail: read error: I/O error > > Now, QNX comes into play. > > First, the SD card must be connected to another bus. That patch is not > > part of this series as I'm considering it a QNX issue. Just FTR here > > is the patch: > > | --- a/hw/arm/bcm2838_peripherals.c > > | +++ b/hw/arm/bcm2838_peripherals.c > > | @@ -190,7 +190,7 @@ static void > > bcm2838_peripherals_realize(DeviceState *dev, Error **errp) > > | &s_base->peri_mr, GPIO_OFFSET, > > | sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->gpio), 0)); > > | > > | - object_property_add_alias(OBJECT(s), "sd-bus", > > OBJECT(&s->gpio), "sd-bus"); > > | + object_property_add_alias(OBJECT(s), "sd-bus", > > OBJECT(&s->emmc2), "sd-bus"); > > | > > | /* BCM2838 RPiVid ASB must be mapped to prevent kernel crash */ > > > > Afterwards, QNX is able to see the SD card, but not able to mount it. > > It complains about the filesystem being corrupted. Looking at `fdisk` > > output, it shows a mismatch between the "total section" value and the > > Cylinders/Heads/etc values. > > | (QEMU) # fdisk /dev/hd0 info > > | Physical disk characteristics: (/dev/hd0) > > | Disk type : Direct Access (0) > > | Cylinders : 520 > > | Heads : 16 > > | Sectors/Track : 63 > > | Total Sectors : 524288 > > | Block Size : 512 > > | > > | Warning: total sectors field does not agree with > > | cylinders*sectors/track*heads!! (524288 vs 524160) > > I'm not sure this mismatch causes the problem. I suspect the bogus > EndLBA does. > > > The "no-mbr" option introduced in patch 1 is something we (Adacore's > > QEMU team) have for a long time. I don't remember the details but we > > are using it for other OSes as well (notably RTEMS). > > Suppressing MBR initialization avoids the partially bogus partition > table. > > But if we create a partition table, it better make sense, don't you > think? My understanding is that `format=vvfat,size=xxxM` results in a valid EndLBA. Is that enough to make a valid partition table ? However, I'm still getting the corrupted error without `no-mbr`. Though, the warning is gone too (compared to `format=raw,size=xxx`). So this is something else QNX doesn't like... Something weird if just noticed, the disk CHS values are changed when passing `no-mbr` | (host) $ qemu-system-aarch64 -drive file=fat:rw:<host_folder>:format=vvfat,size=128M | (QEMU) # fdisk -l /dev/mmcblk1 | Disk /dev/mmcblk1: 128 MB, 134217728 bytes, 262144 sectors | 1024 cylinders, 8 heads, 32 sectors/track | | (host) $ qemu-system-aarch64 -drive file=fat:rw:no-mbr:<host_folder>:format=vvfat,size=128M | (QEMU) # fdisk -l /dev/mmcblk1 | Disk /dev/mmcblk1: 128 MB, 134217728 bytes, 262144 sectors | 4096 cylinders, 4 heads, 16 sectors/track Not sure if it could be related. > > Once added, and the drive command line updated for `-drive > > id=sdcard,file=fat:rw:no-mbr:<host_folder>,format=raw,if=sd,size=256M`, > > I don't have this warning anymore. Though, I'm still getting the > > corrupted filesystem error. > > > > Afterwards, it's a bit blurry but I think by trial and errors we ended > > up removing the SD size error and realize that `-drive > > id=sdcard,file=fat:rw:no-mbr:<host_folder>,format=raw,if=sd` was > > working. However, `size=256M` still results in a corrupted filesystem. > > As a comment in vvfat.c states that it either creates a "32MB or 504 > > MB disk". I decided to check if I can adapt, hence this patch. > > > > I didn't find any VFAT documentation explaining the relation between > > the size and the cylinders, heads, sector per track values. However, > > the SD documentation was giving some recommandations, hence I used it > > as a base. > > > > I was unable to make `vvfat.c` recognize the "size" argument passed > > along `format=raw`, even if hardcoding the value in `vvfat.c` did make > > a difference. And that's why I'm adding the warning in the commit > > message. > > This one: > > Some limitations remains, the size parameter is recognized only when > "format=vvfat" is passed. In particular, "format=raw,size=xxx" is > keeping the previously hardcoded value: 504MB for FAT16 and 32 MB for > FAT12. FAT32 has not been adjusted and thus still default to 504MB. > > > I've also realized that following my patch, the mismatch in between > > the disk and the partition in Linux was going away when using `-drive > > format=vvfat,size=xxx`. Making it not just QNX-oriented. > > | (host) $ qemu-system-aarch64 -M raspi4b -kernel raspi4b-kernel > > -nographic -no-reboot -append "earlycon=pl011,mmio32,0xfe201000 > > console=ttyAMA0 noreboot" -dtb bcm2711-rpi-4-b.dtb -initrd > > rootfs.cpio.gz -drive > > id=sdcard,file=fat:rw:<host_folder>,format=vvfat,if=sd,size=256M > > | (QEMU) # fdisk -l /dev/mmcblk1 > > | Disk /dev/mmcblk1: 256 MB, 268435456 bytes, 524288 sectors > > | 1024 cylinders, 16 heads, 32 sectors/track > > | Units: sectors of 1 * 512 = 512 bytes > > | > > | Device Boot StartCHS EndCHS StartLBA EndLBA > > Sectors Size Id Type > > | /dev/mmcblk1p1 * 0,1,32 1023,15,32 63 524287 > > 524225 255M 6 FAT16 > > EndLBA matches disk size. EndCHS still matches EndLBA. Good. > > The difference to the command line you showed above is format=raw (bad) > vs. format=vvfat (good). > > With format=raw,size=256M you get that size, but a bogus partition > table. > > With format=vvfat,size=256M you get that size, and a sensible partition > table. > > Correct? Yes and the main reason for that is because I don't know how to retrieve the size given to "raw" within `vvfat_open`. My understanding is that raw-format.c is suppressing that option, through `qemu_opts_del` in `raw_read_options`, before calling its block childs (here vvfat). Hence, it assumes the default size 512M. > > I probably missed a few things, but I hope this is clearer to you why > > and how this series was made. >
