iPXE discussion forum

Full Version: Referring to files in the initial RAM disk
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hi iPXE Gurus,

I'm using python's pycdlib to create a bootable ISO that uses isolinux as its boot loader and was excited to find that I can have ipxe.lkrn load my "embedded" script from the initial RAM disk created by my isolinux.cfg as follows:

Code:
SAY iPXE ISO boot image
TIMEOUT 30
DEFAULT ipxe.lkrn
LABEL ipxe.lkrn
KERNEL ipxe.krn
APPEND initrd=embed.ipx

This saves me having to compile an embedded script into the ipxe.lkrn binary making it far easier for me to change the embedded script on the fly.

When ipxe.lkrn loads from the ISO it magically reads the contents of embed.ipx from the initial RAM disk created by isolinux. Happy Days! I have beautiful menus and prompts.

However, I was wondering if I can use the same technique to refer to a background image and somehow combine this technique with the ipxe "console --picture [uri]" command in my embedded ipxe script?

For example, I can place both the embedded script and the background.png in the initial RAM disk by using comma separated file references in the isolinux.cfg:

Code:
SAY iPXE ISO boot image
TIMEOUT 30
DEFAULT ipxe.lkrn
LABEL ipxe.lkrn
KERNEL ipxe.krn
INITRD embed.ipx,background.png

I can see the ipxe kernel, the embedded script and the background.png successfully load into the initial RAM disk but I just can't seem to figure out how to refer to the background.png file (or in fact any files on the initial RAM disk) with ipxe commands.

Any words of advice or wisdom hugely appreciated.

Cheers,

Doug

P.S. I will look into using Joliet or Rock Ridge or UDF ISO extensions so that I don't have to use those stupid 8.3 DOS naming conventions soon Rolleyes
This message from the mailing list might be relevant:

Code:
On 28/01/2019 13:41, Dean Westhead wrote:
I still seem to be hitting a snag ....

I am building the ISO with :

make bin-i386-efi/ipxe.efi bin-x86_64-efi/ipxe.efi EMBED=nic-menu-eiso.ipxe,pic1.png
make bin/ipxe.eiso EMBED=nic-menu-eiso.ipxe,pic1.png

And the ISO builds without any errors.

The first few lines of the nic-menu-eiso.ipxe script are :

#!ipxe
console --picture pic1.png

In your case you will need to load the background.png image, but it will need to be referenced in the ipxe.lkrn embedded script:

Code:
#!ipxe
console --picture background.png
Hi MultimediaMan,

(2019-11-29 17:58)MultimediaMan Wrote: [ -> ]In your case you will need to load the background.png image, but it will need to be referenced in the ipxe.lkrn embedded script:

Code:
#!ipxe
console --picture background.png

I should have included my embedded script. It does exactly the above, however it appears to try to retrieve the background.png file over the network rather than trying the initial RAM Disk contents first.

It gives the following error:

