Hvordan skrive ditt eget operativsystem. La oss skrive en kjerne! Opprette den enkleste fungerende operativsystemkjernen

rTYCHEFUFCHHA CHUEI UCHPYI YUFBFEMEK!

rTEDSHDHEYE CHSHCHRKHULY NPZMY VSHCHFSH OEULPMSHLP ЪBRKhFBOOSCHNY. oBUBMSHOBS ЪБЗТХЛБ, Assembler, BIOS. UEZPDOS NSCH OBLPOEG RETEYIDYN L VPMEE YOFETEUOPK Y RPOSFOPK YUBUFY - NSCH OBUYOBEN RYUBFSH SDTP. RYUBFSH NSCH EZP VKhDEN OM SESSCHLE CHCHUPLPZP HTPCHOS y.

h OBYUBMSHOSHCHK ЪBZTHYUYL PUFBMPUSH CHOEUFY CHUEZP RBTH DPRPMOEOYK Y PO VHDEF RPMOPUFSHA ZPFPCH ZTHYFSH MAVSHCHE 32-VYFOSHCHE SDTB.

PRTEDEMEOYE PVAENB PRETBFYCHOPK RBNSFY

lPOYUOP, NPTsOP RPDUYFBFSH PVYAIN RBNSFY CHTHYUOHA CH SDTE - RETEVYTBFSH BDTEUB PF 0x100000 Y RSHCHFBFSHUS ЪBRYUBFSH FKhDB OBYUEOYE PFMYYOHMS.Y0PFx eUMY RTY YUFEOYY NSCH RPMKHYUBEN RPMHYUEOOPE OBYUEOYE, FP CHUЈ IPTPYP, YOBYUE RBNSFSH LPOYUYMBUSH - ЪBRPNYOBEN BDTEU RPUMEDOEZP KHDYUOPZP YUFEOYS PRETBNSFPIEN YUFEOYS, LRBNSFNPFIEN. pDOBLP FBLPC URPUPV YNEEF DCHB OEDPUFBFLB:

1) EZP UMEDHEF YURPMSHЪPCHBFSH DP CHLMAYUEOYS UFTBOYUOPK BDTEUBGYY, YUFPVSH YNEFSH DPUFHR LP CHUEK ZHJYYUEULPK RBNSFY, MYVP KHUFTBYCHBFSH ЪBRYPLOUSH" RETEFT "BRYPLOUSH" RETEFT. mYYOSS FTBFB CHTENEY, RTY HUMPCHYY, UFP FEUFYTPCHBOYE RBNSFY BIOS Y FBL CHSHPRPMOSEF RTY OBYUBMSHOPK YOYGYBMYBGYY, B NSCH DEMBEN DCHPKOHA TBVPFH.

2). l FPNH CE BIOS RYYEF CH UBNHA PVSHYUOKHA RBNSFSH FBVMYGSH ACPI, LPFPTSHCHE RTYZPDSFUS PRETBGYPOOPK UYUFEN Y OE UFPYF YI ЪBFYTBFSH DP RTPYUFEOOS.

yЪ LFPPZP UMEDHEF, YuFP MHYUYE URTPUYFSH RTP PVYAEN PRETBFYCHOPK RBNSFY X BIOS, VMBZP PÅ RTEDPUFBCHMSEF CHUE OEPVIPDYNSCHE ZHKHOLGYY.

yUFPTYYUEULY RETCHPK JHOLGYEK PRTEDEMEOYS PVYANB PRETBFYCHOPK RBNSFY VSHMP RTETSCHCHBOIE 0x12. pOP OE RTOYNBEF OILBLYI CHIPDOSCHI RBTBNEFTPCH, CH OM CHSHCHIPDE CH TEZYUFTE AX UPDETSYFUS TBNET VBPCHPK RBNSFY CH LYMPVBKFBI. vББПЧБС RBNSFSH - FE UBNSHCHE 640 lv DPUFHROSCHE CH TEBMSHOPN TETSINE. UEKYUBU CHSC HCE OE UNPTSEFE OBKFY LPNRSHAFET, ZDE VSH VSHMP NEOEE 640 lv RBNSFY, OP NBMP MY. yURPMSHЪPCHBFSH EЈ OBN UNSHUMB OEF - EUMY RTPGEUUPT RPDDETSYCHBEF ЪBEEYEЈOOOSCHK TETSYN, FP CHTSD MY KH OEZP VKhDEF NEOSHYE OEULPMSHLYI NEZBVFBKF .

pVYaЈNSCH RBNSFY TPUMY Y 640 lv UFBMP NBMP. fPZDB RPSCHYMBUSH OPCHBS ZHKHOLGYS - RTETSCHCHBOYE 0x15 AH=0x88. pOB CHP'CHTBEBEF CH AX TBNET TBUYYTEOOPK RBNSFY (ELEVER 1 nv) CH LYMPVBKFBI CH AX. bFB ZHOLGYS OE NPTSEF CHPCHTBEBFSH OBYUEOYS VPMSHYE 15 nov (15 + 1 YFPZP 16 nov).

lPZDB Y 16 nv UVBMP OEDPUFBFPYuOP RPSCHYMBUSH OPCHBS ZHOLGYS - RTETSCHCHBOIE 0x15, AX=0xE801. POB CHPCHTBEBEF TEKHMSHFBFSCH BC CH 4 TEZYUFTBI:

AX - TBNET TBUYYTEOOOPK RBNSFY DP 16 nv Ch LYMPVBKFBI
BX - TBNET TBUYYTEOOOPK RBNSFY UCHETI 16 nv L VMPLBI RP 64 lv
CX - TBNET ULPOZHYZHTYTPCHBOOPC TBUYYTEOOPK RBNSFY DP 16 nv Ch LYMPVBKFBI
DX - TBNET ULPOZHYZHTYTPCHBOOPC TBUYYTEOOPK RBNSFY UCHETI 16 nv h VMPLBI RP 64 lv

YuFP FBLPE "ULPOZHYZHTYTPCHBOOBS" RBNSFSH RTPYCHPDYFEMY BIOS UHDS RP CHUENKH OE DPZPCHPTYMYUSH, RPFPNKH OBDP RTPUFP, EUMY CH AX Y BX OHMY, VTBFSH OBYUEOYE Y CX.

oP Y LFPZP PLBBBMPUSH NBMP. CHEDSH CHUE RETEYUUMEOOSCH CHE ZHKHOLGYY YNEAF PZTBOYUEOOYE PVAENB RBNSFY CH 4 stjerner, L FPNH TSE OE KHYYFSHCHBAF FP, YuFP RBNSFSH NPTsEF VSCFS OE OERTETCHCHOSCHN VMPLPN. rPFPNH CH OPCHSHHI BIOS RPSCHYMBUSH EEЈ PDOB ZHOLGYS - RTETSCHCHBOIE 0x15, AX=0xE820. POB CHPCHTBEBEF OE RTPUFP YUYUMP, B LBTFH RBNSFY. CHIPDOSHCHE RBTBNEFTSCH:

EAX=0xE820
EDX=0x534D4150 ("SMAP")
EBX - UNEEEEOYE PF OYUBMB LBTFSH RBNSFY (DMS OYUBMB 0)
ECX - TBNET VKHZHETB (LBL RTBCHYMP 24 VBKFB - TBNET PDOPZP BMENEOFB)
ES:DI - BDTEU VKHZHETB, LKhDB OBDP ЪBRYUBFSH PYUETEDOPK BMENEOF

CHPIPDOSHE RBTBNEFTSCH:

EAX=0x534D4150 ("SMAP")
EBX - OPChPE UNEEOOYE DMS UMEDHAEEZP CHSHCHJPCHB ZHKHOLGYY. eUMY 0, FP CHUS LBTFB RBNSFY RTPYUIFBOB
ECX - LPMYUEUFChP TEBMSHOP CHPCHTBEYOOOSCHI VBKF (20 YMY 24 VBKFB)
h KHLBBOOPN VKHZHETE UPDETSYFUS PYUETEDOPK BMENEOF LBTFSH RBNSFY.

LBTSDSCHK BMENEOF LBTFSH RBNSFY YNEEF UMEDHAEHA UFTHLFHTH (OBRYYKH CH UYOFBLUIUE UI, RPFPNKH YuFP TBVPT DBOOSHI NSCH VKHDEN DEMBFSH HTSE CH SDTE):

Struktur (usignert lang lang base; //vБПЧШЧК ЖЪЪУУУУЛК БДТУ ТЭЗІПOB usignert lang lang lengde; //тБЪNET TEZYPOB CH VBKFBI usignert lang type; /Y fpYrTE lang type; // acetert lang type; OOSH BFTYVHFSCH ACPI );

rPUMEDOYK BMENEOF UFTKHLFKhTSCH OE PVSBFEMEO. eeЈ CH PDOPN YUFPYUOYLE CHYDEM, UFP RETED ЪBRTPUPN BMENEOFB UFPYF RPNEUFYFSH FHDB EDYOYULH. lPOYUOP, UEKYUBU NSCHOE RPDDETSYCHBEN ACPI, OP MHYUYE ЪBTBOEE RPBBVPFYFUS P FPN, YUFPVSH RPMKHYUYFSH LBL NPTsOP VPMSHYE DBOOSCHI. h PFMYYUYY PF RBTBNEFTPCH RBNSFY, CHU PUFBMSHOP NPTsOP MEZLP KHOBFSH Y YY ЪBEEYEЈOOOPZP TETSINB OBRTSNHA, VE BIOS.

TEZYPOSH RBNSFY, PRYUSCHCHBENSHCH LBTFPC, NPZHF VshchFSH OUEULPMSHLYI FYRPCH:

1 - pVSHYUOBS RBNSFSH. nPTsEF VShchFSH UCHPVPDOP YURPMSHЪPCHBOB pu DMS UCHPYI GEMEK. rPLB NSCH FPMSHLP L OEK Y VKhDEN PVTBEBFSHUS, B CHUY PUFBMSHOP RTPRKHULBFSH.
2 - ъБТЭЧТПЧБОП (OBRTYNET, LPD BIOS). bFB RBNSFSH NPTSEF VSCHFSH LBL ZHJYYUEULY OEDPUFHROB DMS ЪBRYUY, FBL Y RTPUFP ЪBRYUSH FHDB OETSEMBFEMSHOB. fBLHA RBNSFSH MHYUYE OE FTPZBFSH.
3 - dPUFHROP RPUME RTPYUFEOOIS FBVMYG ACPI. CHETPSFOP, YNEOOP CH FYI VMPLBI LFY FBVMYGSH Y ITBOSFUS. rPLB DTBKCHET ACPI OE RTPYUIFBEF FBVMYGSHCH, bFH RBNSFSH MHYUYE OE FTPZBFSH. rPFPN NPTsOP YURPMSHЪPCHBFSH FBL CE, LBL Y RBNSFSH FYRB 1.
4 - bFH RBNSFSH UMEDHEF UPITBOSFSH NETSDH NVS UEUUYSNY. fBLHA RBNSFSH NSCH FTPZBFSH OE VKhDEN, RPLB OE KHOBEN, YuFP FBLPE NVS UEUUYY:-)

