This code takes up almost an entire sector of a floppy. The global 'start' label is only used for the linker I used.
Code: Select all
asm(".code16gcc\n");
asm(".globl start\n");
asm("start:\n");
asm("movw $0, %ax; movw %ax, %bx; movw %ax, %cx; movw %ax, %dx;");
asm(".extern _main\n");
asm("jmp _main;\n");
asm("gdt_start: \
.quad 0x0000000000000000; \
.quad 0x00cf9a000000ffff; \
.quad 0x00cf92000000ffff; \
gdt_48: \
.word (gdt_48 - gdt_start - 1); \
.long gdt_start;");
void reset_floppy()
{
unsigned char status = 0;
__asm__ __volatile__("movb %1, %%ah;\
int $0x13;\
movb %%ah, %0;"
:"=r"(status)
:"r"(status)
:"%ax");
if(status){reset_floppy();}
}
void load_floppy_sector(unsigned short segment, unsigned short offset,
unsigned char nSectors, unsigned char Cylinder, unsigned char Start_Sector, unsigned char Head)
{
unsigned char Command = 2, Status = 0;
unsigned short ax, bx, cx, dx;
ax = ((((Command << 8) & 0xFF00)) + (nSectors & 0x00FF));;
bx = offset;
cx = ((((Cylinder << 8) & 0xFF00)) + (Start_Sector & 0x00FF));
dx = ((Head << 8) & 0xFF00);
__asm__ __volatile__("movw %1, %%ax;\
movw %%ax, %%es;\
movw %2, %%ax;\
movw %3, %%bx;\
movw %4, %%cx;\
movw %5, %%dx;\
int $0x13;\
movb %%ah, %0;"
:"=m"(Status)
:"m"(segment), "m"(ax), "m"(bx), "m"(cx), "m"(dx)
:"%ax","%bx","%cx","%dx");
}
void main()
{
reset_floppy();
load_floppy_sector(0x0000, 0x1000, 18, 0, 1, 0); /* place 18 sectors starting at 0x1000:0x0000 */
asm("inb $0x64, %al; \
movb $0xDF, %al; \
outb %al, $0x64;");
asm("lgdt gdt_48; \
movl %cr0, %eax; \
or $1, %eax; \
movl %eax, %cr0; \
ljmp $0x08, $enter_pmode; \
hlt;");
}
asm(".code32 \
.globl enter_pmode; \
enter_pmode: \
hlt;");
asm(".org (0x200 - 2); .word 0xAA55;\n");
/* anything placed past here is in sector 2 of the floppy */
to compile just run a simple batch script
Code: Select all
gcc -ffreestanding -c "boot.c" -o boot.o
ld -T link.ld -o kernel.bin boot.o