?? minimig.c
字號:
#include <errno.h>#include <fcntl.h>#include <stdio.h>#include <stdlib.h>#include <sys/mman.h>#include <sys/types.h>#include <unistd.h>#include <string.h>#include <sched.h>#define PAGE_SIZE 4096#define O_DIRECT 040000#define n_pages 16extern void sha1_digest(unsigned char* out, unsigned char* data, size_t len);unsigned char* page_digests;#define SHA1_DIGEST_SIZE 20void hex(char* out, unsigned char* in){ int i; char* o = out; char digits[] = "0123456789abcdef"; for(i=0; i<SHA1_DIGEST_SIZE; i++) { char c = *in++; *o++= digits[(c & 0xf0)>>4]; *o++= digits[ c & 0xf]; } *o = '\0';}int main(int argc,char** argv){ size_t loader_size; unsigned long loader_pages; unsigned long offset = 0; int dryrun=0; char* page; char* loader = mmap(0, 8*PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0,0); int f; //int i; int o=-1; unsigned long num_mfns; struct sched_param p; struct page_info { unsigned long pfn; char page[PAGE_SIZE]; } ; struct page_info data[n_pages]; memset(loader,0,8*PAGE_SIZE); memset(&p, 0, sizeof(p)); p.sched_priority = -20; sched_setscheduler(getpid(),SCHED_FIFO,&p); if(argc>1) { if(!strcmp("-n",argv[1])) { dryrun = 1; puts("dry run."); } else offset = atoi(argv[1+dryrun]) * 4200 * PAGE_SIZE; } /* to work with O_DIRECT, we need to correctly align the loader. 512 bytes should be * enough, but let's do PAGE_SIZE for now */ f = open("loader", O_RDONLY); if(f>=0) { size_t* a; loader_size = read(f,loader+4, 8*PAGE_SIZE); close(f); loader_pages = (loader_size + 3*sizeof(size_t) + (PAGE_SIZE-1)) / PAGE_SIZE; printf("loader pages %d\n", (int)loader_pages); a = (size_t*) loader; /* first long has length of loader minus arguments */ *a = loader_pages*PAGE_SIZE - 12; a = (size_t*) ( loader+loader_pages * PAGE_SIZE - 8); *a++ = sizeof(size_t); /* four bytes of args */ *a++ = num_mfns; /* argument: number of pages in checkpoint */ /* so loader and arguments ended up page-aligned after all */ } else { puts("no file: 'loader'"); exit(-1); } page = mmap(0, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0,0); if(!dryrun) { o = open("/dev/hda1",O_WRONLY|O_TRUNC|O_DIRECT); if(o<0) { printf("could not open output fd for write %d\n",o); exit(-1); }#if 0 printf("wiping /dev/hda1, fd %d\n",o); memset(page,0,PAGE_SIZE); for(i=0; i<0x1003; i++) { int r; lseek(o, offset + i * PAGE_SIZE, SEEK_SET); r = write(o, page, PAGE_SIZE); if(r<0) { printf("r %d\n",r); exit(-1); } }#endif /* write the loader and its args */ lseek(o, offset + 0, SEEK_SET); write(o, loader, loader_pages * PAGE_SIZE); } f = open("/dev/checkpoint",O_RDONLY); if(f<0) switch(errno) { case ENOENT: puts("no /dev/checkpoint!"); puts("please create with:\n\tmknod /dev/checkpoint c 1 12\n\tchmod 400 /dev/checkpoint"); exit(-1); default: puts("unable to open /dev/checkpoint"); exit(-1); } read(f, &num_mfns, sizeof(num_mfns)); printf("%08lx page frames\n", num_mfns); page_digests = malloc(SHA1_DIGEST_SIZE*num_mfns); if(num_mfns<=0) exit(-1); int last_pfn = -10000; for(;;) { int len = read(f, &data,sizeof(data)); int r; if(len<0) { printf("we have arrived.\n"); if(!dryrun) close(o); close(f); /* if run as init we cannot exit */ //if(getpid()==1) while(1) sleep(100); else exit(0); } if(!dryrun) { int i; int left; for(i=0,left=len; left>0; left-= sizeof(struct page_info)) { struct page_info* p = &data[i++]; size_t l = left-4; if(p->pfn != last_pfn+1) { lseek(o, offset + (loader_pages + p->pfn) * PAGE_SIZE, SEEK_SET); } last_pfn = p->pfn; if(l < PAGE_SIZE) memset(page+PAGE_SIZE-l,0,PAGE_SIZE-l); memcpy(page,p->page,l < PAGE_SIZE ? l : PAGE_SIZE); r = write(o, page, PAGE_SIZE); if(p->pfn == num_mfns) break; else sha1_digest(page_digests + SHA1_DIGEST_SIZE*p->pfn,p->page,PAGE_SIZE); } } if(!dryrun) fsync(o); /* necessary? */ if(len!=sizeof(data)){ printf("exiting with %d bytes read\n",len); break; } } if(!dryrun) close(o); unsigned char final_digest[SHA1_DIGEST_SIZE]; char dout[2*SHA1_DIGEST_SIZE+1]; sha1_digest(final_digest,page_digests,SHA1_DIGEST_SIZE*num_mfns); hex(dout,final_digest); printf("checkpoint chksum is %s\n",dout); puts("done"); return 0;}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -