• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            隨筆-80  評論-24  文章-0  trackbacks-0
                  上篇文章已經將難加載的ELF文件轉化成容易被loader加載的map文件,已經是一個進步,可是仔細想想可能還存在如下問題:boot文件的大小以及在軟盤中的位置是固定的,在軟盤的第一個扇區,大小為512字節,而且boot由BIOS自動加載,但是loader該放到哪呢?內核map文件又該放到哪呢?
            按照linux0.11的思路:將bootsect、setup、head、system壓縮一下,其中bootsect位于整個壓縮后的文件中的前512字節,之后的文件按序排放,然后放入軟盤中。這個方法真的很簡潔。
                  我加載WinixJ的方法同樣借鑒linux,將boot文件放在image文件的最前面512字節,之后是loader文件,再之后是內核map文件。這樣讓boot一次性完成加載loader和內核map文件入內存的工作。其中boot位于軟盤的第一扇區,loader從第二扇區開始延伸,之后是map文件。不過還需要知道的是loader文件和map文件到底有多大,這兩個數字我選擇放到boot文件的尾部,位于boot標志0xaa55的前面。loader和map文件的長度都是以扇區為單位,假設loader文件有1000字節長,則laoder_len = 1000 >> 9 + (1000 % 512 ? 1 : 0);map_len的含義類似。所以image中可能會含有一些空域,這些空域是由于loader或map文件并非正好占用若干扇區而造成的。
            build.c文件代碼如下:

              1 #include <stdio.h>
              2 #include <stdlib.h>
              3 #include <string.h>
              4 #include <unistd.h>
              5 #include <sys/stat.h>
              6 
              7 #define BUF_LEN 520
              8 #define BOOT_BUF_LEN BUF_LEN
              9 #define FILE_NAME_LEN 50
             10 
             11 unsigned char boot_buf[BOOT_BUF_LEN]; //緩存boot文件內容
             12 unsigned char buffer[BOOT_BUF_LEN];
             13 
             14 char boot[FILE_NAME_LEN]; //存儲boot文件名
             15 char loader[FILE_NAME_LEN]; //存儲loader文件名
             16 char kernel[FILE_NAME_LEN]; //存儲kernel文件名
             17 char image[FILE_NAME_LEN]; //存儲輸出文件的文件名
             18 
             19 FILE *bootp = NULL; //boot文件的文件操作句柄
             20 FILE *loaderp = NULL; //loader文件的文件操作句柄
             21 FILE *kernelp = NULL; //kernel文件的文件操作句柄
             22 FILE *imagep = NULL; //image文件的文件操作句柄
             23 
             24 static void usage()
             25 {
             26     fprintf(stderr, "Usage: build [-b ../boot/boot] ");
             27     fprintf(stderr, "[-l ../boot/loader] [-k ../kernel/kernel.map] [-w ../Image]\n");
             28 }
             29 
             30 static void init()
             31 {
             32     //指定默認的boot、loader、kernel和輸出文件的文件名
             33     strcpy(boot, "../boot/boot"); //默認情況下boot文件在頂層目錄的boot子目錄中
             34     strcpy(loader, "../boot/loader"); //默認情況下loader文件在頂層目錄的loader子目錄中
             35     strcpy(kernel, "../kernel/kernel.map"); //默認情況下kernel文件在頂層目錄的kernel子目錄中
             36     strcpy(image, "../System.Image"); //默認在頂層目錄生成系統映像
             37 }
             38 
             39 static void proc_opt(int argc, char * const *argv)
             40 {
             41     int ch;
             42     opterr = 0//不顯示錯誤信息
             43 
             44     while ((ch = getopt(argc, argv, "b:l:k:w:h")) != -1)
             45     {
             46         switch (ch)
             47         {
             48             case 'b'//指定boot文件名
             49                 strcpy(boot, optarg);
             50                 break;
             51             case 'l'//指定loader文件名
             52                 strcpy(loader, optarg);
             53                 break;
             54             case 'k'//指定kernel文件名
             55                 strcpy(kernel, optarg);
             56                 break;
             57             case 'w'//指定輸出的系統映像文件名
             58                 strcpy(image, optarg);
             59                 break;
             60             case 'h':
             61                 usage();
             62                 exit(1);
             63         }
             64     }
             65 }
             66 
             67 static void open_file()
             68 {
             69     //如果指定的boot文件不存在,則退出
             70     if (0 != access(boot, F_OK))
             71     {
             72         fprintf(stderr, "\"%s\": No such file.\n", boot);
             73         exit(1);
             74     }
             75     
             76     //如果指定的loader文件不存在,則退出
             77     if (0 != access(loader, F_OK))
             78     {
             79         fprintf(stderr, "\"%s\": No such file.\n", loader);
             80         exit(1);
             81     }
             82     
             83     //如果指定的kernel文件不存在,則退出
             84     if (0 != access(kernel, F_OK))
             85     {
             86         fprintf(stderr, "\"%s\": No such file.\n", kernel);
             87         exit(1);
             88     }
             89 
             90     //如果指定的image文件存在,則給出warning
             91     if (0 == access(image, F_OK))
             92     {
             93         fprintf(stderr, "Warning: The file \"%s\" exists.\n", image);
             94         fprintf(stderr, "But we will go on \n");
             95     }
             96 
             97     bootp = fopen(boot, "r+");
             98     //如果不能打開boot文件
             99     if (NULL == bootp)
            100     {
            101         fprintf(stderr, "cannot open the file \"%s\".\n", boot);
            102         exit(1);
            103     }
            104 
            105     loaderp = fopen(loader, "r+");
            106     //如果不能打開loader文件
            107     if (NULL == loaderp)
            108     {
            109         fprintf(stderr, "cannot open the file \"%s\".\n", loader);
            110         exit(1);
            111     }
            112 
            113     kernelp = fopen(kernel, "r+");
            114     //如果不能打開kernel文件
            115     if (NULL == kernelp)
            116     {
            117         fprintf(stderr, "cannot open the file \"%s\".\n", kernel);
            118         exit(1);
            119     }
            120 
            121     imagep = fopen(image, "w+");
            122     //如果不能創建image文件
            123     if (NULL == imagep)
            124     {
            125         fprintf(stderr, "cannot create the file \"%s\".\n", image);
            126         exit(1);
            127     }
            128 }
            129 
            130 int main(int argc, char * const *argv)
            131 {
            132     int n;
            133     struct stat loader_stat, kernel_stat;
            134     int loader_len = 0, kernel_len = 0;
            135 
            136     init(); //初始化
            137 
            138     proc_opt(argc, argv); //處理命令行參數
            139 
            140     open_file(); //打開boot、loader、kernel和image文件
            141 
            142     //將boot文件的512字節讀入boot_buf緩沖區
            143     n = fread(boot_buf, 5121, bootp);
            144 
            145     if (1 != n)
            146     {
            147         fprintf(stderr, "cannot read 512 bytes from %s.\n", boot);
            148         exit(1);
            149     }
            150 
            151     //檢查boot文件的末尾兩個字節,如果為0xaa55,則認為是合法的boot文件
            152     if (0xaa55 != *(unsigned short *)(boot_buf + 510))
            153     {
            154         fprintf(stderr, "%s is not bootable file.\n", boot);
            155         exit(1);
            156     }
            157 
            158     //獲取loader文件的信息
            159     n = stat(loader, &loader_stat);
            160     
            161     if (-1 == n)
            162     {
            163         fprintf(stderr, "cannot get %s's status.\n", loader);
            164         exit(1);
            165     }
            166 
            167     //獲取loader文件的長度,按字節計算
            168     loader_len = loader_stat.st_size;
            169 
            170     //獲取kernel文件的信息
            171     n = stat(kernel, &kernel_stat);
            172 
            173     if (-1 == n)
            174     {
            175         fprintf(stderr, "cannot get %s's status.\n", kernel);
            176         exit(1);
            177     }
            178 
            179     //獲取kernel文件的長度,按字節計算
            180     kernel_len = kernel_stat.st_size;
            181 
            182     //修改boot中LOADER_LEN和KERNEL_LEN字段,詳細請查看boot.asm源碼最后10行
            183     boot_buf[507= (0 == (loader_len & 0x1ff)) ? (loader_len >> 9) : (loader_len >> 9+ 1;
            184     *(unsigned short *)(boot_buf + 508= (0 == (kernel_len & 0x1ff)) ? (kernel_len >> 9) : (kernel_len >> 9+ 1;
            185 
            186     //將boot文件內容寫入image文件中
            187     n = fwrite(boot_buf, 5121, imagep);
            188 
            189     if (1 != n)
            190     {
            191         fprintf(stderr, "cannot write into %s.\n", image);
            192         exit(1);
            193     }
            194 
            195     //將loader文件寫入image中,按扇區數來寫入,最后一扇區不夠的用0補足
            196     while (loader_len > 0)
            197     {
            198         memset(buffer, 0sizeof(buffer));
            199         n = fread(buffer, loader_len > 512 ? 512 : loader_len, 1, loaderp);
            200 
            201         if (1 != n)
            202         {
            203             fprintf(stderr, "cannot read %d bytes from %s.\n"
            204                     loader_len > 512 ? 512 : loader_len, boot);
            205             exit(1);
            206         }
            207 
            208         n = fwrite(buffer, 5121, imagep);
            209         
            210         if (1 != n)
            211         {
            212             fprintf(stderr, "cannot write into %s.\n", image);
            213             exit(1);
            214         }
            215 
            216         loader_len -= 512;
            217     }
            218 
            219     //將kernel文件寫入image中,按扇區數來寫入,最后一扇區不夠的用0補足
            220     while (kernel_len > 0)
            221     {
            222         memset(buffer, 0sizeof(buffer));
            223         n = fread(buffer, kernel_len > 512 ? 512 : kernel_len, 1, kernelp);
            224 
            225         if (1 != n)
            226         {
            227             fprintf(stderr, "cannot read %d bytes from %s.\n"
            228                     kernel_len > 512 ? 512 : kernel_len, boot);
            229             exit(1);
            230         }
            231 
            232         n = fwrite(buffer, 5121, imagep);
            233         
            234         if (1 != n)
            235         {
            236             fprintf(stderr, "cannot write into %s.\n", image);
            237             exit(1);
            238         }
            239 
            240         kernel_len -= 512;
            241     }
            242 
            243     fclose(bootp);
            244     fclose(loaderp);
            245     fclose(kernelp);
            246     fclose(imagep);
            247 
            248     return 0;
            249 }

            程序還是比較好理解的,大體思想正如上面所說。最后生成的System.Image是最終的系統映像文件。它的大體組織前述已經比較清晰,不過畫圖更加容易理解:
            posted on 2011-11-20 14:59 myjfm 閱讀(435) 評論(0)  編輯 收藏 引用 所屬分類: 操作系統
            久久青草国产手机看片福利盒子| 97精品伊人久久大香线蕉| 日本强好片久久久久久AAA| 久久精品国产亚洲AV无码偷窥| 久久er99热精品一区二区| 狠狠久久亚洲欧美专区| 国内精品伊人久久久久网站| 久久精品综合网| 久久亚洲国产中v天仙www| 久久99这里只有精品国产| 精品久久久久久综合日本| 性欧美大战久久久久久久| 国产精品久久久久9999高清| 亚洲欧美国产精品专区久久| 久久久久亚洲Av无码专| 亚洲人成无码网站久久99热国产| 久久久久国产精品熟女影院| 久久只这里是精品66| 国产精品久久久久久| 亚洲中文字幕无码一久久区| 久久久久亚洲精品男人的天堂| 婷婷五月深深久久精品| 一级女性全黄久久生活片免费 | 亚洲精品高清一二区久久| 国产精品久久久久久吹潮| 国产成人精品久久| 久久亚洲sm情趣捆绑调教| 久久青青国产| 久久人妻少妇嫩草AV无码蜜桃| 久久国产精品久久精品国产| 日日躁夜夜躁狠狠久久AV| 一本色道久久综合亚洲精品| 欧美成人免费观看久久| 综合久久一区二区三区| 日本高清无卡码一区二区久久| 欧美亚洲另类久久综合婷婷| 色成年激情久久综合| 国产精品日韩欧美久久综合| 精品久久久无码中文字幕| 精品久久久久一区二区三区| 日韩中文久久|