Code:
No such file or directory: (http://ipxe.org/err/2d1260)

This error points to net/udp/tftp.c (line 861) which, understandably, fails because there is no network at this point. We are booting from an ISO, having read the ipxe config file from the ISO in to the initial RAM disk and are about to prompt for static IP details.

I was hoping I could access the background picture from the initial RAM disk, display it to the user, prompt for the IP details and then initialise the network and chain as needed.

Everything works without the background image but it would be nice to know if there is a way of specifying the initial RAM disk image file via some URI magic or not.

Again, any thoughts or advice gratefully received.

Cheers,

Doug
use imgstat to see what you have loaded.
But AFAIK there is no support for loading additional files into ipxe via the "initrd" interface.
If there is data there, it will be parsed as a script and nothing else.

What you might be able to do tho is to embed this into original ipxe build (in which case multiple embeds are supported)
But not sure if it in that case is possible to override the script. You might also have to include both a script and the image, otherwise the script that you send via initrd might "overwrite" the image rather than just adding the script, but this is something that you will have to test, if working at all.
Hi NiKiZe,

Strangely, imgstat returns without printing anything at all in spite of the embedded script having successfully run and presented my menus.

I suspect this is because isolinux is providing the embedded script via the initial RAM disk and that ipxe treats loading the script from isolinux' initial RAM disk in a different way from an ordinary imgfetch or imgload command.

Even if I load the image by embedding it in the ipxe.lkrn I suspect there is no way I can refer to it.

Oh well, it was worth asking.

Many thanks for all your help.

I do think ipxe is a wonderful tool.

Cheers,

Doug
not surprised, as that initial script using intird= is not really loaded as an image, but rather just executed, you can read the sourcecode for the autoboot code to see what is going on there.

if you embed it into your ipxe binary, you can refer to it, there should be examples of that on the forum. (but cant find it, but I think it is EMBED=file1,file2 or similar.)

And since the script provided via initrd= is not in imgstat it also suggest that it wouldn't overwrite those files.

before giving up, I would have at least tried to build with multiple embeded files ans checked what imgstat would give.
Would there be a problem doing the *.lkrn embedded with the PNG, then moving on to the menu and Static IP selection?

I have done a similar thing myself for networks which do not have DHCP or one-offs, but I have never bothered with a background image. Reference this thread: http://forum.ipxe.org/showthread.php?tid=13275

My latest ISO iteration prompts for the IP address first, then it attempts to resolve it's hostname contact a ${17} webserver for ${hostname.ipxe}, or, if it is not in DNS, falling back to ${uuid.ipxe}. Assuming it can reach it's webserver, the rest of the process is automated (Kickstart, DNS Search order, Puppet Group, etc...).

Just some ideas.
Hi NikiZe and MultimediaMan,

I had a cursory look at the ipxe source and saw that the register_image() function uses the "image" DEBUG option to output what it is doing, so I enabled that. I also added my own debug statement in src/core/image.c:

> DBGC ( image, "IMAGE trying to execute [%s].\n", image->name );

I recompiled the ipxe.lkrn binary with my background.png embedded via EMBED=background.png and used isolinux to load my ipxe script via its INITRD directive. Here's the make command:

> EXTRA_CFLAGS=-fno-pie make DEBUG=image TRUST=config/local/quo-vadis-root-ca2.crt EMBED=/home/dug/background.png CONFIG=pcbios bin-x86_64-pcbios/ipxe.lkrn

This is my isolinux.cfg (apologies for the 8.3 names, I haven't got pycdlib Joliet working yet):

> SAY iPXE ISO boot image
> TIMEOUT 30
> DEFAULT ipxe.lkrn
> LABEL ipxe.lkrn
> KERNEL ipxe.krn
> INITRD initrd.ipx

My initrd.ipx script does a similar thing to MultimediaMan's. It displays a menu of available network interfaces, once one is chosen, it displays another menu asking if the user wants DHCP or to specify static IP details, it then brings up the chosen network interface with the desired settings and chains to my API which provides everything needed to install an arbitrary OS.

I confess I used a free online OCR site to read my VM screen output, so please allow for the odd mistake... here's what happened:

> ISOLINUX 6.03 20171017 ETCD Copyright © 1994-2014 H. Peter Anvin et al
> iPXE ISO boot
> image loading ipxe.krn... ok
> loading initrd.ipx...ok
> IMAGE background.png at [bfcef339,bfdcd7da) registered
> IMAGE background.png is not Multiboot: Exec format error (http://ipxe.org/20330001)
> IMAGE background.png is not ELF: Exec format error (http://ipxe.org/20360001)
> IMAGE background.png is not script: Exec format error (http://ipxe.org/20320001)
> IMAGE background.png is not bzImage: Exec format error (http://ipxe.org/20310001)
> IMAGE background.png is not COM32: Exec format error (http://ipxe.org/20300001)
> IMAGE background.png is not COMBOOT: Exec format error (http://ipxe.org/20370001)
> IMAGE background.png is not DER: Error 0x3e00033b (http://ipxe.org/303003310)
> IMAGE background.png is not PEM: No such file or directory (http://ipxe.org/2d09003b)
> IMAGE background.png is PNG PXE
> initialising devices...
> IMAGE <INITRD> at Ibfc4d000,bfc4e76f) registered
> IMAGE <INITRD> is not Multiboot: Exec format error (http://ipxe.org/2e838001)
> IMAGE <INITRD> is not ELF: Exec format error (http://ipxe.org/2e868001)
> IMAGE <INITRD> is script
> iPXE 1.0.0. (a4f8) -- Kicker Firmware: dscoular http://ipxe.org Features: DNS HTTP HTTPS iSCSI NFS TFTP SRP AoE ELF MBOOT PXE bzImage COMBOOT Menu PXEXT
> IMAGE trying to execute [background.png].
> An operating system wasn't found. Try disconnecting any drives that don't
> contain an operating system.
> Press Ctrl+Alt+Del to restart

We see that the embedded background.png file is being loaded, registered and recognised as a PNG file and that the ipxe script I included via isolinux' INITRD command was loaded and recognised as a script by the image_probe() function but with the weird name of <INITRD>.

However, we also see that ipxe is trying to execute the PNG file which, naturally, causes it to crash out into the BIOS.

Based on your forum responses, I think this means that I have to add an extra ipxe script to my make command's EMBED variable.

Let's I try that.

I create the following embedded.ipxe script which I hope will help me identify if it runs:

> #!ipxe
> echo Embedded.ipxe is dropping to the iPXE shell... ||
> shell

I recompile ipxe.lkrn with my new double-barrelled EMBED variable:

> EXTRA_CFLAGS=-fno-pie make DEBUG=image TRUST=config/local/quo-vadis-root-ca2.crt EMBED=embedded.ipxe,/home/dug/background.png CONFIG=pcbios bin-x86_64-pcbios/ipxe.lkrn

I reboot my VM with my new ipxe.lkrn ISO:

------------------------------------------------------------------------------
ISOLINUX 6.03 20171017 ETCD Copyright © 1994-2014 H. Peter Anvin et al
iPXE ISO boot image
Loading ipxe.krn... ok
Loading initrd.ipxe...ok
IMAGE embedded.ipxe at [bfcef349,bfcef368) registered
IMAGE embedded.ipxe is not Multiboot: Exec format error (http://ipxe.org/2eB3ti0a1)
IMAGE embedded.ipxe is not ELF: Exec format error (http://ipxe.org/2e868001)
IMAGE embedded.ipxe is script
IMAGE background.png at [bfcef368,bfdcd809) registered
IMAGE background.png is not Multiboot: Exec format error (http://ipxe.org/2e838001)
IMAGE background.png is not ELF: Exec format error (http://ipxe.org/2e868001)
IMAGE background.png is not script: Exec format error (http://ipxe.org/2e028001)
IMAGE background.png is not bzImage: Exec format error (http://ipxe.org/2e818001)
IMAGE background.png is not COM32: Exec format error (http://ipxe.org/2e888001)
IMAGE background.png is not COMBOOT: Exec format error (http://ipxe.org/2e878001)
IMAGE background.png is not DER: Error 0x3e00e03b (http://ipxe.org/3e00e03b)
IMAGE background.png is not PEM: No such file or directory (http://ipxe.org/2d09803b)
IMAGE background.png is PNG
iPXE initialising devices...
IMAGE <INITRD> at (bfc4d000,bfc4e76f) registered
IMAGE <INITRD> is not Multiboot: Exec format error (http://ipxe.org/2e838001)
IMAGE <INITRD> is not ELF: Exec format error (http://ipxe.org/2e868001)
IMAGE <INITRD> is script
ok
iPXE 1.0.0. (a4f8) -- Kicker Firmware: dscoular http://ipxe.org Features: DNS HTTP HTTPS iSCSI NFS TFTP SRP AoE ELF MBOOT PXE bzImage COMBOOT Menu PXEXT
IMAGE trying to execute [embedded.ipxe].
IMAGE embedded.ipxe unregistered
Embedded.ipxe is dropping to the iPXE shel...
iPXE> imgstat
background.png : 910497 bytes [PNG]
<INITRD> : 6022 bytes [script]
------------------------------------------------------------------------------

It works! I can see that we successfully loaded the embedded.ipxe script.
ipxe then executed and unloaded the embedded.ipxe script. imgstat shows me the background.png and <INITRD> script are available.

So, all I have to do now is see if I can chain to the magical <INITRD> image name. I modify my embedded.ipxe script to:

> #!ipxe
> chain <INITRD> || goto failed
>
> :failed
> echo Failed to load script from initial RAM disk. ||
> shell

I rebuild ipxe.lkrn, rebuild my ISO and reboot... complete success.

My isolinux.cfg loads ipxe.lkrn and the initrd script, ipxe executes and loads its embedded script and background PNG, the embedded script executes and chains to my <INITRD>script, my <INITRD> script loads the background image and my menus!

Many thanks for all the help and clues to get this working.

Cheers,

Doug
Awesome
Sad to see the need for the chain <INITRD> hack, but as I expected you needed to embed both script and png, however my reason for thinking it was needed was wrong.
And to use both of them you needed EMBED=embedded.ipxe,/home/dug/background.png

Again awesome, both that you got it working, and that you reported it in such detail, thanks!
Reference URL's