/* build a cdboot partition if there is an embedded boot floppy image */ int cdpart(Disk *d) { uchar buf[2048]; ulong a, n; uchar *p; if(readdisk(d, buf, 17*2048, 2048) == -1 || strcmp((char*)buf+1, "CD001\x01EL TORITO SPECIFICATION") != 0) return 0; p = buf + 0x47; a = p[0] | (p[1]<<8) | (p[2]<<16) | (p[3]<<24); if(readdisk(d, buf, a*2048, 2048) == -1 || memcmp((char*)buf, "\x01\x00\x00\x00", 4) != 0 || memcmp((char*)buf+30, "\x55\xAA", 2) != 0 || buf[0x20] != 0x88) return 0; p = buf+0x28; a = p[0]|(p[1]<<8)|(p[2]<<16)|(p[3]<<24); switch(buf[0x21]) { case 1: n = 1200*1024; break; case 2: n = 1440*1024; break; case 3: n = 2880*1024; break; default: return 0; } a = a * (uvlong)2048 / d->secsize; n /= d->secsize; addpart(d, "cdboot", a, a+n); return 1; }
void targa_readdisk(unsigned int col, unsigned int row, BYTE *red, BYTE *green, BYTE *blue) { col *= 3; *blue = (BYTE)readdisk(col, row); *green = (BYTE)readdisk(++col, row); *red = (BYTE)readdisk(col+1, row); }
int boot_main(void) { struct elf32hdr eh; struct elf32_phdr ph; Elf32_Half i; entry_t entry; Elf32_Off pos = 0; uart_puts("BL: Hello!\r\n"); struct mbr *mbr = (struct mbr *)MBR_ADDR; uint32_t lba; uintptr_t seg; uint8_t *src = (uint8_t *)&(mbr->part_entry[1].first_sector_lba); uint8_t *des = (uint8_t *)&lba; for (int i = 0; i < sizeof(lba); ++i) { des[i] = src[i]; } /* * Basically, we're reading a statically-linked ELF file. * The logic is very simple: we locate every loadable segment * in the ELF file, putting the content in appropriate memory * address. After everything is loaded into the memory, jump * to the entry address and continue execution. * * Ideally, we want to clean ".bss" section prior to jumping * into the entry point. However, the space in MBR is very * limited, so we'll leave the job to the kernel itself. */ /* Read the ELF header first */ readdisk(lba, pos, &eh, sizeof(eh)); pos = eh.e_phoff; for (i = 0; i < eh.e_phnum; ++i) { readdisk(lba, pos, &ph, sizeof(ph)); if (ph.p_type == PT_LOAD) { seg = (void *)ph.p_paddr; readdisk(lba, ph.p_offset, seg, ph.p_filesz); } pos += eh.e_phentsize; } entry = (entry_t)(eh.e_entry); uart_puts("BL: Kernel loaded.\r\n"); (*entry)(); //spin: while (1); }
void main(void) { kputs("--DEBUG-- Hello world from BIOS in C!\n"); char mbr[SECTOR_SIZE]; readdisk(0,0,mbr,SECTOR_SIZE); (*((void (*)(void*,void*))(VTRC2VTRE(mbr))))(&readdisk,mbr); }
int get_part(int disk, struct part_desc *pl) { int i, next, err; long startsect; err=readdisk(disk, 0, 1, &fs); if (err) return err; if (fs.magic!=FIRST_SECT_MAGIC) return E2E_BADPART; memset(pl,0,sizeof(*pl)*16); for (i=0; i<4; i++) { if (fs.part[i].sys_ind) { pl[i].is_extended = fs.part[i].sys_ind==EXTENDED_PARTITION; pl[i].start = fs.part[i].start_sectlo+(fs.part[i].start_secthi<<16); pl[i].length = fs.part[i].nr_sectslo+(fs.part[i].nr_sectshi<<16); pl[i].parttype = fs.part[i].sys_ind; } } next=4; for (i=0; i<4; i++) { if (fs.part[i].sys_ind==EXTENDED_PARTITION) { startsect = pl[i].start; while (1) { if (next==16) return 0; err=readdisk(disk, startsect, 1, &fs2); if (err) return err; if (fs2.magic!=FIRST_SECT_MAGIC) return E2E_BADPART; pl[next].start = startsect + fs2.part[0].start_sectlo+(fs2.part[0].start_secthi<<16); pl[next].length = fs2.part[0].nr_sectslo+(fs2.part[0].nr_sectshi<<16); next++; if (fs2.part[1].sys_ind!=EXTENDED_PARTITION) break; startsect += fs2.part[1].start_sectlo+(fs2.part[1].start_secthi<<16); } } } return 0; }
void writedisk(size_t sec_num, ssize_t offset, const void *buf, size_t len) { while(len) { readdisk(sec_num,0,NULL,0); int slen=(len+offset<SECTOR_SIZE)?len:(SECTOR_SIZE-offset); memcpy(DMAbuf+offset, buf, slen); SET_DMA(DMA, DMAbuf, sec_num, DMA_WRITE); while(DMA_ISWRITE(DMA)); buf+=slen; sec_num++; len-=slen; offset=0; } }
int getfstype(int disk, unsigned short parttype, unsigned long start) { static union { u_char bytes[512]; u_short shorts[256]; u_long longs[128]; } testblock; int err; if (parttype == PART_SWAP) return SWAP; if (parttype == PART_DOS32) return MSDOSFS; err=readdisk(disk, start, 1, &testblock); if (err) return -err; #if 0 if (strncmp(testblock.bytes+3,"MSDOS",5)==0) /* There must be a better way to do this */ return MSDOSFS; #endif err=readdisk(disk, start+2, 1, &testblock); if (err) return -err; if (testblock.shorts[28]==EXT2_SUPER_MAGIC) return EXT2FS; err=readdisk(disk, start+7, 1, &testblock); if (err) return -err; if (memcmp(testblock.bytes+0x1f6, "SWAP-SPACE", 10)==0) return SWAP; return 0; }
void sbdiskhash(Shabuf *sb, vlong eoffset) { static uchar dbuf[4*M]; int n; while(sb->offset < eoffset){ n = sizeof dbuf; if(sb->offset+n > eoffset) n = eoffset - sb->offset; readdisk(dbuf, sb->offset, n); sbupdate(sb, dbuf, sb->offset, n); } }
static uchar* pagein(vlong offset, int len) { pageout(); if(offset >= partend){ memset(buf, 0xFB, sizeof buf); return buf; } if(offset+len > partend){ memset(buf, 0xFB, sizeof buf); len = partend - offset; } bufoffset = offset; buflen = len; readdisk(buf, offset, len); memmove(sbuf, buf, len); return buf; }
int p9part(Disk *d, char *name, ulong pstart) { char partbuf[512]; char *field[4], *line[Npart+1], *name2; ulong start, end; int i, n; name2 = smprint("%s%s", d->prefix, name); d = opendisk(name2, 1, 0); if(!d) { fprint(2, "%s: %r\n", name2); free(name2); return 0; } free(name2); if(readdisk(d, partbuf, 512, sizeof partbuf) == -1) return 0; partbuf[sizeof partbuf - 1] = '\0'; if(strncmp(partbuf, "part ", 5) != 0 || (n = getfields(partbuf, line, Npart+1, 0, "\n")) == 0) return 0; for(i = 0; i < n; i++) { if(strncmp(line[i], "part ", 5) != 0) break; if(getfields(line[i], field, 4, 0, " ") != 4) break; start = strtoul(field[2], 0, 0); end = strtoul(field[3], 0, 0); if(start >= end) break; addpart(d, field[1], pstart+start, pstart+end); } return 0; }