OE CHUE BIOS NPZHF RPDDETSYCHBFSH UFH ZHKHOLGYA. eUMY LBLBS-FP ZHOLGYS OE RPDDETTSYCHBEFUS, FP RTY CHSHCHIPDE YЪ OEЈ KHUFBOPCHMEO ZHMBZ RETERPMOOYS Y UMEDHEF PVTBEBFSHUS L VPMEE UFBTPC. nsch VKhDEN YURPMSHЪPCHBFSH ZHTNBF LBTFSH RBNSFY ZHKHOLGYY 0xE820. eUMY UBNH YFKH ZHOLGYA CHSHCHBFSH OE RPMHYUMPUSH - RPMKHYUBFSH PVYAIN RBNSFY PVSHYUOSCHNY UTEDUFCHBNY Y UPJDBCHBFSH UCPA UPVUFCHEOOHA LBTFH RBNSPFY Y PDOPZBPENE. rPULPMSHLH PTEDEMEOYE PVYaЈNB RBNSFY ЪBDББУБ ОХЦОБС ЪДС ЪБРХУЛБ 32-VYFOPZP ЪДС ЪБРБХУPUY ЪБРБУPUYY PTMHY, FSH EЈ CH CHYDE RPDRTPZTBNNNSCH. lBTFKH RBNSFY TBNEUFYN RP BDTEUKH 0x7000. OE DKHNBA, YuFP POB NPTsEF VShchFSH VPMSHYE RBTSH LYMPVBKF. rPUMEDOYK BMENEOF CHTHYUOKHA UDEMBEN FYRB 0 - FBLPZP FYRB OE CHPTBEBEF BIOS Y LFP Y VHDEF RTYOBLPN LPOGB.

; rPMHYUEOYE LBTFSH RBNSFY get_memory_map: mov di, 0x7000 xor ebx, ebx @: mov eax, 0xE820 mov edx, 0x534D4150 mov ecx, 24 mov ebx, 1 in dword, 1 in di x jnz @b @:cmp di, 0x7000 ja .ok mov dword, 0x100000 mov dword, 0 mov dword, 0 mov dword, 1 mov dword, 0 mov ax, 0xE801 int 0x15 jnc @f mov ah, 0x88 int 0x15 int 0x15 cx , dx @: test cx, cx jz @f mov ax, cx mov bx, dx @: movzx eax, ax movzx ebx, bx mov ecx, 1024 mul ecx push eax mov eax, ebx mov ecx, 65536 pop mul eax, edx mov , eax add di, 24 jmp .ok .ok: xor øks, ax mov cx, 24 / 2 rep stosw ret

OH CHPF Y ZPFPCH OBY OBYUBMSHOSHCHK ЪБЗТХЪУйЛ VHI 32-VYFOSHCHI SDEt. h ЪBLMAYUEOYE RTYCHPTSKH EZP RPMOSHCHK LPD Y NSCH RETEKDEN L SDTH.

; oYUBMSHOSHCHK ЪБЗТХЪУYЛ SDTB DMS BTIIFELFHTSCH x86-format Binær som "bin" org 0x7C00 jmp boot ; ъБЗПМПЧПЛ ListFS align 4 fs_magic dd ? fs_version dd ? fs_flags dd ? fs_base dq ? fs_size dq ? fs_map_base dq ? fs_map_size dq ? fs_first_file dq? fs_uid dq? fs_block_size dd ? ; ъБЗПМПЧПЛ ЖБКМБ virtuell på 0x800 f_info: f_name rb 256 f_next dq ? f_prev dq ? f_parent dq ? f_flags dq ? f_data dq ? f_størrelse dq ? f_ctime dq ? f_mtime dq ? f_atime dq ? slutt virtuell ; dBOOSHE OBYUBMSHOPZP ЪБЗТХЪУЛБ label sector_per_track ord ved $$ label head_count byte på $$ + 2 label disk_id byte på $$ + 3 reboot_msg db "Trykk på hvilken som helst tast...",13,10,0 boot_file_name db "boot.bin" ; hCHCHPD UFTPLAY DS:SI OM BLTB write_str: push si mov ah, 0x0E @: lodsb test al, al jz @f int 0x10 jmp @b @: pop si ret ; lTYFYUEULBS PYYVLB feil: pop si call write_str ; RETEЪБЗТХЛБ reboot: mov si, reboot_msg call write_str xor ah, ah int 0x16 jmp 0xFFFF:0 ; ъБЗТХЛБ UELFPTB DX:AX CH VHJET ES:DI load_sector: push dx add ax, word adc dx, word cmp byte, 0xFF je .use_EDD push bx cx si div mov cl, dl inc cl div mov dh, ah mov dl, mov bx, di mov al, 1 mov si, 3 @: mov ah, 2 int 0x13 jnc @f xor ah, ah int 0x13 dec si jnz @b .error: call error db "DISK ERROR",13,10 ,0 @: pop si cx bx dx ret .use_EDD: push si mov byte, 0x10 mov byte, 0 mov ord, 1 mov , di push es pop word mov , ax mov , dx mov ord, 0 mov ord, 0 mov ah , 0x42 mov dl, mov si, 0x600 int 0x13 jc .error pop si dx ret ; rPYUL ZHBKMB U YNEOEN DS:SI CH LBFBMPZE DX:AX find_file: push cx dx di .find: cmp ax, -1 jne @f cmp dx, -1 jne @f .not_found: call error db "NOT FOUND",13, 10.0 @: mov di, f_info kall load_sector push di mov cx, 0xFFFF xor al, al repne scasb neg cx dec cx pop di push si repe cmpsb pop si je .funnet mov ax, word mov dx, word jmp .find . funnet: pop di dx cx ret ; ъБЗТХЛБ FELHEEZP ZHBKMB CH RBNSFSH RP BDTEUKH BX:0. lPMYUEUFCHP ЪБЗТХЦЕОШИ UELFPTPCH CHPCHTBEBEFUS CH AX load_file_data: push bx cx dx si di mov ax, word mov dx, word .load_list: cmp ax, -1 jne @f cmp dx, -1 jne @f cmp dx, -1 jne . øks, bx pop bx underøks, bx shr øks, 9 - 4 ret @: mov di, 0x8000 / 16 ring load_sector mov si, di mov cx, 512 / 8 - 1 .load_sector: lodsw mov dx, legg til si, 6 cmp ax, -1 jne @f cmp dx, -1 je .file_end @: push es mov es, bx xor di, di call load_sector add bx, 0x200 / 16 pop es loop .load_sector lodsw mov dx, jmp .load_list ; fPULB CHIPDB CH OBYUBMSHOSHCHK ЪBZTHYUYL oppstart: ; oBUFTPYN UEZNEOFOSHE TEZYUFTSH jmp 0:@f @: mov ax, cs mov ds, ax mov es, ax ; oBUFTPYN UFEL mov ss, øks mov sp, $$ ; TBTEYIN RTETSCHCHBOYS sti; ъBRPNOYN OPNET ЪБЗТХЪПУОПЗП ДУЛБ mov, dl; prtedemyn RBTBNEFTSH ЪБЗТХЪПУОПЗП ДУЛБ mov ah, 0x41 mov bx, 0x55AA int 0x13 jc @f mov byte, 0xFF jmp .disk_detected @: mov x0ah int, in mov x0ah c load_sector.feil inc dh mov , dh og cx, 111111b mov , cx .disk_detected: ; ъзтхън ртпдое оибоз ъ ътхътхъ mol mov si, boot_file_name mov ax, word mov dx, word call find_file mov bx, 0x7e00 / 16 call load_file_data; RETEIPDYN OM RTDDPMCEOYE jmp boot2 ; rKHUFPE RTPUFTBOUFCHP Y UYZOBFKHTB rb 510 - ($ - $$) db 0x55.0xAA ; dPRPMOYFEMSHOSH DBOOSH ЪБЗТХЪУЛБ load_msg_preffix db "Laster "",0 load_msg_suffix db "". ..",0 ok_msg db "OK",13,10,0 config_file_name db "boot.cfg",0 start16_msg db "Starter 16 bit kjerne...",13,10,0 start32_msg db "Starter 32 bit kjerne. ..",13,10,0 label module_list ved 0x6000 label memory_map ved 0x7000 ; @b @: mov byte, 0 mov ax, si pop si ret ; push si mov si, load_msg_suffix kall skrive_str pop si push si bp mov dx, word mov ax, word @: push ax call split_file_name mov bp, ax pop ax call find_file testbyte, 1 jz @f mov si, bp mov dx, word MOV AX, Word JMP @b @: Call Load_File_Data Mov Si, Ok_MSG Call Write_Str Pop Bp Si Ret; RPMHYUEE LBTPHSH RBNSFY Get_Memory_MAP: MOV DI, Memory_map XOR EBX, EBX @: MO: MO: MO: MO: MO: MO: MO: MO: V EAX, 0xe820 MOV EDX, 0x534D4150, 2 MOV 4 MOVX, 2 dword, 1 int 0x15 jc @f add di, 24 test ebx, ebx jnz @b @: cmp di, 0x7000 ja .ok mov dword, 0x100000 mov dword, 0 mov dword, 0 mov dword, 0 mov dword, 0 mov dword , 0xE801 int 0x15 jnc @f mov ah, 0x88 int 0x15 jc .ok mov cx, ax xor dx, dx @: test cx, cx jz @f mov ax, cx mov bx, dx @: movzx eax, ax mov,zx bx mov ecx, 1024 mul ecx push eax mov eax, ebx mov ecx, 65536 mul ecx pop edx legg til eax, edx mov , eax legg til di, 24 jmp .ok .ok: xor ax, ax4 mov cx, 2 rep stow ret ; rTPDPMTSEOYE OBUBMSHOPZP ЪБЗТХЪУЛБ boot2: ; ъБЗТХЪН ЛПОжІЗХТБГИПООСЧК ЖБКМ ЪБЗТХЪУЛБ mov si, config_file_name mov bx, 0x1000_file call; CHSPMOYN ЪБЗТХПУОШК ULTYRF mov bx, 0x9000 / 16 mov bp, module_list mov dx, 0x1000 .parse_line: mov si, dx .parse_char: lodsb test al, al jz .config. .run_command jmp .parse_char .run_command: mov byte, 0 xchg dx, si cmp byte, 0 er .parse_line ; rHUFBS UFTPLB cmp byte, "#" er .parse_line ; lPNNEOFBTYK cmp byte, "L" er .load_file ; ъБЗТХЛБ ЖБКМБ cmp byte, "S" er .start ; ъBRHUL SDTB; oEYCHEUFOBS LPNBODB mov al, mov [.cmd], al call error db "Ukjent oppstartsskriptkommando "" .cmd db ? db ""!",13,10,0 .config_end: ; rTY RTBCHYMSHOPN LPOZHYZHTBGYPOOPN ZHBKME NSCH OE DPMTSOSCH UADB RPRBUFSH; jmp omstart; ъБЗТХЛБ ЖБКМБ.load_file: push dx inc si call load_file push ax mov cx, 512 mul cx mov ord, ax mov ord, dx mov ord, 0 mov ord, 0 mov ax, bx mov cx, 16 mov ord, dx mov ord, 0 mov ord, 0 pop ax shr ax, 9 - 4 legg til bx, øks legg til bp, 16 pop dx jmp .parse_line ; ъBRHUL SDTB.start: ; rTPCHETYN, YuFP ЪBZTHTSEO IPFS VSC PDIO ZhBKM cmp bx, 0x9000 / 16 ja @f call error db "NO KERNEL LOADED",13,10,0 @: ; ъBRPMOSEN RPUMEDOYK BMENEOF URYULB ZHBKMPCH xor øks, øks mov cx, 16 mov di, bp rep stosw ; RETEIPDYN L RTPGEDHTE YOYGYBMYBGYY SDTB DMS OKHTSOPK TBTSDOPUFY inc si cmp word, "16" je .start16 cmp word, "32" je .start32 ;cmp word, "64" ;je .start64 ; oEYCHEUFOBS TSTSDOPUFSH SDTB call error db "Ugyldig startkommando argument",13,10,0 ; ъBRHUL 16-TBTSDOPZP SDTB.start16: mov si, start16_msg mov bx, module_list mov dl, jmp 0x9000 ; ъBRHUL 32-TBTSDOPZP SDTB.start32: ; CHCHCHPDYN HCHEDPNMEOYE P ЪBRHULE 32-VYFOPZP SDTB mov si, start32_msg call write_str ; rTPCHETYN, YuFP RTPGEUUPT OE IHTSE i386 mov ax, 0x7202 push ax popf pushf pop bx cmp ax, bx je @f call error db "Required i386 or better",13,10,0 @: ; rPMKHYUN LBTFH RBNSFY kall get_memory_map ; pYYUFYN FBVMYGSH UFTBOYG xor øks, øks mov cx, 3 * 4096 / 2 mov di, 0x1000 rep stosw ; ъBRPMOIN LBFBMPZ UFTBOIG mov-ord, 0x2000 + 111b mov-ord, 0x3000 + 111b ; ъBRPMOIN RETCHHA FBVMYGH UFTBOYG mov eax, 11b mov cx, 0x100000 / 4096 mov di, 0x2000 @: stosd add eax, 0x1000 loop @b ; ъBRPMOYN RPUMEDOAA FBVMYGH UFTBOYG mov di, 0x3000 mov eax, dword eller eax, 11b mov ecx, dword shr ecx, 12 @: stosd add eax, 0x1000 loop @b mov 00 0x14000; Kjernestabel mov-ord, 0x3000 + 11b ; Kjernesidetabell ; ъБЗТХЪН ЪБУЕОЕЧ CR3 mov eax, 0x1000 mov cr3, eax ; ъБЗТХХЪН ЪБУУЭОЭ Ч GDTR lgdt ; ъBRTEFYN RTETSCHCHBOYS cli; RETEKDEN CH ЪBEEYEЈOOOSCHK TETSYN mov eax, cr0 or eax, 0x80000001 mov cr0, eax ; RETEKDEN OM 32-VYFOSHCHK LPD jmp 8:start32; fBVMYGB DEULTYRFPTPCH UEZNEOFPPCH DMS 32-VYFOPZP SDTB align 16 gdt32: dq 0 ; NULL - 0 dq 0x00CF9A000000FFFF ; KODE - 8 dq 0x00CF92000000FFFF ; DATA - 16 gdtr32: dw $ - gdt32 - 1 dd gdt32 ; 32-VYFOSHCHK LPD use32 start32: ; oBUFTPYN UEZNEOFOSH TEZYUFTSHY UFEL mov eax, 16 mov ds, ax mov es, ax mov fs, ax mov gs, ax mov ss, ax mov esp, 0xFFFFDFFC ; rPNEUFYN CH DL OPNET ЪБЗТХЪПУОПЗП ДУЛБ mov dl, ; rPNEUFYN CH EBX BDTEU URYULB ЪБЗТХЦеOOШ itsХБКМПЧ mov ebx, module_list ; rPNEUFYN CH ESI BDTEU LBTFSH RBNSFY mov esi, memory_map ; RETEIPDYN OM SDTP jmp 0xFFC00000

RETCHPE SDTP

sDTP RPLB KH OBU VKhDEF UPUFPSFSH YJ DCHHI ZHBKMPCH - oppstart.asm Y main.c. startup.asm OHTSEO DMS FPZP, YuFPVSH VShchFSH KHCHETEOOSCHNY, YuFP KHRTBCHMEOYE RPRBDEF OM ZHKHOLGYA kernel_main. CHEDSH POB NPTSEF VSHCHFSH OE CH OBYUBME ZHBKMB, B UPDETSYNPE startup.o NSCH RPMOPUFSHA LPOFTPMYTHEN Y EUMY KHLBTSE EZP RETCHSHCHN MYOLETKH, FP VKHDEN KHRTBCHMSFSH Y RETCHBUFSHOPZCHNY DBHKHOPZCHNY DBHKHOPCHNY VBHKHPCHNY.

Format Elf Public _Start Extn Kernel_main Seksjon ".Text" kjørbar _start: MOVZX EDX, DL PUSH EDX PUSH ESI PUSH EBX LGDT CALL KERNEL_MAIN @:; CLI; HLT JMP @B Seksjon ".data" Writable GDT: DQ 0 DQ0000 0FFFF gdtr: dw $ - gdt dd gdt

OH CHPF Y RPUMEDOYK OM LPD OM YUYUFPN Assembler :-). AV CHSHCHRPMOSEF RTPUFEKYHA ЪBDББУХ - ХМПЦИФШ Ш УФЭЛ ФТИ БТЗХНЭОФБ DMS ZHKHOLGYY kernel_main H REETEBEFSHEM. rPUME CHPCHTBFB YЪ OEЈ SDTP KHIPDYF CH VEULPOYUOSCHK GYLM. rP UPZMBYEOYA CHSHCHJPCHB ZHKHOLGYK ui RBTBNEFTSCH UMEDHEF RYIBFSH CH UFEL CH PVTBBPN RPTSDLE. fBLCE LFPF LPD YOYGYBMYBGYY ЪBZTHTSBEF OPChPE OBYUEOYE CH GDTR - FERTSH FBVMYGB DEULTYRFPTPCH UEZNEOFPCH OBIPDIFUS CH RTPUFTBOUFCHE SDTB Y DBCE EUMY NSCH PFN POFCHKPYTHEN O I PYYVPL.

b FERTSH UBNPE CHLHUOPE - RTPUFEKEEE SDTP OM INNSTILLINGEN CHCHUPLPZP HTPCHOS:

Typedef struct ( usignert lang lang base; usignert lang lang størrelse; ) BootModuleInfo; void kernel_main(char boot_disk_id, void *memory_map, BootModuleInfo *boot_module_list) ( char *screen_buffer = (void*)0xB8000; char *msg = "Hei verden!"; usignert int i = 24 * 80; while (*msg) ( screen_buffer = *msg; msg++; i++; ) )

bFP SDTP OE DEMBEF OYUEZP PUPVEOOOPZP - RTPUFP CHCHCHPDYF UFTPLH "Hei verden!" OM RPUMEDOAA UFTPYULH FELUFPCHPZP LTBOB. uFTHHLFKHTB PRYUBOOBS CH OBYUBME VKhDEF OHTSOB DMS DPUFKHRB L URYULKH ЪBZTHTSEOOSCHI NPDHMEK.

chBTsOP RPNOYFSH, YuFP OILBLPK UFBODBTFOPK VYVMYPFELY KH OBU OEF - OBN DPUFHROSCH FPMSHLP FE ZHKHOLGYY, LPFPTSHCHE NSCH UDEMBEN UBNY. CHUE printf, strcpy, memcpy Y F. R. RTYDFUS TEBMYЪPCHCHCHBFSH UBNPUFPSFEMSHOP, OE RSCHFBKFEUSH PVTBFYFSHUS LOYN. h UMEDHAEEN CHSHCHRKHULE NSCH ЪБКНЈНУС UPЪDBOYEN OBEZP UPVUFCHEOOPZP TsKHFLP KhTEЪBOOPZP BOBMMPZB libc, YUFPVSH RTPZTBNNYTPCHBFSH VSHMP KHDPVOEEE. FHF OBUYOBEFUS UBNBS YOFETEUOBS YUBUFSH, B RTYOSFSHCHE TEYEOYS PE NOPZPN RPCHMYSAF OM CHUA UFTHLFHTH UYUFENSCH.

uVPTLB SDTB

