Unfortunately no one can be told what fun_plug is - you have to see it for yourself.
You are not logged in.
Pages: 1 2
According to the source code it appears there are the following limitations on the size of the initrd and kernel when reloading:
kernel < 200/2 * 32k = 3.2M
initrd < 280/2 * 32k = 4.3M
My Debian initramfs is now pushing 5M
Now I'm sure I could manually trim it down each time i re-make it, but I was wondering if there is any way to change the limitations in the reloaded module.
Are the current limitations hard? Are they do to limited memory? Kernel architecture issues? Arbitrary?
If I can change the size would I just need to change the '.rept' values 280 and 200 in rc.S (see below)?
By the way my kernel is only about 1.3MB while my initrd is 5+M so the combined total would fit within the 280 (4.3MB) + 200 (3.8MB)
.globl dns323_kernel_segments
dns323_kernel_segments:
.rept 200
.long 0x0
.endr
.globl dns323_initrd_segments
dns323_initrd_segments:
.rept 280
.long 0x0
.endr
the
Offline
Well I just tried recompiling the initrd in 2 flavors:
1. Flavor A - kept the total kernel + initrd size constant while increasing the initrd size
Kernel: 130 (130/2 * 32 = 2.1 MB)
Initrd: 350 (350/2 * 32 = 5.6 MB)
2. Flavor B - increased initrd size will keeping kernel size the same
Kernel: 200 (200/2 * 32 = 3.2 MB)
Initrd: 350 (350/2 * 32 = 5.6 MB)
Both new versions were able to boot my smaller initrd (3.8 MB), but both of them *failed* to boot my new 5MB initrd.
This would seem to indicate that I am compiling the module correctly since it still works for smaller initrds.
So it seems like something is not allowing larger initrd's to be loaded.
Any thoughts on what the actual physical size limitations there might be here or what else could be preventing the reloaded module from working?
Offline
I confirmed the issue is purely the size of the initrd by constructing two identical initrd's differing only in that one of them had a junk file about 1.3 MB long so that one weighed in at 3.8MB and the other at about 5.1MB. The first booted, the second hung.
Offline
I don't remember the exact reasons for the limit. But it's a limit on the number of "segments" (for the sum of kernel and initrd). 32k per segment is an assumption/a guess. I think the limit is dues to the maximum allowed size of the stuff in reboot.S. It has to do with ARM addressing modes, but my ARM assembler has never been very good, and I don't remember the details. In the end, I found the limit by experimentation.
A reload can fail due do insufficient memory. The module loads the kernel and initrd into memory, in pieces as large as the kernel memory allocator allows into memory above 16M. If there's not enough physical memory available for the files, or not in large enough pieces, reload fails with a message (all your processes may already be killed, of course, so it may look like crashed).
Offline
Hmmm but this doesn't really explain to me why the version fails where I reduce the size of kernel to 130 (2.1 MB) while increasing the size of initrd to 350 (5.6 MB) which preserves the total number of segments at 480 and should safely fit my kernel (1.3 MB) and my initrd (4.9 MB).
And it shouldn't be an abort on out of memory issue either since the rc.S code loads the 480 segments whether or not there is something there (or at least so i assume). Plus since I am starting loading the initrd now 70 segments (0.9MB) earlier, the end of my initrd is not much past where it was before.
So, it makes me wonder whether there is a separate limit for initrd... (either that or the calculations on segment size are a fair bit off)
Offline
OK - I just modded reload.ko so that I can see what is happening - I commented out 3 lines:
setup_mm_for_reboot(0);
dns323_reboot();
panic("FAILED\n");
Now I can see what is happening in dmesg's by just trying to insmod the kernel directly (with the appropriate parameters added manually).
My command (which works for the 3.8MB initrd so it is *right*) is:
insmod reloaded.ko machtype=1542 kernel=vmlinuz-2.6.32-5-orion5x initrd=initrd.img-2.6.32-5-orion5x-raidlvm cmdline="console=ttyS0,115200 root=LABEL=root-debian rootdelay=10 ip=192.168.1.138::192.168.1.1:255.255.255.0:raider:eth0:none"
And dmesg shows:
reloaded for DNS-323, 2007 tp@fonz.de
vmlinuz-2.6.32-5-orion5x: 1312660 bytes
loaded 131072 of 1312660 bytes at c22a0000 / 022a0000
loaded 131072 of 1312660 bytes at c22e0000 / 022e0000
loaded 131072 of 1312660 bytes at c2320000 / 02320000
loaded 131072 of 1312660 bytes at c2360000 / 02360000
loaded 131072 of 1312660 bytes at c23a0000 / 023a0000
loaded 131072 of 1312660 bytes at c23e0000 / 023e0000
loaded 131072 of 1312660 bytes at c1c20000 / 01c20000
loaded 131072 of 1312660 bytes at c1c60000 / 01c60000
loaded 131072 of 1312660 bytes at c1ca0000 / 01ca0000
loaded 131072 of 1312660 bytes at c1ce0000 / 01ce0000
loaded 1940 of 1312660 bytes at c1d00000 / 01d00000
vmlinuz-2.6.32-5-orion5x: OK (11 segments)
initrd.img-2.6.32-5-orion5x-raidlvm: 5032218 bytes
loaded 131072 of 5032218 bytes at c1d20000 / 01d20000
loaded 131072 of 5032218 bytes at c1d80000 / 01d80000
loaded 131072 of 5032218 bytes at c1de0000 / 01de0000
loaded 131072 of 5032218 bytes at c1e00000 / 01e00000
loaded 131072 of 5032218 bytes at c1e40000 / 01e40000
loaded 131072 of 5032218 bytes at c1e80000 / 01e80000
loaded 131072 of 5032218 bytes at c1ec0000 / 01ec0000
loaded 131072 of 5032218 bytes at c1f00000 / 01f00000
loaded 131072 of 5032218 bytes at c1f40000 / 01f40000
loaded 131072 of 5032218 bytes at c1fa0000 / 01fa0000
loaded 131072 of 5032218 bytes at c1fc0000 / 01fc0000
loaded 131072 of 5032218 bytes at c1800000 / 01800000
loaded 131072 of 5032218 bytes at c1840000 / 01840000
loaded 131072 of 5032218 bytes at c1880000 / 01880000
loaded 131072 of 5032218 bytes at c18c0000 / 018c0000
loaded 131072 of 5032218 bytes at c1900000 / 01900000
loaded 131072 of 5032218 bytes at c1960000 / 01960000
loaded 131072 of 5032218 bytes at c1980000 / 01980000
loaded 131072 of 5032218 bytes at c19c0000 / 019c0000
loaded 131072 of 5032218 bytes at c1a00000 / 01a00000
loaded 131072 of 5032218 bytes at c1a40000 / 01a40000
loaded 131072 of 5032218 bytes at c1a80000 / 01a80000
loaded 131072 of 5032218 bytes at c1ac0000 / 01ac0000
loaded 131072 of 5032218 bytes at c1b20000 / 01b20000
loaded 131072 of 5032218 bytes at c1b40000 / 01b40000
loaded 131072 of 5032218 bytes at c1b80000 / 01b80000
loaded 131072 of 5032218 bytes at c1bc0000 / 01bc0000
loaded 131072 of 5032218 bytes at c1400000 / 01400000
loaded 131072 of 5032218 bytes at c1440000 / 01440000
loaded 131072 of 5032218 bytes at c1480000 / 01480000
loaded 131072 of 5032218 bytes at c14e0000 / 014e0000
loaded 131072 of 5032218 bytes at c1500000 / 01500000
loaded 131072 of 5032218 bytes at c1540000 / 01540000
loaded 131072 of 5032218 bytes at c1580000 / 01580000
loaded 131072 of 5032218 bytes at c15c0000 / 015c0000
loaded 131072 of 5032218 bytes at c1600000 / 01600000
loaded 131072 of 5032218 bytes at c1640000 / 01640000
loaded 131072 of 5032218 bytes at c16a0000 / 016a0000
loaded 51482 of 5032218 bytes at c16c0000 / 016c0000
initrd.img-2.6.32-5-orion5x-raidlvm: OK (39 segments)
dns323_machtype = 1542
CMDLINE: console=ttyS0,115200 root=LABEL=root-debian rootdelay=10 ip=192.168.1.138::192.168.1.1:255.255.255.0:raider:eth0:none
MEM: start 00000000 size 64MB
INITRD: start 00800000 size 5032218
dns323_taglist = 2266000 (c2266000)
copying 2160 bytes reboot code from bf012318 to c2265000
dns323_reboot_start = 2265000
Reloading...
------------------------------------------
So it seems to work ok until the final reload...
Looking at the line: INITRD: start 00800000 size 5032218
again makes me wonder whether there is an independent limitation on the size of the initrd
Offline
Well googling, I found this interesting document that explains the arm boot process http://www.simtec.co.uk/products/SWLIN0 … ticle.html
Indeed it makes the reload.ko module code now much more understandable.
In any case in addition to the ATAG_INITRD2 tag which reload.ko uses to set the size of the *compressed* initrd. It also mentions a tag called ATAG_RAMDISK which sets the size of the *decompressed* initrd. This ATAG is not mentioned in the reload.ko so maybe it assumes a default. And maybe that is part of my problem.
I tried patching the reload.ko to add that tag but either my code is wrong or something else is going on.
Note the code itself works in the sense that it works ok with my smaller initrd but it still hangs when booting the larger 5MB initrd. Note that the smaller initrd decompresses to about 10MB while the larger one decompresses to about 12MB -- both should fit easily within the 16MB ramdisk size I define.
--- main.c.jorig 2007-06-13 17:59:00.905733382 -0400
+++ main.c 2011-01-07 10:58:38.596675379 -0500
@@ -147,6 +147,15 @@
t->u.mem.start = mem_start;
if (initrd_size > 0) {
+ int ramdisk_size=16384; /* 16MB ram disk (size is in K) */
+ printk("RAMDISK: start %08lx size %d KB\n", 0x0lu, ramdisk_size);
+ t = tag_next(t);
+ t->hdr.size = tag_size(tag_ramdisk); /* size tag */
+ t->hdr.tag = ATAG_RAMDISK; /* Ramdisk tag */
+ t->u.ramdisk.flags = 0; /* Load the ramdisk */
+ t->u.ramdisk.size = ramdisk_size; /* Decompressed ramdisk size */
+ t->u.ramdisk.start = 0; /* Unused */
+
printk("INITRD: start %08lx size %d\n", 0x800000lu, initrd_size);
t = tag_next(t);
t->hdr.size = tag_size(tag_initrd);
In any case according to the docs, the only limitations that arm booting seems to have are:
1. The decompressed kernel size must be <4MB
2. There must be enough memory to decompress the initrd on booting
3. The decompressed initrd must align within a single memory region
4. The decompressed initrd must be aligned to a page boundary (typically 4K)
5. The decompressed initrd must not conflict with the memory the zImage head code uses to decompress the kernel or it will be overwritten
#2 seems like the only one that could even potentionally be the problem here.
Is it possible that there is not enough free memory to decompress my larger initrd (and this wouldn't show up in the logs since it would presumably cause issues so early in the boot process - though I imagine if I had a serial console, I might be able to see it)
Now if I am understanding things correctly:
1. There *is* enough memory to load the compressed kernel and initrd into memory as shown by my dmesg debug code in the previous message. I.E., the reload module seems to run just fine up until the reboot is actually triggered.
2. Once the reboot is triggered, I would think that *all* of the memory from the initial boot is cleared except for the area that the ATAGs reserve for the compressed kernel, the initrd, the tag table and perhaps some small boot code fragments. My point is that once you get to this point, I would think that 64MB would be sufficient to hold a 1.3MB compressed kernel, a less than 4MB decompressed kernel, a 5MB compressed initrd and a 12MB decompressed initrd. And I would think there would be enough memory to go through the boot process until the kernel chroot's to the real root and frees up the 12MB ram disk memory.
Now I'm probably wrong here, but I wanted to lay out my thinking of why I don't see where the memory problem would be once we know that reload.ko has enough memory to get up to the reboot...
3
Offline
Have you tried your ramdisk in a qemu? It's almost as good as having a serial console - and may unconver a problem with the contents of your larger initrd.
Offline
Fonz is there potentially a trivial error in your code in the reloaded_init() function.
Specifically, should the line:
flush_icache_range((unsigned long)dns323_reboot_code, (unsigned long)dns323_reboot_code + dns323_reboot_size);
really instead be:
flush_icache_range((unsigned long)dns323_reboot_code, (unsigned long)dns323_reboot_code + dns323_reboot_size-1);
Not sure it makes any real difference but I noticed it in the code. I'm assuming that the arguments of the function are start and end but you are giving start and end+1 (I think)
Offline
Qemu is an interesting suggestion.
I have never played with it.
Any pointers on documentation of how to get it to work with ARM and the dns-323?
(Note: I know I have the executable on my Fedora system)
Thanks
Offline
puterboy wrote:
Any pointers on documentation of how to get it to work with ARM and the dns-323?
I've attached the script I use to start ffp in qemu. You may need to change the kernel command line or the /ffp/... paths to your initrd to start.
Offline
And you need a compatible kernel, of course. E.g. http://www.inreto.de/dns323/misc/zImage … 9-qemu-arm
Offline
Thanks Fonz.
Unfortunately, I am having trouble getting the NFS mount of root to work.
I get the following error message:
eth0: link up, 100Mbps, full-duplex, lpa 0x05E1
IP-Config: Complete:
device=eth0, addr=192.168.1.101, mask=255.255.255.0, gw=192.168.1.100,
host=qemu, domain=, nis-domain=(none),
bootserver=255.255.255.255, rootserver=192.168.1.145, rootpath=
Looking up port of RPC 100003/3 on 192.168.1.100
rpcbind: server 192.168.1.100 not responding, timed out
Root-NFS: Unable to get nfsd port number from server, using default
Looking up port of RPC 100005/3 on 192.168.1.100
rpcbind: server 192.168.1.100 not responding, timed out
Root-NFS: Unable to get mountd port number from server, using default
Root-NFS: Server returned error -5 while mounting /mnt/share/qemu/arm-sysroot
where I changed the append line to:
-append "root=/dev/nfs nfsroot=192.168.1.100:$sysroot,nfsvers=3 ip=192.168.1.101::192.168.1.100:255.255.255.0:qemu:: console=ttyAMA0 rw init=$init panic=1 $extra"
-------
NFS itself is working since I am able to mount the volume directly from the command line from any machine on my LAN
I have tried both with and without my firewall so that is not a problem (and indeed /var/log/messages shows nothing)
I am wondering whether this is a networking issue since:
1. I can't ping 192.168.1.101 (even though the console says eth0 is up)
2. I don't get any messages in /var/log/messages (so nothing is wrongly hitting my firewall and no problems with tcp wrappers).
Any thoughts on what could be wrong?
And if it is a network issue do I need to be doing anything special on my server?
(note: I added the option nfsvers=3 since I run NFS version 3, but the issue occurs with or without that parameter)
Offline
Actually, I think I solved the problem. I outsmarted myself by trying to change the ip address from 10.0.2.2 to my own LAN address
It seems like I need to keep the addresses in your script. Who knew...
Offline
OK just as an FYI for others, to get NFS to work, I needed to add 'insecure' in my /etc/exports line.
Specifically:
<path-to>/arm-sysroot 127.0.0.1(rw,async,no_root_squash,insecure)
This is because it seems like qemu NFS is using ports >1024.
Perhaps there is a better/safer way but this worked for me. (Fonz, any suggestions?)
Offline
Now everything boots *except* I keep getting the error message:
tty '': '/ffp/sbin/getty -L ttyS0 115200 vt100'
qemu auth.err getty[344]: can't open '/dev/ttyS0': No such device or address
I tried copying over /dev/ttyS0 from my dns-323 to sysroot/dev but it still doesn't work.
Then I tried changing the line in /ffp/etc/inittab to: ttyAMA0
but now I get the same error with ttyAMA0:
qemu auth.err getty[345]: can't open '/dev/ttyAMA0': No such device or address
And /dev/ttyAMA0 does exist in arm-sysroot/dev
I also tried using minicom to open /dev/ttys0 on the *host*
So what do I need to do to get the console working so that I can log in over a console from the host.
i.e. how do I set up and access the emulated arm using a serial console
------
Also, I can't seem to ping the machine @10.0.2.15
I did the following
sudo tunctl -u $(whoami) -t tap0
sudo ifconfig tap0 10.0.2.2 netmask 255.255.255.0
I also tried:
sudo route add -net 10.0.2.0 netmask 255.255.255.0 gw <my host computer ip>
But while I can ping 10.0.2.2 (which is the address on my computer now), I can't ping 10.0.2.15 which should be the address of the arm machine.
Last edited by puterboy (2011-01-09 23:16:38)
Offline
You're right with insecure. I have that, too. It's also in the qemu docs, I think. But there's no need for any tun/tap devices on the host. I can ping the host from the guest, but not the other way round. Networking is not fully functional - but that's Ok. My guest's inittab contains this (rc.sysinit attached):
::sysinit:/etc/rc.sysinit ::respawn:/ffp/sbin/getty -L ttyAMA0 115200 vt100
Offline
Thanks Fonz. [IGNORE THIS MESSAGE - CORRECTED LATER]
By the way as an UPDATE on the original size of the reloaded and kernel initrd.
Here are some observations.
1. The zImage is loaded starting at 0x8000 (=32KiB) while the initrd is loaded starting at -0x800000 (=8MiB).
2. The limit on the initrd seems more to do with the later decompression of the initrd than the size of the compressed initrd.
In fact, I tried the following experiments:
- Base initrd (3.88 MB compressed, 10MB decompressed --> works
- Base initrd + 2.5MB file of zeros (3.88MB compressed, 12.4MB decompressed -->hangs
So the issue seems to be more whether it is able to decompress a larger initrd since the compressed 2.5MB file of all zeros doesn't add any space to the compressed base initrd.
Also, I can verify using printk's that the reloaded.ko module runs seemingly fine in both cases until the dns323_reboot() statement.
So I guess I am wondering whether there is a limit on the size of the decompressed initrd.
But it seems like total free memory is not the issue since if it can get through the reloaded.ko code (or at least up to the final printk), I would think that then all the memory is cleared so that in the 64MB of RAM there should be space for the kernel (<4MB) and the 12MB decompressed initrd
I really need to figure this out since I need the bigger initrd in order to get lvm and raid working on debian.
But I am at a loss what to do.
Any suggestions on how to debug further?
(I don't think qemu can help me further since I'm close to 100% sure it is a size of the decompressed initrd issue and not to do with the content or the size of the compressed initrd)
Thanks
Last edited by puterboy (2011-01-11 04:27:52)
Offline
Assuming initrd is decompressed in a RAM disk, the default size of a RAM disk could be the problem. You can find it in the kernel setup in Drivers->Block devices, and I *think* the default size is 8MiB.
Offline
CORRECTION. I reran my experiments more carefully:
initrd-base: [3.88 MB compressed, 10.1 MB decompressed] --> WORKS
initrd-base prepended with archive of zeros (using cpio): [3.88 MB compressed, 12.7 MB decompressed] --> WORKS
initrd-base postpended with archive of zeros (using cpio): [3.88 MB compressed, 12.7 MB decompressed] --> WORKS
initrd-base prepended with archive of non-zero files (using cpio): [5.03 MB compressed, 12.7 MB decompressed] --> HANGS
initrd-base postpended with archive of non-zero files (using cpio): [5.03 MB compressed, 12.7 MB decompressed] --> HANGS
So CONTRARY to what I mistakenly said before, the issue seems to be the size of the decompressed initrd which makes more sense since it needs to be crammed in while the system is still more or less running. Plus with the initrd starting at 3.2MB [0x800000], perhaps it overwrites something critical.
I wish I had a serial port to verify what is happening...
So, it seems to boil back down to what Fonz said earlier that there is a limitation in how reboot.S works. Because again, it all seems to work fine up until reboot.S is called and based on the above experiments, it seems to work fine after the decompression...
Now if only I understood assembler better, I could play with that code...
Note the appended file(s) *do not* mess with the *function* of the initrd itself since they are stored in ./temp2 and hence only contribute to the size of the decompressed and compressed initrds.
Offline
You could use a small dedicated partition on your harddisk as initial filesystem, and just use no initrd at all.
Offline
After spending the day learning arm assembly language and figuring out the basics of kernel memory management , I finally figured out how to at least get it to boot with my bigger initrd.
This required changing the start of the kernel initrd from 0x8000000 (8MiB) to 0x600000 (6MiB) leaving enough room for my compressed initrd to be copied by reboot.S (changes needed to be made to both reboot.S and to main.c)
I also made a slew of changes to main.c and reboot.S that both automate some of this and allow more efficient memory allocation.
1. I added an assembler constants INITRD_START and INITRD_SIZE and associated global variable dns323_initrd_start and dns323_initrd_size to allow one to change the start and maximum size of the initrd by just changing these 2 constants in reboot.S
For completeness, I similarly added constants TAG_START and KERNEL_START along with the corresponding global variables dns323_tag_start and dns323_kernel_start to allow changing the start point of the tag list and the kernel, respectively.
2. I changed the .rept number to be 50 times INITRD_SIZE (the maximum expected initrd in MiB) and left a corresponding 200 repeats for the kernel (since the maximum kernel size on arm systems is 4MiB). This corresponds to 25 segments per MiB and a total of 100 segments for the kernel. This leaves plenty of room (unless your memory is really fragmented) since this gives an average of 40K per segment compared with the attempted kmalloc segment size of 32 * PAGE_SIZE = 128KiB. NOTE: Any compile-time limitation on the sum of the .rept's for kernel and initrd is due to the fact that page-relative addressing is used. (If for some reason you ever need to increase them beyond the limits of page-relative addressing you can move each global section to follow immediately it's respectively copy routine)
3. I changed the order in reboot.S, so that the order of re-writing is first tag list, then kernel, then initrd -- this is parallel to the physical ordering and technically would allow the initrd to write over space that was formally used to store the kernel code (though it probably doesn't happen that often).
4. In main.c, I changed the load_file routine so that you can give it a minimum memory address that with each segment increases by the size of the segment. This is consistent with the fact that the memory is copied over in reboot.S in segment order. Specifically, you can start allocating zImage anywhere above 0x8001u and initrd anywhere above 0x800001u (actually as above I change that to 0x600001u) again since the memory segments are transferred in order.
5. In main.c, I also noticed that the kmalloc's for the tag list and for the dns323_reboot_code kmalloc returns were not tested to make sure they don't collide with code the reboot.S needs to relocate. So, I added the limitation that the tag list be allocated above 0x101u (although I imagine this constraint won't ever be an issue) and that the dns323_reboot_code starts beyond the end of the max initrd final location (INITRD_START + INITRD_SIZE + 1)
5. I made a minor change or two to the printk's in main.c
6. I put the final global variables dns323_reboot_size outside of the relocatable code in reboot.S
I will post the final code when I am done tweaking...
Offline
The fact that changing the start of the initrd fixes things actually doesn't make much sense to me.
Because this proves that:
1. It had nothing to do either with the compressed or uncompressed size of the initrd per-se
2. Everything in main.c reboot.S is working just fine
It seems to follow that the issue is somehow either
A. with the copying over of the compressed kernel and initrd by reboot.S where it bumps into something if it starts at 0x800000 but doesn't if it starts at 0x600000 -- but this doesn't make sense since when reboot.S is running the do_reboot, the only process running is the reboot script and there is no memory protection or control to get in our way other than the physical memory itself. And there is plenty of memory above 8MiB to fit a 12MiB initrd
OR:
B. during the initrd decompression where perhaps if we start the initrd at 8MiB, add in a 5 MiB compressed initrd and then start decompressing the zImage (maybe 3 MB) and then 12MiB for the decompressed initrd that we start bumping into things. Even so, I would still think that 64MB should give enough room to fit this since now the only thing that is running is the kernel itself.
Offline
Any news in the front?
Could you please make your code available?
Offline
Pages: 1 2