/* * Copyright 2008-2011, François Revol, revol@free.fr. All rights reserved. * Copyright 2004-2005, Axel Dörfler, axeld@pinc-software.de. All rights reserved. * Copyright 2005, Ingo Weinhold, bonefish@users.sf.net. * Copyright 2007, Haiku, Inc. All Rights Reserved. * Distributed under the terms of the MIT license. */ /** This file contains the boot floppy, .PRG and BFS boot block entry points * for the stage 2 boot loader. All 3 entry points load and relocate the * loader so that it ends up being at ATARI_ZBEOS_BASE. * This file is built as PIC so it works wherever it is executed. * Some arithmetic is thus needed to set variables in the relocated code. * The loader .PRG file is created from the bootloader by a custom ldscript. * * Known load addresses: * floppy: 0x00a34c (EmuTOS in ARAnyM) * .prg: 0x03543e (depends on the TOS memory) * BFS: is set in the MBR code. * * The floppy and .PRG code is entered at _bs_entry, which jumps further on * to skip some fake FAT descriptor. * It first determines which way it was loaded (floppy boot happens in * supervisor mode, while .PRG are loaded as user code), and jumps to * the specific part. * * The floppy code comes first as it must be in the first sector, * and loads the rest of the loader at ATARI_ZBEOS_BASE+0x200, * sets up the new stack and jumps to _start after setting some variables. * The end of the floppy code contains a placeholder for a checksum which * is calculated at build-time by the fixup_tos_floppy_chksum tool. * * The .PRG code switches to supervisor mode, copies the whole loader * which is already in memory to ATARI_ZBEOS_BASE. It then sets up the new * stack and some variables and jumps to _start. * * The BFS code is yet to be fully written. */ /* * references : * http://ftp.netbsd.org/pub/NetBSD/NetBSD-release-3-0/src/sys/arch/atari/stand/xxboot/fdboot/fdboot.S */ #include "atari_memory_map.h" #include "toscalls.h" // 1 enabled verbose output //#define DEBUG 1 #define GLOBAL(x) .globl x ; x #define FUNCTION(x) .global x; .type x,@function; x #define DRIVE_RETRIES 3 // when the drive reading fails for some reason, it will // retry this many times until it will report a failure #define SECTSIZE 512 //.text _bs_entry: /* main entry point, both from the floppy boot and .prg */ bra.s real_entry //FAT lookalike to avoid nasty things from happening // http://alive.atari.org/alive10/btmania.php // MS-DOS values : // http://support.microsoft.com/kb/75131/en // http://alumnus.caltech.edu/~pje/dosfiles.html .ascii "Haiku " .byte 0xbe, 0x50, 0x38 // id //LITTLE ENDIAN! .byte 0x00, 0x02 //BPS .byte 0x02 //SPC //.byte 0x00 //??? .byte 0x00, 0x02 //RES - number of reserved sectors .byte 0x00 //NFATS .byte 0x00, 0x00 //NDIRS .byte 0x40, 0x0b //NSECTS .byte 0xf0 //MEDIA .byte 0x05, 0x00 //SPF _fat_spt: .byte 0x12, 0x00 //SPT .byte 0x02, 0x00 //NSIDES .byte 0x00, 0x00 //NHID // we're done sNumSectors: // This location will contain the max length of the boot loader // as written by the build system in 512 byte blocks and depends // on the offset of the zipped TAR with the kernel and the boot // modules will start at offset BOOT_ARCHIVE_IMAGE_OFFSET kB. .word BOOT_ARCHIVE_IMAGE_OFFSET*2 real_entry: // save the regs to return safely, like the NetBSD loader does: // http://ftp.netbsd.org/pub/NetBSD/NetBSD-release-3-0/src/sys/arch/atari/stand/xxboot/fdboot/fdboot.S movem.l %d1-%d7/%a0-%a6,-(%sp) //DEBUG: determine load location // lea _bs_entry(%pc),%a0 // move.l %a0,%d0 // bsr putx lea str,%a0 bsr puts // first, determine if .prg (user) or bootsect (super) // Super(SUP_INQUIRE) move.l #SUP_INQUIRE,-(%sp) move.w #0x20,-(%sp) trap #GEMDOS_TRAP addq.l #6,%sp cmp.l #SUP_USER,%d0 bne floppy_start bra prg_start /* * floppy boot support code */ floppy_start: //lea label_floppy,%a0 //bsr puts bsr load_sectors tst.w %d0 bne load_failed floppy_done: move.b #ATARI_BOOT_DRVAPI_FLOPPY,ATARI_ZBEOS_BASE + gBootDriveAPI - _bs_entry move.w TOSVAR_bootdev,%d0 // XXX: use uint16 ?? move.b %d0,ATARI_ZBEOS_BASE + gBootDriveID - _bs_entry move.b #1,ATARI_ZBEOS_BASE + gBootedFromImage - _bs_entry all_done: // setup stack move.l #ATARI_ZBEOS_STACK_END,%sp // say goodbye to TOS lea msg_j1,%a0 bsr puts //bra spin // say hello to haiku_loader jmp _start load_failed: //bra _exit spin: bra spin _exit: /* */ lea failure_string,%a0 bsr puts bsr getc movem.l (%sp)+,%d1-%d7/%a0-%a6 rts //rts /** Loads %d2 sectors from floppy disk, starting at head XXX %dh, sector %cx. * The data is loaded to %a2. */ load_sectors: /* * %d3: remaining sects * %d4: sectno * %d5: trackno * %d6: sideno * %d7: sect / track * %a5: buffer * */ // load the rest // XXX: the NetBSD loader probes it, but trying to asserts ARAnyM clr.l %d7 move.b _fat_spt,%d7 // sect/track //move.w #0,%d7 // sect/track move.w #0,%d6 // sideno move.w #0,%d5 // trackno move.w #1,%d4 // sectno move.w sNumSectors,%d3 // remainder move.l #ATARI_ZBEOS_BASE,%a5 read_sectors_loop: bsr.s read_sect bne read_sectors_fail moveq #'.',%d0 bsr putc subq.w #1,%d3 // remainder-- bne.s read_sectors_next bsr putcrlf clr.l %d0 rts // compute next track/side/sector read_sectors_next: add.l #SECTSIZE,%a5 addq.w #1,%d4 // sectno++ cmp.w %d7,%d4 // if (sectno == spt) bne.s .rs2 // { addq.w #1,%d6 // sideno++ ; cmp.w #2,%d6 // if (sideno == 2) { bne .rs1 clr.w %d6 // sideno = 0 ; addq.w #1,%d5 // trackno++ ; bsr putcrlf .rs1: // } clr.w %d4 // sectno = 0 ; .rs2: // } bra.s read_sectors_loop read_sectors_fail: tst.w %d7 // s/t bne read_sectors_fail2 move.w %d4,%d0 bsr putx move.w %d4,%d7 clr.w %d4 //add.w #1, bra.s read_sectors_next read_sectors_fail2: moveq #1,%d0 rts read_sect: /* read 1 sector */ /* * %d4: sectno * %d5: trackno * %d6: sideno * %d7: remaining count * %a5: buffer * */ move.w #1,-(%sp) movem.w %d4-%d6,-(%sp) move.w TOSVAR_bootdev,-(%sp) // devno clr.l -(%sp) // filler move.l %a5,-(%sp) move.w #8,-(%sp) // floprd trap #XBIOS_TRAP add.l #20,%sp tst.l %d0 rts floppy_end: // .org FAILURE_STRING failure_string: // .string " Loading failed! Press key to reboot.\r\n" .string " Loading failed! Press key.\r\n" // .string "FAIL" putx: movem.l %d0-%d2/%a0-%a2,-(%sp) move.l #8-1,%d2 move.l %d0,%d1 putxloop: move.l %d1,%d0 lsl.l #4,%d1 rol.l #4,%d0 and.l #0x0f,%d0 cmp.b #9,%d0 ble putx0 add.b #'a'-'0'-10,%d0 putx0: add.b #'0',%d0 putxdisp: bsr putc dbf %d2,putxloop bsr putcrlf movem.l (%sp)+,%d0-%d2/%a0-%a2 rts puts: .loopt: move.b (%a0)+,%d0 beq .strout bsr putc bra .loopt .strout: putcrlf: move.b #'\r',%d0 bsr putc move.b #'\n',%d0 bsr putc rts /* prints the char in d0.b to the console */ putc: movem.l %d0-%d2/%a0-%a2,-(%sp) move.w %d0,-(%sp) move.w #DEV_CON,-(%sp) // DEV_CON move.w #3,-(%sp) // Bconout trap #BIOS_TRAP add.l #6,%sp movem.l (%sp)+,%d0-%d2/%a0-%a2 rts /* waits for a key */ getc: movem.l %d1-%d2/%a0-%a2,-(%sp) move.w #DEV_CON,-(%sp) // DEV_CON move.w #2,-(%sp) // Bconin trap #BIOS_TRAP add.l #4,%sp movem.l (%sp)+,%d1-%d2/%a0-%a2 rts str: .string "Haiku!" //label_prg: // .string "P" //"RG boot" //label_floppy: // .string "F" //"loppy boot" msg_j1: .string "Jumping to haiku_loader." shell_end: //.fill (0x01fe - shell_end), 1, 0x55 .org 0x01fe boot_code_checksum: .word 0xaa55-1 // will be replaced by the one calculated by the build. // we make sure PCs don't try to execute it. // this bumps the "start" label to offset 0x0200 as // expected by the BFS boot loader, and also marks // this block as valid boot block for the BIOS //XXX: put bfs_start here bfs_start: //FIXME:write BFS code /* * \AUTO\HAIKU.PRG and ARAnyM BOOTSTRAP() support code */ prg_start: //lea label_prg,%a0 //bsr puts // .prg: // we need to switch to supervisor mode anyway move.l #SUP_SET,-(%sp) move.w #0x20,-(%sp) trap #1 addq.l #6,%sp move.l %d0,saved_super_stack // disable interrupts //or.w #0x0700,%sr // copy the rest of the prg // load counter clr.l %d0 move.w sNumSectors,%d0 sub.w #1,%d0 // load addresses lea _bs_entry,%a0 move.l #ATARI_ZBEOS_BASE,%a1 nextsect: move.l #512/4-1,%d1 copysect_loop: move.l (%a0)+,(%a1)+ dbf %d1,copysect_loop //bsr putx dbf %d0,nextsect super_done: // XXX: copy the rest ! // XXX: force floppy boot for testing to get the kernel tgz for now move.b #ATARI_BOOT_DRVAPI_FLOPPY,ATARI_ZBEOS_BASE + gBootDriveAPI - _bs_entry move.b #0,ATARI_ZBEOS_BASE + gBootDriveID - _bs_entry move.b #1,ATARI_ZBEOS_BASE + gBootedFromImage - _bs_entry // all done, go to _start bra all_done saved_super_stack: .long 0 GLOBAL(gBootedFromImage): .byte 0 GLOBAL(gBootDriveAPI): .byte ATARI_BOOT_DRVAPI_UNKNOWN GLOBAL(gBootDriveID): .byte 0 GLOBAL(gBootPartitionOffset): .long 0