yURPMOSENSCH ZHBKMSCH UPVYTBAFUS CH DCHB LFBRB - LPNRYMSGYS, B RPFPN MYOLPCHLB. OM RETCHPN LFBR LPNRYMSFPT RTEPVTBKHEF YUIPDOSCHK LPD CH LPNBODSCH RTPGEUUPTB Y UPITBOSEF CHUY LFP CH PVYAELFOSHCHK ZHBKM. LBTSDSCHK NPDHMSH UYUFENSCH UPITBOSEFUS CH PFDEMSHOPN ZHBKME. h LFPN ZHBKME FBL CE UPDETSYFUS YOZHPTNBGYS P ZHKHOLGYSI, PRYUBOOSCHI CH NPDHMY, RPFPNH YЪ PDOPZP ZHBKMB NPTsOP UCHPVPDOP CHSCCHCHBFSH ZHKHOLGYA YЪ DTHZPZP. CHEUSH LPD CH PVAELFOSCHI ZHBKMBI OE RTYCHSBO L LPOLTEFOSHCHN BDTEUBN. OM CHFPTPN LFBR MYOLET UPVYTBEF CHUE PVAELFOSCH ZHBKMSCH CH PDYO VYOBTOSHCHK. rTY LFPN LPD RTYCHSCHCHBEFUS L LPOLTEFOSHN BDTEUBN (EUMY, LPOYUOP, NSCH OE UPVYTBEN DIOBNYUEULY ЪBZTHTSBENKHA VYVMYPFELH), CHNEUFP UUSCHMPL OM ZHKHOLGSOMSSCHAFTEUS OHTUBCH. OBN OHTsOP RPMKHYUFSH OM CHSHCHIPDE PUPVSHCHK DCHPYUOSCHK ZHBKM. ьFP RTPUFP LPD Y DBOOSCH, VEЪ LBLYI-MYVP ЪБЗПМЧЛПЧ (ФП EUФШ ЛФП OE PE І OE ELF). h LBUEUFCHE VBPCHPZP BDTEUB YURPMSH'HEFUS BDTEU 0xFFC00000. DMS HRTPEEOYS LFPPZP NSCH PRYYEN CHUЈ, YuFP OBN OHTSOP CH UREGYBMSHOPN ZHTNBFE ULTYRFB ld:

OUTPUT_FORMAT("binær") ENTRY(_start) SECTIONS ( .text 0xFFC00000: ( *(.text) *(.code) *(.rodata*) ) .data ALIGN(0x1000) : ( *(.data) ) .bss ALIGN(0x1000) : ( *(.bss) ) .empty ALIGN(0x1000) - 1: ( BYTE(0) ) )

ьFPF ULTYRF ZPCHPTYF, YuFP OBY ZHBKM VKhDEF METSBFSH CH RBNSFY OERTETCHCHOSCHN VMPLPN OBUYOBS U BDTEUB 0xFFC00000. h UBNPN OBYUBME VKhDEF YDFY UELGYS LPDB, RPFPN UELGYS skrivebeskyttet DBOOSCHI, ЪBFEN PVSHYUOSHI DBOOSCHI, RPFPN OEYOYYBMYYYTPCHBOOSCHI. Chue UELGYY CHSHTPCHOOESCH OM TBNET UFTBOYGSCH 4 levs (CHDTHZ NSCH RPFPN ЪBIPFYN ЪBEIFYFSH OM HTPCHOE FBVMYGSHCH UFTBOYG LPD PF ЪBRYUY). rPUMEDOEE PRYUBOIE UELGYY.empty OEPVIPDYNP DMS FPZP, YUFPVSH DBTSE OEYOYYYBYMYYPTPCHBOOSCH RETENEOOOSCH ЪBOINBMY NEUFP CH ZHBKME (FBN VHDHF OHMY). CHEDSH OBYUBMSHOSHCHK ЪBZTHYUYL CHSHCHDEMSEF RBNSFSH DMS SDTB THLPCHPDUFCHHSUSH TBNETPN ZHBKMB.

uPVTBFSH CHUY SDTP NPTsOP UMEDHAEYNY LPNBODBNY:

Fasm startup.asm startup.o gcc -c -m32 -ffrittstående -o main.o main.c ld --oformat=binær -melf_i386 -T script.ld -o kernel.bin startup.o main.o

rBTBNEFT GCC -ffrittstående KHLBSCCHBEF ENKH PFLMAYUYFSH CHUE UFBODBTFOSCH VYVMYPFELY. CHEDSH SING RTYCHSBOSCH L LPOLTEFOPK PRETBGYPOOPK UYUFENE, B NSCH RYYEN OPCHHA.

uVPTLB PVTBB DYULB

pVPKDHUSH VE MYYOYI LPNNEOFBTYECH Y RTPUFP RTYCHEDH MYOHLUPCHSHCHK ULTYRF UVPTLY PVTBBB:

Dd if=bin/boot.bios.bin of=bin/boot_sector.bin bs=512 count=1 dd if=bin/boot.bios.bin of=disk/boot.bin bs=1 skip=512 cp bin/kernel .bin disk/kernel.bin bin/make_listfs of=disk.img bs=512 size=2880 boot=bin/boot_sector.bin src=./disk

ifølge RTEDRPMBZBEF, YuFP CHUE ULPNRYMYTPCHBOOSCH ZHBKMSCH METSBF Ch bin Ch FELKHEEN LBFBMPZE, B EEЈ YNEEFUS LBFBMPZ disk, Ch LPFPTPN METSYF boot.cfg UMEDHAEEZP UPDETSBOYS:

# Laster kjerne Lkernel.bin # Boot 32 bit kjerne S32

eUMY CHU CHUY UDEMBMY RTBCHYMSHOP, RPMKHYUEOOOSCHK PVTB NPTsOP ЪBRKHUFYFSH CH LNHMSFPTE YMY DBTSE OM TEBMSHOPN TSEMEYE CHSHCH RPMKHYUFE RPDPVOKHA LBTFYOKH:

ъБЗТХЪУйЛ UYFSHCHCHBEF LPOZHYZKHTTBGYPOOSCHK ZHBKM, ЪБЗТХЦБЭФ SDTP, RETEYPDYF CH ЪBEEYEEЈOOOSCHK TETSYN Y RETETHBY KHRBECH. rPMHYUYCH EZP, OBIYE SDTP CHSHCHCHPDYF RPUMEDOAA UFTPLH OM BLTBO. bFP MYYSH OBYUBMP DPMZPZP RKhFY, NSCH RETEIPDYN L UBNPK YOFETEUOPK YUBUFY TBTBVPFLY. FERTSH CHSHCHRKHULY VKHDHF ZPTBJDP VPMEE RTPUFSHCHN DMS CHPURTYSFYS, VMBZPDBTS YURPMSH'PCHBOYA SJSHLB CHSHCHUPLPZP HTPCHOS, LPFPTSCHK LBL S OBDEAUSH CHUE Y FBL ЪOBAF. eUMY CHCH OE IPFYFE TBVYTBFSHUS U Assembler, NPTSEFE RTPUFP CHOSFSH NPK ZPFPCHSHCHK UBZTHYUYL J startup.asm Y YYNEOSFSH HCE FPMSHLP UPDETSYNPE main.c, RPULPMSHLH CHEUSHПФППИДПФП D P . Ф ЦЈУФЛП ЛБЛИЕ-МИВП РБТББНИФТШ ШДТБ (ЛППНЭ ЖУ У ЛППТБП НППНЭ ЖУ У ЛППТБП Н ПЪЧПМСЭФ RPUFTPIFSH OM UCHPEK VBJE YFP KhZPDOP.

bChFPNBFYBGYS UVPTLY YMY Makefile

ChSCH NPZMY ЪBNEFYFSH, YuFP CHTHYUOKHA OBVYCHBFSH UFPMSHLP LPNBOD DPUFBFPYUOP KhFPNYFEMSHOP. l FPNH CE OE CHUEZDB EUFSH OEPVIPDYNPUFSH RETELPNRYMYTCHBFSH CHUE ZhBKMSCH. OBRTYNET, EUMY startup.asm OE VSHM YЪNEOЈO, NPTsOP OE CHSHCHCHBFSH fasm. UREGYBMSHOP DMS HRTPEEOYS LPNRYMSGY RTYMPTSEOYK VSHMB RTYDKHNBOB HFYMYFB merke, LPFPTBS CHIPDIF CH UFBODSBTFOHA RPUFBCHLH GCC Y MinGW.

mAVPK Makefile UFPYF YЪ OBVPTB RTBCHYM U FBLPK UFTHLFKhTPK:

YNSGEMYYMYZHBKMB: yNSRETCHPZPyUIIPDOPZPzhBKMB yNSchFPTPZPyUIIDDOPZPzhBKMB...lPNBODSCHLPNRYMSGYY

RETCHPE RTBCHYMP, LPFPTPE DPMTSOP VShchFSH CH MAVPN Makefile - GEMS alle. lage UNPFTYF OM ЪBCHYUYNPUFY GEMY all Y LPNRYMYTHEF YI, B ЪBFEN CHSHPRMOSEF LPNBODSCH Y LFK GEMY. dMS LBTSDPK DTHZPK GEMY UOBYUBMB UPVYTBAFUS EЈ ЪBCHYUYNPUFY. rTY LFPN YNS GEMY Y YNS ЪBCHYUINPUFEK NPZHF UPCHRBDBFSH U YNEOBNY TEBMSHOSCHI ZHBKMPCH. h FBLPN UMKHYUBE RETEUVPTLB GEMY RTPYЪPKDF FPMSHLP EUMY YUIPDOYLY VSHMY YЪNEOOSHCH.

eEЈ PDOB GEMSH, LPFPTBS YBUFP YURPMSHЪHEFUS CH Makefile - ren. eЈ ЪБДББУБ ХДБМІФШ CHUE VYOBTOSH ZHBKMSCH, YUFPVSH OBYUBFSH UVPTLH "U YUYUFPZP MYUFB". chPF FBL NPTSEF CHSHCHZMSDEFSH Makefile VHI SDTB:

Alle: startup.o main.o script.ld ld --oformat=binær -melf_i386 -T script.ld -o kernel.bin startup.o main.o startup.o: startup.i386.asm fasm startup.i386.asm startup.o main.o: main.c gcc -c -m32 -ffrittstående -o main.o main.c clean: rm -v *.o kernel.bin

bFPF FELUF OEPVIPDYNP UPITBOIFSH CH ZHBKM U YNEOEN Makefile (VEY TBUYYTEOYS) CH LBFBMPZ U YUIPDOSHNY FELUFBNY SDTB. FERTSH DPUFBFPYUOP CHSHPRMOYFSH LPNBODH lage VEЪ RBTBNEFTPC, OBIPDSUSH CH LFPN LBFBMPZE Y NSCH RPMKHYUN ZHBKM kernel.bin (MYVP UPPVEEOYS PV PYYVLOE, EUMY YUFP-FP RPYMP ).

b CHPF FBL S UPVYTBA ЪBZTHYUYL:

Alle: boot.bios.bin boot.bios.bin: boot.bios.asm fasm boot.bios.asm boot.bios.bin ren: rm -v boot.bios.bin

Th make_listfs:

Alle: kompiler kompiler: make_listfs.c gcc -o make_listfs make_listfs.c ren: rm -f make_listfs make_listfs.exe

