Page 1 of 1

Reading my kernel from a CD

Posted: Mon Jun 13, 2011 11:59 am
by SCHiM
Hi everyone,
First things fist, I've searched Google and I found articles all over the place. But most of the answers the OP in those posts got was: "look up this, and look up that". I already know how to create a bootable CD image and how to burn it. So no problem there. My problem is that I don't understand how I can read data from my CD.

I was looking at the INT13 BIOS interrupt and saw that only two types of devices were specified to read from (HDD and floppy) But I'd like to read my image from my CD. How do I use the INT13 interrupt to do that? (or any other)

Re: Reading my kernel from a CD

Posted: Mon Jun 13, 2011 1:18 pm
by drew

Re: Reading my kernel from a CD

Posted: Mon Jun 13, 2011 11:01 pm
by Chandra
drew wrote:does this help? =P~
Unless it yields souce code to peek at, search engines hardly help.

The OSDEV wiki has a complete information regarding this matter, if you can follow them in order. So I'm trying to give a favor here(for everyone who keep asking this question over and over again).

All you need before you begin,
1.El-Torito
2.Int 13h Extension (See Ralf Brown's Interrupt List)
3.ISO_9660 Filesystem

As mentioned in the EL-Torito standard, a bootable-CD can be emulated as a Floppy Disk Image, a Hard Drive Image or a Non-emulated Disk. If you prefer to emulate the CD as a Floppy Image, the BIOS emulates the CD as a Floppy Disk and hence, you can read sectors(512 bytes) as if it were actual Floppy Disk. The same applies for the Hard Disk Image. The rest of these post focuses on the Non-emulation Disk.

To read a sector from the CD(non-emulated), you must use INT13h Extensions(unless you've written a driver). The tricky part on reading the sector is that, the sector size is 2048 bytes long. So you've to locate the kernel in terms of Blocks. Basically, you've two options: Search the Path Table(ISO 9660 Filesystem) or, hard code the Block value. One advantage of preferring the CD as a boot media is that, each CD Block(sector) is 2048 bytes long meaning that, it gives a lot of room to add extra stuffs to the bootloader itself, which also allows you to add the code for parsing the ISO 9660 Filesystem.

Before you execute Int 13h extension commands, check for the availabilty:

Code: Select all

; Just a code snippet. Refer to 'Ralf Brown's Interrupt List' regarding these fields.

mov ah,0x41
mov bh,0x55
mov bl,0xAA
mov dl,[bootdrv]  ; DL contains the drive value provide by the BIOS
int 0x13
cmp bx,0xAA55
jz no_int13h_extension  ; Int 13h Extensions not present
Once you confirm the availability of Int 13h Extensions, you can start reading sectors,

Code: Select all

; Just a code snippet. Refer to 'Ralf Brown's Interrupt List' regarding these fields.
mov ah,0x42		; Extended Read
mov si,DAP_cd		; DS:SI -> Disk Address Packet
mov dl,[bootdrv]
int 0x13
jc Failed			; CF set on Error

DAP_cd:		
db 0x10	; Size of Disk Address Packet
db 0x00	; Reserved	
dw 0		; No. of blocks to transfer (depends upon the size of the kernel)
dw 0x0000	; Transfer buffer (Offset)
dw 0x0000	; Transfer buffer (Segment)
dd 0		; Starting absolute block no.(LBA) (depends upon the location of the kernel on the disk
dd 0		; Unused (Only for big LBA > 4bytes)
As you can see, some values need to be obtained by parsing the Filesystem(ISO 9660). If you want to play a little, you can hardcode these values and see if it's actually working. I use MagicISO for burning a 'Non-emulation' disk. When I provide a raw integrated image of my Bootloader & Kernel(CrOS.img) this file doesn't appear on the PATH Table which obliges me to hardcode these values, so that I at least get to know that it's working. I've been using this integrated image and it works fine. You can follow similar procedure or you can separate the Bootloader and Kernel and so that the bootloader can scan the PATH Table to locate the kernel. Eventually, you'll need to write an ATA driver(for protected mode), anyway.

Ah! one common error I recalled is decoding the block no. Keep in mind that, the CD sector is 2048 bytes long unlike the 512-byte floppy sector.Also don't assume that the bootloader appears at block 1 and the kernel appears at block 2. In my context, the bootloader and kernel(integrated) is located at block 27.

And at last, before worrying about booting from CD, you should focus on creating a better kernel. Once your kernel crosses the 1 Megabyte boundary(in size), you can then start playing with bootable CDs or, let the GRUB do this job for you.

Hope this helped someone.

Cheers.

Re: Reading my kernel from a CD

Posted: Tue Jun 14, 2011 12:49 am
by SCHiM
@Chandra

Thank you for your answer, that extra information about the INT13 was exactly what I was looking for. I'll look up on the articles you said and I'll try to puzzle it out for myself.

Re: Reading my kernel from a CD

Posted: Tue Jun 14, 2011 8:36 am
by quok
Chandra wrote:To read a sector from the CD(non-emulated), you must use INT13h Extensions(unless you've written a driver). The tricky part on reading the sector is that, the sector size is 2048 bytes long. So you've to locate the kernel in terms of Blocks. Basically, you've two options: Search the Path Table(ISO 9660 Filesystem) or, hard code the Block value. One advantage of preferring the CD as a boot media is that, each CD Block(sector) is 2048 bytes long meaning that, it gives a lot of room to add extra stuffs to the bootloader itself, which also allows you to add the code for parsing the ISO 9660 Filesystem.
Don't hard code the block value. Hard coding the value is never a good option. If searching the path table isn't an option, then just parse the entire ISO9660 directory structure. It's not hard, and easily fits into 2048 bytes. If you're using mkisofs/genisofs to create the CD image, then there is a command line option "--boot-info-table". Read the man page for more details, but it basically alters a structure in your boot sector that tells you the exact block to start reading at and the number of blocks to read in order to load your kernel.

Personally I prefer walking the directory structure or using the path table since not every tool that creates CD images supports the boot info table.
Chandra wrote:Before you execute Int 13h extension commands, check for the availabilty
If you're booting a non-emulation disk, there's really no need to check for the availability of int 13h extensions. They're required by the El Torito spec to be able to boot a non-emulation disk. Several BIOSes even have bugs in this regard: they will return bogus values, hang the system, or silently break future int 13h commands. So in this case I recommend not bothering to check for the availability of those commands at all, and just use them. If they're not available, you won't be able to boot from the CD anyway.

Re: Reading my kernel from a CD

Posted: Tue Jun 14, 2011 9:14 pm
by Chandra
quok wrote:If you're booting a non-emulation disk, there's really no need to check for the availability of int 13h extensions.
I beg to differ. When there really is no availability of int 13h extension(especially under some emulator), you can manually start the disk emulation so that you'll be able to load the kernel from a virtual floppy/hard disk image.This is included in the EL-Torito specification.
quok wrote:So in this case I recommend not bothering to check for the availability of those commands at all, and just use them. If they're not available, you won't be able to boot from the CD anyway.
At least you get to know why the read sector command failed in the first place.

Re: Reading my kernel from a CD

Posted: Wed Jun 15, 2011 2:46 am
by Combuster
While the specification technically allows it, it is a no-go in practice. El-torito with emulation is broken in several actual implementations.