GhaSShee


OS


# HELLO-OS `hello.img` という名のファイルを作ります。 まずはじめに、`4096 byte` を `0埋め` します。 ~~~ $ vim hello.img $ sudo dd if=/dev/zero of=hello.img bs=4096 count=16 ~~~ `vim` の `binary` モードで開きます。 ~~~ $ vim -b hello.img :%!xxd ~~~ そして、以下のように改変します。 ~~~ 0000000: eb4e 9048 454c 4c4f 4950 4c00 0201 0100 .N.HELLOIPL..... 0000010: 02e0 0040 0bf0 0900 1200 0200 0000 0000 ...@............ 0000020: 400b 0000 0000 29ff ffff ff48 454c 4c4f @.....)....HELLO 0000030: 2d4f 5320 2020 4641 5431 3220 2020 0000 -OS FAT12 .. 0000040: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 0000050: b800 008e d0bc 007c 8ed8 8ec0 be74 7c8a .......|.....t|. 0000060: 0483 c601 3c00 7409 b40e bb0f 00cd 10eb ....<.t......... 0000070: eef4 ebfd 0a0a 6865 6c6c 6f2c 2077 6f72 ......hello, wor 0000080: 6c64 0a00 0000 0000 0000 0000 0000 0000 ld.............. 0000090: 0000 0000 0000 0000 0000 0000 0000 0000 ................ ... 00001d0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00001e0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00001f0: 0000 0000 0000 0000 0000 0000 0000 55aa ..............U. 0000200: f0ff ff00 0000 0000 0000 0000 0000 0000 ................ ... 0001400: f0ff ff00 0000 0000 0000 0000 0000 0000 ................ ~~~ 書き込みます。 ~~~ :%!xxd -r :wq! ~~~ macOS の場合は、`diskutil` を使用し、デバイスを確認の上、`USB` 記憶装置に書き込みます。 ~~~ # diskutil list (check mount devices) # dd if=hello.img of=/dev/disk1 bs=4096 ~~~ これで、OS 1日目終了です。
`USB` を BIOS から起動してください。

# Assembler DAY02 今度はアセンブラをみていこう nask : developped nasm * A : accumulator : 累積演算機 * C : counter register: 数える * D : data register : * B : base register : 配列のベースアドレスなどを格納 * SP : stack pointer : - スタック用に確保されたメモリ領域のコールスタック位置のアドレスを格納 - `push` 時にアドレスをひとつ手前にもどす - `pop` 時にインクリメントする * BP : starck base pointer : * SI : source index : * DI : destination index : HELLOOS.img (ONLY DISPLAY "HELLO,WORLD!") ~~~ 0000000: eb4e 9048 454c 4c4f 4950 4c00 0201 0100 .N.HELLOIPL..... 0000010: 02e0 0040 0bf0 0900 1200 0200 0000 0000 ...@............ 0000020: 400b 0000 0000 29ff ffff ff48 454c 4c4f @.....)....HELLO 0000030: 2d4f 5320 2020 4641 5431 3220 2020 0000 -OS FAT12 .. 0000040: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 0000050: b800 008e d0bc 007c 8ed8 8ec0 be74 7c8a .......|.....t|. 0000060: 0483 c601 3c00 7409 b40e bb0f 00cd 10eb ....<.t......... 0000070: eef4 ebfd 0a0a 4845 4c4c 4f2c 574f 524c ......HELLO,WORL 0000080: 4421 0a00 D!.. ~~~ HELLOOS.nas (nasm assembler code) ~~~ ; hello-os ; TAB=4 ; Begin MasterBootRecord ; ORG 0x7c00 ; このプログラムがメモリのどこに読み込まれるのか ; ; 以下は標準的なFAT12フォーマットフロッピーディスクのための記述 ; JMP entry DB 0x90 DB "HELLOIPL" ; ブートセクタの名前を自由に書いてよい(8バイト) DW 512 ; 1セクタの大きさ(512にしなければいけない) DB 1 ; クラスタの大きさ(1セクタにしなければいけない) DW 1 ; FATがどこから始まるか(普通は1セクタ目からにする) DB 2 ; FATの個数(2にしなければいけない) DW 224 ; ルートディレクトリ領域の大きさ(普通は224エントリにする) DW 2880 ; このドライブの大きさ(2880セクタにしなければいけない) DB 0xf0 ; メディアのタイプ(0xf0にしなければいけない) DW 9 ; FAT領域の長さ(9セクタにしなければいけない) DW 18 ; 1トラックにいくつのセクタがあるか(18にしなければいけない) DW 2 ; ヘッドの数(2にしなければいけない) DD 0 ; パーティションを使ってないのでここは必ず0 DD 2880 ; このドライブ大きさをもう一度書く DB 0,0,0x29 ; よくわからないけどこの値にしておくといいらしい DD 0xffffffff ; たぶんボリュームシリアル番号 DB "HELLO-OS " ; ディスクの名前(11バイト) DB "FAT12 " ; フォーマットの名前(8バイト) resb 18 ; とりあえず18バイトあけておく ; ; プログラム本体 ; entry: MOV AX,0 ; b80000 レジスタ初期化 MOV SS,AX ; 8ed0 MOV SP,0x7c00 ; bc007c MOV DS,AX ; 8ed8 MOV ES,AX ; 8ec0 ; MOV SI,msg ; be747c ; ; putloop: MOV AL,[SI] ; 8a0483 ADD SI,1 ; c601 SIに1を足す CMP AL,0 ; 3c00 JE fin ; 7409 MOV AH,0x0e ; b40e 一文字表示ファンクション MOV BX,15 ; bb0f00 カラーコード INT 0x10 ; cd10 ビデオBIOS呼び出し JMP putloop ; ebee ; ; fin: HLT ; f4 何かあるまでCPUを停止させる JMP fin ; ebfd 無限ループ ; 0a0a 6865 6c6c 6f2c 2077 6f72 6c64 0a00 msg: DB 0x0a, 0x0a ; 改行を2つ DB "hello, world" DB 0x0a ; 改行 DB 0 resb 0x7dfe-$ ; 0x7dfeまでを0x00で埋める命令 DB 0x55, 0xaa ; ; End MasterBootRecord ; 以下はブートセクタ以外の部分の記述 DB 0xf0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 resb 4600 DB 0xf0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 ; resb 1469432 ~~~