OH Y OBLPOEG TBUULBTSH RTP CHSHCHJPCH DTHZYI Makefil YЪ PDOPZP. med DPUFBFPYUOP MEOYCH, YuFPVSH DBTSE ЪBIPDYFSH CH LBFBMPZY U LBTSDSCHN LPNRPEOFPN UYUFENSH, RPFPNH UPЪDBM 1 Makefile, LPFPTSCHK UPVYTBEF UTBH CHUA UYUPENKH. x NEOS EUFSH RBRLB src, CH OEK RPDLBFBMPZY: boot, kernel, make_listfs. h UBNPC src OBIPDFUS CHPF FBLPC Makefil:

All: make -C boot/ make -C kernel/ make -C make_listfs/ clean: make -C boot/ clean make -C kernel/ clean make -C make_listfs clean

FERETSH, OBIPDSUSH LBFBMPZE src S RTPUFP RYYKH make Y RPMHYUBA RPMOPUFSHHA UPVTBOOHA UYUFENKH, B EUMY OBRYUBFSH make clean, FP CHUE DCHPYYUOSCH ZHBKMSCH VHDHF KHDPMSHEOSH YDOPHEMBOOKY YDOPH.

OH Y CH DPCHETYEOYE RPUMEDOYK ULTYRF, LPFPTSCHK CHSHHRPMOSEF RPMOHA LPNRYMSGYA Y UVPTLH CHUEI LPNRPEOFPCH Y PVTBB DYULB. h PDOPN LBFBMPZE U OIN OBDP TBBNEUFYFSH src, RHUFPK LBFBMPZ bin Y LBFBMPZ disk U ZHBKMPN boot.cfg.

#!/bin/sh make -C src cp src/boot/boot.bios.bin bin/ cp src/kernel/kernel.bin bin/ cp src/make_listfs/make_listfs bin/ dd if=bin/boot.bios.bin of=bin/boot_sector.bin bs=512 count=1 dd if=bin/boot.bios.bin of=disk/boot.bin bs=1 skip=512 cp bin/kernel.bin disk/kernel.bin bin/make_listfs of=disk.img bs=512 size=2880 boot=bin/boot_sector.bin src=./disk read -p "Trykk Enter for å fortsette..." dummy

u FBLYN OBVPTPN ULTYRFPCH UVPTLB UYUFENB UFBOPCHYFUS RTEDEMSHOP RTPUFPK, PUPVEOOOP EUMY HYUEUFSH, YuFP RPUMEDOYK ULTYRF NPTsOP ЪBRHULBFSH DCHPKOSHCHN LMYBLPCENO YUEUFSH. TBMYUOSHE LPNBODSCH CHTPDE dd, cp, rm OE UHEEUFCHHAF RPD Windows, RPFPNH EЈ RPMSHЪPCHBFEMSN RTYZPDYFUS RBBLEF MSYS YMY Cygwin. pDOBLP RTPUFBS UVPTLB CHUEI LPNRPEOFPCH VHDEF TBVPFBFSH DBCE EUMY X CHBU EUFSH FPMSHLP GCC Y fasm (make_listfs MEZLP ULPNRYMYTHEFUS Y ЪBRHUFYFUS CHYDE Windows-RTYMPCEOY C).

rTYNEYUBOYE DMS RPMSHЪPCHBFEMEK pu Windows

ld DMS Windows OE UPCHUEN RPMOPGEOOSHCHK - PO OE RPDDETSYCHBEF CHCHCHPD UTBH CH VYOBTOSHCHK ZHBKM, FPMSHLP CH EXE. YURTBCHYFSH LFP NPTsOP UPЪDBCH UOBYUBMB EXE (ld OE PVTBFYF CHOYNBOYE, YuFP VBPCHSHCHE BDTEUB UELGYK OECHPNPTSOSCHE DMS CHEODPCHSHHI VYOBTOILPC), B RPFPN ChSHPN ChShchFCHEYFUSH PSHPN ChShchFCHEYFUSH Push. eUMY CHSH UFPMLOЈFEUSH U FEN, YuFP ld PFLBSCHCHBEFUS UPЪDBCHBFSH ZhBKM kernel.bin, CHPURPMSHKFEUSH CHPF FBLYN Makefile VHI SDTB:

Alle: startup.o main.o script.ld ld -melf_i386 -T script.ld -o kernel.bin startup.o main.o objcopy kernel.bin -O binær oppstart.o: startup.i386.asm fasm startup.i386 .asm oppstart.o main.o: main.c gcc -c -m32 -ffrittstående -o main.o main.c clean: rm -v *.o kernel.bin

ъБПДОП ХВЭТИФЭ УФТПЛХ OUTPUT_FORMAT("binær") Ъ script.ld. FERETSH Y RPD Windows RPMKHYUFUS UPVTBFSH SDTP UYUFENSCH.

ъБЗТХЪЛБ УИУФЭНШЧ OM TEBMSHOPK NBYYOE

rPUME FBLYI KHUREIPCH X OELPFPTSCHI NPTSEF CHP'OILOHFSH TSEMBOE PRTPVPCHBFSH OPCHHA pu OM TEBMSHOPN TSEMEYE. lFP OE RTEDUFBCHMSEF RTPVMEN. u RPNPESHA HxD CH Vinduer PFLTPKFE DYULEFKH YMY ZHMEYLH, CHSHVTBCH CHBTYBOF "pFLTSCHFSH DYUL". rTY PFLTSCHFY ZHMEYLY CHBTsOP PFLTSCHFSH YNEOOOP UBNH ZHMEYLKH, BOE ET TB'DEM. h DTHZPK CHLMBDLE PFLTPKFE disk.img, CHSHCHDEMYFE EZP UPDETSINPE RPMOPUFSHA Y ULPRYTHKFE OB DYUL U EZP UBNPZP OBYUBMB. rPUME LFPPZP NPTsOP OBTSBFSH "uPITBOIFSH" Y DPTsDBFSHUS PLPOYUBOYS ЪBRYUY. CHUE DBOOSCH OM ZHMEYL YMY DYULEF RTY LFPN VHDHF HOYUFPTSEOSHCH, B DMS FPZP, YUFPVSH EЈ YURPMSHЪPCHBFSH UOPCHB RP OBYUEOYA, EЈ RTYDFUS ЪБОПBHTFПPFYTPFCH!

rPMSHЪPCHBFEMY Linux NPZHF RPUFKHRYFSH RTPEE - CHSHRPMOYFSH UREGYBMSHOHA LPNBODH CH FETNYOBME. DMS DYULEFSH:

Dd if=disk.img av=/dev/fd0

DMS ZHMEYLY:

Dd if=disk.img av=/dev/sdX

chNEUFP sdX OBDP RPDUFBCHYFSH OBUFPSEEE YNS KHUFTPKUFCHB (sda, sdb, sdc, sdd Y F. D.). ZMBCHOPE RTY LFPN OE RETERKHFBFSH Y OE ЪBRYUBFSH PVTB OM UYUFENOSHCHK DYUL, HOYUFPTSYCH CHUE DBOOSCH. TBHNEEFUS, PVE LPNBODSCH DPMTSOSCHCHSHCHRPMOSFSHUS PF YNEOY rot YMY Y RPNPESH sudo.

rPUME LFPPZP OBDP OBUFTPIFSH CH BIOS ЪБЗТХЛХ У ДУЛЭФШЧ ІМИ ЖМИЛХ (UFBTSHCHE BIOS OE RPDDETSYCHBAF ZHMEYDPNFSHUS CHMBYDDBFSHUS CHMBYDDBFSHUS CHMBYDDBFSHUS CHEMBYDDBNFSH).

ъBLMAYUEOOYE

OH CHPF UPVUFCHOOOP Y CHUЈ OM UEZPDOS. nsch OBLPOEG-FP ЪBLPOYUMY RTPZTBNNNYTPCHBOYE OB Assembler (IPFS CH u CHU TBCHOP RTYDFUS YOPZDB DEMBFSH BUUENVMETOSCHE CHUFBCHLY DMS TBVPFSHCH U PVPPTKhDPCHBOYEN) Y RETEYSCHPSCHMY CH. eEЈ PYUEOSH NOPZP RTEDUFPYF UDEMBFSH. NSC NPTSEFE HCE RTPCHPDYFSH TBMYUOSCH LURETYNEOFSH, YЪNEOSS NPK main.c, FPMSHLP KHYUFYFE, YuFP MAVBS PYYVLB (DPUFHR L OEURTPEGYTPCHBOOPC RBNSFY, DEMEOYE OM LBЪZTE REMSHY) ЪBCHYUBOYA UYUFENSCH (NSCH RPLB OE PVTBVBFSCHBEN YULMAYUEOYS, RPFPNH RTPGEUUPT OE NPTSEF RTDPDPMTSYFSH TBVPFH RPUME PYYVLY). dP CHUFTEYUY!

MAvsche CHPRPTUSCH CHSC NPTSEFE ЪBDBFSH OM NPK BDTEU: [e-postbeskyttet]. y DB, UEKYUBU UBNPE CHTENS DMS TBMYUOSHI YDEK RP LPOGERGYY PU Y RTEDMPTSEOYK.

Boken «Operativsystemet fra 0 til 1» er publisert på GitHub og har over 2000 stjerner og 100 gafler. Som tittelen antyder, etter å ha lest den, kan du lage ditt eget operativsystem - og kanskje er det få ting i verden av programmerere som kan være kulere.

Med denne boken lærer du følgende:

  • Du vil lære hvordan du lager et operativsystem basert på maskinvareteknisk dokumentasjon. Slik fungerer det i den virkelige verden, du vil ikke kunne bruke Google for raske svar.
  • Du vil forstå hvordan datakomponenter samhandler med hverandre, fra programvare til maskinvare.
  • Lær å skrive kode selv. Å kopiere kode blindt er ikke læring, du vil faktisk lære hvordan du løser problemer. Blindkopiering er forresten også farlig.
  • Mestre de kjente verktøyene for utvikling på lavt nivå.
  • Bli kjent med assemblerspråk.
  • Finn ut hvilke programmer som er laget av og hvordan operativsystemet kjører dem. Vi ga en kort oversikt over dette emnet for de nysgjerrige i .
  • Du vil finne ut hvordan du feilsøker et program direkte på maskinvare med GDB og QEMU.
  • Programmeringsspråket C. Du kan raskt mestre det ved å følge.
  • Grunnleggende kunnskap om Linux. Bare studer på nettsiden vår.
  • Grunnleggende kunnskaper i fysikk: atomer, elektroner, protoner, nøytroner, spenning.

