Tuesday 9 March 2010

OS X Ubuntu USB Creator

I've spent some time attempting to make a Cocoa that lets you burn an Ubuntu ISO to a USB memory stick on OS X.

I think I've got as far as I'm gonna get with it now, sadly.


How far I got...

  • The UI is pretty concise
  • A USB stick gets detected when plugged in
  • The right signal is sent to the dd process and parses the progress for the progress bar
Major outstanding issues

  • It's really SLOW. I'm not familiar with how the dd command line utility works -- people keep talking about 'eraseblocks' and suchlike and my eyes glaze over..
  • It doesn't detect and inform the user when the write is complete
  • It doesn't seem to create a bootable device
  • I can't see how to automatically remount a device after I've unmounted it with diskutil
  • I'm not amazingly confident that once I've detected the device a volume resides on I'm not then going to end up destroying all the data on the wrong drive 

It would be pretty awesome if you were able to help out.  

9 comments:

  1. Hi Michael,

    A few pointers that can help you take this further:
    a
    1) Take a look at: http://developer.apple.com/mac/library/documentation/Carbon/Reference/File_Manager/Reference/reference.html
    There are some functions that you can use to avoid having to call diskutil to list, mount and unmount volumes. They may use some 'strange' data types but I think that in the long term they're more reliable than trying to parse the diskutil output.

    2) The dd utility does little more than open()ing 2 files, read()ing from one file into a buffer and write()ing to the other. If you're familiar with using these system calls, you may also be able to avoid having to call dd.

    3) When you say it's slow, is it slow when you use your 'USB creator' or is it also slow when you call 'dd' from the command line?

    Cheers,
    Alex

    ReplyDelete
  2. This is a tricky one. Do you want to use a Mac to make a USB stick that is bootable _on_ a Mac? Or do you want to use a Mac to create a bootable USB stick that's usable on 'regular' PCs?

    (comments about whether a Mac is a PC to /dev/null)

    Making it bootable on a Mac is a little different than on 'regular' computers as I understand it. They need to be formatted differently, you might need to use refit..

    http://refit.sourceforge.net/

    ReplyDelete
  3. Alexander - yeah - I had a look at that documentation, tried to get my head around the whole read() write() buffer process, and yes, dd does take that long for me from the command line too. It is nice to see that I was on the right track.

    Popey - I was starting to worry that this sort of thing was going to be an emerging problem - personally I'd like to be able to boot the resulting stick on a mac or any other machine.

    The problem is, I'm gonna get personally bollocked by Mark Shuttleworth himself if I spend any more time on this problem, so if you can help me out, that would be amazing.

    ReplyDelete
  4. /dev/rdiskX could be faster.

    I don't think just transferring the ISO using dd will work. A mac needs a GUID/GPT partition scheme, and a bootable fat32 partition using syslinux to boot (a linux live usb) as i understand it. So, copying the files off the image to a newly created partition scheme is probably the way to go.
    Fedora uses a script that can supposedly create a live USB stick that will run on Mac's as well as PC's It involves injecting some hybrid mbr data (from syslinux, gptmbr.bin). Maybe you should look into that? A couple of links;
    http://superuser.com/questions/27794/how-to-boot-a-linux-live-usb-on-a-mac
    http://katzj.livejournal.com/427577.html

    Sorry i couldn't be of more help.

    ReplyDelete
  5. There's unlikely to be much speed advantage in using read() and write() directly over running 'dd' to do the job - they both amount to the same thing.

    You might get better performance by increasing the size of the buffer that dd uses to read and write. On Linux dd uses a default buffer size of 512 bytes, but I find it can perform better if you increase this to (say) 4k - something like 'dd if=foo of=bar bs=4K' for example. Don't go mad with it - if you make the buffer size too big you remove the concurrency of reading and writing both devices at the same time.

    You can do some basic benchmarking from the command line by adding the 'count' option to limit the amount of data transferred, bearing in mind that count is in units of buffers:

    $ dd if=foo of=bar bs=512 count=8000000
    $ dd if=foo of=bar bs=1K count=4000000
    $ dd if=foo of=bar bs=2K count=2000000
    $ dd if=foo of=bar bs=4K count=1000000

    ReplyDelete
  6. Sadly I'm not much of a programmer, but I do own a Mac and can do some testing and poke it with a stick for you.

    I'd agree with Pelle, in that you need to copy the contents of the ISO to the USB stick rather than dd the ISO. Thing is that dding the ISO may work in some circumstances, but isn't reliable enough to work everywhere, and almost certainly won't boot on the mac.

    Whats the development environment you used to create this? If it's free I'll grab it and look at the code on the mac I have.

    ReplyDelete
  7. popey - it's just an Xcode project so you can use the standard dev tools.

    You can install bzr via macports and do

    bzr branch lp:~michaelforrest/ubuntuusbcreator-osx/trunk

    ReplyDelete
  8. How about a feature to allow the disk to be formatted again once the Ubuntu installer is finished being used? I formatted my USB stick using dd... used it on my laptop... but now I can't reformat the USB stick using OS X or diskutility... it's grayed out!

    ReplyDelete
  9. keep it up I need this right now have a Macbook 7,1 and Ubuntu is not installing correct there is a patched file and it is at 707mb nice huh won't fit a CD was trying to use a USB save the DVD discs

    ReplyDelete