## FAT12 ************************************************************************************* * * * * * 0 -------- * * MBP(512B) * * 200 -------- .---------------------------------------------. * * | | * * | attribute(1) | * * | | | * * | +-------------------+-------.|.---------+ | * * 2600 -------- | | file name(8 byte) |type(3)| | (10| | * * Root Dir -->| +-------------------+----+--+-+---------+ | * * | |) | | | size(4) | | * * | +-------------------+-|--+-|--+---------+ | * * | | | | * * 4200 -------- | | storedSector(2) | * * DataArea | updatedTime(2) | * * (sector 02) | | * * 4400 -------- '---------------------------------------------' * * (sector 03) 32 byte per 1 file information * * 4600 -------- * * .. * * * * 5200 -------- * * (sector 0A) * * -------- * * .. * * until 2848 * ************************************************************************************* ## MEMORYMAP OF BIOS Low Memory (the first MiB) ~~~ 0x00000000 0x000003FF 1 KiB RAM - partially unusable (see above) Real Mode IVT (Interrupt Vector Table) 0x00000400 0x000004FF 256 bytes RAM - partially unusable (see above) BDA (BIOS data area) 0x00000500 0x00007BFF almost 30 KiB RAM (guaranteed free for use) Conventional memory 0x00007C00 0x00007DFF 512 bytes RAM - partially unusable (see above) Your OS BootSector 0x00007E00 0x0007FFFF 480.5 KiB RAM (guaranteed free for use) Conventional memory 0x00080000 0x0009FBFF approximately 120 KiB, depending on EBDA size RAM (free for use, if it exists) Conventional memory 0x0009FC00 0x0009FFFF 1 KiB RAM (unusable) EBDA (Extended BIOS Data Area) 0x000A0000 0x000FFFFF 384 KiB various (unusable) Video memory, ROM Area ~~~ BIOS Data Area (BDA) ~~~ 0x0400 (4 words) IO ports for COM1-COM4 serial (each address is 1 word, zero if none) 0x0408 (3 words) IO ports for LPT1-LPT3 parallel (each address is 1 word, zero if none) 0x040E (word) EBDA base address >> 4 (usually!) 0x0410 (word) packed bit flags for detected hardware 0x0417 (word) keyboard state flags 0x041E (32 bytes) keyboard buffer 0x0449 (byte) Display Mode 0x044A (word) number of columns in text mode 0x0463 (2 bytes, taken as a word) base IO port for video 0x046C (word) # of IRQ0 timer ticks since boot 0x0475 (byte) # of hard disk drives detected 0x0480 (word) keyboard buffer start 0x0482 (word) keyboard buffer end 0x0497 (byte) last keyboard LED/Shift key state ~~~ Extended BIOS Data Area (EBDA) ~~~ 0x000A0000 0x000BFFFF 128 KiB video RAM VGA display memory 0x000C0000 0x000C7FFF 32 KiB (typically) ROM Video BIOS 0x000C8000 0x000EFFFF 160 KiB (typically) ROMs and unusable space Mapped hardware & Misc. 0x000F0000 0x000FFFFF 64 KiB ROM Motherboard BIOS ~~~