Forkortelsen «NT» står for «New Technologies» i markedsføring, men i prosjektdokumentasjonen betydde det noe helt annet. Faktum er at Windows NT ble utviklet for den nye Intel i860-prosessoren, som ennå ikke var utgitt i 1988. Kodenavnet var "N10" ( N T no).

Den første versjonen, Windows NT 3.1, ble utgitt 5 år senere, i 1993. På dette tidspunktet hadde teamet allerede 250 utviklere.

Windows i dag

  • 1 milliard brukere
  • 140 millioner linjer med kode (inkludert testkode og instrumentering)
    Windows-koden er veldig forskjellig. Noen deler ble skrevet for 20 år siden, noen dukket bare opp i den nåværende versjonen. For eksempel eksisterer WSD-koden (Web Services on Devices) i Windows Vista i sin første versjon, GDI-koden er i sluttfasen av utviklingen og forblir nesten uendret, DirectX-koden er allerede godt utviklet, men endres aktivt kl. nåtiden.
  • 8000 utviklere
  • 36 lokaliseringsspråk
  • 20 år med utvikling

Windows utvikling

For 20-30 år siden ble det kun brukt én programmeringsmetodikk, «Waterfall». Det er en sekvens:

Spesifikasjoner → Design → Implementering → Testing → Levering.

Men denne metodikken fungerer bare for små prosjekter. For et produkt som Windows i dag, trengs forskjellige metoder:

  • Produktsyklusmodell
  • Programvareprosess for team
  • "Ekstrem programmering"

Alle disse metodene har både fordeler og ulemper. Avhengig av størrelsen på teamet og utviklingsstadiet til komponenten, bruker forskjellige Windows-utviklingsteam forskjellige utviklingsmetoder.
For Windows, som et produkt som helhet, brukes produktsyklusmodellen:

  • Perioder på 3-4 måneder
  • Inne i perioden - "foss"

Den største utfordringen med å utvikle et produkt i denne skalaen er at utvikling tar tid. I den innledende fasen løses de problemene som eksisterer i den nåværende tiden og ved bruk av eksisterende midler. Men det eneste som er konstant er at alt vil endre seg. Gjennom årene med utvikling:

  • Kravene vil endres
  • Mulighetene vil endre seg
  • Arbeidsplanen vil endres
  • Prosjektet vil endre seg
  • Brukerne vil endre seg

Til tross for at forskjellige lag utvikler seg forskjellig, er det "universelle" regler:

  • Utgivelse av mellomversjoner (milepæler, beta, CTP) for massene av testere
  • Frigjøring av interne sammenstillinger med korte sykluser (1 dag)
  • Enkelhet og pålitelighet av design
  • Personlige og teamkodegjennomganger
  • Enhetstester
  • Byggverifiseringstester
  • Enhver mellommontering må være av høy kvalitet (det som er skrevet må fungere)

Jeg vil på egen hånd legge merke til at etter en måneds arbeid med Windows 7 build 6801 som hovedoperativsystemet på hjemmedatamaskinen min, fikk jeg et positivt inntrykk av denne builden.

Hele Windows-utviklingsprosessen er bygget rundt den daglige byggingen:

  • Dette er pulsen til produktet
  • Utviklingen stopper aldri
  • Daglig automatisk testing
  • Integrasjon på et tidlig stadium
  • Utvikleransvar
  • Produktets åpenbare tilstand

En gang i tiden var det bare én kildekodegren, og alle utviklere gjorde endringer direkte i den. Nå er utviklingsteamet så stort at det ikke fungerer. Mange grener støttes, blant dem er den viktigste - WinMain. Hvert laboratorium har sin egen lokale utviklingsgren som endringer integreres i. Testede endringer blir etter hvert integrert i WinMain.

Daglig utviklingssyklus:

  • 15:00 - Endringer godkjent for integrering i kildekodekontrollsystemet
  • Bygg 6 versjoner (gratis/sjekket - x86, x64, IA64)
  • 18:00 - Nye versjoner er tilgjengelige for testing
  • Den nye versjonen er installert på flere tusen arbeidsstasjoner og servere for testing
  • Automatisert stresstest
  • 05:00 - Testrapporter analyseres, feil diagnostiseres
  • 09:00 - Oppsummeringsrapporter sendes automatisk til lag
  • 09:30 - Konsolidert møte med teamledere for å sette mål

Alle prosjektdeltakere, inkludert de øverste lederne, bruker mellomversjoner på arbeids- (og vanligvis hjemme) datamaskiner.

Hva er Windows skrevet i?

  • C, C++, C#, Assembly (x86, x64, IA64)
    Assembler brukes i ganske begrenset grad i situasjoner der de ikke kan unngås.
  • Visual Studio, Source Insight, build, nmake
  • Kildedepot - kildekontrollsystem
  • WinDbg, KD, NTSD - feilsøkere

Mange interne verktøy, for eksempel build, kan lastes ned fra microsoft.com/whdc/devtools.

Windows 7 kjerneendringer

Windows 7-kjernen har gjennomgått følgende endringer:

  • Refaktorering
    Hvorfor kan jeg ikke fjerne grafikkundersystemet i Windows?
    Svaret på dette spørsmålet fra et teknisk synspunkt er at grafikkundersystemet i Windows ikke er uavhengig, det er en del av Win32-undersystemet.
    Windows 7 har refaktorisert mange komponenter på lavt nivå for å bryte opp avhengigheter. Dette vil ikke være merkbart for brukerne, bare nye Dll-er vil vises, for eksempel ble kernel32.dll delt opp i kernel32.dll og kernelbase.dll.
    Denne partisjoneringen gjorde det mulig å tildele en minimal kjerne kalt MinWin (20 megabyte på disk).
  • EFI-støtte for x86 og x64 (samme som Vista SP1)
    Mange produsenter prøver å bli kvitt BIOS til fordel for EFI.
  • Oppstart fra VHD (virtuell harddisk)
  • Parallell initialisering av enheter og start av tjenester
    Når Windows starter opp, tar det ganske lang tid å bygge enhetstreet. PNP-administratoren må spørre bussdrivere (PCI, USB, FireWire, etc.) for å se hvilke enheter de har. Og mesteparten av tiden venter prosessoren på at enhetene skal svare (eller ikke). Tross alt, for å identifisere enheter på bussen, må du spørre dem. Hvis de er det, vil de svare, og hvis ikke, må du vente og prosessoren er inaktiv. Å kjøre disse oppgavene parallelt reduserer lastetidene.
  • Fjerner Dispatcher-låsen fra planleggeren og PFN-låsen fra minnebehandlingen
    I løpet av de siste årene har ikke prosessorens klokkefrekvenser økt, og utviklingen har gått mot en økning i antall parallelt utførte instruksjoner både på enkeltkjernenivå og på systemnivå (flerkjerne). I denne forbindelse har det blitt gjort mye arbeid for å forbedre skaleringen.
    De to "hotteste" låsene som var i kjernen, Dispatcher-låsen og PFN-låsen, ble fjernet.
    Dispatcher-lås ble brukt av planleggeren når tilstanden til trådene endret seg. Denne låsen ble fjernet, og trådtilstanden "venter" ble delt opp i flere:
    • Venter: Pågår
    • Venter: Fullført
    • Venter: Kansellert
    PFN-lås ble brukt når du endret attributtene til fysiske minnesider. I et multiprosessorsystem ba hver prosessor om tilgang til denne låsen, noe som førte til mye tid.
  • Støtter 256 logiske prosessorer
    Tidligere, i Windows, ble maskinordet brukt som affinitetsmaske. Dette ble gjort fordi det var enkelt å finne ledige prosessorer – hver bit representerer en prosessor. Følgelig støttet et 32-bitssystem 32 logiske prosessorer, og et 64-bitssystem støttet 64.
    I Windows 7, som et resultat av overgangen til affinitetsmaskesegmentmodellen, ble støtte for 256 logiske prosessorer mulig. Prosessorer begynte å bli gruppert i grupper/segmenter. Hver gruppe kan inneholde opptil 64 prosessorer. Resultatet er bakoverkompatibilitet, gamle programmer «ser» kun prosessorer i én gruppe, og nye programmer som bruker nye grensesnitt fungerer med alle prosessorer i systemet.
  • Forbedret strømsparing: deaktivering av prosessorsokler I dag står ikke bare eiere av bærbare datamaskiner, men også eiere av datasenter overfor et alvorlig problem med energisparing. I USA forbrukes 2 % av elektrisiteten av datasentre. Mange av dem slår av deler av serverne sine i perioder med lav brukeraktivitet (helger).
    Det ble funnet at det er mye mer lønnsomt å deaktivere hele prosessorsokkelen enn én kjerne på flere, fordi i dette tilfellet kan du deaktivere hele socket-støtteinfrastrukturen (minnekontrolleren).

Windows vedlikehold, oppdateringer

Tidligere var oppdateringer ofte kumulative. Dette betydde at hvis buggykoden var inneholdt i en tidlig oppdatering av en komponent, ville senere versjoner også inneholde den koden. Men ikke alle brukere trenger alle oppdateringer, de har forskjellige konfigurasjoner.

Det er nå 2 versjoner av kildekoden etter utgivelse (RTM) på Windows:

  • RTM GDR (General Distribution Release)
    Inkluderer de få endringene som er ment for alle. Hovedsakelig sikkerhetsfikser.
  • RTM LDR (Limited Distribution Release)
    Når du installerer en oppdatering, velger Windows Update-klienten grenen den trenger og installerer koden fra den.

Opprette en sikkerhetsoppdatering

Arbeidet med å lage en sikkerhetsoppdatering begynner med å identifisere en sårbarhet. Det finnes massevis av forskjellige deteksjonsmetoder - interne sikkerhetsteam, sikkerhetspartnere, utviklere. Når en sårbarhet oppdages, starter to parallelle prosesser:

  • Utvikler en løsning for alle plattformer
  • Søk etter "alternativer"
    Storskala søk etter lignende sårbarheter på alle plattformer. Søk ikke etter identisk kode, men etter lignende.

Når en rettelse er utviklet, begynner kodegjennomganger. Når de er fullført, blir reparasjonen integrert i bygget og bygget sendes for testing:

  • Manuell og automatisk testing av komponenter
  • Automatisk testing av filformatforvrengninger, nettverkskomponenter, etc. (mer enn en million alternativer)
  • Testing av systemet som helhet, inkludert bakoverkompatibilitetstesting

Bare rettelser som oppfyller alle kvalitetskriterier er tillatt å bli utgitt på Windows Update and Download Center.

  • Videresend >

WikiHow fungerer som en wiki, noe som betyr at mange av artiklene våre er skrevet av flere forfattere. Under opprettelsen av denne artikkelen jobbet 90 personer, inkludert anonymt, med å redigere og forbedre den.

Operativsystemer, sammensatt av hundretusenvis av linjer med kode, lar brukere samhandle med maskinvare. De er vanligvis skrevet på programmeringsspråkene C, C++ og assembly.

Trinn

    Først, lær deg programmering. Kunnskap om montør er nødvendig; Det anbefales også sterkt å ha forståelse for andre programmeringsspråk på lavere nivå, for eksempel C.

    Bestem hvilken enhet du vil laste operativsystemet på. Dette kan være en CD, DVD, flashminneenhet, harddisk eller en annen datamaskin.

    Bestem hvordan du vil at operativsystemet ditt skal se ut. Skal det være et komplett OS med et grafisk brukergrensesnitt (GUI) eller kanskje noe mer minimalistisk? Du må vite hvilken retning du skal gå i før du starter prosessen.

    Sjekk hvilken prosessorplattform operativsystemet ditt støtter. AI-32 og x86_64 er de to vanligste versjonene for personlige datamaskiner, så de kan betraktes som det beste valget.

    Bestem om du foretrekker å gjøre alt selv fra bunnen av, eller om det er kjerner som du ønsker å bygge på systemet på grunnlag av. Linux fra grunnen av er et prosjekt for de som for eksempel ønsker å lage sin egen Linux-distribusjon.

    Velg om du skal bruke din egen bootloader eller den forhåndsbygde Grand Unified Bootloader (GRUB). Fordi koding av ditt eget oppstartsprogram krever omfattende kunnskap om maskinvare og BIOS, kan det presse programmeringsplanen for live-kjernen tilbake.

    Ta en avgjørelse om programmeringsspråket du skal bruke. Selvfølgelig er det fullt mulig å utvikle et OS på et språk som Pascal eller BASIC, men det er å foretrekke å skrive det på C eller assembly-språk. Monteringsspråk er helt nødvendig, siden noen viktige deler av operativsystemet krever kunnskap om dette spesielle språket. C++, derimot, inneholder nøkkelordene som kreves for å kjøre den fullstendige versjonen av operativsystemet.

    • For å bygge et OS ved hjelp av C- eller C++-kode, vil du selvfølgelig bruke en eller annen kompilator. Dette betyr at du må lese manualen/instruksjonene/dokumentasjonen for den valgte C/C++ kompilatoren som følger med programvaren eller er tilgjengelig på distributørens nettside. Du må lære mange komplekse ting om kompilatoren, og du må også lære designen og ABI for å forbedre C++. Du forventes å forstå de ulike formatene for utførelsesoppgaver (ELF, PE, COFF, vanlig binær, etc.) og vil merke seg at det opprinnelige Windows PE-formatet (.exe) er beskyttet av opphavsrett.
  1. Velg Application Programming Interface (API). Et utvalg av gode APIer er POSIX, da det er godt dokumentert. Alle Unix-systemer har i det minste delvis støtte for POSIX, så det ville være trivielt å pakke Unix-programmer inn i operativsystemet ditt.

    Bestem deg for et design. Det er monolittiske kjerner og mikrokjerner. Monolittiske kjerner kjører alle tjenestene i kjernen, mens mikrokjerner har en liten kjerne kombinert med en tilpasset implementering av tjenester. Generelt er monolittiske kjerner raskere, men mikrokjerner har bedre isolasjon og beskyttelse mot mulige feil.

    Vurder utvikling og teamarbeid. På denne måten vil du bruke mindre tid på å løse store problemer, slik at du kan lage et bedre operativsystem på kortere tid.

    Ikke tørk harddisken helt. Husk at formatering av disken vil slette alle dataene dine permanent! Bruk GRUB eller en annen leder for å duplisere oppstart av datamaskinen fra et annet OS til versjonen din er fullt funksjonell klar.

    Begynn i det små. Vær først oppmerksom på de små tingene, som tekstvisning og avbrudd, før du går videre til komplekse elementer som minnehåndtering og multitasking.

    Ta vare på en sikkerhetskopi av den siste fungerende versjonen. Dette gir en viss trygghet i tilfelle noe går helt galt med den gjeldende versjonen av operativsystemet ditt eller påfølgende tillegg. Hvis datamaskinen din går i stykker og ikke kan starte opp, som du selv forstår, vil det være en utmerket mulighet å ha en ekstra kopi å jobbe med, slik at du kan fikse de eksisterende problemene.

    Test ditt nye operativsystem på en virtuell maskin. I stedet for å starte datamaskinen på nytt hver gang du gjør endringer eller overfører filer fra produksjonsdatamaskinen til testmaskinen, kan du bruke en applikasjon til å kjøre operativsystemet i en virtuell maskin mens det nåværende operativsystemet fortsetter å kjøre. VM-applikasjoner inkluderer VMWare (som også har en fritt tilgjengelig server), alternativ åpen kildekode, Bochs, Microsoft Virtual PC (ikke kompatibel med Linux) og XVM VirtualBox.

    Slipp en utgivelsesversjon. Dette vil tillate brukere å fortelle deg om mulige feil i operativsystemet ditt.

  2. Operativsystemet skal også være brukervennlig, så sørg for å legge til nyttige funksjoner som blir en integrert del av designet ditt.

    • Når utviklingen er fullført, bør du vurdere om du vil gjøre koden offentlig tilgjengelig eller gjøre den privat.
    • Sørg for å gjøre sikkerhetsfunksjoner til din høyeste prioritet hvis du vil at systemet skal være levedyktig.
    • Ikke start et med mål om å lære å programmere. Hvis du ikke kan C, C++, Pascal eller noen av de andre relevante språkene og funksjonene, inkludert pekertyper, lavnivåbitoperasjoner, bitbytte, inline assembler osv., så er du ikke klar ennå å lage OS.
    • Bla gjennom portaler som OSDev og OSDever for å hjelpe deg med å forbedre ditt eget operativsystem. Vær spesielt oppmerksom på at for de fleste problemer, foretrekker OSDev.org-fellesskapet at du konsulterer innholdet på nettstedet selv i stedet for å bli med i et forum. Hvis du likevel bestemmer deg for å melde deg inn i rekken av forummedlemmene, må det være visse forutsetninger for dette. Du må ha grundig kjennskap til C eller C++ og x86 assemblerspråk. Du bør også forstå generelle og komplekse konsepter innen programmering som lenkede lister, køer, etc. OSDev-fellesskapet sier eksplisitt i sine regler at ingen kommer til å passe nye programmerere. Hvis du prøver å utvikle et OS, sier det seg selv at du er en programmeringsgud. Du må også lese prosessorhåndboken for prosessorarkitekturen du velger; for eksempel x86 (Intel), ARM, MIPS, PPC, etc. En slik oppslagsbok om prosessorstrukturen kan enkelt finnes ved å søke på Google ("Intel Manuals", "ARM manuals", etc.). Ikke bli med på OSDev.org-forumet for å stille åpenbare spørsmål. Dette vil ganske enkelt resultere i svar som "Les den jævla manualen." Først bør du prøve å lese Wikipedia, manualer for de ulike verktøyene du skal bruke.
    • Se etter potensielle dødpunkter og andre feil. Huller, blindveier og andre problemer kan påvirke utformingen av operativsystemet.
    • Hvis du vil ha en enklere metode, tenk på Linux-distribusjoner som Fedora Revisor, Custom Nimble X, Puppy Remaster, PCLinuxOS mklivecd eller SUSE Studio og SUSE KIWI. OS-et som opprettes tilhører imidlertid selskapet som først introduserte denne tjenesten (selv om du har rettighetene til fritt å distribuere, endre og kjøre det som du vil under GPL).
    • En god løsning vil være å lage en helt ny partisjon for operativsystemet som utvikles.

    Advarsler

    • Uforsiktig kopiering av operativsystemet til harddisken kan skade den fullstendig. vær forsiktig
    • Du vil ikke ha et helt ferdig system på to uker. Start med et oppstartbart operativsystem og gå deretter videre til mer interessante ting.
    • Hvis du gjør noe hensynsløst som å skrive tilfeldige bytes til tilfeldige I/O-porter, vil du ødelegge operativsystemet ditt og kan (i teorien) steke maskinvaren din.
    • Ikke forvent at det skal være enkelt å bygge et kvalitetsoperativsystem. Det er mange komplekse gjensidige avhengigheter. For eksempel, for at OS skal være i stand til å håndtere flere prosessorer, må minnebehandleren din ha "låse"-mekanismer for å hindre ekstra prosessorer fra å få tilgang til den samme ressursen samtidig. "Blokkene" som brukes involverer en planlegger for å sikre at bare én prosessor har tilgang til en kritisk ressurs til enhver tid, mens alle andre er inaktive. Driften av planleggeren avhenger imidlertid av tilstedeværelsen av minnebehandleren. Dette er et eksempel på fastlåst avhengighet. Det er ingen standard måte å løse problemer som dette på; Hver operativsystemskaper forventes å være dyktig nok til å komme opp med sin egen løsning.

Veiledning for å lage en kjerne for et x86-system. Del 1. Bare kjernen

La oss skrive en enkel kjerne som kan startes opp ved hjelp av GRUB-oppstartslasteren på et x86-system. Denne kjernen vil vise en melding på skjermen og vente.

Hvordan starter et x86-system?

Før vi begynner å skrive kjernen, la oss forstå hvordan systemet starter opp og overfører kontroll til kjernen.

De fleste prosessorregistre inneholder allerede visse verdier ved oppstart. Registeret som peker til instruksjonsadressen (Instruction Pointer, EIP) lagrer minneadressen der instruksjonen utført av prosessoren ligger. Standard EIP er 0xFFFFFFFF0. Dermed begynner x86-prosessorer på maskinvarenivå å jobbe på adressen 0xFFFFFFF0. Dette er faktisk de siste 16 bytene av 32-biters adresserom. Denne adressen kalles tilbakestillingsvektoren.

Nå sikrer brikkesettets minnekart at 0xFFFFFFF0 tilhører en bestemt del av BIOS, ikke RAM. På dette tidspunktet kopierer BIOS seg selv til RAM for raskere tilgang. Adresse 0xFFFFFFF0 vil kun inneholde en instruksjon om å hoppe til adressen i minnet der en kopi av BIOS er lagret.

