Override available memory region passed to Linux by U-bootIt looks that u-boot does not make the whole memory region visible to Linux kernel on my N1 box:
123 # hexdump -C /sys/firmware/devicetree/base/memory@0/reg00000000 00 00 00 00 00 00 00 00 00 00 00 00 78 00 00 00 |............x...|00000010
Note the value 78 00 00 00
above, it means u-boot only makes [0, 0x78000000) visible to Linux.
It’s still a puzzle to me why doesn’t u-boot give the whole 2G ram to Linux.
This patch introduced a new property linux,usable-memory
to overcome this.
As the memory regions that should be reserved are already listed in /reserved-memory/
, I think it should be okay to pass the whole memory region to Linux by adding linux,usable-memory = < 0x00 0x00 0x00 0x80000000 >;
to /memory@0/
.
Update: After connected to monitor by chance, I just found that the screen messes up, seemingly at the point when u-boot hand control over the Linux. I assume that this is because u-boot somehow programmed the video adaptor uses the memory somewhere in [0x78000000, 0x80000000] as frame buffer. This shouldn’t hurt, though, I think.
This patch for meson-gxbb-odroidc2.dts
also seems related. That patch does not expose the first 16M to Linux. But as the first 16M has already been reserved in /reserved-memory/hwrom@0
, I don’t see a reason why I should do the same here. It’s still not clear to me why the last 16M is also not exposed to the Linux by that patch.
After applying the patch, Linux is able to see the entire 2G ram:
1 [ 1.000000] On node 0 totalpages: 518912
Of course this is still not 2G (2G should be 524288 pages) in total, that’s because we reserved 5376 pages in /reserved-memory/
:
12345678910111213141516171819202122232425262728 reserved-memory { #address-cells = < 0x02 >; #size-cells = < 0x02 >; ranges; hwrom@0 { reg = < 0x00 0x00 0x00 0x1000000 >; no-map; }; secmon@10000000 { reg = < 0x00 0x10000000 0x00 0x200000 >; no-map; }; secmon@5000000 { reg = < 0x00 0x5000000 0x00 0x300000 >; no-map; }; linux,cma { compatible = "shared-dma-pool"; reusable; size = < 0x00 0x10000000 >; alignment = < 0x00 0x400000 >; linux,cma-default; }; };
After counting the pages we reserved here ((0x1000000 + 0x200000 + 0x300000) / 4096
is 5376
), we finally get the entire 2G ram back.
I run memtester
to check if things do work, but as it’s a user-mode program it cannot do a thorough test (for those pages already allocated).
But anyway, it seems to work well:
123456789101112131415161718192021222324 # memtester 1800M 5memtester version 4.3.0 (64-bit)Copyright (C) 2001-2012 Charles Cazabon.Licensed under the GNU General Public License version 2 (only). pagesize is 4096pagesizemask is 0xfffffffffffff000want 1800MB (1887436800 bytes)got 1800MB (1887436800 bytes), trying mlock ...locked.Loop 1/5: Stuck Address : ok Random Value : ok Compare XOR : ok Compare SUB : ok Compare MUL : ok Compare DIV : ok Compare OR : ok Compare AND : ok Sequential Increment: ok Solid Bits : ok Block Sequential : ok Checkerboard : ok Bit Spread : ok ...
Diff of the DTS file:
12345678910 --- a.dts 2018-01-01 00:00:00.000000000 +0000+++ b.dts 2018-01-01 00:00:00.000000000 +0000@@ -120,6 +120,7 @@ memory@0 { device_type = "memory"; reg = < 0x00 0x00 0x00 0x80000000 >;+ linux,usable-memory = < 0x00 0x00 0x00 0x80000000 >; }; psci {
As always, the compiled DTB with the patch above is available here: meson-gxl-s905d-phicomm-n1-usbfix-ethfix-memfix.zip
Update: I can confirm that this dtb completely breaks the display output of my N1 box in Linux 4.20. So, DO NOT USE IT UNLESS YOU’RE RUNNING YOUR N1 BOX HEADLESSLY. However, as I’m indeed using the box headlessly, I’m still using this dtb.
It looks that u-boot does not make the whole memory region visible to Linux kernel on my N1 box:
1 2 3 | # hexdump -C /sys/firmware/devicetree/base/memory@0/reg 00000000 00 00 00 00 00 00 00 00 00 00 00 00 78 00 00 00 |............x...| 00000010 |
Note the value 78 00 00 00
above, it means u-boot only makes [0, 0x78000000) visible to Linux.
It’s still a puzzle to me why doesn’t u-boot give the whole 2G ram to Linux.
This patch introduced a new property linux,usable-memory
to overcome this.
As the memory regions that should be reserved are already listed in /reserved-memory/
, I think it should be okay to pass the whole memory region to Linux by adding linux,usable-memory = < 0x00 0x00 0x00 0x80000000 >;
to /memory@0/
.
Update: After connected to monitor by chance, I just found that the screen messes up, seemingly at the point when u-boot hand control over the Linux. I assume that this is because u-boot somehow programmed the video adaptor uses the memory somewhere in [0x78000000, 0x80000000] as frame buffer. This shouldn’t hurt, though, I think.
This patch for meson-gxbb-odroidc2.dts
also seems related. That patch does not expose the first 16M to Linux. But as the first 16M has already been reserved in /reserved-memory/hwrom@0
, I don’t see a reason why I should do the same here. It’s still not clear to me why the last 16M is also not exposed to the Linux by that patch.
After applying the patch, Linux is able to see the entire 2G ram:
1 | [ 1.000000] On node 0 totalpages: 518912 |
Of course this is still not 2G (2G should be 524288 pages) in total, that’s because we reserved 5376 pages in /reserved-memory/
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | reserved-memory { #address-cells = < 0x02 >; #size-cells = < 0x02 >; ranges; hwrom@0 { reg = < 0x00 0x00 0x00 0x1000000 >; no-map; }; secmon@10000000 { reg = < 0x00 0x10000000 0x00 0x200000 >; no-map; }; secmon@5000000 { reg = < 0x00 0x5000000 0x00 0x300000 >; no-map; }; linux,cma { compatible = "shared-dma-pool"; reusable; size = < 0x00 0x10000000 >; alignment = < 0x00 0x400000 >; linux,cma-default; }; }; |
After counting the pages we reserved here ((0x1000000 + 0x200000 + 0x300000) / 4096
is 5376
), we finally get the entire 2G ram back.
I run memtester
to check if things do work, but as it’s a user-mode program it cannot do a thorough test (for those pages already allocated).
But anyway, it seems to work well:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | # memtester 1800M 5 memtester version 4.3.0 (64-bit) Copyright (C) 2001-2012 Charles Cazabon. Licensed under the GNU General Public License version 2 (only). pagesize is 4096 pagesizemask is 0xfffffffffffff000 want 1800MB (1887436800 bytes) got 1800MB (1887436800 bytes), trying mlock ...locked. Loop 1/5: Stuck Address : ok Random Value : ok Compare XOR : ok Compare SUB : ok Compare MUL : ok Compare DIV : ok Compare OR : ok Compare AND : ok Sequential Increment: ok Solid Bits : ok Block Sequential : ok Checkerboard : ok Bit Spread : ok ... |
Diff of the DTS file:
1 2 3 4 5 6 7 8 9 10 | --- a.dts 2018-01-01 00:00:00.000000000 +0000 +++ b.dts 2018-01-01 00:00:00.000000000 +0000 @@ -120,6 +120,7 @@ memory@0 { device_type = "memory"; reg = < 0x00 0x00 0x00 0x80000000 >; + linux,usable-memory = < 0x00 0x00 0x00 0x80000000 >; }; psci { |
As always, the compiled DTB with the patch above is available here: meson-gxl-s905d-phicomm-n1-usbfix-ethfix-memfix.zip
Update: I can confirm that this dtb completely breaks the display output of my N1 box in Linux 4.20. So, DO NOT USE IT UNLESS YOU’RE RUNNING YOUR N1 BOX HEADLESSLY. However, as I’m indeed using the box headlessly, I’m still using this dtb.