Imported a bunch of C code from KarlOS + bootboot
This commit is contained in:
parent
94919ad0c7
commit
fcdea29944
4 changed files with 489 additions and 5 deletions
2
Makefile
2
Makefile
|
|
@ -19,5 +19,5 @@ boot.elf: lboot.o loader.o fernlader.ld
|
||||||
lboot.o: lboot.S
|
lboot.o: lboot.S
|
||||||
$(CC) $(CFLAGS) -c -o $@ $(@:.o=.S)
|
$(CC) $(CFLAGS) -c -o $@ $(@:.o=.S)
|
||||||
|
|
||||||
loader.o: loader.c
|
loader.o: loader.c bootboot.h fs.h
|
||||||
$(CC) $(CFLAGS) -m64 -Os -c -o $@ $(@:.o=.c)
|
$(CC) $(CFLAGS) -m64 -Os -c -o $@ $(@:.o=.c)
|
||||||
|
|
|
||||||
358
fs.h
Normal file
358
fs.h
Normal file
|
|
@ -0,0 +1,358 @@
|
||||||
|
/*
|
||||||
|
* x86_64-cb/fs.h
|
||||||
|
*
|
||||||
|
* Copyright (C) 2017 - 2021 bzt (bztsrc@gitlab)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person
|
||||||
|
* obtaining a copy of this software and associated documentation
|
||||||
|
* files (the "Software"), to deal in the Software without
|
||||||
|
* restriction, including without limitation the rights to use, copy,
|
||||||
|
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
* of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* This file is part of the BOOTBOOT Protocol package.
|
||||||
|
* @brief Filesystem drivers for initial ramdisk.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define DBG(...) do {} while (0)
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/**
|
||||||
|
* FS/Z initrd (OS/Z's native file system)
|
||||||
|
*/
|
||||||
|
file_t fsz_initrd(unsigned char *initrd_p, char *kernel)
|
||||||
|
{
|
||||||
|
file_t ret = { NULL, 0 };
|
||||||
|
if(initrd_p==NULL || memcmp(initrd_p + 512,"FS/Z",4) || kernel==NULL){
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
unsigned char passphrase[256],chk[32],iv[32];
|
||||||
|
unsigned int i,j,k,l,ss=1<<(initrd_p[518]+11);
|
||||||
|
unsigned char *ent, *in=(initrd_p+*((uint64_t*)(initrd_p+560))*ss);
|
||||||
|
SHA256_CTX ctx;
|
||||||
|
DBG(" * FS/Z %s\n",kernel);
|
||||||
|
//decrypt initrd
|
||||||
|
if(*((uint32_t*)(initrd_p+520))!=0 && (initrd_p[519]&&0xF0)!=0) {
|
||||||
|
printf("BOOTBOOT-PANIC: Unsupported cipher\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
while(*((uint32_t*)(initrd_p+520))!=0) {
|
||||||
|
printf(" * Passphrase? ");
|
||||||
|
l=ReadLine(passphrase,sizeof(passphrase));
|
||||||
|
if(!l) {
|
||||||
|
printf("\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
if(*((uint32_t*)(initrd_p+520))!=crc32_calc((char*)passphrase,l)) {
|
||||||
|
printf("\rBOOTBOOT-ERROR: Bad passphrase\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
printf("\r * Decrypting...\r");
|
||||||
|
SHA256_Init(&ctx);
|
||||||
|
SHA256_Update(&ctx,passphrase,l);
|
||||||
|
SHA256_Update(&ctx,initrd_p+512,6);
|
||||||
|
SHA256_Final(chk,&ctx);
|
||||||
|
for(i=0;i<32;i++) initrd_p[i+680]^=chk[i];
|
||||||
|
SHA256_Init(&ctx);
|
||||||
|
SHA256_Update(&ctx,initrd_p+680,32);
|
||||||
|
SHA256_Final(iv,&ctx);
|
||||||
|
// FSZ_SB_EALG_SHACBC
|
||||||
|
for(k=ss,j=1;j<*((uint32_t*)(initrd_p+528));j++) {
|
||||||
|
memcpy(chk,iv,32);
|
||||||
|
for(i=0;i<ss;i++) {
|
||||||
|
if(i%32==0) {
|
||||||
|
SHA256_Init(&ctx);
|
||||||
|
SHA256_Update(&ctx,&chk,32);
|
||||||
|
SHA256_Update(&ctx,&j,4);
|
||||||
|
SHA256_Final(chk,&ctx);
|
||||||
|
}
|
||||||
|
initrd_p[k++]^=chk[i%32]^iv[i%32];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
memset(initrd_p+680,0,32); *((uint32_t*)(initrd_p+520)) = 0;
|
||||||
|
*((uint32_t*)(initrd_p+1020))=crc32_calc((char *)initrd_p+512,508);
|
||||||
|
printf(" \r");
|
||||||
|
}
|
||||||
|
// Get the inode
|
||||||
|
char *s,*e;
|
||||||
|
s=e=kernel;
|
||||||
|
i=0;
|
||||||
|
again:
|
||||||
|
while(*e!='/'&&*e!=0){e++;}
|
||||||
|
if(*e=='/'){e++;}
|
||||||
|
if(!memcmp(in,"FSIN",4)){
|
||||||
|
//is it inlined?
|
||||||
|
if(!memcmp(initrd_p[520]&1? in + 2048 : in + 1024,"FSDR",4)){
|
||||||
|
ent=(initrd_p[520]&1? in + 2048 : in + 1024);
|
||||||
|
} else if(!memcmp(initrd_p+*((uint64_t*)(in+448))*ss,"FSDR",4)){
|
||||||
|
// go, get the sector pointed
|
||||||
|
ent=(initrd_p+*((uint64_t*)(in+448))*ss);
|
||||||
|
} else {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
//skip header
|
||||||
|
unsigned char *hdr=ent; ent+=128;
|
||||||
|
//iterate on directory entries
|
||||||
|
int j=*((uint64_t*)(hdr+16));
|
||||||
|
while(j-->0){
|
||||||
|
if(!memcmp(ent + 16,s,e-s)) {
|
||||||
|
if(*e==0) {
|
||||||
|
i=*((uint64_t*)(ent+0));
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
s=e;
|
||||||
|
in=(initrd_p+*((uint64_t*)(ent+0))*ss);
|
||||||
|
goto again;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ent+=128;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
i=0;
|
||||||
|
}
|
||||||
|
if(i!=0) {
|
||||||
|
// fid -> inode ptr -> data ptr
|
||||||
|
unsigned char *in=(initrd_p+i*ss);
|
||||||
|
if(!memcmp(in,"FSIN",4)){
|
||||||
|
ret.size=*((uint64_t*)(in+464));
|
||||||
|
if(*((uint64_t*)(in+448)) == i) {
|
||||||
|
if(!(in[488]&31)) {
|
||||||
|
// inline data
|
||||||
|
ret.ptr=(uint8_t*)(initrd_p+i*ss+(initrd_p[520]&1? 2048 : 1024));
|
||||||
|
} else {
|
||||||
|
// sector directory or list inlined
|
||||||
|
ret.ptr=(uint8_t*)(initrd_p + *((uint64_t*)(initrd_p[520]&1? in + 2048 : in + 1024))*ss);
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
if(*((uint64_t*)(in+448))) {
|
||||||
|
switch((in[488]&15) + (in[488]&16 ? 1 : 0)) {
|
||||||
|
case 0: // direct data
|
||||||
|
ret.ptr=(uint8_t*)(initrd_p + *((uint64_t*)(in+448)) * ss);
|
||||||
|
break;
|
||||||
|
case 1: // sector directory or list (only one level supported here, and no holes in files)
|
||||||
|
ret.ptr=(uint8_t*)(initrd_p + *((uint64_t*)(initrd_p + *((uint64_t*)(in+448))*ss)) * ss);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else ret.size=0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Minix3 file system
|
||||||
|
* directories only checked for their first block, and kernel must be defragmented
|
||||||
|
*/
|
||||||
|
file_t mfs_initrd(unsigned char *initrd_p, char *kernel)
|
||||||
|
{
|
||||||
|
uint32_t o, bs, ino_tbl;
|
||||||
|
uint8_t *ino, *d;
|
||||||
|
char *s = kernel, *e;
|
||||||
|
file_t ret = { NULL, 0 };
|
||||||
|
if(initrd_p[1048] != 'Z' || initrd_p[1049] != 'M') return ret;
|
||||||
|
DBG(" * MFS %s\n",kernel);
|
||||||
|
bs = *((uint16_t*)(initrd_p + 1052));
|
||||||
|
ino_tbl = (2 + *((uint16_t*)(initrd_p + 1030)) + *((uint16_t*)(initrd_p + 1032))) * bs;
|
||||||
|
ino = initrd_p + ino_tbl;
|
||||||
|
again:
|
||||||
|
for(e = s; *e && *e != '/'; e++);
|
||||||
|
d = initrd_p + *((uint32_t*)(ino + 24)) * bs;
|
||||||
|
for(o = 0; o < *((uint32_t*)(ino + 8)) && o < bs; o += 64, d += 64) {
|
||||||
|
if(*((uint32_t*)d) && !memcmp(s, d + 4, e - s) && !d[e - s]) {
|
||||||
|
ino = initrd_p + ino_tbl + (*((uint32_t*)d) - 1) * 64;
|
||||||
|
d = initrd_p + *((uint32_t*)(ino + 24)) * bs;
|
||||||
|
if(!*e) { ret.ptr = d; ret.size = *((uint32_t*)(ino + 8)); return ret; }
|
||||||
|
s = e + 1; goto again;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cpio archive
|
||||||
|
*/
|
||||||
|
file_t cpio_initrd(unsigned char *initrd_p, char *kernel)
|
||||||
|
{
|
||||||
|
unsigned char *ptr=initrd_p;
|
||||||
|
int k;
|
||||||
|
file_t ret = { NULL, 0 };
|
||||||
|
if(initrd_p==NULL || kernel==NULL ||
|
||||||
|
(memcmp(initrd_p,"070701",6) && memcmp(initrd_p,"070702",6) && memcmp(initrd_p,"070707",6)))
|
||||||
|
return ret;
|
||||||
|
DBG(" * cpio %s\n",kernel);
|
||||||
|
k=strlen(kernel);
|
||||||
|
// hpodc archive
|
||||||
|
while(!memcmp(ptr,"070707",6)){
|
||||||
|
int ns=octbin(ptr+8*6+11,6);
|
||||||
|
int fs=octbin(ptr+8*6+11+6,11);
|
||||||
|
if(!memcmp(ptr+9*6+2*11,kernel,k+1) ||
|
||||||
|
(ptr[9*6+2*11] == '.' && ptr[9*6+2*11+1] == '/' && !memcmp(ptr+9*6+2*11+2,kernel,k+1))) {
|
||||||
|
ret.size=fs;
|
||||||
|
ret.ptr=(uint8_t*)(ptr+9*6+2*11+ns);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
ptr+=(76+ns+fs);
|
||||||
|
}
|
||||||
|
// newc and crc archive
|
||||||
|
while(!memcmp(ptr,"07070",5)){
|
||||||
|
int fs=hexbin(ptr+8*6+6,8);
|
||||||
|
int ns=hexbin(ptr+8*11+6,8);
|
||||||
|
if(!memcmp(ptr+110,kernel,k+1) || (ptr[110] == '.' && ptr[111] == '/' && !memcmp(ptr+112,kernel,k+1))) {
|
||||||
|
ret.size=fs;
|
||||||
|
ret.ptr=(uint8_t*)(ptr+((110+ns+3)/4)*4);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
ptr+=((110+ns+3)/4)*4 + ((fs+3)/4)*4;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ustar tarball archive
|
||||||
|
*/
|
||||||
|
file_t tar_initrd(unsigned char *initrd_p, char *kernel)
|
||||||
|
{
|
||||||
|
unsigned char *ptr=initrd_p;
|
||||||
|
int k;
|
||||||
|
file_t ret = { NULL, 0 };
|
||||||
|
if(initrd_p==NULL || kernel==NULL || memcmp(initrd_p+257,"ustar",5))
|
||||||
|
return ret;
|
||||||
|
DBG(" * tar %s\n",kernel);
|
||||||
|
k=strlen(kernel);
|
||||||
|
while(!memcmp(ptr+257,"ustar",5)){
|
||||||
|
int fs=octbin(ptr+0x7c,11);
|
||||||
|
if(!memcmp(ptr,kernel,k+1) || (ptr[0] == '.' && ptr[1] == '/' && !memcmp(ptr+2,kernel,k+1))) {
|
||||||
|
ret.size=fs;
|
||||||
|
ret.ptr=(uint8_t*)(ptr+512);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
ptr+=(((fs+511)/512)+1)*512;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simple File System
|
||||||
|
*/
|
||||||
|
file_t sfs_initrd(unsigned char *initrd_p, char *kernel)
|
||||||
|
{
|
||||||
|
unsigned char *ptr, *end;
|
||||||
|
int k,bs,ver;
|
||||||
|
file_t ret = { NULL, 0 };
|
||||||
|
if(initrd_p==NULL || kernel==NULL || (memcmp(initrd_p+0x1AC,"SFS",3) && memcmp(initrd_p+0x1A6,"SFS",3)))
|
||||||
|
return ret;
|
||||||
|
// 1.0 Brendan's version, 1.10 BenLunt's version
|
||||||
|
ver=!memcmp(initrd_p+0x1A6,"SFS",3)?10:0;
|
||||||
|
bs=1<<(7+(uint8_t)initrd_p[ver?0x1B6:0x1BC]);
|
||||||
|
end=initrd_p + *((uint64_t *)&initrd_p[ver?0x1AA:0x1B0]) * bs; // base + total_number_of_blocks * blocksize
|
||||||
|
// get index area
|
||||||
|
ptr=end - *((uint64_t *)&initrd_p[ver?0x19E:0x1A4]); // end - size of index area
|
||||||
|
// got a Starting Marker Entry?
|
||||||
|
if(ptr[0]!=2)
|
||||||
|
return ret;
|
||||||
|
DBG(" * SFS 1.%s %s\n", ver?"10":"0",kernel);
|
||||||
|
k=strlen(kernel);
|
||||||
|
// iterate on index until we reach the end or Volume Identifier
|
||||||
|
while(ptr<end && ptr[0]!=0x01){
|
||||||
|
ptr+=64;
|
||||||
|
// file entry?
|
||||||
|
if(ptr[0]!=0x12)
|
||||||
|
continue;
|
||||||
|
// filename match?
|
||||||
|
if(!memcmp(ptr+(ver?0x23:0x22),kernel,k+1)){
|
||||||
|
ret.size=*((uint64_t*)&ptr[ver?0x1B:0x1A]); // file_length
|
||||||
|
ret.ptr=initrd_p + *((uint64_t*)&ptr[ver?0x0B:0x0A]) * bs; // base + start_block * blocksize
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* James Molloy's initrd (for some reason it's popular among hobby OS developers)
|
||||||
|
* http://www.jamesmolloy.co.uk/tutorial_html
|
||||||
|
*/
|
||||||
|
file_t jamesm_initrd(unsigned char *initrd_p, char *kernel)
|
||||||
|
{
|
||||||
|
unsigned char *ptr=initrd_p+4;
|
||||||
|
int i,k,nf=*((int*)initrd_p);
|
||||||
|
file_t ret = { NULL, 0 };
|
||||||
|
// no real magic, so we assume initrd contains at least one file...
|
||||||
|
if(initrd_p==NULL || kernel==NULL || initrd_p[2]!=0 || initrd_p[3]!=0 || initrd_p[4]!=0xBF)
|
||||||
|
return ret;
|
||||||
|
DBG(" * JamesM %s\n",kernel);
|
||||||
|
k=strlen(kernel);
|
||||||
|
for(i=0;i<nf && ptr[0]==0xBF;i++) {
|
||||||
|
if(!memcmp(ptr+1,kernel,k+1)){
|
||||||
|
ret.ptr=*((uint32_t*)(ptr+65)) + initrd_p;
|
||||||
|
ret.size=*((uint32_t*)(ptr+69));
|
||||||
|
}
|
||||||
|
ptr+=73;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* EchFS
|
||||||
|
* http://github.com/echfs/echfs
|
||||||
|
*/
|
||||||
|
file_t ech_initrd(unsigned char *initrd_p, char *kernel)
|
||||||
|
{
|
||||||
|
uint64_t parent = 0xffffffffffffffffUL, n;
|
||||||
|
unsigned char *ptr;
|
||||||
|
char *end, *fn;
|
||||||
|
int k = 0;
|
||||||
|
file_t ret = { NULL, 0 };
|
||||||
|
if(initrd_p==NULL || kernel==NULL || memcmp(initrd_p+4,"_ECH_FS_",8))
|
||||||
|
return ret;
|
||||||
|
DBG(" * EchFS %s\n",kernel);
|
||||||
|
memcpy(&k, initrd_p + 28, 4);
|
||||||
|
memcpy(&n, initrd_p + 12, 8);
|
||||||
|
ptr = initrd_p + (((n * 8 + k - 1) / k) + 16) * k;
|
||||||
|
for(end = fn = kernel; *end && *end != '/'; end++);
|
||||||
|
while(*((uint64_t*)ptr)) {
|
||||||
|
if(*((uint64_t*)ptr) == parent && !memcmp(ptr + 9, fn, end - fn) && !ptr[9 + end - fn]) {
|
||||||
|
parent = *((uint64_t*)(ptr + 240));
|
||||||
|
if(!*end) {
|
||||||
|
ret.size=*((uint64_t*)(ptr + 248));
|
||||||
|
ret.ptr=(uint8_t*)(initrd_p + parent * k);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
end++;
|
||||||
|
for(fn = end; *end && *end != '/'; end++);
|
||||||
|
}
|
||||||
|
ptr += 256;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Static file system drivers registry
|
||||||
|
*/
|
||||||
|
file_t (*fsdrivers[]) (unsigned char *, char *) = {
|
||||||
|
//fsz_initrd,
|
||||||
|
mfs_initrd,
|
||||||
|
cpio_initrd,
|
||||||
|
tar_initrd,
|
||||||
|
sfs_initrd,
|
||||||
|
jamesm_initrd,
|
||||||
|
ech_initrd,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
#undef DBG
|
||||||
11
lboot.S
11
lboot.S
|
|
@ -1,9 +1,12 @@
|
||||||
// vim: et:sw=12:ts=12:sts=12
|
// vim: et:sw=12:ts=12:sts=12
|
||||||
|
// lboot.S: boot code for legacy BIOS boot over PXE.
|
||||||
|
|
||||||
.global _start
|
.global _start
|
||||||
.text
|
.text
|
||||||
.code16
|
.code16
|
||||||
|
|
||||||
|
.set PACKET_SIZE, 1024
|
||||||
|
|
||||||
.macro pxe_call, opcode
|
.macro pxe_call, opcode
|
||||||
mov %sp, %bx
|
mov %sp, %bx
|
||||||
push %ss
|
push %ss
|
||||||
|
|
@ -66,7 +69,7 @@ _start: cli
|
||||||
push $0
|
push $0
|
||||||
push %cs
|
push %cs
|
||||||
push $tx_buf
|
push $tx_buf
|
||||||
push $1024
|
push $PACKET_SIZE
|
||||||
push $2
|
push $2
|
||||||
push $0
|
push $0
|
||||||
pxe_call PXE_GET_CACHED_INFO
|
pxe_call PXE_GET_CACHED_INFO
|
||||||
|
|
@ -254,8 +257,8 @@ _aerr: mov $msg_aerr, %si
|
||||||
|
|
||||||
read_file:
|
read_file:
|
||||||
.set PXE_TFTP_OPEN, 0x0020
|
.set PXE_TFTP_OPEN, 0x0020
|
||||||
push $1024
|
push $PACKET_SIZE
|
||||||
push $0x4500
|
push $69<<8
|
||||||
sub $128, %sp
|
sub $128, %sp
|
||||||
|
|
||||||
mov $fn_config, %esi
|
mov $fn_config, %esi
|
||||||
|
|
@ -424,7 +427,7 @@ pml4_ptr: .long 0
|
||||||
// Points to the end of the memory map
|
// Points to the end of the memory map
|
||||||
memmap_end: .word 0
|
memmap_end: .word 0
|
||||||
|
|
||||||
tx_buf: .space 1024
|
tx_buf: .space PACKET_SIZE
|
||||||
|
|
||||||
.code64
|
.code64
|
||||||
// trampo64: Trampoline function to load long-mode segments
|
// trampo64: Trampoline function to load long-mode segments
|
||||||
|
|
|
||||||
123
loader.c
123
loader.c
|
|
@ -1,3 +1,126 @@
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
// minimal set of string routines, copied from KarlOS
|
||||||
|
|
||||||
|
void *memset(void *ptr, int value, size_t num)
|
||||||
|
{
|
||||||
|
__asm__ ("rep stosb"
|
||||||
|
: "+D"(ptr), "+c"(num)
|
||||||
|
: "a"(value)
|
||||||
|
: "memory");
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *memcpy(void *restrict dest, const void *restrict src, size_t num)
|
||||||
|
{
|
||||||
|
__asm__ ("rep movsb"
|
||||||
|
: "+D"(dest), "+S"(src), "+c"(num)
|
||||||
|
:
|
||||||
|
: "memory");
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
int memcmp(const void *ptr, const void *ptr2, size_t num)
|
||||||
|
{
|
||||||
|
unsigned char *d = (unsigned char *)ptr;
|
||||||
|
unsigned char *b = (unsigned char *)ptr2;
|
||||||
|
for (size_t i = 0; i < num; i++) {
|
||||||
|
if (d[i] != b[i]) {
|
||||||
|
return (d[i] - b[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t strlen(const char *s)
|
||||||
|
{
|
||||||
|
size_t len = 0;
|
||||||
|
while (*s != '\0') {
|
||||||
|
s++;
|
||||||
|
len++;
|
||||||
|
}
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helpers from bztsrc's bootboot codebase
|
||||||
|
|
||||||
|
/**
|
||||||
|
* convert ascii octal number to binary number
|
||||||
|
*/
|
||||||
|
int octbin(unsigned char *str,int size)
|
||||||
|
{
|
||||||
|
int s=0;
|
||||||
|
unsigned char *c=str;
|
||||||
|
while(size-->0){
|
||||||
|
s*=8;
|
||||||
|
s+=*c-'0';
|
||||||
|
c++;
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* convert ascii hex number to binary number
|
||||||
|
*/
|
||||||
|
int hexbin(unsigned char *str, int size)
|
||||||
|
{
|
||||||
|
int v=0;
|
||||||
|
while(size-->0){
|
||||||
|
v <<= 4;
|
||||||
|
if(*str>='0' && *str<='9')
|
||||||
|
v += (int)((unsigned char)(*str)-'0');
|
||||||
|
else if(*str >= 'A' && *str <= 'F')
|
||||||
|
v += (int)((unsigned char)(*str)-'A'+10);
|
||||||
|
str++;
|
||||||
|
}
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t *ptr;
|
||||||
|
uint64_t size;
|
||||||
|
} file_t;
|
||||||
|
|
||||||
|
#include "bootboot.h"
|
||||||
|
#include "fs.h"
|
||||||
|
|
||||||
|
// ELF64
|
||||||
|
|
||||||
|
#define EI_NIDENT 16
|
||||||
|
#define EI_MAG0 0x7F
|
||||||
|
#define EI_MAG1 'E'
|
||||||
|
#define EI_MAG2 'L'
|
||||||
|
#define EI_MAG3 'F'
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned char e_ident[EI_NIDENT];
|
||||||
|
uint16_t e_type;
|
||||||
|
uint16_t e_machine;
|
||||||
|
uint32_t e_version;
|
||||||
|
uint64_t e_entry;
|
||||||
|
uint64_t e_phoff;
|
||||||
|
uint64_t e_shoff;
|
||||||
|
uint32_t e_flags;
|
||||||
|
uint16_t e_ehsize;
|
||||||
|
uint16_t e_phentsize;
|
||||||
|
uint16_t e_phnum;
|
||||||
|
uint16_t e_shentsize;
|
||||||
|
uint16_t e_shnum;
|
||||||
|
uint16_t e_shstrndx;
|
||||||
|
} Elf64_Ehdr;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32_t p_type;
|
||||||
|
uint32_t p_flags;
|
||||||
|
uint64_t p_offset;
|
||||||
|
uint64_t p_vaddr;
|
||||||
|
uint64_t p_paddr;
|
||||||
|
uint64_t p_filesz;
|
||||||
|
uint64_t p_memsz;
|
||||||
|
uint64_t p_align;
|
||||||
|
} Elf64_Phdr;
|
||||||
|
|
||||||
void
|
void
|
||||||
loader_main(void)
|
loader_main(void)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue