There are lots of problems with this code that you might find on real hardware:
The state of most of the registers when you enter your bootloader is undefined - but the registers need to be valid when you call into interrupt routines. Make sure you set up your segment registers immediately on starting the bootsector. For example, if ES != CS, your jump to the second stage will land in the wrong place.
Ensure you have a valid stack before calling into interrupt routines.
Do not rely on interrupt routines being available. Many hardware vendors recognise build their hardware to work for Windows and Linux (since that's what 99.999% of their customers want), and don't bother implementing interrupt routines they know Windows and Linux won't call.
Before doing disk-accesses, try doing something simpler, like printing a string out to the video display. Next, write a way of printing a register to the screen. Only then will you be in a position where you can start writing a bootloader in a way that you can debug.