## Makefile ~~~ Makefile ---------- opt: component01 component02 .. shellScript ~~~ then type ~~~ $ make opt ~~~

## edimg bin コマンドの `edimg` が使いにくそうなのでつくってみる ~~~c #include #include #define READNUM 1024 FILE *fpr,*fpw; char *input,*output,*addsrc; int len,from,to; char buf[1024]; void usage(){printf("\ *********\n\ * usage *\n\ *********\n\ \n\ ******************************************\n\ $ edimg -i input \n\ -o output \n\ --addsrc src\n\ startpoint-of-input\n\ startpoint-of-srcfile\n\ length\n\ ******************************************\n");exit(1); } void configure_args(int argc, char** argv) { if(argc==1) usage(); int i=1; while(i < argc) { if (argv[i][0]=='-') switch(argv[i][1]) { case 'i': input=argv[i+1]; i+=2;break; case 'o': output=argv[i+1]; i+=2;break; case '-': if (strcmp(&argv[i][2],"addsrc")!=0) usage(); addsrc=argv[i+1]; from=atoi(argv[i+2]); to=atoi(argv[i+3]); len=atoi(argv[i+4]); i+=5;;break; default: usage(); } else usage(); } } void copyonestep(FILE * fpr, FILE * fpw, int bufnum) { int r = fread(buf,1,bufnum,fpr); int w = fwrite(buf,1,r,fpw); if(r!=READNUM) printf("Skipped some %d bytes.\n",READNUM - r); } void copy(char * read,long start, long end) { FILE * fpr = fopen(read, "rb"); FILE * fpw = fopen(output, "ab"); if (end-EOF==0) { fseek(fpr,start,SEEK_SET); while(1){ copyonestep(fpr,fpw,READNUM); if (feof(fpr)) break; } } else { int i = (end-start) / READNUM; int rest = (end-start) % READNUM; while ( i > 0 ) { copyonestep(fpr,fpw,READNUM); --i; } copyonestep(fpr,fpw,rest); } fclose(fpr); fclose(fpw); } int main(int argc, char** argv) { configure_args(argc, argv); fpw = fopen(output,"w"); fclose(fpw); copy(input,0,from); copy(addsrc,from,from+len); copy(input,from+len,EOF); return 0; } ~~~

# LOAD DISK DAY03 ## `INT 0x13` - READ , WRITE , VERIFY ,or SEEK disk ~~~ AH = 0x02 -> READ AH = 0x03 -> WRITE AH = 0x04 -> VERIFY AH = 0x0c -> SEEK AL = length of sectors CH = $Cylinder & 0xff (0..79) CL = $Sector (1..18) DH = $Header (0,1) DL = $Drive ES:BX = buffer address (only when READ & WRITE) RETURN VALUE FLAGS.CF == 0 : no err AH = 0 == 1 : error AH = err code ~~~ ![](/image/hard-disk.gif) from [here ](http://www.computableminds.com/post/Hard-disk/HDD/HD/partition/good/bad/track/sector/cylinder/head)


## MEMORY ADDRESS ****************************************************** * * * [BX] ~0xffff * * | * * | enlarge * * v * * [ES:BX] := [ES*16 + BX] ~0xfffff * * | * * | * * v * * [EBX] ~0xfffffff * * * ******************************************************
Being the Old System,
BIOS couldn't use EBX . So,
`[ES:BX]` was needed .


you have to initialise with ~~~ DS = 0; ~~~ because ~~~ [1234] := [DS * 16 + 1234] ~~~

## Into the C program world ****************************************************** * * * bootpack.c * * | * * v cc * * bootpack.gas * * | * * v gas2nask * * bootpack.nas * * | * * v nasm(nask) * * bootpack.obj * * | * * v obj2bim (linker) * * bootpack.bim * * | * * v +header +zip * * bootpack.hrb * * | * * v $ cat asmhead bootpack.hrb * * os.img * * * ****************************************************** # read & write memory on c operate register1 ~~~ char c; volatile char *reg1 = (char *)0x10000000; c = *reg1; // read from reg1 *reg1 = 0x01; // write to reg1 ~~~