There's actually a very good detailed specification on the bitcoin.it site.
Essentially, what it comes down to is that there's some data inserted into the coinbase transaction of the parent chain. So, assuming, for example, that Bitcoin is the parent chain and Namecoin the child chain, anyone merge-mining would be using a coinbase transaction in Bitcoin that has a particular script that looks like this:
- 4 bytes magic (0xfa, 0xbe)
- 32 bytes hash of auxPOW header
- 4 bytes merkle size
- 4 bytes merkle nonce
For now, note that the 32 byte hash of the auxPOW header is the important thing. We'll get to explaining what that is later.
The actual block submitted to Namecoin is actually slightly different. It has a few extra fields like:
- Bitcoin's coinbase txn
- merkle branch (essentially an SPV proof) of the coinbase txn being in Bitcoin's block
- Namecoin's previous block hash
This block is called the AuxPOW block and is actually what gets submitted to the Namecoin block chain. Now, what's to stop anyone finding a block on Bitcoin and submitting the block to Namecoin by adding this extra data? This is where the hash of the AuxPOW in the coinbase transaction of Bitcoin is important.
The AuxPOW hash can be computed ahead of time and must be included in the coinbase transaction of Bitcoin in order for Namecoin to accept it. Thus, anyone merge-mining must be aware of the Namecoin blockchain as they're looking for Bitcoin blocks. Otherwise, Namecoin doesn't accept blocks that just have data added afterwards. The Proof-of-work on Bitcoin already has previous Namecoin block information in the coinbase transaction, tying the two chains together.
merkle size and merkle nonce are 1 and 0 if you're merge mining only 1 other chain. These two variables were set up so that you could merge-mine more than 1 other child blockchain, but it's actually broken. There's a workaround described here.