Dette er hvordan BIOS-koden begynner å kjøre. BIOS ser først etter en enhet som kan starte opp fra, i en forhåndsinnstilt rekkefølge. Det søkes etter et magisk tall for å avgjøre om enheten er oppstartbar (511. og 512. byte i den første sektoren må være lik 0xAA55).

Når BIOS finner en oppstartsenhet, kopierer den innholdet i den første sektoren av enheten til RAM, med start på den fysiske adressen 0x7c00; går deretter til adressen og kjører den nedlastede koden. Denne koden kalles bootloader.

Oppstartslasteren laster inn kjernen på en fysisk adresse 0x100000. Denne adressen brukes som startadresse i alle store kjerner på x86-systemer.

Alle x86-prosessorer starter i en enkel 16-bits modus kalt ekte modus. GRUB bootloader bytter modus til 32-bit beskyttet modus, setter den lave biten av register CR0 til 1 . Dermed blir kjernen lastet i 32-bits beskyttet modus.

Merk at når det gjelder Linux-kjernen, ser GRUB Linux-oppstartsprotokollene og starter opp kjernen i ekte modus. Kjernen bytter automatisk til beskyttet modus.

Hva trenger vi?

  • x86 datamaskin;
  • Linux;
  • ld (GNU Linker);

Innstilling av inngangspunkt i assembler

Uansett hvor mye du ønsker å begrense deg til C alene, må du skrive noe i assembler. Vi vil skrive en liten fil på den som vil tjene som utgangspunkt for kjernen vår. Alt det vil gjøre er å kalle en ekstern funksjon skrevet i C og stoppe programflyten.

Hvordan kan vi forsikre oss om at denne koden er utgangspunktet?

Vi vil bruke et linkerskript som kobler objektfiler for å lage den endelige kjørbare filen. I dette skriptet vil vi eksplisitt indikere at vi ønsker å laste data på adressen 0x100000.

Her er assembler-koden:

;;kernel.asm bits 32 ;nasm direktiv - 32 bit seksjon .text global start ekstern kmain ;kmain er definert i c-filstart: cli ;block interrupts mov esp, stack_space ;set stack pointer call kmain hlt ;stopp CPU delen .bss resb 8192 ;8KB for stack stack_space:

Den første instruksjonen, bits 32, er ikke en x86-monteringsinstruksjon. Dette er et direktiv til NASM assembler som spesifiserer kodegenerering for en prosessor som opererer i 32-bits modus. I vårt tilfelle er dette ikke nødvendig, men generelt nyttig.

Seksjonen med koden begynner på den andre linjen.

global er et annet NASM-direktiv som gjør kildekodesymboler globale. På denne måten vet linkeren hvor startsymbolet er - vårt inngangspunkt.

kmain er en funksjon som vil bli definert i kernel.c-filen. ekstern betyr at funksjonen er deklarert et annet sted.

Deretter kommer startfunksjonen, som kaller opp kmain-funksjonen og stopper prosessoren med hlt-instruksjonen. Dette er grunnen til at vi deaktiverer avbrudd på forhånd ved å bruke cli-instruksjonen.

Ideelt sett må vi allokere noe minne og peke på det med en stabelpeker (esp). Det ser imidlertid ut til at GRUB allerede har gjort dette for oss. Du vil imidlertid fortsatt tildele litt plass i BSS-delen og flytte stabelpekeren til begynnelsen. Vi bruker resb-instruksjonen, som reserverer det angitte antallet byte. Umiddelbart før du kaller kmain, settes stabelpekeren (esp) til riktig plassering med mov-instruksjonen.

Kjernen i C

I kernel.asm gjorde vi et kall til funksjonen kmain(). Dermed bør "C"-koden vår starte kjøringen med kmain() :

/* * kernel.c */ void kmain(void) ( const char *str = "min første kjerne"; char *vidptr = (char*)0xb8000; //video mem begynner her. usignert int i = 0; usignert int j = 0; /* denne løkker tømmer skjermen * det er 25 linjer hver av 80 kolonner; hvert element tar 2 byte */ while(j< 80 * 25 * 2) { /* blank character */ vidptr[j] = " "; /* attribute-byte - light grey on black screen */ vidptr = 0x07; j = j + 2; } j = 0; /* this loop writes the string to video memory */ while(str[j] != "\0") { /* the character"s ascii */ vidptr[i] = str[j]; /* attribute-byte: give character black bg and light grey fg */ vidptr = 0x07; ++j; i = i + 2; } return; }

Alt vår kjerne vil gjøre er å tømme skjermen og vise linjen "min første kjerne".

Først lager vi en vidptr-peker som peker til adressen 0xb8000. I beskyttet modus starter "videominne" fra denne adressen. For å vise tekst på skjermen reserverer vi 25 linjer med 80 ASCII-tegn, fra 0xb8000.

Hvert tegn vises ikke med de vanlige 8 bitene, men med 16. Den første byten lagrer selve tegnet, og den andre - attributt-byte . Den beskriver formateringen av tegnet, for eksempel fargen.

For å vise de grønne tegnene på en svart bakgrunn, skriver vi dette tegnet i den første byten og verdien 0x02 i den andre. 0 betyr svart bakgrunn, 2 betyr grønn tekstfarge.

Her er fargekartet:

0 - svart, 1 - blå, 2 - grønn, 3 - cyan, 4 - rød, 5 - magenta, 6 - brun, 7 - lysegrå, 8 - mørk grå, 9 - lys blå, 10/a - lys grønn, 11/b - Lys Cyan, 12/c - Lys Rød, 13/d - Lys Magenta, 14/e - Lys Brun, 15/f - Hvit.

I kjernen vår vil vi bruke lys grå tekst på svart bakgrunn, så vår attributtbyte vil ha verdien 0x07.

I den første sløyfen skriver programmet ut et tomt symbol over hele 80x25-sonen. Dette vil tømme skjermen. I neste syklus blir tegn fra den nullterminerte strengen "min første kjerne" med en attributtbyte lik 0x07 skrevet til "videominne". Dette vil skrive ut strengen til skjermen.

Koblingsdel

Vi må sette sammen kernel.asm til en objektfil ved hjelp av NASM; bruk deretter GCC til å kompilere kernel.c til en annen objektfil. De må da kobles til den kjørbare oppstartskjernen.

For å gjøre dette vil vi bruke et bindende skript, som sendes til ld som et argument.

/* * link.ld */ OUTPUT_FORMAT(elf32-i386) ENTRY(start) SECTIONS ( . = 0x100000; .text: ( *(.text) ) .data: ( *(.data) ) .bss: ( *( .bss) ) )

Først vil vi spørre Utgående format som 32-biters kjørbart og koblingsbart format (ELF). ELF er et standard binært filformat for Unix x86-systemer. INNGANG tar ett argument som spesifiserer navnet på symbolet som er inngangspunktet. SEKSJONER– dette er den viktigste delen. Den definerer markeringen av vår kjørbare fil. Vi bestemmer hvordan de ulike seksjonene skal kobles sammen og hvor de skal plasseres.

I parentes etter SECTIONS viser prikken (.) posisjonstelleren, som er standard på 0x0. Det kan endres, og det er det vi gjør.

La oss se på følgende linje: .text: ( *(.text) ) . Stjernen (*) er et spesialtegn som samsvarer med et hvilket som helst filnavn. Uttrykket *(.text) betyr alle .text-seksjoner fra alle inndatafiler.

Dermed kobler linkeren sammen alle kodedelene av objektfilene til én del av den kjørbare filen på adressen i posisjonstelleren (0x100000). Etter dette vil tellerverdien være lik 0x100000 + størrelsen på den resulterende delen.

Det samme skjer med andre seksjoner.

Grub og Multiboot

Nå er alle filene klare for å lage kjernen. Men det er ett skritt igjen.

Det er en standard for lasting av x86-kjerner ved å bruke en bootloader kalt Multiboot-spesifikasjon. GRUB vil bare starte opp kjernen vår hvis den oppfyller disse spesifikasjonene.

Etter dem skal kjernen inneholde en overskrift i de første 8 kilobytene. I tillegg må denne overskriften inneholde 3 felt, som er 4 byte:

  • magisk felt: inneholder magisk tall 0x1BADB002 for å identifisere kjernen.
  • felt flagg: vi trenger det ikke, la oss sette det til null.
  • felt sjekksum: hvis du legger den til med de to foregående, bør du få null.

Vår kernel.asm vil se slik ut:

;;kernel.asm ;nasm-direktiv - 32 bits biter 32 seksjon .tekst ;multiboot spec align 4 dd 0x1BADB002 ;magic dd 0x00 ;flagg dd - (0x1BADB002 + 0x00) ;sjekksum. m+f+c skal være null global start ekstern kmain ;kmain er definert i c-filstarten: cli ;block interrupts mov esp, stack_space ;set stack pointer call kmain hlt ;stopp CPU-delen .bss resb 8192 ;8KB for stack stack_space:

Bygger kjernen

Nå skal vi lage objektfiler fra kernel.asm og kernel.c og koble dem ved hjelp av skriptet vårt.

Nasm -f elf32 kernel.asm -o kasm.o

Denne linjen vil kjøre assembleren for å lage objektfilen kasm.o i ELF-32-format.

Gcc -m32 -c kernel.c -o kc.o

Alternativet "-c" sikrer at ingen skjult kobling oppstår etter kompilering.

Ld -m elf_i386 -T link.ld -o kjerne kasm.o kc.o

Dette vil kjøre linkeren med skriptet vårt og lage en kjørbar kalt kjerne.

Sette opp grub og starte kjernen

GRUB krever kjernenavnet for å tilfredsstille mønsterkjerne- . Så gi nytt navn til kjernen. Jeg kalte min kjerne-701.

Legg den nå i katalogen /støvel. For å gjøre dette trenger du superbrukerrettigheter.

I GRUB-konfigurasjonsfilen grub.cfg legger du til følgende:

Tittel myKernel root (hd0,0) kjerne /boot/kernel-701 ro

Ikke glem å fjerne hiddenmenu-direktivet hvis det finnes.

Start datamaskinen på nytt og du vil se en liste over kjerner inkludert dine. Velg den og du vil se:

Dette er kjernen din! La oss legge til et input/output system.

P.S.

  • For alle kjernetriks er det bedre å bruke en virtuell maskin.
  • For å kjøre kjernen inn grub2 konfigurasjonen skal se slik ut: menyoppføring "kernel 7001" (sett root="hd0,msdos1" multiboot /boot/kernel-7001 ro )
  • hvis du vil bruke qemu-emulatoren, bruk: qemu-system-i386 -kernel kjerne