├── .CodeCounter ├── details.md ├── results.md └── results.txt ├── .DS_Store ├── .vscode └── settings.json ├── CMakeLists.txt ├── Dockerfile ├── FreeFlyOS.img ├── LICENSE ├── boot ├── CMakeLists.txt ├── boot.ld ├── bootmain.c ├── bootsector.S ├── readme.assets │ ├── image-20201230095709041.png │ ├── image-20201230214125113.png │ ├── image-20201231091731488.png │ ├── image-20201231092306216.png │ ├── image-20201231095526365.png │ └── image-20201231095811107.png ├── readme.md └── sign.c ├── cmake ├── linux_x86_toolchain.cmake ├── mac_x86_toolchain.cmake ├── readme.assets │ ├── image-20201231134824896.png │ └── image-20201231134914604.png └── readme.md ├── develop log ├── shell开发.assets │ ├── image-20201210141746062.png │ ├── image-20201210141802361.png │ ├── image-20201210162817621.png │ ├── image-20201210180204522.png │ ├── image-20201211114727013.png │ ├── image-20201211115111247.png │ ├── image-20201211115139940.png │ ├── image-20201212133824917.png │ ├── image-20201214094952276.png │ ├── image-20201214095126291.png │ ├── image-20201214095313387.png │ ├── image-20201214095401220.png │ ├── image-20201214101216810.png │ ├── image-20201214101253092.png │ ├── image-20201214184902024.png │ ├── image-20201214184910842.png │ ├── image-20201214184928696.png │ ├── image-20201218121235555.png │ ├── image-20201218121455968.png │ ├── image-20201220104640561.png │ ├── image-20201220104705559.png │ ├── image-20201220105407188.png │ ├── image-20201220105828910.png │ ├── image-20201220110111956.png │ ├── image-20201220113400355.png │ ├── image-20201224122944221.png │ ├── image-20201224123224878.png │ ├── image-20201224125320840.png │ ├── image-20201227135455095.png │ ├── image-20201227135731370.png │ ├── image-20201227145031868.png │ └── image-20201227145054871.png ├── shell开发.md ├── 文件系统.assets │ ├── image-20201130230830833.png │ ├── image-20201202164254808.png │ ├── image-20201204104926918.png │ ├── image-20201209165527135.png │ └── image-20201210100047188.png ├── 文件系统.md ├── 进程管理.assets │ ├── image-20201028150553357.png │ ├── image-20201028150622797.png │ ├── image-20201028150635512.png │ ├── image-20201028150719522.png │ ├── image-20201028155912857.png │ ├── image-20201028163341544.png │ ├── image-20201028170650987.png │ ├── image-20201028171053566.png │ ├── image-20201028172237622.png │ ├── image-20201029105108233.png │ ├── image-20201031110400779.png │ ├── image-20201107214550971.png │ ├── image-20201109113404986.png │ ├── image-20201109113620711.png │ ├── image-20201109114654694.png │ ├── image-20201109114703529.png │ ├── image-20201109114725570.png │ ├── image-20201109115238292.png │ ├── image-20201109115339566.png │ ├── image-20201109115838554.png │ ├── image-20201109120022622.png │ ├── image-20201109120038458.png │ ├── image-20201109120046496.png │ ├── image-20201109120730976.png │ ├── image-20201109120740246.png │ ├── image-20201109141540434.png │ ├── image-20201109142503518.png │ ├── image-20201109142957276.png │ ├── image-20201109143011225.png │ ├── image-20201112213907790.png │ ├── image-20201112220433866.png │ ├── image-20201114223946224.png │ ├── image-20201114225423431.png │ ├── image-20201115001143139.png │ ├── image-20201115130126586.png │ ├── image-20201116163832938.png │ ├── image-20201116163900130.png │ ├── image-20201116170112119.png │ ├── image-20201116170203467.png │ ├── image-20201116175645950.png │ ├── image-20201116175701794.png │ ├── image-20201116175715739.png │ ├── image-20201116180033538.png │ ├── image-20201116185536261.png │ ├── image-20201116185841415.png │ ├── image-20201118111651158.png │ ├── image-20201118162706509.png │ ├── image-20201118174311301.png │ ├── image-20201118221800059.png │ ├── image-20201118221810548.png │ ├── image-20201125100131036.png │ ├── image-20201125101932808.png │ ├── image-20201125102130838.png │ ├── image-20201125102310696.png │ ├── image-20201125102808331.png │ ├── image-20201125102907078.png │ └── image-20201125102942400.png └── 进程管理.md ├── disassembly ├── boot_disass.md ├── kernel_disass.md ├── readme.assets │ ├── image-20201231143254582.png │ ├── image-20201231143309533.png │ ├── image-20201231143320631.png │ └── image-20201231143332349.png ├── readme.md ├── test_cat_disass.md ├── test_cpp_disass.md ├── test_exec_disass.md ├── test_pipe_disass.md └── test_socket_disass.md ├── elf ├── kernel_elf.md ├── readme.assets │ └── image-20201231143543363.png └── readme.md ├── gdbinit ├── kernel ├── .DS_Store ├── CMakeLists.txt ├── ap │ ├── CMakeLists.txt │ ├── ap.c │ ├── ap.h │ ├── apheader.h │ └── start_ap.S ├── apic │ ├── CMakeLists.txt │ ├── apic.c │ └── apic.h ├── asm │ ├── CMakeLists.txt │ ├── asm.c │ ├── asm.h │ └── readme.md ├── debug │ ├── CMakeLists.txt │ ├── debug.c │ ├── debug.h │ ├── monitor.c │ ├── monitor.h │ ├── readline.c │ ├── readline.h │ ├── readme.assets │ │ ├── image-20201231154556175.png │ │ └── image-20201231155706920.png │ └── readme.md ├── dt │ ├── CMakeLists.txt │ ├── dt.c │ ├── dt.h │ ├── readme.assets │ │ ├── image-20210101122530922.png │ │ ├── image-20210101122550051.png │ │ ├── image-20210101122704418.png │ │ ├── image-20210101123853989.png │ │ └── image-20210101130142268.png │ └── readme.md ├── file │ ├── CMakeLists.txt │ ├── bitmap.h │ ├── dir.c │ ├── dir.h │ ├── file.c │ ├── file.h │ ├── fs.c │ ├── fs.h │ ├── ide-dev.c │ ├── ide-dev.h │ ├── inode.c │ ├── inode.h │ ├── readme.assets │ │ ├── image-20210101195008006.png │ │ ├── image-20210101195425185.png │ │ ├── image-20210101203558547.png │ │ ├── image-20210101211548668.png │ │ ├── image-20210101212332720.png │ │ ├── image-20210101214644423.png │ │ ├── image-20210101214931418.png │ │ ├── image-20210101215216128.png │ │ └── image-20210101220317718.png │ ├── readme.md │ └── super_block.h ├── init │ ├── CMakeLists.txt │ ├── init.c │ ├── init.h │ ├── readme.assets │ │ └── image-20210102105209154.png │ └── readme.md ├── internet │ ├── CMakeLists.txt │ ├── arp.c │ ├── arp.h │ ├── ethernet.c │ ├── ethernet.h │ ├── icmp.c │ ├── icmp.h │ ├── ip.c │ ├── ip.h │ ├── pci.c │ ├── pci.h │ ├── rtl8139.c │ └── rtl8139.h ├── interrupt │ ├── CMakeLists.txt │ ├── readme.assets │ │ ├── image-20210102111920939.png │ │ ├── image-20210102112300909.png │ │ ├── image-20210102112516846.png │ │ └── image-20210102113658283.png │ ├── readme.md │ ├── syscall.c │ ├── syscall.h │ ├── trap.c │ ├── trap.h │ ├── trapentry.S │ └── vector.S ├── kernel.ld ├── keyboard │ ├── CMakeLists.txt │ ├── keyboard.c │ ├── keyboard.h │ ├── readme.assets │ │ ├── image-20210102114526926.png │ │ ├── image-20210102114611098.png │ │ ├── image-20210102114624229.png │ │ ├── image-20210102114638187.png │ │ ├── image-20210102114657210.png │ │ ├── image-20210102114730257.png │ │ ├── image-20210102114752810.png │ │ ├── image-20210102114805015.png │ │ ├── image-20210102114819159.png │ │ ├── image-20210102115246364.png │ │ ├── image-20210102115255006.png │ │ ├── image-20210102115304459.png │ │ ├── image-20210102115317484.png │ │ ├── image-20210102115333510.png │ │ ├── image-20210102115342960.png │ │ └── image-20210102115355715.png │ └── readme.md ├── main │ ├── CMakeLists.txt │ ├── main.c │ ├── main.h │ └── readme.md ├── mem │ ├── CMakeLists.txt │ ├── memlayout.h │ ├── pmm.c │ ├── pmm.h │ ├── readme.assets │ │ └── image-20210102163754215.png │ ├── readme.md │ ├── vmm.c │ └── vmm.h ├── mp │ ├── CMakeLists.txt │ ├── mp_config.c │ └── mp_config.h ├── pic │ ├── CMakeLists.txt │ ├── pic.c │ ├── pic.h │ ├── readme.assets │ │ └── image-20210102164946298.png │ └── readme.md ├── pipe │ ├── CMakeLists.txt │ ├── ioqueue.c │ ├── ioqueue.h │ ├── pipe.c │ ├── pipe.h │ └── readme.md ├── readme.md ├── serial │ ├── CMakeLists.txt │ ├── readme.md │ ├── serial.c │ └── serial.h ├── socket │ ├── CMakeLists.txt │ ├── errno.h │ ├── localsocket.c │ └── localsocket.h ├── stl │ ├── defs.h │ ├── elf.h │ ├── hash.h │ ├── list.h │ └── readme.md ├── sync │ ├── CMakeLists.txt │ ├── readme.md │ ├── sync.c │ └── sync.h ├── task │ ├── CMakeLists.txt │ ├── exec.c │ ├── exec.h │ ├── readme.assets │ │ ├── image-20210103125344968.png │ │ ├── image-20210103132009043.png │ │ ├── image-20210103134220781.png │ │ └── image-20210103134240827.png │ ├── readme.md │ ├── switch.S │ ├── task.c │ ├── task.h │ ├── thread_entry.S │ └── 寄存器.md ├── timer │ ├── CMakeLists.txt │ ├── readme.assets │ │ ├── image-20210102223147461.png │ │ ├── image-20210102223250050.png │ │ ├── image-20210102223302336.png │ │ ├── image-20210102223314668.png │ │ ├── image-20210102223326120.png │ │ ├── image-20210102223339670.png │ │ └── image-20210102223356663.png │ ├── readme.md │ ├── timer.c │ └── timer.h ├── user │ ├── CMakeLists.txt │ ├── buildin_cmd.c │ ├── buildin_cmd.h │ ├── readme.assets │ │ └── image-20210103111642543.png │ ├── readme.md │ ├── shell.c │ ├── shell.h │ ├── stdio.c │ ├── stdio.h │ ├── string.c │ ├── string.h │ ├── user_main.c │ ├── user_main.h │ ├── user_syscall.c │ ├── user_syscall.h │ └── va_list.h └── vga │ ├── CMakeLists.txt │ ├── readme.md │ ├── vga.c │ └── vga.h ├── readme.assets ├── image-20201228212745678.png ├── image-20201228213055895.png ├── image-20201228213344675.png ├── image-20201228222144608.png ├── image-20201228223246325.png ├── image-20201228223255211.png └── image-20201228223304979.png ├── readme.md ├── run.sh ├── rundocker.sh ├── test_ap ├── CMakeLists.txt ├── ap_ld.ld └── start_ap.S ├── test_cat ├── CMakeLists.txt ├── readme.md ├── start.S ├── test.c └── test.ld ├── test_cpp ├── CMakeLists.txt ├── test.cpp ├── test.hpp └── test.ld ├── test_exec ├── CMakeLists.txt ├── readme.md ├── start.S ├── test.c └── test.ld ├── test_pipe ├── CMakeLists.txt ├── readme.md ├── start.S ├── test.c └── test.ld ├── test_socket ├── CMakeLists.txt ├── start.S ├── test.c └── test.ld ├── xxd.sh └── 体会.md /.CodeCounter/results.md: -------------------------------------------------------------------------------- 1 | # Summary 2 | 3 | Date : 2020-12-27 21:30:26 4 | 5 | Directory : ./ 6 | 7 | Total : 132 files, 31359 codes, 3514 comments, 4044 blanks, all 38917 lines, 10.08% comment rate 8 | 9 | [details](details.md) 10 | 11 | ## Languages 12 | | language | files | code | comment | blank | total | comment rate | 13 | | :--- | ---: | ---: | ---: | ---: | ---: | ---: | 14 | | Markdown | 26 | 21,365 | 0 | 1,185 | 22,550 | 0.00% | 15 | | C | 38 | 5,563 | 1,795 | 774 | 8,132 | 24.40% | 16 | | Makefile | 23 | 2,570 | 1,255 | 1,740 | 5,565 | 32.81% | 17 | | C++ | 41 | 1,691 | 443 | 311 | 2,445 | 20.76% | 18 | | Log | 2 | 156 | 0 | 31 | 187 | 0.00% | 19 | | Shell Script | 2 | 14 | 21 | 3 | 38 | 60.00% | 20 | 21 | ## Directories 22 | | path | files | code | comment | blank | total | comment rate | 23 | | :--- | ---: | ---: | ---: | ---: | ---: | ---: | 24 | | . | 132 | 31,359 | 3,514 | 4,044 | 38,917 | 10.08% | 25 | | boot | 3 | 141 | 66 | 48 | 255 | 31.88% | 26 | | build | 27 | 3,729 | 1,357 | 1,999 | 7,085 | 26.68% | 27 | | build/CMakeFiles | 4 | 1,159 | 102 | 259 | 1,520 | 8.09% | 28 | | build/CMakeFiles/3.17.3 | 2 | 1,003 | 102 | 228 | 1,333 | 9.23% | 29 | | build/CMakeFiles/3.17.3/CompilerIdC | 1 | 507 | 50 | 115 | 672 | 8.98% | 30 | | build/CMakeFiles/3.17.3/CompilerIdCXX | 1 | 496 | 52 | 113 | 661 | 9.49% | 31 | | build/boot | 1 | 113 | 54 | 76 | 243 | 32.34% | 32 | | build/kernel | 18 | 1,887 | 895 | 1,312 | 4,094 | 32.17% | 33 | | build/kernel/asm | 1 | 89 | 47 | 65 | 201 | 34.56% | 34 | | build/kernel/debug | 1 | 125 | 53 | 83 | 261 | 29.78% | 35 | | build/kernel/dt | 1 | 89 | 47 | 65 | 201 | 34.56% | 36 | | build/kernel/file | 1 | 161 | 59 | 101 | 321 | 26.82% | 37 | | build/kernel/init | 1 | 89 | 47 | 65 | 201 | 34.56% | 38 | | build/kernel/interrupt | 1 | 119 | 52 | 80 | 251 | 30.41% | 39 | | build/kernel/keyboard | 1 | 89 | 47 | 65 | 201 | 34.56% | 40 | | build/kernel/main | 1 | 89 | 47 | 65 | 201 | 34.56% | 41 | | build/kernel/mem | 1 | 107 | 50 | 74 | 231 | 31.85% | 42 | | build/kernel/pic | 1 | 89 | 47 | 65 | 201 | 34.56% | 43 | | build/kernel/pipe | 1 | 107 | 50 | 74 | 231 | 31.85% | 44 | | build/kernel/serial | 1 | 89 | 47 | 65 | 201 | 34.56% | 45 | | build/kernel/sync | 1 | 89 | 47 | 65 | 201 | 34.56% | 46 | | build/kernel/task | 1 | 119 | 52 | 80 | 251 | 30.41% | 47 | | build/kernel/timer | 1 | 89 | 47 | 65 | 201 | 34.56% | 48 | | build/kernel/user | 1 | 179 | 62 | 110 | 351 | 25.73% | 49 | | build/kernel/vga | 1 | 89 | 47 | 65 | 201 | 34.56% | 50 | | build/test_cat | 1 | 104 | 51 | 72 | 227 | 32.90% | 51 | | build/test_exec | 1 | 104 | 51 | 72 | 227 | 32.90% | 52 | | build/test_pipe | 1 | 104 | 51 | 72 | 227 | 32.90% | 53 | | develop log | 3 | 254 | 0 | 281 | 535 | 0.00% | 54 | | disassembly | 6 | 20,149 | 0 | 764 | 20,913 | 0.00% | 55 | | elf | 1 | 803 | 0 | 10 | 813 | 0.00% | 56 | | kernel | 86 | 6,137 | 2,068 | 898 | 9,103 | 25.20% | 57 | | kernel/asm | 3 | 159 | 69 | 17 | 245 | 30.26% | 58 | | kernel/debug | 6 | 161 | 35 | 19 | 215 | 17.86% | 59 | | kernel/dt | 3 | 192 | 57 | 33 | 282 | 22.89% | 60 | | kernel/file | 12 | 1,802 | 522 | 227 | 2,551 | 22.46% | 61 | | kernel/init | 3 | 77 | 41 | 20 | 138 | 34.75% | 62 | | kernel/interrupt | 5 | 498 | 128 | 41 | 667 | 20.45% | 63 | | kernel/keyboard | 3 | 208 | 27 | 35 | 270 | 11.49% | 64 | | kernel/main | 3 | 185 | 84 | 28 | 297 | 31.23% | 65 | | kernel/mem | 6 | 334 | 297 | 71 | 702 | 47.07% | 66 | | kernel/pic | 3 | 42 | 17 | 18 | 77 | 28.81% | 67 | | kernel/pipe | 4 | 141 | 36 | 34 | 211 | 20.34% | 68 | | kernel/serial | 3 | 137 | 16 | 26 | 179 | 10.46% | 69 | | kernel/stl | 5 | 117 | 93 | 30 | 240 | 44.29% | 70 | | kernel/sync | 2 | 88 | 38 | 10 | 136 | 30.16% | 71 | | kernel/task | 5 | 837 | 374 | 161 | 1,372 | 30.88% | 72 | | kernel/timer | 3 | 23 | 2 | 6 | 31 | 8.00% | 73 | | kernel/user | 13 | 844 | 171 | 78 | 1,093 | 16.85% | 74 | | kernel/vga | 3 | 287 | 61 | 41 | 389 | 17.53% | 75 | | test_cat | 1 | 40 | 2 | 0 | 42 | 4.76% | 76 | | test_exec | 1 | 7 | 0 | 0 | 7 | 0.00% | 77 | | test_pipe | 1 | 20 | 0 | 0 | 20 | 0.00% | 78 | 79 | [details](details.md) -------------------------------------------------------------------------------- /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/.DS_Store -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.associations": { 3 | "typeinfo": "cpp", 4 | "array": "cpp", 5 | "functional": "cpp", 6 | "istream": "cpp", 7 | "ostream": "cpp", 8 | "tuple": "cpp", 9 | "type_traits": "cpp", 10 | "utility": "cpp", 11 | "cstring": "c", 12 | "*.tcc": "c", 13 | "algorithm": "c", 14 | "string_view": "c", 15 | "initializer_list": "c", 16 | "random": "c", 17 | "string": "c", 18 | "sync.h": "c", 19 | "user_main.h": "c", 20 | "limits": "c", 21 | "chrono": "c", 22 | "ratio": "c", 23 | "fstream": "c", 24 | "iosfwd": "c", 25 | "sstream": "c", 26 | "streambuf": "c" 27 | } 28 | } -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #CMake最低版本号要求 2 | cmake_minimum_required(VERSION 3.12) 3 | 4 | # skip cmake compiler check 5 | set(CMAKE_C_COMPILER_WORKS TRUE) 6 | set(CMAKE_CXX_COMPILER_WORKS TRUE) 7 | 8 | #项目信息 9 | project(FreeFlyOS CXX C ASM) 10 | 11 | set(CMAKE_C_FLAGS "-Os -nostdlib -fno-builtin -Wall -ggdb -m32 -gstabs -nostdinc -fno-stack-protector") 12 | set(CMAKE_ASM_FLAGS "${CMAKE_C_FLAGS}") 13 | set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS}") 14 | 15 | # Set cmake moudle path 16 | #set(CMAKE_MODULE_PATH "${FreeFlyOS_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH}) 17 | 18 | 19 | #增加boot子目录和kernel子目录 20 | add_subdirectory(boot) 21 | 22 | #add_subdirectory(user) 23 | #set(${user}.out obj_user.out) 24 | set(CMAKE_C_FLAGS "-nostdlib -g -m32") 25 | add_subdirectory(kernel) 26 | add_subdirectory(test_exec) 27 | add_subdirectory(test_cat) 28 | add_subdirectory(test_pipe) 29 | add_subdirectory(test_cpp) 30 | add_subdirectory(test_socket) 31 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | #version 0.1 2 | FROM 3292900173/qemu 3 | ADD FreeFlyOS.img /usr 4 | WORKDIR /usr 5 | #CMD ["qemu-system-i386","-curses","-m 2048","-net nic,model=rtl8139","-smp 2" "-hda","FreeFlyOS.img"] 6 | -------------------------------------------------------------------------------- /FreeFlyOS.img: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/FreeFlyOS.img -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 dashanji 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /boot/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #设置项目名 2 | project (bootblock C ASM) 3 | 4 | add_library(bootsector OBJECT bootsector.S) 5 | add_library(bootmain OBJECT bootmain.c) 6 | 7 | #链接 8 | add_executable(${PROJECT_NAME}.o 9 | $ 10 | $ 11 | ) 12 | 13 | target_link_options(${PROJECT_NAME}.o PRIVATE -T ${FreeFlyOS_SOURCE_DIR}/boot/boot.ld) 14 | target_link_options(${PROJECT_NAME}.o PRIVATE -Wl,-melf_i386) 15 | 16 | 17 | add_custom_command(TARGET ${PROJECT_NAME}.o 18 | POST_BUILD 19 | COMMAND 20 | ${CMAKE_OBJCOPY} -S -O binary ${PROJECT_NAME}.o ${PROJECT_NAME}.out 21 | COMMAND 22 | gcc ${FreeFlyOS_SOURCE_DIR}/boot/sign.c -o sign 23 | COMMAND 24 | ./sign ${PROJECT_NAME}.out ${PROJECT_NAME} 25 | ) 26 | 27 | -------------------------------------------------------------------------------- /boot/boot.ld: -------------------------------------------------------------------------------- 1 | /* 2 | ** 链接脚本 3 | */ 4 | OUTPUT_FORMAT(elf32-i386) 5 | OUTPUT_ARCH(i386) 6 | ENTRY(start) 7 | /* 8 | * ld有多种方法设置进程入口地址, 按以下顺序: (编号越前, 优先级越高) 9 | * 1, ld命令行的-e选项 10 | * 2, 连接脚本的ENTRY(SYMBOL)命令 11 | * 3, 如果定义了start 符号, 使用start符号值 12 | * 4, 如果存在 .text section , 使用.text section的第一字节的位置值 13 | * 5, 使用值0 14 | * 15 | * 16 | */ 17 | 18 | SECTIONS 19 | { 20 | /* 将定位器符号置为0x7c00 */ 21 | . = 0x7C00; 22 | 23 | /* 24 | 将所有(*符号代表任意输入文件)输入文件bootsector.S的.start section合并 25 | 成一个.start section, 该section的地址由定位器符号的值 26 | 指定, 即0x7c00. 27 | bootsector.o整体作为一个start节 28 | */ 29 | .start : { 30 | *bootsector.o(.text) 31 | } 32 | 33 | /* 34 | 将所有(*符号代表任意输入文件)输入文件的.text section合并 35 | 成一个.text section, 该section的地址紧接.start节. 36 | bootmain.o中的text作为一个text节 37 | */ 38 | .text : { *(.text) } 39 | 40 | /* 41 | 将所有(*符号代表任意输入文件)输入文件的.data section合并 42 | 成一个.data section, 该section的地址紧接.text节. 43 | bootmain.o中的data作为一个data节 44 | */ 45 | .data : { *(.data .rodata) } 46 | 47 | /DISCARD/ : { *(.eh_*) } 48 | } -------------------------------------------------------------------------------- /boot/bootsector.S: -------------------------------------------------------------------------------- 1 | /* 2 | * 主要功能:关中断、内存探测、80x86 CPU从实模式变成保护模式 3 | * 跳转到加载内核的32位代码段 4 | * 注意:本文件不是MBR(512B),而是和bootmain.c链接成MBR 5 | */ 6 | .text 7 | .code16 #.code16表示16位代码段 8 | .global start 9 | /* 10 | *将ds、es和ss段寄存器均设置成cs段寄存器的值,并将栈顶指针esp指向 11 | *0x7c00,栈向低地址增长。这步操作其实也可省略,因为在16位代码段中 12 | *还用不到其他段寄存器,在需要使用的时候再初始化不迟 13 | */ 14 | start: 15 | movw %cs,%ax 16 | movw %ax,%ds # ->Data Segment 17 | movw %ax,%es # ->Extra Segment 18 | movw %ax,%ss # ->Stack Segment 19 | movl $0x7C00,%esp 20 | 21 | /* 22 | *关中断,在后面我们在内存中会建立中断向量表,所以事先关好中断, 23 | *防止在建表过程中来了中断,所以事先屏蔽,防止这种情况产生。 24 | */ 25 | cli 26 | 27 | 28 | /* 内存探测,内存地址0x8000作为内存探测段数的存储地址, 29 | 方便后面调用 */ 30 | movw $0,0x8000 31 | movw $0x8004,%di 32 | xor %ebx,%ebx 33 | mm_probe: 34 | movl $0xe820,%eax 35 | movl $20,%ecx 36 | movl $0x534D4150,%edx 37 | int $0x15 38 | #产生进位则跳转 39 | jnc cont 40 | jmp probe_end 41 | cont: 42 | incl 0x8000 43 | addw $20,%di 44 | cmpl $0,%ebx 45 | jnz mm_probe 46 | probe_end: 47 | 48 | 49 | /* 50 | *打开地址线A20。实际上若我们使用qemu跑这个程序时,A20默认打开, 51 | *但为了兼容性,最好还是手动将A20地址线打开.读者可以试一试将打开 52 | *A20代码删去后,在保护模式(32位代码段#)下用回滚机制测试时是否 53 | *仍然显示字符 54 | * 55 | *8042(键盘控制器)端口的P21和A20相连,置1则打开 56 | *0x64端口 读:位1=1 输入缓冲器满(0x60/0x64口有给8042的数据) 57 | *0x64端口 写: 0xd1->写8042的端口P2,比如位2控制P21 58 | *当写时,0x60端口提供数据,比如0xdf,这里面把P2置1 59 | * 60 | *由于MacOS下编译器的版本原因,若加上下面代码会超出512B,故舍去 61 | */ 62 | 63 | /*waitforbuffernull1: 64 | 65 | #先确定8042是不是为空,如果不为空,则一直等待 66 | xorl %eax,%eax 67 | inb $0x64,%al 68 | testb $0x2,%al 69 | jnz waitforbuffernull1 70 | 71 | #8042中没有命令,则开始向0x64端口发出写P2端口的命令 72 | movb $0xd1,%al 73 | outb %al,$0x64 74 | waitforbuffernull2: 75 | 76 | #再确定8042是不是为空,如果不为空,则一直等待 77 | xorl %eax,%eax 78 | inb $0x64,%al 79 | testb $0x2,%al 80 | jnz waitforbuffernull2 81 | 82 | #向0x60端口发送数据,即把P2端口设置为0xdf 83 | movb $0xdf,%al 84 | outb %al,$0x60*/ 85 | 86 | /* 加载gdt表,即将内存中的gdt基址和表长写入GDTR寄存器 */ 87 | lgdt gdt_48 88 | 89 | /* 打开保护模式,将cr0的位0置为1,一般而言BIOS中断 90 | 只在实模式下进行调用 */ 91 | movl %cr0,%eax 92 | orl $0x1,%eax 93 | movl %eax,%cr0 94 | 95 | /* 96 | *进入到32位代码段。0x8代表段选择子(16位)——0000000000001000 97 | *其中最后2为代表特权级.linux内核只使用了2个特权级(0和3),00代表 98 | *0特权级(内核级),倒数第3位的代表是gdt(全局描述符表)还是 99 | *idt(局部描述符表),0代表全局描述符表,前13位代表gdt的项数(第1项), 100 | *属于代码段。所以0x8代表特权级为0(内核级)的全局代码段,promode代表 101 | *偏移地址。 102 | */ 103 | ljmp $0x8,$promode 104 | 105 | /* 保护模式下的32位代码段 */ 106 | promode: 107 | .code32 108 | movw $0x10,%ax 109 | movw %ax,%ds #->Data Segment 110 | movw %ax,%es #->Extra Segment 111 | movw %ax,%ss #->Stack Segment 112 | 113 | movw $0x18,%ax 114 | movw %ax,%gs 115 | 116 | movl $0x0,%ebp 117 | movl $start,%esp 118 | 119 | /* 调用bootmain.c中的bootmain函数 */ 120 | call bootmain 121 | 122 | /* 在内存中做一块GDT表 */ 123 | .align 2 124 | gdt: 125 | .word 0,0,0,0 126 | 127 | .word 0xFFFF #第1项CS,基地址为0,限长 128 | .word 0x0000 129 | .word 0x9A00 130 | .word 0x00CF 131 | 132 | .word 0xFFFF #第2项DS,基地址为0 133 | .word 0x0000 134 | .word 0x9200 135 | .word 0x00CF 136 | 137 | .word 0xFFFF #第3项VGA,基地址位0xb8000 138 | .word 0x8000 139 | .word 0x920b 140 | .word 0x0000 141 | 142 | /* 143 | *将gdtr专用寄存器指向我们在内存中做的一块GDT表,GDTR寄存器格式: 144 | *48位(高32位地址+低16位限长),intel是小端方式 145 | */ 146 | gdt_48: 147 | .word 0x1f #gdt表限长 sizeof(gdt)-1 低地址,放在gdtr的低字节 148 | .long gdt #gdt表基址  高地址,放在gdtr的高字节 149 | 150 | 151 | -------------------------------------------------------------------------------- /boot/readme.assets/image-20201230095709041.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/boot/readme.assets/image-20201230095709041.png -------------------------------------------------------------------------------- /boot/readme.assets/image-20201230214125113.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/boot/readme.assets/image-20201230214125113.png -------------------------------------------------------------------------------- /boot/readme.assets/image-20201231091731488.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/boot/readme.assets/image-20201231091731488.png -------------------------------------------------------------------------------- /boot/readme.assets/image-20201231092306216.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/boot/readme.assets/image-20201231092306216.png -------------------------------------------------------------------------------- /boot/readme.assets/image-20201231095526365.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/boot/readme.assets/image-20201231095526365.png -------------------------------------------------------------------------------- /boot/readme.assets/image-20201231095811107.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/boot/readme.assets/image-20201231095811107.png -------------------------------------------------------------------------------- /boot/readme.md: -------------------------------------------------------------------------------- 1 | ## boot.ld 2 | 3 | 生成bootblock的链接格式,起始地址从0x7c00开始 4 | 5 | ## bootsector.S 6 | 7 | 关中断、内存探测、80x86 CPU从实模式变成保护模式。 8 | 9 | ## bootmain.c 10 | 11 | 将elf格式的内核代码读入到指定内存区域中。 12 | 13 | ## sign.c 14 | 15 | 将某文件格式化为合法MBR文件,末尾以0xaa55结束。 16 | 17 | ## CMakeLists.txt 18 | 19 | 1、编译bootsector.S以及bootmain.c文件生成bootsector.o和bootmain.o 20 | 21 | 2、将boosector.o和bootmain.o链接到0x7c00地址处生成bootblock.o 22 | 23 | 3、使用objcopy将bootblack.o复制生成可执行文件bootblock.out 24 | 25 | 4、使用格式化工具sign将bootblack.out格式化成MBR 26 | 27 | 5、之后为了给主分区表预留空间,该MBR从0x1BE-0x1FD的空间为主分区表信息,本项目的MBR如下图所示。 28 | 29 | ![image-20201230095709041](readme.assets/image-20201230095709041.png) 30 | 31 | ## 功能说明 32 | 33 | 作为一个内核的bootloader,它的主要功能如下: 34 | 35 | 1、在16位代码段下,应先设置段寄存器(DS、ES、SS)的值(CS默认上电赋值)。 36 | 37 | 2、关中断,为之后建立中断向量表打好基础。 38 | 39 | 3、内存探测,通过BIOS提供的0x15中断获取可用内存数据,并存储在内存物理地址0x8000处。 40 | 41 | 4、打开地址A20,按理说这步应该是要做的,但由于本人环境编译器版本问题,加上这段代码会使MBR超过512B,故只能删掉这部分代码,经过测试,在qemu模拟器不影响后续代码的执行,以此来减少MBR的空间,并为主分区表预留空间。 42 | 43 | 5、加载gdt表,其中设置了CS和DS段基址为0,段限长为4GB,这样就能访问0-4GB的物理地址了,而实际分配给虚拟机2GB内存,为后面地址映射作准备。 44 | 45 | 6、接着就是打开保护模式了,把cr0的第0位置1即可,此时就无法调用BIOS中断了,所以如果需要用BIOS中断获取硬件信息,最好在保护模式前就写好。 46 | 47 | 7、使用ljmp长跳转到保护模式下的32位代码段,该段的属性已经在gdt表中写好,只需确定跳转代码的偏移地址即可。 48 | 49 | 8、上一步操作已经确定了CS段,而数据段并未确定,所以需要设置DS、ES、SS段的值,这里还设置了gs段的值,之前主要是为了能够用VGA输出字符,但后续直接写了VGA的驱动,所以这里的GS段设置和之前GDT中的VGA段均可删掉。 50 | 51 | 9、设置下栈地址,栈顶指针指向0x7c00,也就是bootloader开始的位置,但栈是向下增长的,故不会影响bootloader代码,在bootmain.c中会调用函数,故需要一个栈来存放参数和返回地址等信息。 52 | 53 | 10、将内核加载到内存中,一般内核文件都是elf文件格式,为了能够读取内核的elf头,我们将内核文件放在引导扇区MBR后面一个扇区,通过x86_64-elf-readelf -a build/kernel/kernel可以看到内核的elf文件布局,如下图所示。 54 | 55 | ![image-20201230214125113](readme.assets/image-20201230214125113.png) 56 | 57 | 从这张图中我们能看到整个内核文件基本分为3个部分:init部分(.init.text/data)、user部分(.user.text/data/rodata/bss)、kernel部分(.text/rodata/data/bss),各个部分的段地址由链接脚本决定,由于这个时候我们还没开启分页,虚拟地址=物理地址,而且实际物理内存只有2G,所以内核部分(即从C1000000开始)的代码,故在bootmain中需要进行一个判断,若虚拟地址大于2G,即内核代码,放在0x1000000处,当然,也可以设置qemu模拟器的内存大小,比如分配4G,但要注意的一点是,当分配给qemu模拟器4G内存中,可用只有3.5G,此后到4G之间的物理地址无法使用。 58 | 59 | 然后就是通过IO端口和硬盘进行交互,将各个部分的各个段读到对应的虚拟地址上(虚拟地址=物理地址),最后跳转到ELF文件的entry中,即0x100000(init部分的代码)。 60 | 61 | 12、boot下的链接脚本,如下图所示,0x7C00为约定好的系统引导地址,即BIOS执行完后,会自动执行0x7C00开始的bootloader。 62 | 63 | ![image-20201231091731488](readme.assets/image-20201231091731488.png) 64 | 65 | 13、关于CMakeLists.txt的一些解释 66 | 67 | ![image-20201231092306216](readme.assets/image-20201231092306216.png) 68 | 69 | 1⃣️project ( )------首先设置项目名称,一般这个可以随意设置,然后要注明使用了哪些语言,比如C语言,ASM汇编,若不指定则在编译时会自动看成C语言,.S文件就编译不了,需要在上层目录下的CMakeLists.txt下使能编译器。 70 | 71 | ![image-20201231095526365](readme.assets/image-20201231095526365.png) 72 | 73 | 2⃣️add_library------将源文件编译成静态库文件,可以把它看成x86_64-elf-gcc(MAC下)/gcc(Ubuntu下) -c bootsector.c -o bootsector.o,当然这个编译选项在上一层也就是整个项目目录下的CMakeLists.txt确定的,如下图所示。 74 | 75 | ![image-20201231095811107](readme.assets/image-20201231095811107.png) 76 | 77 | 具体说明下每个参数是啥意思吧: 78 | 79 | -Os:主要对程序的尺寸进行优化,为了减少MBR的大小,可谓绞尽脑汁。 80 | 81 | -nostdlib:不连接系统标准启动文件和标准哭文件,只把指定的文件传递给连接库,这样我们就能重写printf等,不会和标准C库重名了。 82 | 83 | -fno-builtin:不使用C语言的内建函数,所以我们设置的函数名可以和内建函数同名。 84 | 85 | -Wall:显示所有警告。 86 | 87 | -ggdb:产生debug信息,用于gdb调试 88 | 89 | -m32:生成32位机器的汇编代码 90 | 91 | -gstabs:以stabs格式声称调试信息,但是不包括gdb调试信息。 92 | 93 | -nostdinc:不包含C语言的标准库的头文件。 94 | 95 | -fno-stack-protector:不使用栈保护检测。 96 | 97 | 3⃣️add_executable------将静态库文件链接成可执行文件,实际使用时为x86_64-elf-ld命令(MAC下)/ld命令(Ubuntu下) 98 | 99 | 4⃣️target_link_options-----设置链接选项,-T指定链接脚本,-Wl 传递参数 ,-melf_i386链接为32位程序 100 | 101 | 5⃣️add_custom_command-----在生成项目文件后,继续执行指定的命令,比如把.o文件转化为二进制文件,然后通过格式化文件sign将bootloader格式化为MBR。 102 | 103 | 最后,boot目录大概就总结这么多吧,有不懂的地方随时联系我,295957410@qq.com。 104 | 105 | -------------------------------------------------------------------------------- /boot/sign.c: -------------------------------------------------------------------------------- 1 | /* 2 | * 主要功能:在bootsector.S和bootmain.c链接成的 3 | * bootblock.out文件末尾添加0xaa55结束符 4 | * 注意: 合法的MBR文件末尾以0xaa55结束。 5 | * 6 | */ 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | /* 13 | * main(argc,argv):在第一个参数argv[1]文件的末尾 14 | * 添加0x55AA,然后写入第二个参数argv[2]文件中 15 | */ 16 | int main(int argc, char *argv[]) { 17 | struct stat st; 18 | 19 | if (argc != 3) { 20 | fprintf(stderr, "Usage: \n"); 21 | return -1; 22 | } 23 | 24 | if (stat(argv[1], &st) != 0) { 25 | fprintf(stderr, "Error opening file '%s': %s\n", argv[1], strerror(errno)); 26 | return -1; 27 | } 28 | printf("'%s' size: %lld bytes\n", argv[1], (long long)st.st_size); 29 | 30 | if (st.st_size > 510) { 31 | fprintf(stderr, "%lld >> 510!!\n", (long long)st.st_size); 32 | return -1; 33 | } 34 | 35 | char buf[512]; 36 | memset(buf, 0, sizeof(buf)); 37 | 38 | FILE *ifp = fopen(argv[1], "rb"); 39 | int size = fread(buf, 1, st.st_size, ifp); 40 | if (size != st.st_size) { 41 | fprintf(stderr, "read '%s' error, size is %d.\n", argv[1], size); 42 | return -1; 43 | } 44 | fclose(ifp); 45 | 46 | buf[510] = 0x55; 47 | buf[511] = 0xAA; 48 | 49 | FILE *ofp = fopen(argv[2], "wb+"); 50 | size = fwrite(buf, 1, 512, ofp); 51 | if (size != 512) { 52 | fprintf(stderr, "write '%s' error, size is %d.\n", argv[2], size); 53 | return -1; 54 | } 55 | fclose(ofp); 56 | printf("build 512 bytes boot sector: '%s' success!\n", argv[2]); 57 | return 0; 58 | } 59 | 60 | -------------------------------------------------------------------------------- /cmake/linux_x86_toolchain.cmake: -------------------------------------------------------------------------------- 1 | set(CMAKE_SYSTEM_NAME Linux) 2 | set(CMAKE_SYSTEM_VERSION 1) 3 | set(CMAKE_SYSTEM_PROCESSOR x86_64) 4 | 5 | # GCC 6 | find_program(X86_64 x86_64-elf-gcc REQUIRED) 7 | if (NOT X86_64) 8 | message(FATAL_ERROR "x86_64-elf-gcc not found.\n" 9 | "Run `brew install x86_64-elf-gcc` to install the toolchain.") 10 | else () 11 | message(STATUS "Found x86_64-elf-gcc ${X86_64}.") 12 | endif () 13 | 14 | set(TOOLCHAIN_PREFIX x86_64-elf-) 15 | set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}gcc) 16 | set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}g++) 17 | set(CMAKE_OBJCOPY ${TOOLCHAIN_PREFIX}objcopy) -------------------------------------------------------------------------------- /cmake/mac_x86_toolchain.cmake: -------------------------------------------------------------------------------- 1 | set(CMAKE_SYSTEM_NAME Darwin) 2 | set(CMAKE_SYSTEM_VERSION 1) 3 | set(CMAKE_SYSTEM_PROCESSOR x86_64) 4 | 5 | # GCC 6 | find_program(X86_64 x86_64-elf-gcc REQUIRED) 7 | if (NOT X86_64) 8 | message(FATAL_ERROR "x86_64-elf-gcc not found.\n" 9 | "Run `brew install x86_64-elf-gcc` to install the toolchain.") 10 | else () 11 | message(STATUS "Found x86_64-elf-gcc ${X86_64}.") 12 | endif () 13 | 14 | set(TOOLCHAIN_PREFIX x86_64-elf-) 15 | set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}gcc) 16 | set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}g++) 17 | set(CMAKE_OBJCOPY ${TOOLCHAIN_PREFIX}objcopy) -------------------------------------------------------------------------------- /cmake/readme.assets/image-20201231134824896.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/cmake/readme.assets/image-20201231134824896.png -------------------------------------------------------------------------------- /cmake/readme.assets/image-20201231134914604.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/cmake/readme.assets/image-20201231134914604.png -------------------------------------------------------------------------------- /cmake/readme.md: -------------------------------------------------------------------------------- 1 | #### mac_x86_toolchain.cmake 2 | 3 | 通过.cmake设置不同环境下的编译工具链,mac环境下的工具链如下图所示。 4 | 5 | ![image-20201231134914604](readme.assets/image-20201231134914604.png) 6 | 7 | 另外说明一下,本人用的是64位的x86机器,如果使用的是32位的机器,那就需要根据情况来设定,看到这里,有很多读者可能会问,MAC电脑下自带gcc版本,为什么要用x86_64-elf-gcc呢,因为MAC电脑下的gcc只支持MAC系统下的文件系统,不认elf文件系统,那我们要写一个类似Linux的内核,肯定要用到它的文件系统,而gcc早就帮我们想到了这一点,所以其提供了跨平台的编译器----x86_64-elf-gcc,这样我们编译链接运行出来的就是elf文件格式了。 8 | 9 | #### linux_x86_toolchain.cmake 10 | 11 | linux环境下的工具链如下图 12 | 13 | ![image-20201231134824896](readme.assets/image-20201231134824896.png) 14 | 15 | 看到这里是不是很奇怪,怎么和MAC环境下的配置一模一样吗,按理说,linux环境下的gcc支持elf文件格式,没必要使用跨平台的x86_64-elf-gcc啊,呃,这实际上和MBR有关,FreeFlyOS的MBR中的内容太多了,又要开保护模式,又要设置gdt,还得读取内核,还用到了函数,这就会导致最后生成的二进制文件超过512B。其实这也不是主要原因,我发现了linux下的gcc编译链接出来的文件都会加上一些其他的section,讲道理,要运行FreeFlyOS的MBR包括.text和.data段就足够了,所以其他section就没用了,还会增加文件大小。而用跨平台的x86_64-elf-gcc就不会有这个问题了,当然,我也试过把其他section剥离,最后还是会超过512B,无奈只能选择x86_64-elf-gcc了。对编译链接以及elf文件感兴趣的同学可以看看下面的链接,教你打造史上最小的可执行ELF文件(45字节)。 16 | 17 | https://www.bookstack.cn/read/open-c-book/zh-chapters-02-chapter8.markdown#%E6%89%93%E9%80%A0%E5%8F%B2%E4%B8%8A%E6%9C%80%E5%B0%8F%E5%8F%AF%E6%89%A7%E8%A1%8C%20ELF%20%E6%96%87%E4%BB%B6%EF%BC%8845%20%E5%AD%97%E8%8A%82%EF%BC%8C%E5%8F%AF%E6%89%93%E5%8D%B0%E5%AD%97%E7%AC%A6%E4%B8%B2%EF%BC%89 18 | 19 | -------------------------------------------------------------------------------- /develop log/shell开发.assets/image-20201210141746062.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/shell开发.assets/image-20201210141746062.png -------------------------------------------------------------------------------- /develop log/shell开发.assets/image-20201210141802361.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/shell开发.assets/image-20201210141802361.png -------------------------------------------------------------------------------- /develop log/shell开发.assets/image-20201210162817621.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/shell开发.assets/image-20201210162817621.png -------------------------------------------------------------------------------- /develop log/shell开发.assets/image-20201210180204522.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/shell开发.assets/image-20201210180204522.png -------------------------------------------------------------------------------- /develop log/shell开发.assets/image-20201211114727013.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/shell开发.assets/image-20201211114727013.png -------------------------------------------------------------------------------- /develop log/shell开发.assets/image-20201211115111247.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/shell开发.assets/image-20201211115111247.png -------------------------------------------------------------------------------- /develop log/shell开发.assets/image-20201211115139940.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/shell开发.assets/image-20201211115139940.png -------------------------------------------------------------------------------- /develop log/shell开发.assets/image-20201212133824917.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/shell开发.assets/image-20201212133824917.png -------------------------------------------------------------------------------- /develop log/shell开发.assets/image-20201214094952276.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/shell开发.assets/image-20201214094952276.png -------------------------------------------------------------------------------- /develop log/shell开发.assets/image-20201214095126291.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/shell开发.assets/image-20201214095126291.png -------------------------------------------------------------------------------- /develop log/shell开发.assets/image-20201214095313387.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/shell开发.assets/image-20201214095313387.png -------------------------------------------------------------------------------- /develop log/shell开发.assets/image-20201214095401220.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/shell开发.assets/image-20201214095401220.png -------------------------------------------------------------------------------- /develop log/shell开发.assets/image-20201214101216810.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/shell开发.assets/image-20201214101216810.png -------------------------------------------------------------------------------- /develop log/shell开发.assets/image-20201214101253092.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/shell开发.assets/image-20201214101253092.png -------------------------------------------------------------------------------- /develop log/shell开发.assets/image-20201214184902024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/shell开发.assets/image-20201214184902024.png -------------------------------------------------------------------------------- /develop log/shell开发.assets/image-20201214184910842.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/shell开发.assets/image-20201214184910842.png -------------------------------------------------------------------------------- /develop log/shell开发.assets/image-20201214184928696.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/shell开发.assets/image-20201214184928696.png -------------------------------------------------------------------------------- /develop log/shell开发.assets/image-20201218121235555.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/shell开发.assets/image-20201218121235555.png -------------------------------------------------------------------------------- /develop log/shell开发.assets/image-20201218121455968.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/shell开发.assets/image-20201218121455968.png -------------------------------------------------------------------------------- /develop log/shell开发.assets/image-20201220104640561.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/shell开发.assets/image-20201220104640561.png -------------------------------------------------------------------------------- /develop log/shell开发.assets/image-20201220104705559.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/shell开发.assets/image-20201220104705559.png -------------------------------------------------------------------------------- /develop log/shell开发.assets/image-20201220105407188.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/shell开发.assets/image-20201220105407188.png -------------------------------------------------------------------------------- /develop log/shell开发.assets/image-20201220105828910.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/shell开发.assets/image-20201220105828910.png -------------------------------------------------------------------------------- /develop log/shell开发.assets/image-20201220110111956.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/shell开发.assets/image-20201220110111956.png -------------------------------------------------------------------------------- /develop log/shell开发.assets/image-20201220113400355.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/shell开发.assets/image-20201220113400355.png -------------------------------------------------------------------------------- /develop log/shell开发.assets/image-20201224122944221.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/shell开发.assets/image-20201224122944221.png -------------------------------------------------------------------------------- /develop log/shell开发.assets/image-20201224123224878.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/shell开发.assets/image-20201224123224878.png -------------------------------------------------------------------------------- /develop log/shell开发.assets/image-20201224125320840.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/shell开发.assets/image-20201224125320840.png -------------------------------------------------------------------------------- /develop log/shell开发.assets/image-20201227135455095.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/shell开发.assets/image-20201227135455095.png -------------------------------------------------------------------------------- /develop log/shell开发.assets/image-20201227135731370.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/shell开发.assets/image-20201227135731370.png -------------------------------------------------------------------------------- /develop log/shell开发.assets/image-20201227145031868.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/shell开发.assets/image-20201227145031868.png -------------------------------------------------------------------------------- /develop log/shell开发.assets/image-20201227145054871.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/shell开发.assets/image-20201227145054871.png -------------------------------------------------------------------------------- /develop log/文件系统.assets/image-20201130230830833.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/文件系统.assets/image-20201130230830833.png -------------------------------------------------------------------------------- /develop log/文件系统.assets/image-20201202164254808.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/文件系统.assets/image-20201202164254808.png -------------------------------------------------------------------------------- /develop log/文件系统.assets/image-20201204104926918.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/文件系统.assets/image-20201204104926918.png -------------------------------------------------------------------------------- /develop log/文件系统.assets/image-20201209165527135.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/文件系统.assets/image-20201209165527135.png -------------------------------------------------------------------------------- /develop log/文件系统.assets/image-20201210100047188.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/文件系统.assets/image-20201210100047188.png -------------------------------------------------------------------------------- /develop log/文件系统.md: -------------------------------------------------------------------------------- 1 | #### 2020.11.29 2 | 3 | 搞了两天bochs没弄出来,就这样吧,等以后再看看别人怎么踩坑的。 4 | 5 | 开始在qemu下搞文件系统了。。 6 | 7 | 目前计划:先从简单的扇区读写操作开始,然后一步步地向上层走,那么今天先实现下扇区读写吧! 8 | 9 | 由于之前在写boot的时候已经有扇区读写的操作,那么首先进行复用吧,现在缺少的是写扇区操作,看下其他OS是怎么实现的。 10 | 11 | #### 2020.11.30 12 | 13 | 现在基本的扇区读写已经完成了,后续继续进行文件系统的编写。 14 | 15 | ![image-20201130230830833](文件系统.assets/image-20201130230830833.png) 16 | 17 | 感觉之前的task全局变量未初始化是symtab没对应的关系? 18 | 19 | 想多了,应该还是更换页表啥,刷内存了? 20 | 21 | #### 2020.12.2 22 | 23 | ![image-20201204104926918](文件系统.assets/image-20201204104926918.png) 24 | 25 | ![image-20201202164254808](文件系统.assets/image-20201202164254808.png) 26 | 27 | #### 2020.12.3 28 | 29 | 测试之前的代码! 30 | 31 | 文件系统,冲! 32 | 33 | #### 2020.12.8 34 | 35 | 主要问题,初始化分区时会覆盖0x815扇区的东西,所以主分区只需要初始化一次,后面就无需再改了。文件系统目前基本搞定了, 36 | 37 | 考虑下一步做啥?年底前把该项目完结吧! 38 | 39 | 目前需要的模块: 40 | 41 | shell交互 42 | 43 | 进程的fork 44 | 45 | exec加载用户进程 46 | 47 | 进程通信 48 | 49 | #### 2020.12.9 50 | 51 | ![image-20201209165527135](文件系统.assets/image-20201209165527135.png) 52 | 53 | 设置user属性 54 | 55 | ![image-20201210100047188](文件系统.assets/image-20201210100047188.png) -------------------------------------------------------------------------------- /develop log/进程管理.assets/image-20201028150553357.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/进程管理.assets/image-20201028150553357.png -------------------------------------------------------------------------------- /develop log/进程管理.assets/image-20201028150622797.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/进程管理.assets/image-20201028150622797.png -------------------------------------------------------------------------------- /develop log/进程管理.assets/image-20201028150635512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/进程管理.assets/image-20201028150635512.png -------------------------------------------------------------------------------- /develop log/进程管理.assets/image-20201028150719522.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/进程管理.assets/image-20201028150719522.png -------------------------------------------------------------------------------- /develop log/进程管理.assets/image-20201028155912857.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/进程管理.assets/image-20201028155912857.png -------------------------------------------------------------------------------- /develop log/进程管理.assets/image-20201028163341544.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/进程管理.assets/image-20201028163341544.png -------------------------------------------------------------------------------- /develop log/进程管理.assets/image-20201028170650987.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/进程管理.assets/image-20201028170650987.png -------------------------------------------------------------------------------- /develop log/进程管理.assets/image-20201028171053566.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/进程管理.assets/image-20201028171053566.png -------------------------------------------------------------------------------- /develop log/进程管理.assets/image-20201028172237622.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/进程管理.assets/image-20201028172237622.png -------------------------------------------------------------------------------- /develop log/进程管理.assets/image-20201029105108233.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/进程管理.assets/image-20201029105108233.png -------------------------------------------------------------------------------- /develop log/进程管理.assets/image-20201031110400779.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/进程管理.assets/image-20201031110400779.png -------------------------------------------------------------------------------- /develop log/进程管理.assets/image-20201107214550971.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/进程管理.assets/image-20201107214550971.png -------------------------------------------------------------------------------- /develop log/进程管理.assets/image-20201109113404986.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/进程管理.assets/image-20201109113404986.png -------------------------------------------------------------------------------- /develop log/进程管理.assets/image-20201109113620711.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/进程管理.assets/image-20201109113620711.png -------------------------------------------------------------------------------- /develop log/进程管理.assets/image-20201109114654694.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/进程管理.assets/image-20201109114654694.png -------------------------------------------------------------------------------- /develop log/进程管理.assets/image-20201109114703529.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/进程管理.assets/image-20201109114703529.png -------------------------------------------------------------------------------- /develop log/进程管理.assets/image-20201109114725570.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/进程管理.assets/image-20201109114725570.png -------------------------------------------------------------------------------- /develop log/进程管理.assets/image-20201109115238292.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/进程管理.assets/image-20201109115238292.png -------------------------------------------------------------------------------- /develop log/进程管理.assets/image-20201109115339566.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/进程管理.assets/image-20201109115339566.png -------------------------------------------------------------------------------- /develop log/进程管理.assets/image-20201109115838554.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/进程管理.assets/image-20201109115838554.png -------------------------------------------------------------------------------- /develop log/进程管理.assets/image-20201109120022622.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/进程管理.assets/image-20201109120022622.png -------------------------------------------------------------------------------- /develop log/进程管理.assets/image-20201109120038458.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/进程管理.assets/image-20201109120038458.png -------------------------------------------------------------------------------- /develop log/进程管理.assets/image-20201109120046496.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/进程管理.assets/image-20201109120046496.png -------------------------------------------------------------------------------- /develop log/进程管理.assets/image-20201109120730976.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/进程管理.assets/image-20201109120730976.png -------------------------------------------------------------------------------- /develop log/进程管理.assets/image-20201109120740246.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/进程管理.assets/image-20201109120740246.png -------------------------------------------------------------------------------- /develop log/进程管理.assets/image-20201109141540434.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/进程管理.assets/image-20201109141540434.png -------------------------------------------------------------------------------- /develop log/进程管理.assets/image-20201109142503518.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/进程管理.assets/image-20201109142503518.png -------------------------------------------------------------------------------- /develop log/进程管理.assets/image-20201109142957276.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/进程管理.assets/image-20201109142957276.png -------------------------------------------------------------------------------- /develop log/进程管理.assets/image-20201109143011225.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/进程管理.assets/image-20201109143011225.png -------------------------------------------------------------------------------- /develop log/进程管理.assets/image-20201112213907790.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/进程管理.assets/image-20201112213907790.png -------------------------------------------------------------------------------- /develop log/进程管理.assets/image-20201112220433866.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/进程管理.assets/image-20201112220433866.png -------------------------------------------------------------------------------- /develop log/进程管理.assets/image-20201114223946224.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/进程管理.assets/image-20201114223946224.png -------------------------------------------------------------------------------- /develop log/进程管理.assets/image-20201114225423431.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/进程管理.assets/image-20201114225423431.png -------------------------------------------------------------------------------- /develop log/进程管理.assets/image-20201115001143139.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/进程管理.assets/image-20201115001143139.png -------------------------------------------------------------------------------- /develop log/进程管理.assets/image-20201115130126586.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/进程管理.assets/image-20201115130126586.png -------------------------------------------------------------------------------- /develop log/进程管理.assets/image-20201116163832938.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/进程管理.assets/image-20201116163832938.png -------------------------------------------------------------------------------- /develop log/进程管理.assets/image-20201116163900130.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/进程管理.assets/image-20201116163900130.png -------------------------------------------------------------------------------- /develop log/进程管理.assets/image-20201116170112119.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/进程管理.assets/image-20201116170112119.png -------------------------------------------------------------------------------- /develop log/进程管理.assets/image-20201116170203467.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/进程管理.assets/image-20201116170203467.png -------------------------------------------------------------------------------- /develop log/进程管理.assets/image-20201116175645950.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/进程管理.assets/image-20201116175645950.png -------------------------------------------------------------------------------- /develop log/进程管理.assets/image-20201116175701794.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/进程管理.assets/image-20201116175701794.png -------------------------------------------------------------------------------- /develop log/进程管理.assets/image-20201116175715739.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/进程管理.assets/image-20201116175715739.png -------------------------------------------------------------------------------- /develop log/进程管理.assets/image-20201116180033538.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/进程管理.assets/image-20201116180033538.png -------------------------------------------------------------------------------- /develop log/进程管理.assets/image-20201116185536261.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/进程管理.assets/image-20201116185536261.png -------------------------------------------------------------------------------- /develop log/进程管理.assets/image-20201116185841415.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/进程管理.assets/image-20201116185841415.png -------------------------------------------------------------------------------- /develop log/进程管理.assets/image-20201118111651158.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/进程管理.assets/image-20201118111651158.png -------------------------------------------------------------------------------- /develop log/进程管理.assets/image-20201118162706509.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/进程管理.assets/image-20201118162706509.png -------------------------------------------------------------------------------- /develop log/进程管理.assets/image-20201118174311301.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/进程管理.assets/image-20201118174311301.png -------------------------------------------------------------------------------- /develop log/进程管理.assets/image-20201118221800059.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/进程管理.assets/image-20201118221800059.png -------------------------------------------------------------------------------- /develop log/进程管理.assets/image-20201118221810548.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/进程管理.assets/image-20201118221810548.png -------------------------------------------------------------------------------- /develop log/进程管理.assets/image-20201125100131036.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/进程管理.assets/image-20201125100131036.png -------------------------------------------------------------------------------- /develop log/进程管理.assets/image-20201125101932808.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/进程管理.assets/image-20201125101932808.png -------------------------------------------------------------------------------- /develop log/进程管理.assets/image-20201125102130838.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/进程管理.assets/image-20201125102130838.png -------------------------------------------------------------------------------- /develop log/进程管理.assets/image-20201125102310696.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/进程管理.assets/image-20201125102310696.png -------------------------------------------------------------------------------- /develop log/进程管理.assets/image-20201125102808331.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/进程管理.assets/image-20201125102808331.png -------------------------------------------------------------------------------- /develop log/进程管理.assets/image-20201125102907078.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/进程管理.assets/image-20201125102907078.png -------------------------------------------------------------------------------- /develop log/进程管理.assets/image-20201125102942400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/develop log/进程管理.assets/image-20201125102942400.png -------------------------------------------------------------------------------- /disassembly/readme.assets/image-20201231143254582.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/disassembly/readme.assets/image-20201231143254582.png -------------------------------------------------------------------------------- /disassembly/readme.assets/image-20201231143309533.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/disassembly/readme.assets/image-20201231143309533.png -------------------------------------------------------------------------------- /disassembly/readme.assets/image-20201231143320631.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/disassembly/readme.assets/image-20201231143320631.png -------------------------------------------------------------------------------- /disassembly/readme.assets/image-20201231143332349.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/disassembly/readme.assets/image-20201231143332349.png -------------------------------------------------------------------------------- /disassembly/readme.md: -------------------------------------------------------------------------------- 1 | #### 该目录主要是可执行文件的反汇编 2 | 3 | 只能看到.text段的数据,简单示意下。 4 | 5 | boot_disass.md =====》》》》bootblock(引导程序)的反汇编 6 | 7 | kernel_disass.md =====》》》》kernel(内核)的反汇编代码 8 | 9 | test_cat.md =====》》》》test_cat(cat测试程序)的反汇编代码 10 | 11 | test_exec_disass.md =====》》》》test_exec(exec测试程序)的反汇编代码 12 | 13 | test_pipe_disass.md =====》》》》test_pipe(pipe测试程序)的反汇编代码 14 | 15 | 通过以下命令可获得: 16 | 17 | ![image-20201231143254582](readme.assets/image-20201231143254582.png) 18 | 19 | ![image-20201231143309533](readme.assets/image-20201231143309533.png) 20 | 21 | ![image-20201231143320631](readme.assets/image-20201231143320631.png) 22 | 23 | ![image-20201231143332349](readme.assets/image-20201231143332349.png) 24 | 25 | -------------------------------------------------------------------------------- /elf/readme.assets/image-20201231143543363.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/elf/readme.assets/image-20201231143543363.png -------------------------------------------------------------------------------- /elf/readme.md: -------------------------------------------------------------------------------- 1 | #### 该目录主要记录了kernel内核作为一个ELF文件的基本信息,通过以下命令获得。 2 | 3 | ![image-20201231143543363](readme.assets/image-20201231143543363.png) 4 | 5 | 要注意的一个点是,ELF文件在硬盘中的大小和在内存中的大小并不是一样的,打个比方,硬盘中的ELF文件并不包括BSS段的大小,也就是未初始化的全局变量等(默认为0的变量),那我们需要读取ELF文件信息来查看它到底有多大,读到内存后,给bss段也要分配空间,防止产生页错误。 -------------------------------------------------------------------------------- /gdbinit: -------------------------------------------------------------------------------- 1 | target remote 127.0.0.1:1234 2 | file build/kernel/kernel 3 | #file build/test_pipe/test_pipe 4 | #b syscall_exit 5 | #b wait 6 | #b task_exit 7 | #b sys_exit 8 | #b main 9 | 10 | #b my_shell 11 | #b sys_wait 12 | #b sys_execv 13 | #b sys_exit 14 | #b copy_thread 15 | #b exit 16 | #b sys_exit 17 | #b main 18 | b do_fork 19 | c 20 | -------------------------------------------------------------------------------- /kernel/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/kernel/.DS_Store -------------------------------------------------------------------------------- /kernel/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #设置项目名 2 | project (kernel C ASM) 3 | 4 | add_subdirectory(init) 5 | add_subdirectory(asm) 6 | add_subdirectory(debug) 7 | add_subdirectory(dt) 8 | add_subdirectory(interrupt) 9 | add_subdirectory(keyboard) 10 | add_subdirectory(main) 11 | add_subdirectory(mem) 12 | add_subdirectory(task) 13 | add_subdirectory(pic) 14 | add_subdirectory(serial) 15 | add_subdirectory(timer) 16 | add_subdirectory(vga) 17 | add_subdirectory(sync) 18 | add_subdirectory(file) 19 | add_subdirectory(user) 20 | add_subdirectory(pipe) 21 | add_subdirectory(apic) 22 | add_subdirectory(mp) 23 | add_subdirectory(ap) 24 | add_subdirectory(internet) 25 | add_subdirectory(socket) 26 | add_executable(${PROJECT_NAME} 27 | $ 28 | $ 29 | $ 30 | $ 31 | $ 32 | $ 33 | $ 34 | $ 35 | $ 36 | $ 37 | $ 38 | $ 39 | $ 40 | $ 41 | $ 42 | $ 43 | $ 44 | $ 45 | $ 46 | $ 47 | $ 48 | $ 49 | ) 50 | 51 | target_link_options(${PROJECT_NAME} PRIVATE -T ${FreeFlyOS_SOURCE_DIR}/kernel/kernel.ld) 52 | target_link_options(${PROJECT_NAME} PRIVATE -Wl,-melf_i386) 53 | #target_link_options(${PROJECT_NAME} PRIVATE -Wl,--format=binary $) 54 | 55 | #set(IMG "FreeFlyOS.img") 56 | #add_custom_command(OUTPUT ${IMG} 57 | #DEPENDS 58 | # ${PROJECT_NAME} 59 | add_custom_command(TARGET ${PROJECT_NAME} 60 | POST_BUILD 61 | COMMAND 62 | x86_64-elf-objdump -d ../../build/boot/bootblock.o > ../../disassembly/boot_disass.md 63 | COMMAND 64 | x86_64-elf-objdump -d kernel > ../../disassembly/kernel_disass.md 65 | COMMAND 66 | x86_64-elf-readelf -a kernel > ../../elf/kernel_elf.md 67 | COMMAND 68 | echo "Generating FreeFlyOS.img..." 69 | #COMMAND 70 | # dd if=/dev/zero of=${IMG} count=10000 71 | #COMMAND 72 | # cp /Users/caoy/Downloads/FreeFlyOS.img ../../FreeFlyOS.img 73 | COMMAND 74 | dd if=../boot/bootblock of=../../FreeFlyOS.img bs=446 count=1 conv=notrunc 75 | COMMAND 76 | dd if=kernel of=../../FreeFlyOS.img seek=1 conv=notrunc 77 | ) 78 | #add_custom_target(Test1 ALL DEPENDS ${IMG}) 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | -------------------------------------------------------------------------------- /kernel/ap/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #设置项目名 2 | project (ap) 3 | 4 | add_library(${PROJECT_NAME} OBJECT ap.c start_ap.S) 5 | target_include_directories(${PROJECT_NAME} 6 | PUBLIC 7 | ${FreeFlyOS_SOURCE_DIR}/kernel/ap 8 | ${FreeFlyOS_SOURCE_DIR}/kernel/mem 9 | ${FreeFlyOS_SOURCE_DIR}/kernel/apic 10 | ${FreeFlyOS_SOURCE_DIR}/kernel/asm 11 | ) -------------------------------------------------------------------------------- /kernel/ap/ap.h: -------------------------------------------------------------------------------- 1 | /* ap start args */ 2 | #define AP_PGDIR (0x8110) 3 | #define AP_KSTACK (AP_PGDIR + 4) 4 | #define AP_MAIN (AP_KSTACK + 4) 5 | #define AP_INDEX (AP_MAIN + 4) 6 | 7 | #define AP_START_ADDR (0x9000) /* 36k, APs will start from here */ 8 | 9 | #define SEG_KCODE (1) 10 | #define SEG_KDATA (2) 11 | /* for cr0 */ 12 | #define CR0_PE 0x00000001 13 | #define CR0_PG 0x80000000 14 | #define CR0_WP 0x00010000 15 | 16 | #define CPU_NUM 2 17 | -------------------------------------------------------------------------------- /kernel/ap/apheader.h: -------------------------------------------------------------------------------- 1 | void ap_init(); 2 | void start_ap(unsigned int id,unsigned int addr); 3 | void apmain(unsigned int index); -------------------------------------------------------------------------------- /kernel/ap/start_ap.S: -------------------------------------------------------------------------------- 1 | #include "ap.h" 2 | .text 3 | .code16 4 | .global apstart 5 | apstart: 6 | cli 7 | 8 | xorw %ax, %ax 9 | movw %ax, %ds 10 | movw %ax, %es 11 | movw %ax, %ss 12 | movl $0x7C00,%esp 13 | 14 | lgdt gdt_ptr 15 | movl %cr0, %eax 16 | orl $CR0_PE, %eax 17 | movl %eax, %cr0 18 | #display: 19 | #movw $0x18,%ax 20 | #movw %ax,%gs 21 | #movl $((80*1+1)*2),%edi/*第11行,79列*/ 22 | #movb $0x0c,%ah/*高四位表示黑底,低四位表示红字*/ 23 | #movb $'Y',%al/*显示的字符*/ 24 | #movw %ax,%gs:(%edi) 25 | 26 | #2: 27 | # jmp display 28 | ljmpl $(SEG_KCODE<<3), $(apstart32) 29 | 30 | .code32 31 | apstart32: 32 | movw $(SEG_KDATA<<3), %ax 33 | movw %ax, %ds 34 | movw %ax, %es 35 | movw %ax, %ss 36 | xorw %ax, %ax 37 | movw %ax, %fs 38 | movw %ax, %gs 39 | 40 | # setup page directory 41 | movl (AP_PGDIR), %eax 42 | movl %eax, %cr3 43 | 44 | # turn on paging 45 | movl %cr0, %eax 46 | orl $(CR0_PG), %eax 47 | movl %eax, %cr0 48 | 49 | # set a new stack 50 | movl (AP_KSTACK), %esp 51 | pushl (AP_INDEX) 52 | call apmain 53 | 1: 54 | jmp 1b 55 | 56 | 57 | 58 | 59 | .align 2 60 | gdt: 61 | .quad 0x0000000000000000 62 | .quad 0x00cf9a000000ffff 63 | .quad 0x00cf92000000ffff 64 | .quad 0x0000920b8000ffff 65 | 66 | gdt_ptr: 67 | .word (gdt_ptr - gdt - 1) 68 | .long gdt 69 | 70 | -------------------------------------------------------------------------------- /kernel/apic/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #设置项目名 2 | project (apic) 3 | 4 | add_library(${PROJECT_NAME} OBJECT apic.c) 5 | target_include_directories(${PROJECT_NAME} 6 | PUBLIC 7 | ${FreeFlyOS_SOURCE_DIR}/kernel/apic 8 | ${FreeFlyOS_SOURCE_DIR}/kernel/vga 9 | ${FreeFlyOS_SOURCE_DIR}/kernel/timer 10 | ${FreeFlyOS_SOURCE_DIR}/kernel/asm 11 | ) -------------------------------------------------------------------------------- /kernel/apic/apic.h: -------------------------------------------------------------------------------- 1 | /********************** 多核 ***************************/ 2 | #define APIC_BASE (0xfee00000) 3 | #define HZ (100) 4 | #define CALIBRATE_LOOP (HZ/10) 5 | #define MSR_IA32_APICBASE (0x1b) 6 | #define MSR_IA32_APICBASE_ENABLE (1<<11) 7 | 8 | #define APIC_ID 0x20 9 | #define APIC_LVR 0x30 10 | #define APIC_TPR 0x80 11 | #define APIC_EOI 0xb0 12 | #define APIC_SPIV 0xf0 13 | 14 | /* Local Vector Table */ 15 | #define APIC_LVT_CMCI 0x2f0 /* LVT Machine Check */ 16 | #define APIC_ICR_LOW 0x300 /* Interrupt Command Register 0-31 */ 17 | #define APIC_ICR_HIGH 0x310 /* Interrupt Command Register 32-63 */ 18 | #define APIC_LVT_TIMER 0x320 /* LVT Timer register */ 19 | #define APIC_LVT_THMR 0x330 /* LVT Thermal Sensor register */ 20 | #define APIC_LVT_PMCR 0x340 /* LVT Performance Monitoring Counter register */ 21 | #define APIC_LVT_LINT0 0x350 /* LVT LINT0 register */ 22 | #define APIC_LVT_LINT1 0x360 /* LVT LINT1 register */ 23 | #define APIC_LVT_ERROR 0x370 /* LVT Error register */ 24 | 25 | #define APIC_SPIV_DIRECTED_EOI (1 << 12) 26 | #define APIC_SPIV_FOCUS_DISABLED (1 << 9) 27 | #define APIC_SPIV_APIC_ENABLED (1 << 8) 28 | 29 | /* Timer */ 30 | #define APIC_TIMER_ICT 0x380 /* Timer initial count register */ 31 | #define APIC_TIMER_CCT 0x390 /* Timer current count register */ 32 | #define APIC_TIMER_DCR 0x3E0 /* Timer divide configuration register */ 33 | 34 | #define MASKED 0x00010000 /* Interrupt masked */ 35 | 36 | /* ICR */ 37 | #define APIC_DM_INIT 0x500 38 | #define APIC_DM_STARTUP 0x600 39 | #define APIC_INT_ASSERT 0x4000 40 | #define APIC_INT_LEVEL_TRIG 0x8000 41 | 42 | #define IO_APIC_REG_ID 0x00 43 | #define IO_APIC_REG_VER 0x01 44 | #define IO_APIC_REG_TABLE 0x10 /* redirection table */ 45 | 46 | #define INT_DISABLED 0x00010000 47 | 48 | #define IO_APIC_BASE 0xfec00000 /* default address map */ 49 | 50 | /* SPIV */ 51 | #define APIC_SOFT_ENABLE (0x100) 52 | 53 | #define rdmsr(msr,val1,val2) \ 54 | __asm__ volatile("rdmsr" \ 55 | : "=a" (val1), "=d" (val2) \ 56 | : "c" (msr)) 57 | 58 | #define wrmsr(msr,val1,val2) \ 59 | __asm__ volatile("wrmsr" \ 60 | : /* no outputs */ \ 61 | : "c" (msr), "a" (val1), "d" (val2)) 62 | 63 | #define rdtsc(low,high) \ 64 | __asm__ __volatile__("rdtsc" : "=a" (low), "=d" (high)) 65 | 66 | #define rdtsc64(val) \ 67 | __asm__ __volatile__("rdtsc" : "=A" (val)) 68 | 69 | #define io_mfence() __asm__ __volatile__ ("mfence \n\t":::"memory") 70 | /********************** 多核 ***************************/ 71 | void apic_write(unsigned int reg, unsigned int v); 72 | void apic_write64(unsigned long long reg, unsigned long long v); 73 | unsigned int apic_read(unsigned int reg); 74 | unsigned long long apic_read64(unsigned int reg); 75 | void test_apic(); 76 | int check(); 77 | void setup_lvt_timer(unsigned int clocks); 78 | unsigned int calibrate_clock(); 79 | int init_timer(); 80 | int init_apic(); 81 | void init_lapic(void); 82 | void do_timer_irq(); 83 | void eoi(); 84 | void ioapic_init(); 85 | void enable_irq(unsigned int irq, unsigned int cpu_id); 86 | unsigned int ioapic_read(unsigned int reg); 87 | void ioapic_write(unsigned int reg, unsigned int data); 88 | void get_cpuid(unsigned int Mop,unsigned int Sop,unsigned int * a,unsigned int * b,unsigned int * c,unsigned int * d); 89 | void Local_APIC_init(); 90 | void APIC_IOAPIC_init(); -------------------------------------------------------------------------------- /kernel/asm/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #设置项目名 2 | project (asm) 3 | 4 | add_library(${PROJECT_NAME} OBJECT asm.c) 5 | target_include_directories(${PROJECT_NAME} 6 | PUBLIC 7 | ${FreeFlyOS_SOURCE_DIR}/kernel/asm 8 | ) -------------------------------------------------------------------------------- /kernel/asm/asm.h: -------------------------------------------------------------------------------- 1 | #ifndef _ASM_H_ 2 | #define _ASM_H_ 3 | 4 | /* 5 | ** 32位机下只能使用被除数最大为32位的除法,为了支持64位被除数的除法,构建do_div宏 6 | ** 支持任意除数除操作。n 被除数;base 除数。结果 n 为商,函数返回值为余数。 7 | */ 8 | #define do_div(n, base) ({ \ 9 | unsigned long __upper, __low, __high, __mod, __base; \ 10 | __base = (base); \ 11 | asm ("" : "=a" (__low), "=d" (__high) : "A" (n)); \ 12 | __upper = __high; \ 13 | if (__high != 0) { \ 14 | __upper = __high % __base; \ 15 | __high = __high / __base; \ 16 | } \ 17 | asm ("divl %2" : "=a" (__low), "=d" (__mod) \ 18 | : "rm" (__base), "0" (__low), "1" (__upper)); \ 19 | asm ("" : "=A" (n) : "a" (__low), "d" (__high)); \ 20 | __mod; \ 21 | }) 22 | 23 | //read a byte from port 24 | unsigned char inb(unsigned short port); 25 | //read a word from port 26 | unsigned short inw(unsigned short port); 27 | //read two word from port 28 | unsigned int inl(unsigned short port); 29 | //write a byte to port 30 | void outb(unsigned short port,unsigned char data); 31 | //write a word to port 32 | void outw(unsigned short port, unsigned short data); 33 | //write two word to port 34 | void outl(unsigned short port, unsigned int data); 35 | void *memset(void *s, char c, unsigned int n); 36 | void *memcpy(void *dst, const void *src, unsigned int n); 37 | unsigned int strlen(const char *s); 38 | int strcmp(const char *s1, const char *s2); 39 | char* strrchr(const char* str, const unsigned char ch); 40 | char* strcat(char* dst_, const char* src_); 41 | char* strcpy(char* dst_, const char* src_); 42 | void CPU_INVLPG(unsigned int addr); 43 | void lcr3(unsigned int cr3); 44 | int memcmp(const void* a_, const void* b_, unsigned int size) ; 45 | void nop(void); 46 | #endif -------------------------------------------------------------------------------- /kernel/asm/readme.md: -------------------------------------------------------------------------------- 1 | ## asm.c 2 | 3 | 通过C语言函数实现嵌入汇编指令 4 | 5 | ## asm.h 6 | 7 | 函数的声明以及64位除法的实现 8 | 9 | 呃,这个asm目录其实写的有点乱,不仅有嵌入汇编代码,还有字符串的一些操作,以及刷新TLB、加载cr3寄存器等,看看就好了。 -------------------------------------------------------------------------------- /kernel/debug/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #设置项目名 2 | project (debug) 3 | 4 | add_library(${PROJECT_NAME} OBJECT debug.c monitor.c readline.c) 5 | target_include_directories(${PROJECT_NAME} 6 | PUBLIC 7 | ${FreeFlyOS_SOURCE_DIR}/kernel/debug 8 | ${FreeFlyOS_SOURCE_DIR}/kernel/vga 9 | ${FreeFlyOS_SOURCE_DIR}/kernel/interrupt 10 | ${FreeFlyOS_SOURCE_DIR}/kernel/asm 11 | ) 12 | -------------------------------------------------------------------------------- /kernel/debug/debug.c: -------------------------------------------------------------------------------- 1 | #include "debug.h" 2 | #include "monitor.h" 3 | #include "../vga/vga.h" 4 | #include "../interrupt/trap.h" 5 | 6 | /* 7 | * 打印段寄存器信息 8 | */ 9 | void print_seg() 10 | { 11 | unsigned short cs,ds,gs,es,fs,ss; 12 | asm volatile("movw %%cs, %0;" 13 | "movw %%ds, %1;" 14 | "movw %%gs, %2;" 15 | "movw %%es, %3;" 16 | "movw %%fs, %4;" 17 | "movw %%ss, %5;": "=m"(cs),"=m"(ds),"=m"(gs),"=m"(es),"=m"(fs),"=m"(ss)); 18 | printk("cs=%04x\n",cs); 19 | printk("ds=%04x\n",ds); 20 | printk("gs=%04x\n",gs); 21 | printk("es=%04x\n",es); 22 | printk("fs=%04x\n",fs); 23 | printk("ss=%04x\n",ss); 24 | } 25 | 26 | /* * 27 | * __panic - __panic is called on unresolvable fatal errors. it prints 28 | * "panic: 'message'", and then enters the kernel monitor. 29 | * */ 30 | void 31 | __PANIC(const char *file, int line, const char *func, const char *condition) { 32 | 33 | // 关中断 34 | intr_disable(); 35 | 36 | // 打印错误信息 37 | printk("kernel panic at %s:%d:\n ", file, line); 38 | printk("In %s , the condition(%s) is wrong\n",func,condition); 39 | 40 | //printk("stack trackback:\n"); 41 | //print_seg(); 42 | 43 | while (1) { 44 | monitor(); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /kernel/debug/debug.h: -------------------------------------------------------------------------------- 1 | #ifndef _DEBUG_H_ 2 | #define _DEBUG_H_ 3 | 4 | #define PANIC(...) \ 5 | __PANIC(__FILE__ , __LINE__ , __func__ , __VA_ARGS__) 6 | 7 | #define ASSERT(x) \ 8 | if (!(x)) { \ 9 | PANIC(#x); \ 10 | } \ 11 | else{} 12 | 13 | 14 | void print_seg(); 15 | void __attribute__((noreturn)) 16 | __PANIC(const char *file, int line, const char *func, const char *condition); 17 | 18 | #endif -------------------------------------------------------------------------------- /kernel/debug/monitor.c: -------------------------------------------------------------------------------- 1 | #include "monitor.h" 2 | #include "readline.h" 3 | #include "../vga/vga.h" 4 | #include "../interrupt/trap.h" 5 | #include "../asm/asm.h" 6 | extern unsigned int shift; 7 | 8 | /* 9 | ** 初始化指令数组 10 | */ 11 | struct instr instr_list[]={ 12 | {"hello","The instruction is to welcome you!",instr_hello}, 13 | {"help","You can use the following instructions!",instr_help}, 14 | {"game","Play a simple game---Guess number!",instr_game} 15 | }; 16 | 17 | #define instr_num (sizeof(instr_list)/sizeof(struct instr)) 18 | 19 | /* 20 | ** 监视器:用于监控用户输入字符 21 | */ 22 | void monitor(){ 23 | char *buf; 24 | shift=0; 25 | while(1){ 26 | if((buf=(readline("K<")))!=NULL){ 27 | run(buf); 28 | } 29 | } 30 | } 31 | /* 32 | ** 解析器:用于解析用户输入字符 33 | */ 34 | void run(char *buf){ 35 | for(int i=0;i= ' ' && i < BUFSIZE - 1) { 47 | cons_putc(c); 48 | buf[i ++] = c; 49 | } 50 | else if (c == '\b' && i > 0) { 51 | cons_putc(c); 52 | i --; 53 | } 54 | else if (c == '\n' || c == '\r') { 55 | cons_putc(c); 56 | buf[i] = '\0'; 57 | return buf; 58 | } 59 | } 60 | } 61 | 62 | -------------------------------------------------------------------------------- /kernel/debug/readline.h: -------------------------------------------------------------------------------- 1 | #ifndef _READLINE_H_ 2 | #define _READLINE_H_ 3 | 4 | int getchar(void); 5 | char *readline(const char *prompt); 6 | #endif -------------------------------------------------------------------------------- /kernel/debug/readme.assets/image-20201231154556175.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/kernel/debug/readme.assets/image-20201231154556175.png -------------------------------------------------------------------------------- /kernel/debug/readme.assets/image-20201231155706920.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/kernel/debug/readme.assets/image-20201231155706920.png -------------------------------------------------------------------------------- /kernel/debug/readme.md: -------------------------------------------------------------------------------- 1 | #### debug.c 2 | 3 | 包含两个函数,一个是打印寄存器信息,另一个是设置断言失败的结果 4 | 5 | #### debug.h 6 | 7 | 设置断言 8 | 9 | ![image-20201231155706920](readme.assets/image-20201231155706920.png) 10 | 11 | 什么是断言呢,简单来讲就是当程序执行到某一步时,它的状态一定是我预料的状态,也就是我设置的条件必须为真,如果不为真,那么内核就会退出(PANIC),然后运行PANIC函数。这里简单说明下PANIC的几个参数,__FILE__、__LINE__和__func__为C语言中预定义的宏,分别代表当前文件名、当前函数名、运行当前文件的行数,而__VA_ARGS__则是预处理器专门提供的一个标识符,只允许在具有可变参数的宏替换列表中出现,表示该参数至少有一个,但可以为空。我们这里设置的PANIC函数除了前3个宏,只有一个参数,就是断言的判断条件。 12 | 13 | #### monitor.c 14 | 15 | 该文件主要定义了一个类似shell的对话机制,首先需要初始化指令数组,然后分配一个监视器不断读取用户输入的字符,然后使用解析器将用户的字符和预设的指令名称进行匹配,若匹配成功则运行相应指令。 16 | 17 | #### monitor.h 18 | 19 | monitor.c对应的头文件,其中设置了一个函数指针,用于处理不同指令。 20 | 21 | #### readline.c 22 | 23 | 主要是对输入的字符进行处理,当输入普通字符时,将其记录在buf中,输入退格键,则buf数组清一位,当输入回车键或者换行符,表示指令输入完成,输出buf。 24 | 25 | #### readline.h 26 | 27 | readline.c对应的头文件,相对比较简单,没啥可讲的。 28 | 29 | 讲真的,断言其实没必要实现,但实现之后对我们调试有很大的帮助,因为当你无法判断某个函数会不会受某些事件(比如进程切换)影响时,就可以加上一个断言,确认其他事件的状态,保证函数能够正常运行,或者函数出错,再去对断言条件进行分析。呃,由于FreeFlyOS调试好了,基本不会出现断言错误,即monitor不会运行。之前是做这个是因为还没实现shell机制,所以想着先搞个对话机制,支持3种命令。hello、help和game,嘻嘻,一个简单的猜数字游戏,无聊时做的。。。 30 | 31 | -------------------------------------------------------------------------------- /kernel/dt/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #设置项目名 2 | project (dt) 3 | add_library(${PROJECT_NAME} OBJECT dt.c) 4 | target_include_directories(${PROJECT_NAME} 5 | PUBLIC 6 | ${FreeFlyOS_SOURCE_DIR}/kernel/asm 7 | ${FreeFlyOS_SOURCE_DIR}/kernel/dt 8 | ) 9 | -------------------------------------------------------------------------------- /kernel/dt/dt.c: -------------------------------------------------------------------------------- 1 | #include "dt.h" 2 | #include "../asm/asm.h" 3 | #include "../mem/memlayout.h" 4 | /* * 5 | * Global Descriptor Table: 6 | * 7 | * The kernel and user segments are identical (except for the DPL). To load 8 | * the %ss register, the CPL must equal the DPL. Thus, we must duplicate the 9 | * segments for the user and the kernel. Defined as follows: 10 | * - 0x0 : unused (always faults -- for trapping NULL far pointers) 11 | * - 0x8 : kernel code segment 12 | * - 0x10: kernel data segment 13 | * - 0x18: user code segment 14 | * - 0x20: user data segment 15 | * - 0x28: defined for tss 16 | * */ 17 | struct segdesc gdt[] = { 18 | SEG_NULL, //null 19 | SEG(STA_X | STA_R, 0x0, 0xFFFFFFFF, DPL_KERNEL), //kernel text 20 | SEG(STA_W, 0x0, 0xFFFFFFFF, DPL_KERNEL), //kernel data 21 | SEG(STA_X | STA_R, 0x0, 0xFFFFFFFF, DPL_USER), //user text 22 | SEG(STA_W, 0x0, 0xFFFFFFFF, DPL_USER), //user data 23 | SEG_NULL, //tss 24 | SEG_NULL //ldt0 25 | }; 26 | 27 | /* * 28 | * Interrupt descriptor table: 29 | * 30 | * Must be built at run time because shifted function addresses can't 31 | * be represented in relocation records. 32 | * */ 33 | static struct gatedesc idt[256] = {{0}}; 34 | 35 | /* * 36 | * set gdt's info 37 | * */ 38 | static struct dtdesc gdtinfo={ 39 | sizeof(gdt)-1,(unsigned int)gdt 40 | }; 41 | 42 | /* * 43 | * set tss 44 | * */ 45 | static struct taskstate ts = {0}; 46 | 47 | /* * 48 | * set idt's info 49 | * */ 50 | static struct dtdesc idtinfo = { 51 | sizeof(idt) - 1, (unsigned int)idt 52 | }; 53 | 54 | /* * 55 | * lgdt - load the global descriptor table register and reset the 56 | * data/code segement registers for kernel. 57 | * */ 58 | static inline void lgdt(struct dtdesc *dt){ 59 | asm volatile ("lgdt (%0)" :: "r" (dt)); 60 | asm volatile ("movw %%ax, %%gs" :: "a" (USER_DS)); 61 | asm volatile ("movw %%ax, %%fs" :: "a" (USER_DS)); 62 | asm volatile ("movw %%ax, %%es" :: "a" (KERNEL_DS)); 63 | asm volatile ("movw %%ax, %%ds" :: "a" (KERNEL_DS)); 64 | asm volatile ("movw %%ax, %%ss" :: "a" (KERNEL_DS)); 65 | // reload cs 66 | asm volatile ("ljmp %0, $1f\n 1:\n" :: "i" (KERNEL_CS)); 67 | } 68 | 69 | /* * 70 | * 加载任务寄存器 71 | * */ 72 | void ltr(unsigned short sel) { 73 | asm volatile ("ltr %0" :: "r" (sel) : "memory"); 74 | } 75 | 76 | /* * 77 | * 加载全局描述符表 78 | * */ 79 | void gdt_init(){ 80 | // set boot kernel stack and default SS0 81 | ts.ts_esp0=(unsigned int)KERNEL_STACK_START; 82 | ts.ts_ss0 = KERNEL_DS; 83 | 84 | // initialize the TSS filed of the gdt 85 | gdt[SEG_TSS] = SEGTSS(STS_T32A, (unsigned int)&ts, sizeof(ts), DPL_KERNEL); 86 | 87 | // reload all segment registers 88 | lgdt(&gdtinfo); 89 | 90 | // load the TSS 91 | ltr(GD_TSS); 92 | } 93 | 94 | /* * 95 | * 加载中断描述符表 96 | * */ 97 | static inline void lidt(struct dtdesc *dt) { 98 | asm volatile ("lidt (%0)" :: "r" (dt) : "memory"); 99 | } 100 | 101 | /* * 102 | * 103 | * 将中断向量号和中断向量进行绑定 104 | * 加载中断描述符表 105 | * 106 | * */ 107 | void idt_init(){ 108 | extern unsigned int __vectors[]; 109 | int i; 110 | for (i = 0; i < sizeof(idt) / sizeof(struct gatedesc); i ++) { 111 | SETGATE(idt[i], 0, GD_KTEXT, __vectors[i], DPL_KERNEL); 112 | } 113 | SETGATE(idt[T_SYSCALL], 1, GD_KTEXT, __vectors[T_SYSCALL], DPL_USER); 114 | //测试专用 115 | SETGATE(idt[0x60], 1, GD_KTEXT, __vectors[0x60], DPL_USER); 116 | lidt(&idtinfo); 117 | } 118 | 119 | /* * 120 | * 设置TSS的内核栈(ring0权限) 121 | * */ 122 | void set_ts_esp0(unsigned int esp){ 123 | ts.ts_esp0=esp; 124 | } -------------------------------------------------------------------------------- /kernel/dt/readme.assets/image-20210101122530922.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/kernel/dt/readme.assets/image-20210101122530922.png -------------------------------------------------------------------------------- /kernel/dt/readme.assets/image-20210101122550051.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/kernel/dt/readme.assets/image-20210101122550051.png -------------------------------------------------------------------------------- /kernel/dt/readme.assets/image-20210101122704418.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/kernel/dt/readme.assets/image-20210101122704418.png -------------------------------------------------------------------------------- /kernel/dt/readme.assets/image-20210101123853989.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/kernel/dt/readme.assets/image-20210101123853989.png -------------------------------------------------------------------------------- /kernel/dt/readme.assets/image-20210101130142268.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/kernel/dt/readme.assets/image-20210101130142268.png -------------------------------------------------------------------------------- /kernel/dt/readme.md: -------------------------------------------------------------------------------- 1 | ## dt.c 2 | 3 | 主要功能:GDT和IDT表的建立和加载 4 | 5 | 1、GDT表在bootsector.S中就建立了,但那处于16位实模式下,而此时程序已进入32位保护模式,GDT每个段描述符限长变成4GB,所以需要建立一个新的GDT表,并加载到GDTR寄存器中。 6 | 7 | 2、IDT表和GDT表不同的是需要设置中断号和中断向量,并将硬件PIC上的中断号和中断向量绑定,当发生一个硬件中断时,比如按下键盘,PIC就会向系统送一个中断号(硬件完成),然后就会去IDT表中找该中断号对应的中断向量,然后执行相应的中断服务处理程序。 8 | 9 | ## dt.h 10 | 11 | gdt和idt的属性设置 12 | 13 | 大概说下我理解的gdt和idt吧,详情可见intel手册或者博客。 14 | 15 | gdt一般分为3个部分,一个部分为内核使用的段,KERNEL_CS也就是kernel code segment(内核代码段),KERNEL_DS也就是kernel data segment(内核数据段),一个部分是用户使用的段,USER_CS也就是user code segment(用户代码段),USER_DS是user data segment(用户数据段),最后一部分为TSS段,为什么要分为这3部分呢,就我的理解,内核段和用户段主要是为了区分内核代码和用户代码,从而保护内核数据,现代的TSS段一般没多大作用,因为以前的TSS段可以起到分割进程的作用,比如每个任务占有多少MB,多少个任务就有多少个TSS,但现在由于使用虚拟地址,每个任务都看似独占4G空间,以前由TSS界定进程地址空间,现在由进程自己的页表指定,而现在TSS的作用一般是用户代码切换到内核代码时,会自动切换到TSS设置的内核栈。 16 | 17 | Idt主要是通过中断门实现的,如果大概理解下是这样的,这个中断门是我们人为设置的,同时还需绑定中断向量,当输入int 0x20时,表示我们访问0x20号的中断门,首先产生一个中断,硬件自动压栈,此后CS和SS会变为内核段代码,esp为我们设置的内核栈,eip为我们设置的中断向量,这均由硬件自动完成。如下图所示。 18 | 19 | ![image-20210101123853989](readme.assets/image-20210101123853989.png) 20 | 21 | 由于已经绑定好中断向量,接着就会执行对应的中断向量,如下图所示。 22 | 23 | ![image-20210101122550051](readme.assets/image-20210101122550051.png) 24 | 25 | 其实中断向量就是一个地址,然后会调用相应地址的程序,如下所示。 26 | 27 | ![image-20210101122704418](readme.assets/image-20210101122704418.png) 28 | 29 | ![image-20210101130142268](readme.assets/image-20210101130142268.png) 30 | 31 | 接着就会保存当前的段寄存器,然后ds和es段寄存器切换到内核的数据段,当执行完中断程序就会切回原来特权级下的代码和数据。 32 | 33 | 再说下为什么设置一个trapret吧,是这样的,当我们需要一个用户进程的时候,怎么实现从KERNEL_CS段到USER_CS段的跨越呢,中断是一个很好的方法,我们在中断栈中保存用户段的状态,并设置进程的EIP为__trapret,那么这就模拟了一个中断处理程序完成后返回的操作,把中断栈的数据放出来后,自然就变成USER_CS段了,这就实现了用户进程的初始化,即CS为USER_CS。 34 | 35 | 另外需要注意的是系统调用门需要设置DPL为user,这样用户就可以进行系统调用了,默认中断向量号为0x80.如下图。 36 | 37 | ![image-20210101122530922](readme.assets/image-20210101122530922.png) 38 | 39 | 关于intel中断详情可见 40 | 41 | https://blog.csdn.net/huang987246510/article/details/88954782?utm_medium=distribute.pc_relevant.none-task-blog-baidujs_title-7&spm=1001.2101.3001.4242 -------------------------------------------------------------------------------- /kernel/file/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #设置项目名 2 | project (file) 3 | add_library(${PROJECT_NAME} OBJECT ide-dev.c fs.c dir.c file.c ide-dev.c inode.c) 4 | target_include_directories(${PROJECT_NAME} 5 | PUBLIC 6 | ${FreeFlyOS_SOURCE_DIR}/kernel/file 7 | ${FreeFlyOS_SOURCE_DIR}/kernel/asm 8 | ${FreeFlyOS_SOURCE_DIR}/kernel/vga 9 | ${FreeFlyOS_SOURCE_DIR}/kernel/mem 10 | ${FreeFlyOS_SOURCE_DIR}/kernel/debug 11 | ${FreeFlyOS_SOURCE_DIR}/kernel/task 12 | ${FreeFlyOS_SOURCE_DIR}/kernel/keyboard 13 | ${FreeFlyOS_SOURCE_DIR}/kernel/pipe 14 | ${FreeFlyOS_SOURCE_DIR}/kernel/socket 15 | ) 16 | -------------------------------------------------------------------------------- /kernel/file/bitmap.h: -------------------------------------------------------------------------------- 1 | #ifndef _BITMAP_H_ 2 | #define _BITMAP_H_ 3 | /* 4 | ** 在遍历位图时,整体上以字节为单位,细节上是以位为单位, 5 | ** 所以此处位图的指针必须是单字节 6 | */ 7 | struct bitmap { 8 | unsigned int btmp_bytes_len; 9 | unsigned char* bits; 10 | }; 11 | #endif -------------------------------------------------------------------------------- /kernel/file/dir.h: -------------------------------------------------------------------------------- 1 | #ifndef _DIR_H_ 2 | #define _DIR_H_ 3 | #include "fs.h" 4 | #include "ide-dev.h" 5 | #define MAX_FILE_NAME_LEN 16 6 | 7 | /* 目录结构 */ 8 | struct dir 9 | { 10 | struct inode *inode; 11 | unsigned int dir_pos; //记录在目录内的偏移 12 | unsigned char dir_buf[512]; //目录的数据缓存 13 | }; 14 | /* 目录项结构 */ 15 | struct dir_entry 16 | { 17 | char filename[MAX_FILE_NAME_LEN]; //普通文件或目录名称 18 | unsigned i_no; //普通文件或目录对应的inode结点号 19 | enum file_types f_type; //文件类型 20 | }; 21 | void open_root_dir(struct partition* part); 22 | struct dir* dir_open(struct partition* part, unsigned int inode_no); 23 | char search_dir_entry(struct partition* part, struct dir* pdir, const char* name, struct dir_entry* dir_e); 24 | void dir_close(struct dir* dir); 25 | void create_dir_entry(char* filename, unsigned int inode_no, unsigned char file_type, struct dir_entry* p_de); 26 | struct dir_entry* dir_read(struct dir* dir); 27 | #endif -------------------------------------------------------------------------------- /kernel/file/file.h: -------------------------------------------------------------------------------- 1 | #ifndef _FILE_H_ 2 | #define _FILE_H_ 3 | #define MAX_FILE_OPEN 32 //可打开的最大文件数 4 | #include "dir.h" 5 | #include "ide-dev.h" 6 | #include "../socket/localsocket.h" 7 | /* 文件结构 */ 8 | struct file{ 9 | unsigned int fd_pos; 10 | unsigned int fd_flag; 11 | struct socket_local_t *lsocket; 12 | struct inode *fd_inode; 13 | }; 14 | /* 标准输入输出描述符 */ 15 | enum std_fd{ 16 | stdin_no, //0 标准输入 17 | stdout_no, //1 标准输出 18 | stderr_no //2 标准错误 19 | }; 20 | /* 位图类型 */ 21 | enum bitmap_type{ 22 | INODE_BITMAP, //inode位图 23 | BLOCK_BITMAP //块位图 24 | }; 25 | int get_free_slot_in_global(void); 26 | int task_fd_install(int global_fd_idx); 27 | int inode_bitmap_alloc(struct partition *part); 28 | int block_bitmap_alloc(struct partition *part); 29 | void bitmap_sync(struct partition *part,unsigned int bit_idx,unsigned char btmp); 30 | int file_create(struct dir* parent_dir, char* filename, unsigned char flag); 31 | int file_open(unsigned int inode_no, unsigned char flag); 32 | int file_close(struct file* file); 33 | int file_write(struct file* file, const void* buf, unsigned int count); 34 | int file_read(struct file* file, void* buf, unsigned int count); 35 | #endif -------------------------------------------------------------------------------- /kernel/file/fs.h: -------------------------------------------------------------------------------- 1 | #ifndef _FS_H_ 2 | #define _FS_H_ 3 | #define MAX_FILE 1000 //一个分区最大文件数 4 | #define SEC_SIZE 512 //扇区大小 5 | #define MAX_PATH_LEN 512 // 路径最大长度 6 | /* 文件类型 */ 7 | enum file_types { 8 | FT_UNKNOWN, // 不支持的文件类型 9 | FT_REGULAR, // 普通文件 10 | FT_DIRECTORY // 目录 11 | }; 12 | 13 | /* 打开文件的选项 */ 14 | enum oflags { 15 | O_RDONLY, // 只读 16 | O_WRONLY, // 只写 17 | O_RDWR, // 读写 18 | O_CREAT = 4 // 创建 19 | }; 20 | 21 | /* 文件读写位置偏移量 */ 22 | enum whence { 23 | SEEK_SET = 1, 24 | SEEK_CUR, 25 | SEEK_END 26 | }; 27 | 28 | /* 文件属性结构体 */ 29 | struct stat { 30 | unsigned int st_ino; // inode编号 31 | unsigned int st_size; // 尺寸 32 | enum file_types st_filetype; // 文件类型 33 | }; 34 | /* 用来记录查找文件过程中已找到的上级路径,也就是查找文件过程中"走过的地方" */ 35 | struct path_search_record { 36 | char searched_path[MAX_PATH_LEN]; // 查找过程中的父路径 37 | struct dir* parent_dir; // 文件或目录所在的直接父目录 38 | enum file_types file_type; // 找到的是普通文件还是目录,找不到将为未知类型(FT_UNKNOWN) 39 | }; 40 | void mount_partition(); 41 | int path_depth_cnt(char* pathname); 42 | unsigned int fd_local2global(unsigned int local_fd); 43 | int sys_open(const char* pathname, unsigned char flags); 44 | int sys_close(int fd); 45 | int sys_write(int fd, const void* buf, unsigned int count); 46 | int sys_read(int fd, void* buf, unsigned int count); 47 | int sys_lseek(int fd, int offset, unsigned char whence); 48 | int sys_unlink(const char* pathname); 49 | int sys_mkdir(const char* pathname); 50 | struct dir_entry* sys_readdir(struct dir* dir); 51 | void sys_rewinddir(struct dir* dir); 52 | int sys_rmdir(const char* pathname); 53 | char* sys_getcwd(char* buf, unsigned int size); 54 | int sys_stat(const char* path, struct stat* buf); 55 | int sys_chdir(const char* path); 56 | struct dir* sys_opendir(const char* name); 57 | int sys_closedir(struct dir* dir); 58 | struct dir_entry* sys_readdir(struct dir* dir); 59 | void fs_init(); 60 | #endif -------------------------------------------------------------------------------- /kernel/file/ide-dev.h: -------------------------------------------------------------------------------- 1 | #ifndef _IDE_DEV_H_ 2 | #define _IDE_DEV_H_ 3 | #include "bitmap.h" 4 | #include "super_block.h" 5 | #define SECTSIZE 512 6 | 7 | /* 分区表项结构 */ 8 | struct partition 9 | { 10 | unsigned char active_flag; //活动分区标记,0x80代表活动分区,0代表非活动分区 11 | unsigned char start_magnetic; //分区起始磁头号 12 | unsigned char start_sector; //分区起始扇区号 13 | unsigned char start_cylinder; //分区起始柱面号 14 | unsigned char file_type; //文件系统类型ID,0表示不可识别,0x83表示linux文件系统 15 | unsigned char end_magnetic; //分区结束磁头号 16 | unsigned char end_sector; //分区结束扇区号 17 | unsigned char end_cylinder; //分区结束柱面号 18 | unsigned int start_offset; //分区起始偏移扇区 19 | unsigned int sector_size; //分区扇区总数 20 | struct super_block *sb; //该分区超级块 21 | struct bitmap block_bitmap; //空闲块位图 22 | struct bitmap inode_bitmap; //inode节点位图 23 | }__attribute__((packed)); 24 | 25 | void ide_read(void *dst,unsigned int secno,unsigned int num); 26 | void ide_write(void *src,unsigned int secno,unsigned int num); 27 | void test_ide_io(); 28 | struct partition *read_main_partition(); 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /kernel/file/inode.h: -------------------------------------------------------------------------------- 1 | #ifndef _INODE_H_ 2 | #define _INODE_H_ 3 | #include "../stl/list.h" 4 | #include "ide-dev.h" 5 | 6 | /* inode结点 */ 7 | struct inode{ 8 | unsigned int i_num; //inode编号 9 | /* 当此inode是文件,i_size表示文件大小 10 | 当此inode是目录,i_size是指该目录下所有目录项大小之和 */ 11 | unsigned int i_size; 12 | 13 | unsigned int i_open_cnts; //记录文件被打开的次数 14 | char write_lock; //写文件时需要锁住,不能并行 15 | /* i_sectors[0-11]是直接数据块,i_sectors[12]用来存储一级间接块 */ 16 | unsigned int i_sectors[13]; 17 | //list_entry_t inode_tag; //文件缓存列表 18 | }; 19 | void inode_sync(struct partition *part,struct inode *inode,void *io_buf); 20 | struct inode* inode_open(struct partition *part,unsigned int inode_no); 21 | void inode_close(struct inode *inode); 22 | void inode_init(unsigned int inode_num,struct inode *new_inode); 23 | #endif -------------------------------------------------------------------------------- /kernel/file/readme.assets/image-20210101195008006.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/kernel/file/readme.assets/image-20210101195008006.png -------------------------------------------------------------------------------- /kernel/file/readme.assets/image-20210101195425185.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/kernel/file/readme.assets/image-20210101195425185.png -------------------------------------------------------------------------------- /kernel/file/readme.assets/image-20210101203558547.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/kernel/file/readme.assets/image-20210101203558547.png -------------------------------------------------------------------------------- /kernel/file/readme.assets/image-20210101211548668.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/kernel/file/readme.assets/image-20210101211548668.png -------------------------------------------------------------------------------- /kernel/file/readme.assets/image-20210101212332720.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/kernel/file/readme.assets/image-20210101212332720.png -------------------------------------------------------------------------------- /kernel/file/readme.assets/image-20210101214644423.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/kernel/file/readme.assets/image-20210101214644423.png -------------------------------------------------------------------------------- /kernel/file/readme.assets/image-20210101214931418.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/kernel/file/readme.assets/image-20210101214931418.png -------------------------------------------------------------------------------- /kernel/file/readme.assets/image-20210101215216128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/kernel/file/readme.assets/image-20210101215216128.png -------------------------------------------------------------------------------- /kernel/file/readme.assets/image-20210101220317718.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/kernel/file/readme.assets/image-20210101220317718.png -------------------------------------------------------------------------------- /kernel/file/super_block.h: -------------------------------------------------------------------------------- 1 | #ifndef _SUPER_BLOCK_H_ 2 | #define _SUPER_BLOCK_H_ 3 | 4 | /* 5 | ** 超级块-super block 6 | */ 7 | struct super_block{ 8 | unsigned int magic; //魔数,用来标识文件系统 9 | unsigned int sec_cnt; //本分区总共扇区数 10 | unsigned int inode_cnt; //本分区中inode数量 11 | unsigned int part_lba_base; //本分区的起始lba地址 12 | 13 | unsigned int block_bitmap_lba; //块位图本身起始扇区地址 14 | unsigned int block_bitmap_sects; //块位图占用扇区数 15 | 16 | unsigned int inode_bitmap_lba; //inode节点位图本身起始扇区地址 17 | unsigned int inode_bitmap_sects; //inode节点位图占用扇区数 18 | 19 | unsigned int inode_table_lba; //inode表本身起始扇区地址 20 | unsigned int inode_table_sects; //inode表占用扇区数 21 | 22 | unsigned int data_start_lba; //数据块起始扇区地址 23 | unsigned int root_inode_no; //根目录所在I节点号 24 | unsigned int dir_entry_size; //根目录大小 25 | 26 | unsigned char pad[460]; //加上460字节,凑一个扇区 27 | }__attribute__((packed)); 28 | 29 | #endif -------------------------------------------------------------------------------- /kernel/init/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #设置项目名 2 | project (init) 3 | add_library(${PROJECT_NAME} OBJECT init.c) 4 | target_include_directories(${PROJECT_NAME} 5 | PUBLIC 6 | ${FreeFlyOS_SOURCE_DIR}/kernel/init 7 | ${FreeFlyOS_SOURCE_DIR}/kernel/mem 8 | ${FreeFlyOS_SOURCE_DIR}/kernel/main 9 | ${FreeFlyOS_SOURCE_DIR}/kernel/debug 10 | ${FreeFlyOS_SOURCE_DIR}/kernel/mp 11 | ) 12 | -------------------------------------------------------------------------------- /kernel/init/init.h: -------------------------------------------------------------------------------- 1 | #ifndef _INIT_H_ 2 | #define _INIT_H_ 3 | 4 | #include "../main/main.h" 5 | 6 | #define vmm_page_size 0x1000 7 | #define page_table_size 0x400 8 | #define page_dir_size 0x400 9 | 10 | #define page_mask 0xFFFFF000 11 | 12 | #define vmm_page_present 0x1 13 | #define vmm_page_rw 0x2 14 | #define vmm_page_kernel 0x0 15 | /* 16 | *__attribute__( (section(".init.data") ) )将其设置为特定的.init.data节 17 | *方便在链接脚本中区分init部分和kernel部分 18 | */ 19 | __attribute__( (section(".init.data") ) ) unsigned int pdt[page_dir_size]__attribute__( (aligned(vmm_page_size) ) ); 20 | __attribute__( (section(".init.data") ) ) unsigned int pt_init[page_table_size]__attribute__( (aligned(vmm_page_size) ) ); 21 | //专门为VGA设备映射建立的页表 22 | __attribute__( (section(".init.data") ) ) unsigned int pt[page_table_size]__attribute__( (aligned(vmm_page_size) ) ); 23 | //目前内核还不大,假定其大小不超过12MB,即三个页表 24 | __attribute__( (section(".init.data") ) ) unsigned int pt1[page_table_size]__attribute__( (aligned(vmm_page_size) ) ); 25 | __attribute__( (section(".init.data") ) ) unsigned int pt2[page_table_size]__attribute__( (aligned(vmm_page_size) ) ); 26 | __attribute__( (section(".init.data") ) ) unsigned int pt3[page_table_size]__attribute__( (aligned(vmm_page_size) ) ); 27 | //__attribute__( (section(".init.data") ) ) unsigned int pt4[page_table_size]__attribute__( (aligned(vmm_page_size) ) ); 28 | //内核栈大小为8KB,起始地址为0xF8000000,只需一个页表即可 29 | __attribute__( (section(".init.data") ) ) unsigned int stack_pt[page_table_size]__attribute__( (aligned(vmm_page_size) ) ); 30 | //user部分 31 | __attribute__( (section(".init.data") ) ) unsigned int user_pt[page_table_size]__attribute__( (aligned(vmm_page_size) ) ); 32 | 33 | 34 | __attribute__( (section(".init.text") ) ) void init(); 35 | 36 | extern void main(void); 37 | 38 | #endif -------------------------------------------------------------------------------- /kernel/init/readme.assets/image-20210102105209154.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/kernel/init/readme.assets/image-20210102105209154.png -------------------------------------------------------------------------------- /kernel/init/readme.md: -------------------------------------------------------------------------------- 1 | ### init.c 2 | 3 | 该文件是为了内核代码前开启分页,主要解决下面的问题: 4 | 5 | 在ld文件中,我们必须确定内核代码的VMA(虚拟空间地址)和LMA(物理空间地址),如果在这之前不开启分页,那么内核代码的虚拟地址和物理地址均是从16MB处开始,若在这之后开启分页,那么整个虚拟地址空间就很难改变了(链接确定虚拟地址),所以会出错。 6 | 7 | 现在的解决方案时,使用init.c建立一个临时页表,并开启分页,然后把init代码放在1MB处(VMA和LMA均为1MB),而内核代码则放在VMA=0xC1000000处,LMA=0x01000000(16MB)处,因为不开启分页,那么VMA然后init代码执行完毕,跳转到内核代码后,这部分就没用了,所以直接新建一个页表,然后就可以删除这部分代码。 8 | 9 | 当然还有一种方案,就是qemu模拟器申请4GB内存,然后把VMA和LMA都放在0xC1000000处,在建立页表后,就把内核移到0x01000000处,这种方法笔者也试过,但是当用模拟器申请4G内存时,3.5G以上是不可用的,所以这种方案在使用模拟器时不可取,当使用真机时可能有效,读者们可以自行尝试。 10 | 11 | ![avatar](https://github.com/dashanji/picture/blob/main/image-20201005211626185.png) 12 | 13 | 14 | 15 | init部分主要功能就是建立临时页表,主要包括内核代码部分和内核栈部分的映射,从下图的elf文件解析中我们可以看出需要3个页目录项,也就是12MB,才能包含bss段。 16 | 17 | ![image-20210102105209154](readme.assets/image-20210102105209154.png) 18 | 19 | 然后映射下内核栈,接着就把页目录表地址读入cr3寄存器,需要注意的是,cr3寄存器存储的都是物理地址,但由于init部分在链接脚本中没有指定虚拟地址,所以其虚拟地址=物理地址,接着开启cr0寄存器的PG位,从而打开分页模式,然后将esp指针指向内核栈的栈顶,最后跳转到内核的main函数,自此,init部分结束。 -------------------------------------------------------------------------------- /kernel/internet/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #设置项目名 2 | project (internet) 3 | 4 | add_library(${PROJECT_NAME} OBJECT pci.c rtl8139.c ethernet.c arp.c ip.c icmp.c) 5 | target_include_directories(${PROJECT_NAME} 6 | PUBLIC 7 | ${FreeFlyOS_SOURCE_DIR}/kernel/internet 8 | ${FreeFlyOS_SOURCE_DIR}/kernel/mem 9 | ${FreeFlyOS_SOURCE_DIR}/kernel/asm 10 | ${FreeFlyOS_SOURCE_DIR}/kernel/vga 11 | ${FreeFlyOS_SOURCE_DIR}/kernel/apic 12 | ${FreeFlyOS_SOURCE_DIR}/kernel/interrupt 13 | ${FreeFlyOS_SOURCE_DIR}/kernel/stl 14 | ) 15 | -------------------------------------------------------------------------------- /kernel/internet/arp.h: -------------------------------------------------------------------------------- 1 | #ifndef _ARP_H_ 2 | #define _ARP_H_ 3 | #include "ethernet.h" 4 | #define ipaddr_len 4 5 | 6 | #define ARP_OP_REQUEST 1 7 | #define ARP_OP_REPLY 2 8 | 9 | #define ARP_CACHE_NUM 100 10 | #include "../stl/list.h" 11 | #include "../stl/defs.h" 12 | struct arp_header{ 13 | unsigned short hardware_type; //硬件类型 14 | unsigned short protocol_type; //上层协议类型 15 | unsigned char hardware_addr_len; //硬件地址长度 16 | unsigned char protocol_addr_len; //协议地址长度 17 | unsigned short op; //协议码 18 | unsigned char src_mac_addr[eth_macaddr_len]; //发送端以太网地址 19 | unsigned char src_ip_addr[ipaddr_len]; //发送端IP地址 20 | unsigned char dst_mac_addr[eth_macaddr_len]; //目的以太网地址 21 | unsigned char dst_ip_addr[ipaddr_len]; //目的IP地址 22 | }; 23 | struct arp_cache_t{ 24 | unsigned char ip_addr[ipaddr_len]; //IP地址 25 | unsigned char mac_addr[eth_macaddr_len]; //mac地址 26 | struct list_entry node; 27 | }; 28 | 29 | //将list_entry_t转化为sturct task_struct 30 | #define list_to_arpcache(list_entry_addr,member) \ 31 | to_struct(list_entry_addr,struct arp_cache_t,member) 32 | 33 | unsigned short ntohs(unsigned short n); 34 | struct net_buf *arp_request(unsigned char dst_mac[eth_macaddr_len],unsigned char dst_ip[ipaddr_len], 35 | char *data,int len,int type); 36 | void arp_receive(struct net_buf *bl); 37 | struct arp_cache_t *find_arp_cache(unsigned char dstip[ipaddr_len]); 38 | char insert_arp_cache(unsigned char dstip[ipaddr_len],unsigned char dstmac[eth_macaddr_len]); 39 | #endif -------------------------------------------------------------------------------- /kernel/internet/ethernet.c: -------------------------------------------------------------------------------- 1 | #include "ethernet.h" 2 | #include "../mem/vmm.h" 3 | #include "rtl8139.h" 4 | #include "../asm/asm.h" 5 | #include "arp.h" 6 | #include "ip.h" 7 | extern unsigned char my_mac[eth_macaddr_len];//{0xd2,0xc0,0xcb,0x35,0xb2,0xd3};//{0xae,0xe7,0xc1,0x79,0xd8,0x64}; 8 | //发送数据给指定MAC地址 构造以太网帧 9 | struct net_buf *build_ef(unsigned char dst[eth_macaddr_len],unsigned short protocal,char *data,int len){ 10 | //首先需要构造一个以太网帧,先确定帧长度 11 | int ef_length=len; 12 | //最小的以太网帧为46字节 13 | if(ef_length<46){ 14 | ef_length=46; 15 | } 16 | //不能发送给本机 17 | if(memcmp(my_mac,dst,eth_macaddr_len)==0){ 18 | return ; 19 | } 20 | //数据+帧头 21 | struct net_buf *buf=vmm_malloc(ef_length+sizeof(struct ethernet_frame_header)+sizeof(struct net_buf),1); 22 | struct ethernet_frame_header efh; 23 | memcpy(efh.dst,dst,eth_macaddr_len); 24 | memcpy(efh.src,my_mac,eth_macaddr_len); 25 | //大端序 26 | efh.proto=ntohs(protocal); 27 | buf->data_len=ef_length+sizeof(struct ethernet_frame_header); 28 | buf->data=(char *)buf+sizeof(struct net_buf); 29 | char *p=buf->data; 30 | memcpy(p,&efh,sizeof(struct ethernet_frame_header)); 31 | p+=sizeof(struct ethernet_frame_header); 32 | memcpy(p,data,len); 33 | if(lendata_len=len; 42 | buf->data=(char *)buf+sizeof(struct net_buf); 43 | memcpy(buf->data,data,len); 44 | struct ethernet_frame_header efh; 45 | memcpy(&efh,buf->data,sizeof(struct ethernet_frame_header)); 46 | printk("receive ethernet_frame from [%02x:%02x:%02x:%02x:%02x:%02x] to [%02x:%02x:%02x:%02x:%02x:%02x]\n",efh.src[0],efh.src[1],efh.src[2], 47 | efh.src[3],efh.src[4],efh.src[5],efh.dst[0],efh.dst[1],efh.dst[2], 48 | efh.dst[3],efh.dst[4],efh.dst[5]); 49 | //如果上层协议是ARP协议 50 | if(ntohs(efh.proto)==ethernet_arp){ 51 | arp_receive(buf); 52 | } 53 | //如果上层协议是IP协议 54 | else if(ntohs(efh.proto)==ethernet_ipv4){ 55 | receive_ip_packet(buf); 56 | } 57 | else{ 58 | //如果发送的MAC地址是本机 59 | if(memcmp(my_mac,efh.dst,eth_macaddr_len)==0){ 60 | printk("data:%s\n",(char *)(buf->data+sizeof(struct ethernet_frame_header))); 61 | } 62 | } 63 | 64 | } -------------------------------------------------------------------------------- /kernel/internet/ethernet.h: -------------------------------------------------------------------------------- 1 | #ifndef _ETHERNET_H_ 2 | #define _ETHERNET_H_ 3 | #define eth_macaddr_len 6 4 | #define ethernet_arp 0x0806 5 | #define ethernet_ipv4 0x0800 6 | struct ethernet_frame_header{ 7 | unsigned char dst[eth_macaddr_len];//目的MAC地址 8 | unsigned char src[eth_macaddr_len];//源MAC地址 9 | unsigned short proto;//帧类型 10 | }; 11 | struct net_buf{ 12 | unsigned int data_len; //数据长度 13 | char *data; //数据 14 | }; 15 | struct net_buf *build_ef(unsigned char dst[eth_macaddr_len],unsigned short protocal,char *data,int len); 16 | void receive_ef(char *data,int len); 17 | #endif -------------------------------------------------------------------------------- /kernel/internet/icmp.h: -------------------------------------------------------------------------------- 1 | #ifndef _ICMP_H_ 2 | #define _ICMP_H_ 3 | #include "arp.h" 4 | #include "ethernet.h" 5 | #include "ip.h" 6 | #include "rtl8139.h" 7 | #define ECHO_REQUEST 8 8 | #define ECHO_REPLY 0 9 | struct icmp_header{ 10 | unsigned char type; //类型(0或8) 11 | unsigned char code; //代码(0) 12 | unsigned short checksum; //校验和 13 | unsigned short id; //标识符 14 | unsigned short seqnum; //序号 15 | }; 16 | void send_icmp_request(unsigned int ip,unsigned short id,unsigned short seq, 17 | char *data,int len); 18 | void send_icmp_reply(unsigned int ip,unsigned short id,unsigned short seq, 19 | char *data,int len); 20 | void receive_icmp_reply(struct net_buf *nb,unsigned int ip); 21 | void receive_echo_request(struct net_buf *nb,unsigned int ip); 22 | void receive_echo_reply(struct net_buf *nb,unsigned int ip); 23 | #endif -------------------------------------------------------------------------------- /kernel/internet/ip.h: -------------------------------------------------------------------------------- 1 | #ifndef _IP_H_ 2 | #define _IP_H_ 3 | #include "ethernet.h" 4 | #include "arp.h" 5 | #include "rtl8139.h" 6 | #include "icmp.h" 7 | #define IP_protocal 0x4 8 | #define ICMP_protocol 0x1 9 | #define RAW_protocal 0xff 10 | struct ip_header{ 11 | unsigned char ihl:4; //高4位:首部长度 12 | unsigned char version:4; //低4位:版本 13 | unsigned char type_of_service; //区分服务(DSCP、ECN) 14 | unsigned short total_length; //总长度 15 | unsigned short identification; //标识 16 | unsigned short fragment_offset; //标志+片偏移 17 | unsigned char time_to_live; //生存时间 18 | unsigned char protocol; //协议 19 | unsigned short header_checksum; //首部校验和 20 | unsigned int src_ip; //源地址 21 | unsigned int dst_ip; //目标地址 22 | }; 23 | unsigned int chartoui(char ip[ipaddr_len]); 24 | unsigned int htonl(unsigned int n); 25 | char check_same_subnet(unsigned int ip1,unsigned int ip2,unsigned int mask); 26 | unsigned short checksum(char *data,int len); 27 | struct net_buf *build_ip_packet(char *data,int len,unsigned int dstip,unsigned char protocol); 28 | void send_ip_packet(char *data,int len,unsigned int dstip,unsigned char protocol); 29 | void receive_ip_packet(struct net_buf *nb); 30 | char wake_up_ip_packet(struct net_buf *nb); 31 | #endif -------------------------------------------------------------------------------- /kernel/internet/pci.h: -------------------------------------------------------------------------------- 1 | #ifndef _PCI_H_ 2 | #define _PCI_H_ 3 | #define PCI_CONFIG_ADDR 0xCF8 4 | #define PCI_CONFIG_DATA 0xCFC 5 | 6 | #define PCI_CONFIG_VENDOR 0x00 7 | #define PCI_CONFIG_COMMAND 0x04 8 | #define PCI_CONFIG_CLASS_REV 0x08 9 | #define PCI_CONFIG_HDR_TYPE 0x0C 10 | #define PCI_CONFIG_BASE_ADDR0 0x10 11 | #define PCI_CONFIG_INTR 0x3C 12 | 13 | #define PCI_BASE_ADDR_MEM_MASK (~0x0FUL) 14 | #define PCI_BASE_ADDR_IO_MASK (~0x03UL) 15 | enum type_e { 16 | TYPE_INVALID = -1, 17 | TYPE_MEM = 0, 18 | TYPE_IO, 19 | }; 20 | typedef struct pci_device_bar_t{ 21 | unsigned int type; 22 | unsigned int base_addr; 23 | unsigned int length; 24 | }pci_device_bar; 25 | typedef struct pci_device{ 26 | unsigned char bus; 27 | unsigned char dev; 28 | unsigned char function; 29 | 30 | unsigned short vendor_id; 31 | unsigned short device_id; 32 | unsigned int class_code; 33 | char multi_function; 34 | unsigned char interrupt_line; 35 | unsigned char interrupt_pin; 36 | unsigned char revision; 37 | pci_device_bar bar[6]; 38 | }pci_device_t; 39 | unsigned int pci_read(unsigned int bus, unsigned int device, unsigned int function, unsigned int addr); 40 | void pci_write(unsigned int bus, unsigned int device, unsigned int function, unsigned int addr, unsigned int val); 41 | void check_device(unsigned char bus, unsigned char device); 42 | void enum_buses(); 43 | void pci_device_init(pci_device_t *pdt,unsigned char bus, unsigned char dev, unsigned char function, unsigned short vendor_id, unsigned short device_id, 44 | unsigned int class_code, unsigned char revision, char multi_function); 45 | void pci_device_bar_init(pci_device_bar *pci_db,unsigned int addr_reg_val, unsigned int len_reg_val); 46 | void dump(pci_device_t *pdt); 47 | void enable_bus_mastering(pci_device_t* device); 48 | void pci_init(); 49 | #endif -------------------------------------------------------------------------------- /kernel/internet/rtl8139.h: -------------------------------------------------------------------------------- 1 | #ifndef _RTL8139_H_ 2 | #define _RTL8139_H_ 3 | #include "ethernet.h" 4 | #include "arp.h" 5 | #include "ip.h" 6 | #include "../stl/list.h" 7 | #define RTL8139_VENDOR_ID 0x10ec 8 | #define RTL8139_DEVICE_ID 0x8139 9 | #define NUM_TX_BUFFER 4 10 | 11 | #define NULL (void *)0 12 | 13 | #define RTL8139_VENDOR_ID 0x10ec 14 | #define RTL8139_DEVICE_ID 0x8139 15 | 16 | #define RTL8139_MAC 0x00 17 | #define RTL8139_TX_STATUS0 0x10 18 | #define RTL8139_TX_ADDR0 0x20 19 | #define RTL8139_RX_BUF_ADDR 0x30 20 | #define RTL8139_COMMAND 0x37 21 | #define RTL8139_CAPR 0x38 22 | #define RTL8139_INTR_MASK 0x3C 23 | #define RTL8139_INTR_STATUS 0x3E 24 | #define RTL8139_RCR 0x44 25 | #define RTL8139_CONFIG_0 0x51 26 | #define RTL8139_CONFIG_1 0x52 27 | 28 | #define RTL8139_RX_OK 0x0001 29 | #define RTL8139_RX_ERROR 0x0002 30 | #define RTL8139_TX_OK 0x0004 31 | #define RTL8139_TX_ERROR 0x0008 32 | #define RTL8139_RX_OVERFLOW 0x0010 33 | #define RTL8139_RX_UNDERRUN 0x0020 34 | #define RTL8139_RX_FIFOOVER 0x0040 35 | #define RTL8139_PCS_TIMEOUT 0x4000 36 | #define RTL8139_PCI_ERROR 0x8000 37 | 38 | //发送包队列长度 39 | #define NET_BUF_SEND_LIST_LENGTH 20 40 | //等待包队列长度 41 | #define NET_BUF_WAIT_LIST_LENGTH 20 42 | 43 | #define ETHERNET_TYPE 0 //以太网帧 44 | #define ARP_TYPE 1 //ARP包 45 | #define IPV4_TYPE 2 //IPV4包 46 | typedef struct rtl8139_t{ 47 | char inited; 48 | unsigned int io_address; 49 | unsigned int irq; 50 | unsigned char mac_addr[6]; 51 | 52 | unsigned char* rx_buffer; 53 | unsigned int current_rx; /* CAPR, Current Address of Packet Read */ 54 | unsigned int rx_buf_len; 55 | 56 | unsigned char* tx_buffers[NUM_TX_BUFFER]; 57 | unsigned char current_tx; 58 | }rtl8139; 59 | //网络包发送队列 60 | typedef struct net_buf_send_list_t{ 61 | struct net_buf *nb; 62 | char type; 63 | list_entry_t node; 64 | }nb_send_list_t; 65 | //将list_entry_t转化为nb_send_list_t 66 | #define list_to_nb_send_list(list_entry_addr,member) \ 67 | to_struct(list_entry_addr,nb_send_list_t,member) 68 | //网络包等待队列 69 | typedef struct net_buf_wait_list_t{ 70 | struct net_buf *nb; 71 | char type; 72 | list_entry_t node; 73 | }nb_wait_list_t; 74 | //将list_entry_t转化为nb_wait_list_t 75 | #define list_to_nb_wait_list(list_entry_addr,member) \ 76 | to_struct(list_entry_addr,nb_wait_list_t,member) 77 | 78 | unsigned int get_info_from_pci(); 79 | void rtl8139_init(); 80 | void do_rtl8139_irq(rtl8139 *rtl); 81 | int transmit(struct net_buf* buf); 82 | void receive(); 83 | char insert_net_send_list(struct net_buf *nb,char type); 84 | char delete_net_send_list(struct net_buf *nb,char type); 85 | char insert_net_wait_list(struct net_buf *nb,char type); 86 | char delete_net_wait_list(); 87 | void clear_net_send_list(); 88 | #endif -------------------------------------------------------------------------------- /kernel/interrupt/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #设置项目名 2 | project (interrupt C ASM) 3 | set(SOURCES 4 | trap.c 5 | trapentry.S 6 | vector.S 7 | syscall.c 8 | ) 9 | add_library(${PROJECT_NAME} OBJECT ${SOURCES}) 10 | 11 | target_include_directories(${PROJECT_NAME} 12 | PUBLIC 13 | ${FreeFlyOS_SOURCE_DIR}/kernel/asm 14 | ${FreeFlyOS_SOURCE_DIR}/kernel/interrupt 15 | ${FreeFlyOS_SOURCE_DIR}/kernel/debug 16 | ${FreeFlyOS_SOURCE_DIR}/kernel/timer 17 | ${FreeFlyOS_SOURCE_DIR}/kernel/vga 18 | ${FreeFlyOS_SOURCE_DIR}/kernel/task 19 | ${FreeFlyOS_SOURCE_DIR}/kernel/file 20 | ${FreeFlyOS_SOURCE_DIR}/kernel/sync 21 | ${FreeFlyOS_SOURCE_DIR}/kernel/keyboard 22 | ${FreeFlyOS_SOURCE_DIR}/kernel/mem 23 | ${FreeFlyOS_SOURCE_DIR}/kernel/pipe 24 | ${FreeFlyOS_SOURCE_DIR}/kernel/apic 25 | ${FreeFlyOS_SOURCE_DIR}/kernel/internet 26 | ) 27 | -------------------------------------------------------------------------------- /kernel/interrupt/readme.assets/image-20210102111920939.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/kernel/interrupt/readme.assets/image-20210102111920939.png -------------------------------------------------------------------------------- /kernel/interrupt/readme.assets/image-20210102112300909.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/kernel/interrupt/readme.assets/image-20210102112300909.png -------------------------------------------------------------------------------- /kernel/interrupt/readme.assets/image-20210102112516846.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/kernel/interrupt/readme.assets/image-20210102112516846.png -------------------------------------------------------------------------------- /kernel/interrupt/readme.assets/image-20210102113658283.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/kernel/interrupt/readme.assets/image-20210102113658283.png -------------------------------------------------------------------------------- /kernel/interrupt/readme.md: -------------------------------------------------------------------------------- 1 | ## trap.c 2 | 3 | 中断服务程序IRQ的实现,目前只实现了时钟、串口和键盘中断。 4 | 5 | ## trap.h 6 | 7 | trap号,硬件IRQ号,两者主要区别是陷阱门发生后不会关中断,可能会出现中断嵌套,而中断门发生后会关闭中断,防止出现中断嵌套。 8 | 9 | ## trapentry.S 10 | 11 | 用于保存中断处理程序前的现场(上下文),当程序执行完毕后返回原来的现场,各种段寄存器恢复成原值。 12 | 13 | ## vector.S 14 | 15 | 中断向量表,在IDT初始化时和中断号绑定,初始化了256个中断向量,实际只用了几个。 16 | 17 | 18 | 19 | 关于中断,网上有很多详细的资料,背景类知识就不再赘述,大概说一下FreeFlyOS的中断体系把,主要包含两种,一种是硬件中断,比如缺页异常、时钟中断、键盘中断、串口中断、硬盘中断等等,这些中断处理程序设计的比较简单。还有一种是软中断,我们通过中断门实现的一种中断,主要用于系统调用,也就是ring3权限的用户想要对系统资源进行访问时,ring0权限的OS提供给用户访问的一种接口。大概讲一下系统调用怎么传递参数吧,首先我们看用户视角下的系统调用。 20 | 21 | ![image-20210102111920939](readme.assets/image-20210102111920939.png) 22 | 23 | 一般而言,系统调用的中断号是0x80,这个大家应该都知道,那么参数应该如何传递呢,这里我们规定最多只能传递5个参数,而且每个参数需要放在指定的寄存器中,首先把参数数量放在eax中,然后第一个参数放在edx参数,依次类推。 24 | 25 | 同样,内核中的中断服务程序会根据栈帧接受到这些信息,从而完成参数的传递。 26 | 27 | ![image-20210102112300909](readme.assets/image-20210102112300909.png) 28 | 29 | 现在还需说明一个问题,我们使用中断的时候,硬件会自动压栈,只包含SS、ESP、EFLAGS、CS、EIP、ERROR等信息,而这些寄存器信息并不包含在内,所以我们需要构建一个参数传递栈帧,如下图所示。 30 | 31 | ![image-20210102112516846](readme.assets/image-20210102112516846.png) 32 | 33 | 硬件压栈的部分我们就不需要继续压栈了,只需要对栈帧其他寄存器进行压栈即可,构造过程如下,注意pushal是压入所有通用寄存器。 34 | 35 | ![image-20210102113658283](readme.assets/image-20210102113658283.png) 36 | 37 | 就说这么多吧,拜拜。 -------------------------------------------------------------------------------- /kernel/interrupt/syscall.h: -------------------------------------------------------------------------------- 1 | #ifndef _SYSCALL_H_ 2 | #define _SYSCALL_H_ 3 | #include "trap.h" 4 | /* syscall number */ 5 | #define SYS_exit 1 6 | #define SYS_fork 2 7 | #define SYS_wait 3 8 | #define SYS_exec 4 9 | #define SYS_clone 5 10 | #define SYS_yield 10 11 | #define SYS_sleep 11 12 | #define SYS_kill 12 13 | #define SYS_gettime 17 14 | #define SYS_getpid 18 15 | #define SYS_brk 19 16 | #define SYS_mmap 20 17 | #define SYS_munmap 21 18 | #define SYS_shmem 22 19 | 20 | #define SYS_fdread 24 21 | 22 | #define SYS_pgdir 31 23 | 24 | #define SYS_print_char 36 25 | #define SYS_print_string 37 26 | #define SYS_print_num 38 27 | #define SYS_backtrace 39 28 | #define SYS_open 40 29 | #define SYS_close 41 30 | #define SYS_write 42 31 | #define SYS_lseek 43 32 | #define SYS_unlink 44 33 | #define SYS_mkdir 45 34 | #define SYS_rmdir 46 35 | #define SYS_rewinddir 47 36 | #define SYS_getcwd 48 37 | #define SYS_chdir 49 38 | #define SYS_stat 50 39 | #define SYS_opendir 51 40 | #define SYS_closedir 52 41 | #define SYS_readdir 53 42 | #define SYS_print_task 54 43 | #define SYS_malloc 55 44 | #define SYS_free 56 45 | #define SYS_mmap 57 46 | #define SYS_pipe 58 47 | //internet 48 | #define SYS_socket 59 49 | #define SYS_bind 60 50 | #define SYS_listen 61 51 | #define SYS_accept 62 52 | #define SYS_connect 63 53 | void syscall_trap(struct trapframe *tf); 54 | int user_sys_getpid(void); 55 | void user_print_char(char c); 56 | void user_print_string(char *str); 57 | void user_print_num(int num,unsigned char base,char len,int flag); 58 | #endif -------------------------------------------------------------------------------- /kernel/interrupt/trapentry.S: -------------------------------------------------------------------------------- 1 | #define GD_KDATA ((2) << 3) // kernel data 2 | .code32 3 | # vectors.S sends all traps here. 4 | .section .text 5 | .globl __alltraps 6 | __alltraps: 7 | # push registers to build a trap frame 8 | # therefore make the stack look like a struct trapframe 9 | pushl %ds 10 | pushl %es 11 | pushl %fs 12 | pushl %gs 13 | pushal 14 | 15 | # load GD_KDATA into %ds and %es to set up data segments for kernel 16 | movl $GD_KDATA, %eax 17 | movw %ax, %ds 18 | movw %ax, %es 19 | 20 | # push %esp to pass a pointer to the trapframe as an argument to trap() 21 | pushl %esp 22 | 23 | # call trap(tf), where tf=%esp 24 | call trap 25 | 26 | # pop the pushed stack pointer 27 | popl %esp 28 | 29 | # return falls through to trapret... 30 | .globl __trapret 31 | __trapret: 32 | # restore registers from stack 33 | popal 34 | 35 | # restore %ds, %es, %fs and %gs 36 | popl %gs 37 | popl %fs 38 | popl %es 39 | popl %ds 40 | 41 | # get rid of the trap number and error code 42 | addl $0x8, %esp 43 | iret 44 | 45 | .globl forkrets 46 | forkrets: 47 | # set stack to this new task's trapframe 48 | movl 4(%esp), %esp 49 | jmp __trapret -------------------------------------------------------------------------------- /kernel/kernel.ld: -------------------------------------------------------------------------------- 1 | /* 2 | ** 链接脚本 3 | */ 4 | OUTPUT_FORMAT(elf32-i386) 5 | OUTPUT_ARCH(i386) 6 | ENTRY(init) 7 | /* 8 | * ld有多种方法设置进程入口地址, 按以下顺序: (编号越前, 优先级越高) 9 | * 1, ld命令行的-e选项 10 | * 2, 连接脚本的ENTRY(SYMBOL)命令 11 | * 3, 如果定义了start 符号, 使用start符号值 12 | * 4, 如果存在 .text section , 使用.text section的第一字节的位置值 13 | * 5, 使用值0 14 | * 15 | * 16 | */ 17 | 18 | SECTIONS 19 | { 20 | . = 0x9000; 21 | .apstart.text : 22 | { 23 | ap/CMakeFiles/ap.dir/start_ap.S.o(.text) 24 | } 25 | .apstart.data : 26 | { 27 | ap/CMakeFiles/ap.dir/start_ap.S.o(.data) 28 | 29 | } 30 | .apstart.rodata : 31 | { 32 | ap/CMakeFiles/ap.dir/start_ap.S.o(.rodata) 33 | } 34 | .apstart.bss : 35 | { 36 | ap/CMakeFiles/ap.dir/start_ap.S.o(.bss) 37 | } 38 | /* VMA 为顺序排列,LMA 按照 AT(addr) 排列 ,若未指定AT则LMA=VMA */ 39 | /* 指定init部分从虚拟地址0x100000(1MB)处开始 */ 40 | /* 物理地址也从0x100000(1MB)处开始 */ 41 | . = 0x100000; 42 | 43 | .init.text : { 44 | *(.init.text) 45 | } 46 | .init.data : { 47 | *(.init.data) 48 | *(.init.bss) 49 | } 50 | PROVIDE(init_end = .); 51 | 52 | /* 指定user从虚拟地址0x40000000处开始 */ 53 | /* 物理地址也从0x40000000处开始*/ 54 | . = 0x40000000; 55 | .user.text : 56 | { 57 | user/CMakeFiles/user.dir/*.o(.text) 58 | } 59 | .user.data : 60 | { 61 | user/CMakeFiles/user.dir/*.o(.data) 62 | 63 | } 64 | .user.rodata : 65 | { 66 | user/CMakeFiles/user.dir/*.o(.rodata) 67 | } 68 | .user.bss : 69 | { 70 | user/CMakeFiles/user.dir/*.o(.bss) 71 | } 72 | 73 | PROVIDE(user_end = .); 74 | /* 指定内核从虚拟地址0xC0000000+0x01000000(16MB)处开始 */ 75 | /* 物理地址从0x01000000(16MB)处开始,通过AT命令指定 */ 76 | . = 0xC1000000; 77 | 78 | .text : AT(ADDR(.text) - 0xC0000000) 79 | { 80 | *(.text .stub .text.* .gnu.linkonce.t.*) 81 | } 82 | PROVIDE(kernel_rodata = .); 83 | .rodata : AT(ADDR(.rodata) - 0xC0000000) 84 | { 85 | *(.rodata .rodata.* .gnu.linkonce.r.*) 86 | } 87 | 88 | /* Adjust the address for the data segment to the next page */ 89 | . = ALIGN(0x1000); 90 | 91 | PROVIDE(kernel_data = .); 92 | /* The data segment */ 93 | .data : AT(ADDR(.data) - 0xC0000000) 94 | { 95 | *(.data) 96 | } 97 | 98 | PROVIDE(kernel_bss = .); 99 | 100 | .bss : AT(ADDR(.bss) - 0xC0000000) 101 | { 102 | *(.bss) 103 | } 104 | 105 | 106 | PROVIDE(kernel_end = .); 107 | 108 | /DISCARD/ : { 109 | *(.eh_frame .note.GNU-stack) 110 | } 111 | } -------------------------------------------------------------------------------- /kernel/keyboard/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #设置项目名 2 | project (keyboard) 3 | 4 | add_library(${PROJECT_NAME} OBJECT keyboard.c) 5 | target_include_directories(${PROJECT_NAME} 6 | PUBLIC 7 | ${FreeFlyOS_SOURCE_DIR}/kernel/interrupt 8 | ${FreeFlyOS_SOURCE_DIR}/kernel/keyboard 9 | ${FreeFlyOS_SOURCE_DIR}/kernel/serial 10 | ${FreeFlyOS_SOURCE_DIR}/kernel/vga 11 | ${FreeFlyOS_SOURCE_DIR}/kernel/apic 12 | ) 13 | -------------------------------------------------------------------------------- /kernel/keyboard/readme.assets/image-20210102114526926.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/kernel/keyboard/readme.assets/image-20210102114526926.png -------------------------------------------------------------------------------- /kernel/keyboard/readme.assets/image-20210102114611098.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/kernel/keyboard/readme.assets/image-20210102114611098.png -------------------------------------------------------------------------------- /kernel/keyboard/readme.assets/image-20210102114624229.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/kernel/keyboard/readme.assets/image-20210102114624229.png -------------------------------------------------------------------------------- /kernel/keyboard/readme.assets/image-20210102114638187.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/kernel/keyboard/readme.assets/image-20210102114638187.png -------------------------------------------------------------------------------- /kernel/keyboard/readme.assets/image-20210102114657210.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/kernel/keyboard/readme.assets/image-20210102114657210.png -------------------------------------------------------------------------------- /kernel/keyboard/readme.assets/image-20210102114730257.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/kernel/keyboard/readme.assets/image-20210102114730257.png -------------------------------------------------------------------------------- /kernel/keyboard/readme.assets/image-20210102114752810.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/kernel/keyboard/readme.assets/image-20210102114752810.png -------------------------------------------------------------------------------- /kernel/keyboard/readme.assets/image-20210102114805015.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/kernel/keyboard/readme.assets/image-20210102114805015.png -------------------------------------------------------------------------------- /kernel/keyboard/readme.assets/image-20210102114819159.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/kernel/keyboard/readme.assets/image-20210102114819159.png -------------------------------------------------------------------------------- /kernel/keyboard/readme.assets/image-20210102115246364.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/kernel/keyboard/readme.assets/image-20210102115246364.png -------------------------------------------------------------------------------- /kernel/keyboard/readme.assets/image-20210102115255006.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/kernel/keyboard/readme.assets/image-20210102115255006.png -------------------------------------------------------------------------------- /kernel/keyboard/readme.assets/image-20210102115304459.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/kernel/keyboard/readme.assets/image-20210102115304459.png -------------------------------------------------------------------------------- /kernel/keyboard/readme.assets/image-20210102115317484.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/kernel/keyboard/readme.assets/image-20210102115317484.png -------------------------------------------------------------------------------- /kernel/keyboard/readme.assets/image-20210102115333510.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/kernel/keyboard/readme.assets/image-20210102115333510.png -------------------------------------------------------------------------------- /kernel/keyboard/readme.assets/image-20210102115342960.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/kernel/keyboard/readme.assets/image-20210102115342960.png -------------------------------------------------------------------------------- /kernel/keyboard/readme.assets/image-20210102115355715.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/kernel/keyboard/readme.assets/image-20210102115355715.png -------------------------------------------------------------------------------- /kernel/keyboard/readme.md: -------------------------------------------------------------------------------- 1 | ## keyboard.c 2 | 3 | 键盘驱动程序 4 | 5 | 6 | 7 | 键盘驱动还是有点复杂的,话不多说,直接看图,自己理解,看完下面的原理,再对着代码看一看应该就OK了,驱动了解一下就行。 8 | 9 | ![image-20210102114611098](readme.assets/image-20210102114611098.png) 10 | 11 | ![image-20210102114624229](readme.assets/image-20210102114624229.png) 12 | 13 | ![image-20210102114657210](readme.assets/image-20210102114657210.png) 14 | 15 | 16 | 17 | ![image-20210102114752810](readme.assets/image-20210102114752810.png) 18 | 19 | ![image-20210102114805015](readme.assets/image-20210102114805015.png) 20 | 21 | ![image-20210102114819159](readme.assets/image-20210102114819159.png) 22 | 23 | 24 | 25 | ![image-20210102115246364](readme.assets/image-20210102115246364.png) 26 | 27 | ![image-20210102115255006](readme.assets/image-20210102115255006.png) 28 | 29 | ![image-20210102115304459](readme.assets/image-20210102115304459.png) 30 | 31 | ![image-20210102115317484](readme.assets/image-20210102115317484.png) 32 | 33 | ![image-20210102115333510](readme.assets/image-20210102115333510.png) 34 | 35 | ![image-20210102115342960](readme.assets/image-20210102115342960.png) 36 | 37 | ![image-20210102115355715](readme.assets/image-20210102115355715.png) 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /kernel/main/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project(main) 2 | 3 | add_library(${PROJECT_NAME} OBJECT main.c) 4 | target_include_directories(${PROJECT_NAME} 5 | PUBLIC 6 | ${FreeFlyOS_SOURCE_DIR}/kernel/asm 7 | ${FreeFlyOS_SOURCE_DIR}/kernel/debug 8 | ${FreeFlyOS_SOURCE_DIR}/kernel/dt 9 | ${FreeFlyOS_SOURCE_DIR}/kernel/interrupt 10 | ${FreeFlyOS_SOURCE_DIR}/kernel/keyboard 11 | ${FreeFlyOS_SOURCE_DIR}/kernel/mem 12 | ${FreeFlyOS_SOURCE_DIR}/kernel/pic 13 | ${FreeFlyOS_SOURCE_DIR}/kernel/serial 14 | ${FreeFlyOS_SOURCE_DIR}/kernel/timer 15 | ${FreeFlyOS_SOURCE_DIR}/kernel/vga 16 | ${FreeFlyOS_SOURCE_DIR}/kernel/task 17 | ${FreeFlyOS_SOURCE_DIR}/kernel/file 18 | ${FreeFlyOS_SOURCE_DIR}/kernel/user 19 | ${FreeFlyOS_SOURCE_DIR}/kernel/apic 20 | ${FreeFlyOS_SOURCE_DIR}/kernel/ap 21 | ${FreeFlyOS_SOURCE_DIR}/kernel/internet 22 | ${FreeFlyOS_SOURCE_DIR}/kernel/sync 23 | ) -------------------------------------------------------------------------------- /kernel/main/main.h: -------------------------------------------------------------------------------- 1 | #ifndef _MAIN_H_ 2 | #define _MAIN_H_ 3 | 4 | void main(void); 5 | void test(); 6 | static void write2fs(); 7 | #endif -------------------------------------------------------------------------------- /kernel/main/readme.md: -------------------------------------------------------------------------------- 1 | ## main.c 2 | 3 | ELF格式的内核入口,包含各种外设初始化,以及GDT和IDT表的设置等。 4 | 5 | 6 | 7 | main函数基本上就是整个内核的执行过程了,包含以下几个主要步骤: 8 | 9 | 1、GDT初始化 10 | 11 | 2、PIC中断和IDT初始化。 12 | 13 | 3、串口初始化。 14 | 15 | 4、键盘初始化。 16 | 17 | 5、建立新页表 18 | 19 | 6、内存初始化。 20 | 21 | 7、文件系统初始化。 22 | 23 | 8、内核进程初始化。 24 | 25 | 9、时钟初始化。 26 | 27 | 10、信号量初始化。 28 | 29 | 11、用户进程初始化。 30 | 31 | 从以上步骤我们基本能看出FreeFlyOS具有哪些功能了。 -------------------------------------------------------------------------------- /kernel/mem/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #设置项目名 2 | project (mem) 3 | 4 | add_library(${PROJECT_NAME} OBJECT pmm.c vmm.c) 5 | target_include_directories(${PROJECT_NAME} 6 | PUBLIC 7 | ${FreeFlyOS_SOURCE_DIR}/kernel/asm 8 | ${FreeFlyOS_SOURCE_DIR}/kernel/mem 9 | ${FreeFlyOS_SOURCE_DIR}/kernel/vga 10 | ${FreeFlyOS_SOURCE_DIR}/kernel/stl 11 | ${FreeFlyOS_SOURCE_DIR}/kernel/task 12 | ) 13 | -------------------------------------------------------------------------------- /kernel/mem/pmm.h: -------------------------------------------------------------------------------- 1 | #ifndef _PMM_H_ 2 | #define _PMM_H_ 3 | 4 | //内存探测时存储数据地址 5 | #define mem_seg_num 0x8000 6 | #define mem_seg_start 0x8004 7 | 8 | //物理页大小 4KB 9 | #define PMM_PAGE_SIZE 0x1000 10 | //物理页掩码 11 | #define PMM_PAGE_MASK 0xFFFFF000 12 | 13 | //物理页标志位 14 | #define PMM_PAGE_KERNEL 0 15 | #define PMM_PAGE_USER 1 16 | #define PMM_PAGE_DIRTY 2 17 | #define PMM_PAGE_LOCK 4 18 | #define PMM_PAGE_INVALID 8 19 | 20 | #define PMM_PAGE_DMA 0 21 | #define PMM_PAGE_NORMAL 16 22 | #define PMM_PAGE_HIGHMEM 32 23 | 24 | //管理区域起始地址 25 | #define DMA_START 0x0 26 | #define NORMAL_START 0x1000000 //16MB 27 | #define HIGHMEM_START 0x38000000 //896MB 28 | //2GB的内存,最多有2GB/4KB=2^19个页=524288页 29 | #define MAX_PMM_PAGE 0x80000 30 | //将物理地址转化为物理页号 31 | #define pa_idx(pa) ((pa&PMM_PAGE_MASK)>>12) 32 | 33 | struct memory_seg{ 34 | unsigned long long base; 35 | unsigned long long size; 36 | unsigned int state; 37 | }__attribute__((packed)); 38 | 39 | //内存管理单位:页 40 | typedef struct page{ 41 | /* 42 | 一组标志位 43 | 位0代表页属性,0代表内核页,1代表用户页 44 | 位1代表是否被修改,即脏位,1代表已修改 45 | 位2代表是否上锁,1代表已上锁 46 | 位3代表该页是不是处于MMIO区域,即不可用内存,1代表该页不可用 47 | 位4和位5代表该页所属管理区,00代表DMA区域,01代表NORMAL区域,10代表HIGHMEM区域 48 | */ 49 | unsigned char flags; 50 | int count; //页的引用计数器,字段为-1时,代表空闲 51 | unsigned int addr; //页起始地址 52 | //struct address_space *mapping; 53 | }pm_page; 54 | 55 | //内存管理区域 56 | typedef struct zone{ 57 | pm_page *pmpage; //指向该区域下的物理页数组 58 | unsigned int all_pages; //管理区下的物理页数量 59 | unsigned int free_pages; //管理区下的空闲页数量 60 | }pm_zone; 61 | 62 | void pmm_init(); 63 | unsigned int pmm_alloc(unsigned int bytes,char zone); 64 | void pmm_free(unsigned int addr,unsigned int bytes); 65 | 66 | #endif -------------------------------------------------------------------------------- /kernel/mem/readme.assets/image-20210102163754215.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/kernel/mem/readme.assets/image-20210102163754215.png -------------------------------------------------------------------------------- /kernel/mem/readme.md: -------------------------------------------------------------------------------- 1 | #### memlayout.h 2 | 3 | 内存布局信息 4 | 5 | #### pmm.c 6 | 7 | 物理内存管理 8 | 9 | 10 | 11 | 呃,关于内存管理这块,说实话感觉自己写的很烂,烂归烂,分配和释放内存还是没问题的,只是有些情况没有考虑全面,比如内存用完之后,分配算法就会失效,不多说了,先来看下怎么实现的吧,如下图所示,代码很简单,就是页表映射稍微复杂点,另外注明一下,cr3为页表基址,这个地址必须为页表的物理地址,然后页表项和页项分别存的是页表的物理地址和页的物理地址,所以需要进行一个线性变换(若内核页使用直接映射方式)。 12 | 13 | ![image-20210102163754215](readme.assets/image-20210102163754215.png) -------------------------------------------------------------------------------- /kernel/mem/vmm.h: -------------------------------------------------------------------------------- 1 | #ifndef _VMM_H_ 2 | #define _VMM_H_ 3 | 4 | #include "../stl/list.h" 5 | //虚拟页大小 6 | #define VMM_PAGE_SIZE 0x1000 7 | 8 | //页目录项数 9 | #define PAGE_DIR_SIZE 0x400 10 | //页表项数 11 | #define PAGE_TABLE_SIZE 0x400 12 | 13 | //虚拟页掩码 14 | #define VMM_PAGE_MASK 0xFFFFF000 15 | 16 | //bit0代表页或页表存在位,为1时,说明页在物理内存中,指向地址转换 17 | // 为0时,表示页不在内存中,若访问则出现页故障异常 18 | #define VMM_PAGE_PRESENT 0x1 19 | #define VMM_PAGE_UNPRESENT 0x0 20 | //bit1代表一个页或一组页的读/写标志,为0时只读,为1时可读可写 21 | #define VMM_PAGE_RW 0x2 22 | //bit2代表一个页或一组页的权限,为0时内核权限,为1时用户权限 23 | #define VMM_PAGE_KERNEL 0x0 24 | #define VMM_PAGE_USER 0x4 25 | 26 | //addr开始的虚拟地址在页目录表中的项数 27 | #define idx(addr) (unsigned int)((unsigned int)addr)/((unsigned int)PAGE_TABLE_SIZE*(unsigned int)VMM_PAGE_SIZE) 28 | 29 | //将链表节点转化为vma_struct起始地址 30 | #define le2vma(le, member) \ 31 | to_struct((le), struct vma_struct, member) 32 | 33 | #define VMA_READ 0x1 //只读 34 | #define VMA_WRITE 0x2 //只写 35 | #define VMA_EXEC 0x4 //只执行 36 | 37 | //VMA数据结构,为了分配大量连续的页 38 | struct vma_struct{ 39 | //struct mm_struct *vm_mm; 40 | unsigned int vm_start; //虚拟内存区域起始地址 41 | unsigned int vm_end; //结束地址 42 | unsigned int vm_flags; //标志变量 43 | //list_entry_t link; 44 | }; 45 | 46 | //highmem区域虚拟地址转换为物理地址 47 | struct highmem_va_pa 48 | { 49 | unsigned int va; //页表虚拟地址 50 | unsigned int pa; //页表物理地址 51 | }; 52 | 53 | //包含所有VMA的共同属性 54 | /*struct mm_struct{ 55 | list_entry_t mmap_link; 56 | struct vma_struct *mmap_cache; //包含的所有VMA区域 57 | unsigned int *pgdir; //包含的VMA区域所属页表 58 | int map_count; //包含的VMA区域计数器 59 | }; */ 60 | 61 | void setup_vpt(); 62 | unsigned int vmm_malloc(unsigned int bytes,char zonenum); 63 | void vmm_free(unsigned int addr,unsigned int bytes); 64 | 65 | void vmm_map(unsigned int *pdt,unsigned int va_start,unsigned int va_end,unsigned int pa_start); 66 | unsigned int setup_pgdir(); 67 | unsigned int sys_malloc(unsigned int bytes); 68 | void sys_free(unsigned int addr,unsigned int size); 69 | void sys_mmap(unsigned int va_start,unsigned int va_end,unsigned int pa_start); 70 | #endif -------------------------------------------------------------------------------- /kernel/mp/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #设置项目名 2 | project (mp) 3 | 4 | add_library(${PROJECT_NAME} OBJECT mp_config.c) 5 | target_include_directories(${PROJECT_NAME} 6 | PUBLIC 7 | ${FreeFlyOS_SOURCE_DIR}/kernel/mp 8 | ${FreeFlyOS_SOURCE_DIR}/kernel/mem 9 | ${FreeFlyOS_SOURCE_DIR}/kernel/asm 10 | ${FreeFlyOS_SOURCE_DIR}/kernel/init 11 | ) 12 | -------------------------------------------------------------------------------- /kernel/pic/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #设置项目名 2 | project (pic) 3 | 4 | add_library(${PROJECT_NAME} OBJECT pic.c) 5 | target_include_directories(${PROJECT_NAME} 6 | PUBLIC 7 | ${FreeFlyOS_SOURCE_DIR}/kernel/pic 8 | ) 9 | -------------------------------------------------------------------------------- /kernel/pic/pic.c: -------------------------------------------------------------------------------- 1 | #include "pic.h" 2 | 3 | static unsigned short irq_mask = 0xFFFF & ~(1 << 2); 4 | static char did_init = 0; 5 | 6 | static void pic_setmask(unsigned short mask) { 7 | irq_mask = mask; 8 | unsigned char mask_low=mask&0xff; 9 | unsigned char mask_high=(mask>>8)&0xff; 10 | if (did_init) 11 | { 12 | outb(0x21, mask_low); 13 | outb(0xA1, mask_high); 14 | } 15 | } 16 | 17 | void pic_enable(unsigned int irq) { 18 | pic_setmask(irq_mask & ~(1 << irq)); 19 | } 20 | 21 | void pic_init(){ 22 | did_init = 1; 23 | //屏蔽所有中断 24 | outb(0x21,0xFF); 25 | outb(0xA1,0xFF); 26 | 27 | // 重新映射 IRQ 表 28 | // 两片级联的 Intel 8259A 芯片 29 | // 主片端口 0x20 0x21 30 | // 从片端口 0xA0 0xA1 31 | 32 | //设置ICW1命令字, 33 | // 初始化主片、从片 34 | // 0001 0001 35 | outb(0x20, 0x11); 36 | outb(0xA0, 0x11); 37 | 38 | 39 | // 设置主片 IRQ 从 0x20(32) 号中断开始 40 | outb(0x21, 0x20); 41 | 42 | // 设置从片 IRQ 从 0x28(40) 号中断开始 43 | outb(0xA1, 0x28); 44 | 45 | // 设置主片 IR2 引脚连接从片 46 | outb(0x21, 0x04); 47 | 48 | // 告诉从片输出引脚和主片 IR2 号相连 49 | outb(0xA1, 0x02); 50 | 51 | //NB Automatic EOI mode doesn't tend to work on the slave. 52 | outb(0x21, 0x03); 53 | outb(0xA1, 0x03); 54 | 55 | // OCW3: 0ef01prs 56 | // ef: 0x = NOP, 10 = clear specific mask, 11 = set specific mask 57 | // p: 0 = no polling, 1 = polling mode 58 | // rs: 0x = NOP, 10 = read IRR, 11 = read ISR 59 | outb(0x20, 0x68); // clear specific mask 60 | outb(0xA0, 0x68); // OCW3 61 | outb(0x20, 0x0a); // read IRR by default 62 | outb(0xA0, 0x0a); // OCW3 63 | 64 | if (irq_mask != 0xFFFF) 65 | pic_setmask(irq_mask); 66 | 67 | } -------------------------------------------------------------------------------- /kernel/pic/pic.h: -------------------------------------------------------------------------------- 1 | #ifndef _PIC_H_ 2 | #define _PIC_H_ 3 | 4 | void pic_init(); 5 | void pic_enable(unsigned int irq); 6 | 7 | #endif -------------------------------------------------------------------------------- /kernel/pic/readme.assets/image-20210102164946298.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/kernel/pic/readme.assets/image-20210102164946298.png -------------------------------------------------------------------------------- /kernel/pic/readme.md: -------------------------------------------------------------------------------- 1 | ## pic.c 2 | 3 | 8259A芯片级联控制器PIC的初始化 4 | 5 | #### 8259A芯片 6 | 7 | 8259A是[专门](https://baike.baidu.com/item/专门/8698309)为了对8085A和8086/8088进行中断[控制](https://baike.baidu.com/item/控制/17222)而设计的芯片,它是可以用程序控制的中断控制器。单个的8259A能管理8级向量优先级中断。在不增加其他电路的情况下,最多可以级联成64级的向量优级[中断系统](https://baike.baidu.com/item/中断系统/10480702)。8259A有多种工作方式,能用于各种系统。各种工作方式的设定是在初始化时通过软件进行的。 在[总线控制器](https://baike.baidu.com/item/总线控制器/8829516)的控制下,8259A芯片可以处于编程状态和操作状态,编程状态是CPU使用IN或OUT指令对8259A芯片进行初始化编程的状态。 8 | 9 | 一个外部[中断请求](https://baike.baidu.com/item/中断请求)信号通过中断请求线[IRQ](https://baike.baidu.com/item/IRQ/1229055),传输到IMR([中断屏蔽](https://baike.baidu.com/item/中断屏蔽)[寄存器](https://baike.baidu.com/item/寄存器)),IMR根据所设定的[中断屏蔽字](https://baike.baidu.com/item/中断屏蔽字)(OCW1),决定是将其丢弃还是接受。如果可以接受,则8259A将IRR(中断请求暂存寄存器)中代表此IRQ的位置置1,以表示此IRQ有中断请求信号,并同时向CPU的INTR(中断请求)管脚发送一个信号。但CPU这时可能正在执行一条指令,因此CPU不会立即响应。而当这CPU正忙着执行某条指令时,还有可能有其余的IRQ线送来中断请求,这些请求都会接受IMR的挑选。如果没有被屏蔽,那么这些请求也会被放到IRR中,也即IRR中代表它们的IRQ的相应位会被置1。 10 | 11 | 当CPU执行完一条指令时后,会检查一下INTR管脚是否有信号。如果发现有信号,就会转到中断服务,此时,CPU会立即向8259A芯片的INTA(中断应答)管脚发送一个信号。当芯片收到此信号后,判优部件开始工作,它在IRR中,挑选优先级最高的中断,将[中断请求](https://baike.baidu.com/item/中断请求)送到ISR(中断服务[寄存器](https://baike.baidu.com/item/寄存器)),也即将ISR中代表此[IRQ](https://baike.baidu.com/item/IRQ/1229055)的位置一,并将IRR中相应位置零,表明此中断正在接受CPU的处理。同时,将它的编号写入[中断向量](https://baike.baidu.com/item/中断向量)寄存器[IVR](https://baike.baidu.com/item/IVR/279431)的低三位(IVR正是由ICW2所指定的,不知你是否还记得ICW2的最低三位在指定时都是0,而在这里,它们被利用了!)这时,CPU还会送来第二个INTA信号,当收到此信号后,芯片将IVR中的内容,也就是此中断的[中断号](https://baike.baidu.com/item/中断号)送上通向CPU的数据线。 12 | 13 | 这个内容看起来仿佛十分复杂,但如果我们用一个很简单的比喻来解释就好理解了。CPU就相当于一个公司的老总,而8259A芯片就相当于这个老总的秘书。比如有很多人想见老总,但老总正在打电话,于是交由秘书先行接待。每个想见老总的人都需要把自己的名片交给秘书,秘书首先看看名片,有没有老总明确表示不愿见到的人,如果没有就把它放到一个盒子里面。这时老总的电话还没打完,但不停的有人递上名片求见老总,秘书就把符合要求的名片全放在盒子里了。老总打完电话了,探出头来问秘书:有人想见我吗?这时,秘书就从盒子里挑选一个级别最高的,并把他的名片交给老总。 14 | 15 | ![image-20210102164946298](readme.assets/image-20210102164946298.png) 16 | 17 | 初始化流程: 18 | 19 | 1、根据ICW1的格式,当发送的字节第5比特位(D4)=1,并且地址线A0=0时,表示对ICW1编程。一般把ICW1设置为0x11,表示中断请求是边沿触发、多片8259A级联并且需要发送ICW4。 20 | 21 | 2、在设置了ICW1后,当A0=1时表示对ICW2进行设置,此时8259A主芯片的端口地址是0x21,从芯片的端口地址是0xA1。在Linux-0.11系统中,主片的ICW2设置为0x20,表示主片中断请求0-7级对应的中断号是0x20-0x27,从片的ICW设置为0x28,表示从片中断请求从中断号0x28开始。 22 | 23 | 3、对于ICW3来说,把8259A主片的ICW3设置为0x04,表示IR2连接了从片,8259A从片设置为0x02,表示该片连接到主片的IR2引脚。 24 | 25 | 4、8259A主片和从片的ICW4命令字均设置为0x01,表示8259A 芯片被设置成普通全嵌套、非缓冲、非自动结束中断方式,并且用于8086及其兼容系统。 26 | 27 | 5、允许8259A主片和从片的中断。 -------------------------------------------------------------------------------- /kernel/pipe/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #设置项目名 2 | project (pipe) 3 | 4 | add_library(${PROJECT_NAME} OBJECT pipe.c ioqueue.c) 5 | target_include_directories(${PROJECT_NAME} 6 | PUBLIC 7 | ${FreeFlyOS_SOURCE_DIR}/kernel/task 8 | ${FreeFlyOS_SOURCE_DIR}/kernel/sync 9 | ${FreeFlyOS_SOURCE_DIR}/kernel/file 10 | ${FreeFlyOS_SOURCE_DIR}/kernel/mem 11 | ${FreeFlyOS_SOURCE_DIR}/kernel/debug 12 | ) 13 | -------------------------------------------------------------------------------- /kernel/pipe/ioqueue.c: -------------------------------------------------------------------------------- 1 | #include "ioqueue.h" 2 | #include "../task/task.h" 3 | #include "../debug/debug.h" 4 | extern struct task_struct *current; 5 | /* 初始化io队列ioq */ 6 | void ioqueue_init(struct ioqueue* ioq) { 7 | lock_init(&ioq->lock); // 初始化io队列的锁 8 | ioq->producer = ioq->consumer = NULL; // 生产者和消费者置空 9 | ioq->head = ioq->tail = 0; // 队列的首尾指针指向缓冲区数组第0个位置 10 | } 11 | 12 | /* 返回pos在缓冲区中的下一个位置值 */ 13 | static int next_pos(int pos) { 14 | return (pos + 1) % bufsize; 15 | } 16 | 17 | /* 判断队列是否已满 */ 18 | char ioq_full(struct ioqueue* ioq) { 19 | //ASSERT(get_now_intr_status() == INTR_OFF); 20 | return next_pos(ioq->head) == ioq->tail; 21 | } 22 | 23 | /* 判断队列是否已空 */ 24 | static char ioq_empty(struct ioqueue* ioq) { 25 | //ASSERT(get_now_intr_status() == INTR_OFF); 26 | return ioq->head == ioq->tail; 27 | } 28 | 29 | /* 使当前生产者或消费者在此缓冲区上等待 */ 30 | static void ioq_wait(struct task_struct** waiter) { 31 | ASSERT(*waiter == NULL && waiter != NULL); 32 | *waiter = current; 33 | thread_block(STOPPED); 34 | } 35 | 36 | /* 唤醒waiter */ 37 | static void wakeup(struct task_struct** waiter) { 38 | ASSERT(*waiter != NULL); 39 | thread_unblock(*waiter); 40 | *waiter = NULL; 41 | } 42 | 43 | /* 消费者从ioq队列中获取一个字符 */ 44 | char ioq_getchar(struct ioqueue* ioq) { 45 | //ASSERT(get_now_intr_status() == INTR_OFF); 46 | 47 | /* 若缓冲区(队列)为空,把消费者ioq->consumer记为当前线程自己, 48 | * 目的是将来生产者往缓冲区里装商品后,生产者知道唤醒哪个消费者, 49 | * 也就是唤醒当前线程自己*/ 50 | while (ioq_empty(ioq)) { 51 | lock_acquire(&ioq->lock); 52 | ioq_wait(&ioq->consumer); 53 | lock_release(&ioq->lock); 54 | } 55 | 56 | char byte = ioq->buf[ioq->tail]; // 从缓冲区中取出 57 | ioq->tail = next_pos(ioq->tail); // 把读游标移到下一位置 58 | 59 | if (ioq->producer != NULL) { 60 | wakeup(&ioq->producer); // 唤醒生产者 61 | } 62 | 63 | return byte; 64 | } 65 | 66 | /* 生产者往ioq队列中写入一个字符byte */ 67 | void ioq_putchar(struct ioqueue* ioq, char byte) { 68 | //ASSERT(get_now_intr_status() == INTR_OFF); 69 | 70 | /* 若缓冲区(队列)已经满了,把生产者ioq->producer记为自己, 71 | * 为的是当缓冲区里的东西被消费者取完后让消费者知道唤醒哪个生产者, 72 | * 也就是唤醒当前线程自己*/ 73 | while (ioq_full(ioq)) { 74 | lock_acquire(&ioq->lock); 75 | ioq_wait(&ioq->producer); 76 | lock_release(&ioq->lock); 77 | } 78 | ioq->buf[ioq->head] = byte; // 把字节放入缓冲区中 79 | ioq->head = next_pos(ioq->head); // 把写游标移到下一位置 80 | 81 | if (ioq->consumer != NULL) { 82 | wakeup(&ioq->consumer); // 唤醒消费者 83 | } 84 | } 85 | 86 | /* 返回环形缓冲区中的数据长度 */ 87 | unsigned int ioq_length(struct ioqueue* ioq) { 88 | unsigned int len = 0; 89 | if (ioq->head >= ioq->tail) { 90 | len = ioq->head - ioq->tail; 91 | } else { 92 | len = bufsize - (ioq->tail - ioq->head); 93 | } 94 | return len; 95 | } 96 | -------------------------------------------------------------------------------- /kernel/pipe/ioqueue.h: -------------------------------------------------------------------------------- 1 | #ifndef _IOQUEUE_H_ 2 | #define _IOQUEUE_H_ 3 | #include "../sync/sync.h" 4 | #include "../task/task.h" 5 | 6 | #define bufsize 64 7 | 8 | /* 环形队列 */ 9 | struct ioqueue { 10 | // 生产者消费者问题 11 | struct lock lock; 12 | /* 生产者,缓冲区不满时就继续往里面放数据, 13 | * 否则就睡眠,此项记录哪个生产者在此缓冲区上睡眠。*/ 14 | struct task_struct* producer; 15 | 16 | /* 消费者,缓冲区不空时就继续从往里面拿数据, 17 | * 否则就睡眠,此项记录哪个消费者在此缓冲区上睡眠。*/ 18 | struct task_struct* consumer; 19 | char buf[bufsize]; // 缓冲区大小 20 | int head; // 队首,数据往队首处写入 21 | int tail; // 队尾,数据从队尾处读出 22 | }; 23 | 24 | void ioqueue_init(struct ioqueue* ioq); 25 | char ioq_full(struct ioqueue* ioq); 26 | char ioq_getchar(struct ioqueue* ioq); 27 | void ioq_putchar(struct ioqueue* ioq, char byte); 28 | unsigned int ioq_length(struct ioqueue* ioq); 29 | #endif 30 | -------------------------------------------------------------------------------- /kernel/pipe/pipe.c: -------------------------------------------------------------------------------- 1 | #include "pipe.h" 2 | #include "ioqueue.h" 3 | #include "../file/file.h" 4 | #include "../file/fs.h" 5 | #include "../mem/vmm.h" 6 | #define NULL ((void *)0) 7 | extern struct file file_table[MAX_FILE_OPEN]; 8 | /* 判断文件描述符local_fd是否是管道 */ 9 | char is_pipe(unsigned int local_fd) { 10 | unsigned int global_fd = fd_local2global(local_fd); 11 | return file_table[global_fd].fd_flag == PIPE_FLAG; 12 | } 13 | 14 | /* 创建管道,成功返回0,失败返回-1 */ 15 | int sys_pipe(int pipefd[2]) { 16 | int global_fd = get_free_slot_in_global(); 17 | 18 | /* 申请一页内核内存做环形缓冲区 */ 19 | file_table[global_fd].fd_inode =vmm_malloc(VMM_PAGE_SIZE,1); 20 | 21 | /* 初始化环形缓冲区 */ 22 | ioqueue_init((struct ioqueue*)file_table[global_fd].fd_inode); 23 | if (file_table[global_fd].fd_inode == NULL) { 24 | return -1; 25 | } 26 | 27 | /* 将fd_flag复用为管道标志 */ 28 | file_table[global_fd].fd_flag = PIPE_FLAG; 29 | 30 | /* 将fd_pos复用为管道打开数 */ 31 | file_table[global_fd].fd_pos = 2; 32 | pipefd[0] = task_fd_install(global_fd); 33 | pipefd[1] = task_fd_install(global_fd); 34 | return 0; 35 | } 36 | 37 | /* 从管道中读数据 */ 38 | unsigned int pipe_read(int fd, void* buf, unsigned int count) { 39 | char* buffer = buf; 40 | unsigned int bytes_read = 0; 41 | unsigned int global_fd = fd_local2global(fd); 42 | 43 | /* 获取管道的环形缓冲区 */ 44 | struct ioqueue* ioq = (struct ioqueue*)file_table[global_fd].fd_inode; 45 | 46 | /* 选择较小的数据读取量,避免阻塞 */ 47 | unsigned int ioq_len = ioq_length(ioq); 48 | unsigned int size = ioq_len > count ? count : ioq_len; 49 | while (bytes_read < size) { 50 | *buffer = ioq_getchar(ioq); 51 | bytes_read++; 52 | buffer++; 53 | } 54 | return bytes_read; 55 | } 56 | 57 | /* 往管道中写数据 */ 58 | unsigned int pipe_write(int fd, const void* buf, unsigned int count) { 59 | unsigned int bytes_write = 0; 60 | unsigned int global_fd = fd_local2global(fd); 61 | struct ioqueue* ioq = (struct ioqueue*)file_table[global_fd].fd_inode; 62 | 63 | /* 选择较小的数据写入量,避免阻塞 */ 64 | unsigned int ioq_left = bufsize - ioq_length(ioq); 65 | unsigned int size = ioq_left > count ? count : ioq_left; 66 | 67 | const char* buffer = buf; 68 | while (bytes_write < size) { 69 | ioq_putchar(ioq, *buffer); 70 | bytes_write++; 71 | buffer++; 72 | } 73 | return bytes_write; 74 | } 75 | -------------------------------------------------------------------------------- /kernel/pipe/pipe.h: -------------------------------------------------------------------------------- 1 | #ifndef _PIPE_H_ 2 | #define _PIPE_H_ 3 | 4 | #define PIPE_FLAG 0xFFFF 5 | char is_pipe(unsigned int local_fd); 6 | int sys_pipe(int pipefd[2]); 7 | unsigned int pipe_read(int fd, void* buf, unsigned int count); 8 | unsigned int pipe_write(int fd, const void* buf, unsigned int count); 9 | #endif 10 | -------------------------------------------------------------------------------- /kernel/pipe/readme.md: -------------------------------------------------------------------------------- 1 | 该目录主要是双向管道的实现,很像一个生产者和消费者问题,主要步骤如下: 2 | 3 | 1、初始化一个IO队列,主要包含了一个锁和一个缓冲区队列,进程通过该IO队列进行通信。 4 | 5 | 2、管道本质上是文件描述符表对应的i节点,对于一个双向管道,需要有读管道和写管道,将其对应到全局文件表中,之后将其分别安装在进程自己的文件描述符表中。 6 | 7 | 3、父子进程通过自己的文件描述符表信息可以获取全局文件表的i节点,从而进行通信,缓冲区有数据则唤醒消费者,若无数据则消费者等待。 8 | 9 | -------------------------------------------------------------------------------- /kernel/readme.md: -------------------------------------------------------------------------------- 1 | ## kernel.ld 2 | 3 | 内核各个节的链接地址,从物理内存0x1000000(16MB)开始 4 | 5 | ## CMakeLists.txt 6 | 7 | 生成elf格式的内核kernel,接着使用dd命令将boot中的bootblock(MBR)和内核kernel生成启动盘 8 | 接着通过32位qemu运行该盘(按硬盘方式),即可得到截图结果。 -------------------------------------------------------------------------------- /kernel/serial/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #设置项目名 2 | project (serial) 3 | 4 | add_library(${PROJECT_NAME} OBJECT serial.c) 5 | target_include_directories(${PROJECT_NAME} 6 | PUBLIC 7 | ${FreeFlyOS_SOURCE_DIR}/kernel/asm 8 | ${FreeFlyOS_SOURCE_DIR}/kernel/interrupt 9 | ${FreeFlyOS_SOURCE_DIR}/kernel/pic 10 | ${FreeFlyOS_SOURCE_DIR}/kernel/serial 11 | ${FreeFlyOS_SOURCE_DIR}/kernel/vga 12 | ${FreeFlyOS_SOURCE_DIR}/kernel/keyboard 13 | ${FreeFlyOS_SOURCE_DIR}/kernel/apic 14 | ) 15 | -------------------------------------------------------------------------------- /kernel/serial/readme.md: -------------------------------------------------------------------------------- 1 | ## serial.c 2 | 3 | 串口设备驱动 4 | 5 | 6 | 7 | 串口在FreeFlyOS中好像没有起多大作用,不多说了,有兴趣的读者可以深入研究。 -------------------------------------------------------------------------------- /kernel/serial/serial.c: -------------------------------------------------------------------------------- 1 | #include "serial.h" 2 | #include "../pic/pic.h" 3 | #include "../asm/asm.h" 4 | #include "../interrupt/trap.h" 5 | #include "../vga/vga.h" 6 | #include "../keyboard/keyboard.h" 7 | #include "../apic/apic.h" 8 | struct consle cons; 9 | 10 | static char serial_exists = 0; 11 | extern char shell_input; //shell输入字符 12 | /* stupid I/O delay routine necessitated by historical PC design flaws */ 13 | void delay(void) 14 | { 15 | inb(0x84); 16 | inb(0x84); 17 | inb(0x84); 18 | inb(0x84); 19 | } 20 | 21 | void serial_init(void) { 22 | 23 | // Turn off the FIFO 24 | outb(COM1 + COM_FCR, 0); 25 | 26 | // Set speed; requires DLAB latch 27 | outb(COM1 + COM_LCR, COM_LCR_DLAB); 28 | outb(COM1 + COM_DLL, (unsigned char) (115200 / 9600)); 29 | outb(COM1 + COM_DLM, 0); 30 | 31 | // 8 data bits, 1 stop bit, parity off; turn off DLAB latch 32 | outb(COM1 + COM_LCR, COM_LCR_WLEN8 & ~COM_LCR_DLAB); 33 | 34 | // No modem controls 35 | outb(COM1 + COM_MCR, 0); 36 | // Enable rcv interrupts 37 | outb(COM1 + COM_IER, COM_IER_RDI); 38 | 39 | // Clear any preexisting overrun indications and interrupts 40 | // Serial port doesn't exist if COM_LSR returns 0xFF 41 | serial_exists = (inb(COM1 + COM_LSR) != 0xFF); 42 | (void) inb(COM1+COM_IIR); 43 | (void) inb(COM1+COM_RX); 44 | 45 | if (serial_exists) { 46 | printk("serial exist!\n"); 47 | pic_enable(IRQ_COM1); 48 | //enable_irq(IRQ_COM1,0); 49 | } 50 | } 51 | void lpt_putc_sub(int c) { 52 | int i; 53 | for (i = 0; !(inb(LPTPORT + 1) & 0x80) && i < 12800; i ++) { 54 | delay(); 55 | } 56 | outb(LPTPORT + 0, c); 57 | outb(LPTPORT + 2, 0x08 | 0x04 | 0x01); 58 | outb(LPTPORT + 2, 0x08); 59 | } 60 | 61 | /* lpt_putc - copy console output to parallel port */ 62 | void lpt_putc(int c) { 63 | if (c != '\b') { 64 | lpt_putc_sub(c); 65 | } 66 | else { 67 | lpt_putc_sub('\b'); 68 | lpt_putc_sub(' '); 69 | lpt_putc_sub('\b'); 70 | } 71 | } 72 | 73 | 74 | /* * 75 | * cons_intr - called by device interrupt routines to feed input 76 | * characters into the circular console input buffer. 77 | * */ 78 | void cons_intr(int (*proc)(void)) { 79 | int c; 80 | while ((c = (*proc)()) != -1) { 81 | if (c != 0) { 82 | cons.buf[cons.wpos ++] = c; 83 | shell_input= c; 84 | if (cons.wpos == CONSBUFSIZE) { 85 | cons.wpos = 0; 86 | } 87 | } 88 | } 89 | } 90 | 91 | /* serial_proc_data - get data from serial port */ 92 | int serial_proc_data(void) { 93 | if (!(inb(COM1 + COM_LSR) & COM_LSR_DATA)) { 94 | return -1; 95 | } 96 | int c = inb(COM1 + COM_RX); 97 | if (c == 127) { 98 | c = '\b'; 99 | } 100 | return c; 101 | } 102 | 103 | /* serial_intr - try to feed input characters from serial port */ 104 | void serial_intr(void) { 105 | if (serial_exists) { 106 | cons_intr(serial_proc_data); 107 | } 108 | } 109 | 110 | void serial_putc_sub(int c) { 111 | int i; 112 | for (i = 0; !(inb(COM1 + COM_LSR) & COM_LSR_TXRDY) && i < 12800; i ++) { 113 | delay(); 114 | } 115 | outb(COM1 + COM_TX, c); 116 | } 117 | 118 | /* serial_putc - print character to serial port */ 119 | void serial_putc(int c) { 120 | if (c != '\b') { 121 | serial_putc_sub(c); 122 | } 123 | else { 124 | serial_putc_sub('\b'); 125 | serial_putc_sub(' '); 126 | serial_putc_sub('\b'); 127 | } 128 | } 129 | 130 | 131 | -------------------------------------------------------------------------------- /kernel/serial/serial.h: -------------------------------------------------------------------------------- 1 | #ifndef _SERIAL_H_ 2 | #define _SERIAL_H_ 3 | 4 | #define COM1 0x3F8 5 | 6 | #define COM_RX 0 // In: Receive buffer (DLAB=0) 7 | #define COM_TX 0 // Out: Transmit buffer (DLAB=0) 8 | #define COM_DLL 0 // Out: Divisor Latch Low (DLAB=1) 9 | #define COM_DLM 1 // Out: Divisor Latch High (DLAB=1) 10 | #define COM_IER 1 // Out: Interrupt Enable Register 11 | #define COM_IER_RDI 0x01 // Enable receiver data interrupt 12 | #define COM_IIR 2 // In: Interrupt ID Register 13 | #define COM_FCR 2 // Out: FIFO Control Register 14 | #define COM_LCR 3 // Out: Line Control Register 15 | #define COM_LCR_DLAB 0x80 // Divisor latch access bit 16 | #define COM_LCR_WLEN8 0x03 // Wordlength: 8 bits 17 | #define COM_MCR 4 // Out: Modem Control Register 18 | #define COM_MCR_RTS 0x02 // RTS complement 19 | #define COM_MCR_DTR 0x01 // DTR complement 20 | #define COM_MCR_OUT2 0x08 // Out2 complement 21 | #define COM_LSR 5 // In: Line Status Register 22 | #define COM_LSR_DATA 0x01 // Data available 23 | #define COM_LSR_TXRDY 0x20 // Transmit buffer avail 24 | #define COM_LSR_TSRE 0x40 // Transmitter off 25 | #define LPTPORT 0x378 26 | #define CONSBUFSIZE 512 27 | 28 | struct consle{ 29 | unsigned char buf[CONSBUFSIZE]; 30 | unsigned int rpos; 31 | unsigned int wpos; 32 | } ; 33 | extern struct consle cons; 34 | 35 | 36 | void delay(void); 37 | void serial_init(void); 38 | void lpt_putc_sub(int c); 39 | void lpt_putc(int c); 40 | void cons_intr(int (*proc)(void)); 41 | int serial_proc_data(void); 42 | void serial_intr(void); 43 | void serial_putc_sub(int c); 44 | void serial_putc(int c); 45 | 46 | #endif -------------------------------------------------------------------------------- /kernel/socket/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #设置项目名 2 | project (socket) 3 | 4 | add_library(${PROJECT_NAME} OBJECT localsocket.c) 5 | target_include_directories(${PROJECT_NAME} 6 | PUBLIC 7 | ${FreeFlyOS_SOURCE_DIR}/kernel/socket 8 | ${FreeFlyOS_SOURCE_DIR}/kernel/file 9 | ${FreeFlyOS_SOURCE_DIR}/kernel/asm 10 | ${FreeFlyOS_SOURCE_DIR}/kernel/sync 11 | ${FreeFlyOS_SOURCE_DIR}/kernel/task 12 | ${FreeFlyOS_SOURCE_DIR}/kernel/stl 13 | ${FreeFlyOS_SOURCE_DIR}/kernel/mem 14 | ) 15 | -------------------------------------------------------------------------------- /kernel/socket/localsocket.h: -------------------------------------------------------------------------------- 1 | #ifndef _LOCALSOCKET_H_ 2 | #define _LOCALSOCKET_H_ 3 | #include "errno.h" 4 | #include "../sync/sync.h" 5 | #define MAX_LOCAL_SOCKET 128 6 | #define MAX_LOCAL_ADDR 4 7 | #define MAX_BUF_SIZE 1024 8 | typedef enum address_family_e { 9 | AF_LOCAL = 1, 10 | AF_INET = 2, 11 | AF_MAX, 12 | }address_family_t; 13 | typedef enum sock_type_e { 14 | SOCK_STREAM = 1, 15 | SOCK_DGRAM, 16 | SOCK_RAW, 17 | }sock_type_t; 18 | typedef enum protocol_e { 19 | PROTO_ICMP = 1, 20 | PROTO_TCP = 6, 21 | PROTO_UDP = 17, 22 | }protocol_t; 23 | typedef enum socket_state_e { 24 | SS_FREE = 0, 25 | SS_UNCONNECTED, 26 | SS_CONNECTING, 27 | SS_CONNECTED, 28 | SS_DISCONNECTING, 29 | }socket_state_t; 30 | typedef enum socket_flag_e { 31 | SF_ACCEPTCON = (1 << 16), /* performed a listen */ 32 | SF_WAITDATA = (1 << 17), /* wait data to read */ 33 | SF_NOSPACE = (1 << 18), /* no space to write */ 34 | }socket_flag_t; 35 | typedef enum socket_call_e { 36 | SOCK_SOCKET = 0, 37 | SOCK_BIND, 38 | SOCK_LISTEN, 39 | SOCK_ACCEPT, 40 | SOCK_CONNECT, 41 | MAX_SYS_SOCKET, 42 | }socket_call_t; 43 | struct socket_local_t{ 44 | unsigned int ref; //引用计数 45 | char addr[MAX_LOCAL_ADDR]; //目前socket地址 46 | socket_flag_t flag; //socket标志符 47 | struct socket_local_t *connecting_list; //连接链表 48 | struct socket_local_t *connected_socket; //已经连接的socket 49 | struct semaphore *wait_connect_sem; //等待连接信号 50 | struct semaphore *wait_accept_sem; //等待接收信号 51 | struct lock *lock; //互斥访问缓冲区 52 | char buf[MAX_BUF_SIZE]; //缓冲区 53 | //unsigned short family; //address family AF_xxx 54 | //struct socket_t socket; 55 | 56 | }; 57 | struct socket_t{ 58 | unsigned int flags; 59 | unsigned int family; 60 | unsigned int type; 61 | unsigned int protocol; 62 | socket_state_t state; 63 | }; 64 | void socket_init(); 65 | int sys_socket(); 66 | int sys_bind(int fd,char myaddr[MAX_LOCAL_ADDR]); 67 | int sys_listen(int fd); 68 | int sys_accept(int fd,char clientaddr[MAX_LOCAL_ADDR]); 69 | int sys_connect(int fd,char serveraddr[MAX_LOCAL_ADDR]); 70 | #endif -------------------------------------------------------------------------------- /kernel/stl/defs.h: -------------------------------------------------------------------------------- 1 | #ifndef _DEFS_H_ 2 | #define _DEFS_H_ 3 | 4 | 5 | /* Return the offset of 'member' relative to the beginning of a struct type */ 6 | #define offsetof(type, member) \ 7 | ((unsigned int)(&((type *)0)->member)) 8 | 9 | /* * 10 | * to_struct - get the struct from a ptr 11 | * @ptr: a struct pointer of member 12 | * @type: the type of the struct this is embedded in 13 | * @member: the name of the member within the struct 14 | * */ 15 | //char * =unsigned int 16 | #define to_struct(ptr, type, member) \ 17 | ((type *)((char *)(ptr) - offsetof(type, member))) 18 | 19 | //将一个字节某位设置为flag 20 | #define set_char_bit(c,offset,flag) c&(flag<> (32 - bits)); 19 | } 20 | 21 | #endif -------------------------------------------------------------------------------- /kernel/stl/readme.md: -------------------------------------------------------------------------------- 1 | ## list.h 2 | 3 | 链表数据结构 4 | 5 | 6 | 7 | 这个目录主要就是一些常见的数据结构,以及转换的小技巧。 8 | 9 | 包含链表、哈希表、elf文件以及已知结构体成员如何获取结构体等。 -------------------------------------------------------------------------------- /kernel/sync/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #设置项目名 2 | project (sync) 3 | 4 | add_library(${PROJECT_NAME} OBJECT sync.c) 5 | target_include_directories(${PROJECT_NAME} 6 | PUBLIC 7 | ${FreeFlyOS_SOURCE_DIR}/kernel/sync 8 | ${FreeFlyOS_SOURCE_DIR}/kernel/debug 9 | ${FreeFlyOS_SOURCE_DIR}/kernel/interrupt 10 | ${FreeFlyOS_SOURCE_DIR}/kernel/task 11 | ${FreeFlyOS_SOURCE_DIR}/kernel/stl 12 | ${FreeFlyOS_SOURCE_DIR}/kernel/vga 13 | ) 14 | -------------------------------------------------------------------------------- /kernel/sync/readme.md: -------------------------------------------------------------------------------- 1 | 该目录主要为同步操作的实现,包含信号量和锁。 2 | 3 | 信号量是这样的,初始化为1,表示最多只有1个进程能够获取,每个进程都可以竞争获取这个信号量,获取后,信号量的值变为0,表示该信号量已被占用,其他需要这个信号量的进程全部进入等待队列。 4 | 5 | 锁实际上也可以看作是信号量,但比它多了一个步骤,就是当锁被一个进程持有时,它申请锁多少次,在释放的时候就要释放多少次。 6 | 7 | -------------------------------------------------------------------------------- /kernel/sync/sync.c: -------------------------------------------------------------------------------- 1 | #include "sync.h" 2 | #include "../debug/debug.h" 3 | #include "../interrupt/trap.h" 4 | #include "../task/task.h" 5 | #include "../vga/vga.h" 6 | extern struct task_struct *current; 7 | /* 初始化信号量 */ 8 | void sema_init(struct semaphore* psema, unsigned char value) { 9 | psema->value = value; // 为信号量赋初值 10 | list_init(&psema->waiters); //初始化信号量的等待队列 11 | } 12 | 13 | /* 初始化锁plock */ 14 | void lock_init(struct lock* plock) { 15 | plock->holder = NULL; 16 | plock->holder_repeat_nr = 0; 17 | sema_init(&plock->semaphore, 1); // 信号量初值为1 18 | } 19 | 20 | /* 信号量down操作 */ 21 | void sema_down(struct semaphore* psema) { 22 | /* 关中断来保证原子操作 */ 23 | enum intr_status flag; 24 | list_entry_t *head=&psema->waiters; 25 | list_entry_t *ite=head; 26 | struct task_struct *task; 27 | //printk(" %08d\n",get_now_intr_status()); 28 | local_intr_save(flag); 29 | //printk(" %08d\n",get_now_intr_status()); 30 | { 31 | //printk("check 3"); 32 | // 若value为0,表示已经被别人持有 33 | while(psema->value == 0) { 34 | //printk("check 4"); 35 | /* 当前线程不应该已在信号量的waiters队列中 */ 36 | while((ite=list_next(ite))!=head){ 37 | if(ite==¤t->link){ 38 | PANIC("sema_down: thread blocked has been in waiters_list\n"); 39 | } 40 | } 41 | //printk("check 5"); 42 | //task=list_to_task(list_next(¤t->link),link); 43 | /* 若信号量的值等于0,则当前线程把自己加入该锁的等待队列,然后阻塞自己 */ 44 | list_add_before(&psema->waiters,¤t->link); 45 | //printk("check 6"); 46 | //list_append(&psema->waiters, &running_thread()->general_tag); 47 | //current=task; 48 | thread_block(STOPPED); // 阻塞线程,直到被唤醒 49 | //printk("check 7"); 50 | } 51 | /* 若value为1或被唤醒后,会执行下面的代码,也就是获得了锁。*/ 52 | psema->value--; 53 | //ASSERT(psema->value == 0); 54 | //printk("check 8"); 55 | } 56 | /* 恢复之前的中断状态 */ 57 | local_intr_restore(flag); 58 | } 59 | 60 | /* 信号量的up操作 */ 61 | void sema_up(struct semaphore* psema) { 62 | /* 关中断,保证原子操作 */ 63 | enum intr_status flag; 64 | list_entry_t *head=&psema->waiters; 65 | list_entry_t *ite=head; 66 | //printk("sema_up \n"); 67 | local_intr_save(flag); 68 | { 69 | //ASSERT(psema->value == 0); 70 | //释放所有等待该信号量的进程 71 | if((ite=list_next(ite))!=head){ 72 | list_del(ite); 73 | struct task_struct* task =list_to_task(ite,link); 74 | thread_unblock(task); 75 | } 76 | psema->value++; 77 | //ASSERT(psema->value == 1); 78 | } 79 | /* 恢复之前的中断状态 */ 80 | local_intr_restore(flag); 81 | } 82 | 83 | /* 获取锁plock */ 84 | void lock_acquire(struct lock* plock) { 85 | /* 排除曾经自己已经持有锁但还未将其释放的情况。*/ 86 | //printk("check 1"); 87 | if (plock->holder != current) { 88 | //printk("check 2"); 89 | sema_down(&plock->semaphore); // 对信号量P操作,原子操作 90 | plock->holder = current; 91 | //ASSERT(plock->holder_repeat_nr == 0); 92 | plock->holder_repeat_nr = 1; 93 | } else { 94 | plock->holder_repeat_nr++; 95 | } 96 | } 97 | 98 | /* 释放锁plock */ 99 | void lock_release(struct lock* plock) { 100 | //ASSERT(plock->holder == current); 101 | if (plock->holder_repeat_nr > 1) { 102 | plock->holder_repeat_nr--; 103 | return; 104 | } 105 | //ASSERT(plock->holder_repeat_nr == 1); 106 | 107 | plock->holder = NULL; // 把锁的持有者置空放在V操作之前 108 | plock->holder_repeat_nr = 0; 109 | sema_up(&plock->semaphore); // 信号量的V操作,也是原子操作 110 | } 111 | -------------------------------------------------------------------------------- /kernel/sync/sync.h: -------------------------------------------------------------------------------- 1 | #ifndef _SYNC_H_ 2 | #define _SYNC_H_ 3 | #include "../stl/list.h" 4 | #include "../task/task.h" 5 | /* 信号量结构 */ 6 | struct semaphore { 7 | unsigned char value; 8 | list_entry_t waiters; 9 | }; 10 | 11 | /* 锁结构 */ 12 | struct lock { 13 | struct task_struct* holder; // 锁的持有者 14 | struct semaphore semaphore; // 用二元信号量实现锁 15 | unsigned int holder_repeat_nr; // 锁的持有者重复申请锁的次数 16 | }; 17 | 18 | void sema_init(struct semaphore* psema, unsigned char value); 19 | void sema_down(struct semaphore* psema); 20 | void sema_up(struct semaphore* psema); 21 | void lock_init(struct lock* plock); 22 | void lock_acquire(struct lock* plock); 23 | void lock_release(struct lock* plock); 24 | 25 | #endif -------------------------------------------------------------------------------- /kernel/task/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #设置项目名 2 | project (task) 3 | 4 | add_library(${PROJECT_NAME} OBJECT task.c thread_entry.S switch.S exec.c) 5 | target_include_directories(${PROJECT_NAME} 6 | PUBLIC 7 | ${FreeFlyOS_SOURCE_DIR}/kernel/dt 8 | ${FreeFlyOS_SOURCE_DIR}/kernel/mem 9 | ${FreeFlyOS_SOURCE_DIR}/kernel/asm 10 | ${FreeFlyOS_SOURCE_DIR}/kernel/interrupt 11 | ${FreeFlyOS_SOURCE_DIR}/kernel/vga 12 | ${FreeFlyOS_SOURCE_DIR}/kernel/task 13 | ${FreeFlyOS_SOURCE_DIR}/kernel/stl 14 | ${FreeFlyOS_SOURCE_DIR}/kernel/debug 15 | ${FreeFlyOS_SOURCE_DIR}/kernel/sync 16 | ${FreeFlyOS_SOURCE_DIR}/kernel/file 17 | ) 18 | -------------------------------------------------------------------------------- /kernel/task/exec.h: -------------------------------------------------------------------------------- 1 | #ifndef _EXEC_H_ 2 | #define _EXEC_H_ 3 | 4 | int sys_execv(const char* path, const char* argv[]); 5 | #endif -------------------------------------------------------------------------------- /kernel/task/readme.assets/image-20210103125344968.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/kernel/task/readme.assets/image-20210103125344968.png -------------------------------------------------------------------------------- /kernel/task/readme.assets/image-20210103132009043.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/kernel/task/readme.assets/image-20210103132009043.png -------------------------------------------------------------------------------- /kernel/task/readme.assets/image-20210103134220781.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/kernel/task/readme.assets/image-20210103134220781.png -------------------------------------------------------------------------------- /kernel/task/readme.assets/image-20210103134240827.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/kernel/task/readme.assets/image-20210103134240827.png -------------------------------------------------------------------------------- /kernel/task/readme.md: -------------------------------------------------------------------------------- 1 | 关于进程这一块,还是比较复杂的。 2 | 3 | 首先看下FreeFlyOS的进程描述符,如下图所示。 4 | 5 | ![image-20210103125344968](readme.assets/image-20210103125344968.png) 6 | 7 | 1、首先我们会创建一个内核进程,这些信息均已写好,该进程主要任务是怠速,也就是当其他进程无法运行时,该任务就会占用CPU。 8 | 9 | 2、接着手动创建一个用户进程,主要步骤如下,先构造好用户进程的信息,主要是用户进程的内核栈和用户本身使用的栈,一般在创建任务时,会分配2页给进程使用,前一页页尾作为用户自己使用的栈,后一页页尾作为用户内核栈。所以我们只需要在用户内核栈中构造好用户进程信息(USER_CS、USER_DS等),然后切换到用户内核栈,调用__trapret函数,模拟中断返回的后续操作,则该函数会将用户进程信息弹出,故当前状态变为USER_CS,即用户权限下的环境。 10 | 11 | 3、用户进程会直接调用user目录下的shell,从而实现用户和系统的交互操作。 12 | 13 | 4、一般情况下,时钟中断会进行进程切换,但由于增加了shell,所以当一个进程等待时,也会进行进程切换。进程切换时需要注意的是,更换内核栈和页表,内核栈是用户在进行系统调用时,内核权限下访问资源的栈,然后进行上下文切换,一般的上下文由以下寄存器组成。如果是线程切换,由于共用一套内核栈和页表,所以只需要进行上下文切换即可。 14 | 15 | ![image-20210103132009043](readme.assets/image-20210103132009043.png) 16 | 17 | 5、简单说下FreeFlyOS中fork的原理,假定有一个用户进程调用了fork代码,首先我们会创建一个子进程信息,关键在于构造子进程的用户栈信息和内核栈信息,首先子进程的用户栈需要拷贝父进程的用户栈,保存之前父进程的函数调用关系,不然等待子进程执行时,函数就会跑飞,但是需要改下栈中和进程地址有关的信息,也就是要构造两套地址不同、功能相同的栈,不然还是用了同样的栈。接着中断栈直接拷贝父进程的中断栈帧,但是需要改下esp的地址,让它指向用户进程栈,同时上下文中设置esp为当前中断栈地址,eip为forkre函数(调用__trapret)。当子进程数据构造完毕时,当时钟中断开始进程调度时,子进程会按照它的上下文信息执行,记住此时栈指向了中断栈帧的启示地址,首先调用forkret,然后forkret调用forkrets,接着把esp设置为中断栈帧的esp(用户栈),要记住内核权限转化为用户权限是软件模拟的过程,没有硬件自动切换栈的操作,这样子进程就会变成和父进程一样的用户进程,并且获取了之前的函数调用信息,开始下一步的操作。 18 | 19 | ![image-20210103134220781](readme.assets/image-20210103134220781.png) 20 | 21 | ![image-20210103134240827](readme.assets/image-20210103134240827.png) 22 | 23 | 大概就讲这么多了,写文档的过程太枯燥了,去打游戏了,88!若有疑问可以联系295957410@qq.com -------------------------------------------------------------------------------- /kernel/task/switch.S: -------------------------------------------------------------------------------- 1 | .text 2 | .globl switch_to 3 | switch_to: # switch_to(from, to) 4 | 5 | # 参数是结构体指针,所以需要进行两次内存寻址 6 | # save from's registers 7 | movl 4(%esp), %eax # eax points to from 8 | popl 0(%eax) # save eip !popl 9 | movl %esp, 4(%eax) 10 | movl %ebx, 8(%eax) 11 | movl %ecx, 12(%eax) 12 | movl %edx, 16(%eax) 13 | movl %esi, 20(%eax) 14 | movl %edi, 24(%eax) 15 | movl %ebp, 28(%eax) 16 | 17 | # eax=0 18 | # restore to's registers 19 | movl 4(%esp), %eax # not 8(%esp): popped return address already 20 | # eax now points to to 21 | movl 28(%eax), %ebp 22 | movl 24(%eax), %edi 23 | movl 20(%eax), %esi 24 | movl 16(%eax), %edx 25 | movl 12(%eax), %ecx 26 | movl 8(%eax), %ebx 27 | movl 4(%eax), %esp 28 | 29 | # 将寄存器恢复为下一个进程的进程上下文,下一步执行to->context.eip 30 | pushl 0(%eax) # push eip 31 | 32 | ret 33 | 34 | -------------------------------------------------------------------------------- /kernel/task/thread_entry.S: -------------------------------------------------------------------------------- 1 | .code32 2 | 3 | .global kernel_thread_entry 4 | .extern do_exit 5 | 6 | kernel_thread_entry: # void kernel_thread(void) 7 | sti #open interrrupt 8 | pushl %edx # push arg 9 | call *%ebx # call fn 10 | ret 11 | #pushl %eax # save the return value of fn(arg) 12 | #call do_exit # call do_exit to terminate current thread 13 | -------------------------------------------------------------------------------- /kernel/task/寄存器.md: -------------------------------------------------------------------------------- 1 | ## 寄存器 2 | 3 | #### 通用寄存器 4 | 5 | ![image-20201028145830878](/Users/caoy/Library/Application Support/typora-user-images/image-20201028145830878.png) 6 | 7 | #### 标志寄存器 8 | 9 | ![image-20201028145958344](/Users/caoy/Library/Application Support/typora-user-images/image-20201028145958344.png) 10 | 11 | 12 | 13 | #### 指令寄存器 14 | 15 | ![image-20201028150018153](/Users/caoy/Library/Application Support/typora-user-images/image-20201028150018153.png) 16 | 17 | #### 段寄存器 18 | 19 | ![image-20201028150041729](/Users/caoy/Library/Application Support/typora-user-images/image-20201028150041729.png) 20 | 21 | ![image-20201028150107710](/Users/caoy/Library/Application Support/typora-user-images/image-20201028150107710.png) 22 | 23 | ![image-20201028150141552](/Users/caoy/Library/Application Support/typora-user-images/image-20201028150141552.png) 24 | 25 | ![image-20201028150206911](/Users/caoy/Library/Application Support/typora-user-images/image-20201028150206911.png) 26 | 27 | #### 控制寄存器 28 | 29 | ![image-20201028150241131](/Users/caoy/Library/Application Support/typora-user-images/image-20201028150241131.png) 30 | 31 | ![image-20201028150313516](/Users/caoy/Library/Application Support/typora-user-images/image-20201028150313516.png) 32 | 33 | #### 调试寄存器 34 | 35 | ![image-20201028150411258](/Users/caoy/Library/Application Support/typora-user-images/image-20201028150411258.png) 36 | 37 | ![image-20201028150430038](/Users/caoy/Library/Application Support/typora-user-images/image-20201028150430038.png) 38 | 39 | ![image-20201028150448357](/Users/caoy/Library/Application Support/typora-user-images/image-20201028150448357.png) 40 | 41 | ![image-20201028150458191](/Users/caoy/Library/Application Support/typora-user-images/image-20201028150458191.png) 42 | 43 | #### 描述符寄存器 44 | 45 | ![image-20201028150530099](/Users/caoy/Library/Application Support/typora-user-images/image-20201028150530099.png) 46 | 47 | ![image-20201028150541422](/Users/caoy/Library/Application Support/typora-user-images/image-20201028150541422.png) 48 | 49 | ![image-20201028150553357](/Users/caoy/Library/Application Support/typora-user-images/image-20201028150553357.png) 50 | 51 | ![image-20201028150610774](/Users/caoy/Library/Application Support/typora-user-images/image-20201028150610774.png) 52 | 53 | ![image-20201028150622797](/Users/caoy/Library/Application Support/typora-user-images/image-20201028150622797.png) 54 | 55 | #### 任务寄存器 56 | 57 | ![image-20201028150635512](/Users/caoy/Library/Application Support/typora-user-images/image-20201028150635512.png) 58 | 59 | ![image-20201028150719522](/Users/caoy/Library/Application Support/typora-user-images/image-20201028150719522.png) 60 | 61 | ![image-20201028150734256](/Users/caoy/Library/Application Support/typora-user-images/image-20201028150734256.png) 62 | 63 | #### 模型特定寄存器 64 | 65 | ![image-20201028150749433](/Users/caoy/Library/Application Support/typora-user-images/image-20201028150749433.png) 66 | 67 | #### 总结 68 | 69 | ![image-20201028150818675](/Users/caoy/Library/Application Support/typora-user-images/image-20201028150818675.png) -------------------------------------------------------------------------------- /kernel/timer/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #设置项目名 2 | project (timer) 3 | 4 | add_library(${PROJECT_NAME} OBJECT timer.c) 5 | target_include_directories(${PROJECT_NAME} 6 | PUBLIC 7 | ${FreeFlyOS_SOURCE_DIR}/kernel/asm 8 | ${FreeFlyOS_SOURCE_DIR}/kernel/interrupt 9 | ${FreeFlyOS_SOURCE_DIR}/kernel/pic 10 | ${FreeFlyOS_SOURCE_DIR}/kernel/timer 11 | ${FreeFlyOS_SOURCE_DIR}/kernel/apic 12 | ) 13 | -------------------------------------------------------------------------------- /kernel/timer/readme.assets/image-20210102223147461.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/kernel/timer/readme.assets/image-20210102223147461.png -------------------------------------------------------------------------------- /kernel/timer/readme.assets/image-20210102223250050.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/kernel/timer/readme.assets/image-20210102223250050.png -------------------------------------------------------------------------------- /kernel/timer/readme.assets/image-20210102223302336.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/kernel/timer/readme.assets/image-20210102223302336.png -------------------------------------------------------------------------------- /kernel/timer/readme.assets/image-20210102223314668.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/kernel/timer/readme.assets/image-20210102223314668.png -------------------------------------------------------------------------------- /kernel/timer/readme.assets/image-20210102223326120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/kernel/timer/readme.assets/image-20210102223326120.png -------------------------------------------------------------------------------- /kernel/timer/readme.assets/image-20210102223339670.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/kernel/timer/readme.assets/image-20210102223339670.png -------------------------------------------------------------------------------- /kernel/timer/readme.assets/image-20210102223356663.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/kernel/timer/readme.assets/image-20210102223356663.png -------------------------------------------------------------------------------- /kernel/timer/readme.md: -------------------------------------------------------------------------------- 1 | ## timer.c 2 | 3 | 定时器初始化 4 | 5 | 定时器8253驱动原理如下,另外补充了FreeFlyOS的时钟每过1S中断一次,同时进行进程调度。 6 | 7 | ![image-20210102223147461](readme.assets/image-20210102223147461.png) 8 | 9 | ![image-20210102223250050](readme.assets/image-20210102223250050.png) 10 | 11 | ![image-20210102223302336](readme.assets/image-20210102223302336.png) 12 | 13 | ![image-20210102223314668](readme.assets/image-20210102223314668.png) 14 | 15 | ![image-20210102223326120](readme.assets/image-20210102223326120.png) 16 | 17 | ![image-20210102223339670](readme.assets/image-20210102223339670.png) 18 | 19 | ![image-20210102223356663](readme.assets/image-20210102223356663.png) -------------------------------------------------------------------------------- /kernel/timer/timer.c: -------------------------------------------------------------------------------- 1 | #include "timer.h" 2 | #include "../asm/asm.h" 3 | #include "../pic/pic.h" 4 | #include "../interrupt/trap.h" 5 | 6 | unsigned int volatile jiffies; //记录自系统启动以来产生的节拍总数 7 | 8 | unsigned int volatile second; //根据节拍总数换算成秒数 9 | 10 | void timer_init(unsigned int frequency){ 11 | //Intel 8253/8254 PIT芯片 I/O端口地址范围是40h-43h,输入频率为1193180,frequency为每秒中断次数 12 | unsigned int divisor=1193180/frequency; 13 | //将8253/8254芯片设置为模式3 14 | outb(0x43,0x36); 15 | unsigned char low=divisor&0xff; 16 | unsigned char high=(divisor>>8)&0xff; 17 | outb(0x40,low); 18 | outb(0x40,high); 19 | jiffies=0; //初始化节拍总数,防止更换页表时初始化值更改 20 | second=0; //初始化秒数 21 | pic_enable(IRQ_TIMER); 22 | //enable_irq(IRQ_TIMER,0); 23 | } -------------------------------------------------------------------------------- /kernel/timer/timer.h: -------------------------------------------------------------------------------- 1 | #ifndef _TIMER_H_ 2 | #define _TIMER_H_ 3 | 4 | void timer_init(unsigned int frequency); 5 | 6 | #endif -------------------------------------------------------------------------------- /kernel/user/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #设置项目名 2 | project (user) 3 | 4 | add_library(${PROJECT_NAME} OBJECT user_main.c user_syscall.c stdio.c shell.c string.c buildin_cmd.c) 5 | target_include_directories(${PROJECT_NAME} 6 | PUBLIC 7 | ${FreeFlyOS_SOURCE_DIR}/kernel/user 8 | ${FreeFlyOS_SOURCE_DIR}/kernel/file 9 | ) 10 | -------------------------------------------------------------------------------- /kernel/user/buildin_cmd.h: -------------------------------------------------------------------------------- 1 | #ifndef _BUILDIN_CMD_H_ 2 | #define _BUILDIN_CMD_H_ 3 | #include "../file/fs.h" 4 | #define MAX_FILE_NAME_LEN 16 5 | #define NULL ((void *)0) 6 | #define MAX_PATH_LEN 512 // 路径最大长度 7 | 8 | /* 9 | enum user_file_types { 10 | FT_UNKNOWN, // 不支持的文件类型 11 | FT_REGULAR, // 普通文件 12 | FT_DIRECTORY // 目录 13 | }; 14 | 15 | struct stat { 16 | unsigned int st_ino; // inode编号 17 | unsigned int st_size; // 尺寸 18 | enum file_types st_filetype; // 文件类型 19 | };*/ 20 | void make_clear_abs_path(char* path, char* final_path); 21 | void buildin_pwd(int argc, char** argv __attribute__ ((unused))) ; 22 | char* buildin_cd(int argc, char** argv); 23 | void buildin_ls(int argc, char** argv); 24 | int buildin_mkdir(int argc, char** argv); 25 | int buildin_rmdir(int argc, char** argv); 26 | int buildin_rm(int argc, char** argv); 27 | void buildin_help(int argc, char** argv); 28 | #endif -------------------------------------------------------------------------------- /kernel/user/readme.assets/image-20210103111642543.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/kernel/user/readme.assets/image-20210103111642543.png -------------------------------------------------------------------------------- /kernel/user/readme.md: -------------------------------------------------------------------------------- 1 | 关于用户目录,首先要说的是这部分代码和内核代码是分开存储的,从elf文件头信息中可以看到区别。 2 | 3 | ![image-20210103111642543](readme.assets/image-20210103111642543.png) 4 | 5 | 这部分用户代码和内核代码一样都是需要常驻内存的,其主要区别是地址空间不同还有内存页权限不同,那么说一下用户代码主要做了些啥吧。 6 | 7 | 1、提供了系统调用的接口。 8 | 9 | 2、实现了用户命令,包括内部命令和外部命令,简单讲下他们的区别吧,外部命令是说该命令是存储在文件系统的外部程序,执行该命令实际上是从文件系统上加载该程序到内存后运行的过程,也就是说外部命令会以进程的方式执行,比如ls命令,它通常的存储路径是/bin/ls。内部命令也叫内建命令,是系统本身提供的功能,它们并不以单独的程序文件存在,只是提供一些单独的功能函数。在FreeFlyOS中,为了简单,将ls、cd等命令均弄成了内部命令,外部命令主要有cat、pipe、prog等,以文件形式存在于根目录下。 10 | 11 | 3、提供了用户系统交互的shell。 12 | 13 | 大概就这么多吧,这些命令的实现还是比较简单的,搞清楚每个系统调用干了啥基本就OK了。 14 | 15 | -------------------------------------------------------------------------------- /kernel/user/shell.h: -------------------------------------------------------------------------------- 1 | #ifndef _SHELL_H_ 2 | #define _SHELL_H_ 3 | //__attribute__( (section(".user.text") ) ) 4 | void print_prompt(void); 5 | //__attribute__( (section(".user.text") ) ) 6 | static void user_readline(char* buf, int count); 7 | //__attribute__( (section(".user.text") ) ) 8 | void my_shell(void); 9 | #endif -------------------------------------------------------------------------------- /kernel/user/stdio.h: -------------------------------------------------------------------------------- 1 | #ifndef _STDIO_H_ 2 | #define _STDIO_H_ 3 | //the max of unsigned char is 255 in dec(3 character) 4 | #define uchar_max 3 5 | //the max of unsigned short is 65535 in dec(5 character) 6 | #define ushort_max 5 7 | //the max of unsigned int is 4294967295 in dec(10 character) 8 | #define int_max 10 9 | //the max of unsigned long long is 18446744073709551615 in dec(20 character) 10 | #define ulonglong_max 20 11 | 12 | 13 | #define dec 10 //Decimal 14 | #define hex 16 //Hexadecimal 15 | 16 | #define display_bits 1 //display x bits number ex. 100->00100 17 | #define display_num 0 //display only number bits ex. 100->100 18 | //__attribute__( (section(".user.text") ) ) 19 | void printf(char *fmt,...); 20 | #endif -------------------------------------------------------------------------------- /kernel/user/string.h: -------------------------------------------------------------------------------- 1 | #ifndef _STRING_H_ 2 | #define _STRING_H_ 3 | //__attribute__( (section(".user.text") ) ) 4 | static inline void *__memset(void *s, char c, unsigned int n); 5 | //__attribute__( (section(".user.text") ) ) 6 | void *user_memset(void *s, char c, unsigned int n); 7 | char *user_strcat(char* dst_, const char* src_); 8 | int user_strcmp(const char *s1, const char *s2); 9 | char* user_strrchr(const char* str, const unsigned char ch); 10 | unsigned int user_strlen(const char *s); 11 | void *user_memcpy(void *dst, const void *src, unsigned int n); 12 | char* user_strcpy(char* dst_, const char* src_); 13 | #endif 14 | -------------------------------------------------------------------------------- /kernel/user/user_main.c: -------------------------------------------------------------------------------- 1 | #include "user_main.h" 2 | #include "stdio.h" 3 | #include "shell.h" 4 | // 定义一个延时xus毫秒的延时函数 5 | static void delay(unsigned int xus) // xus代表需要延时的微秒数 6 | { 7 | unsigned int x,y; 8 | for(x=xus;x>0;x--) 9 | for(y=110;y>0;y--); 10 | } 11 | void test_fork(){ 12 | unsigned int ret_pid=fork(); 13 | printf("my pid is %d",ret_pid); 14 | while(1); 15 | } 16 | void user_main(){ 17 | char str[50]="Hello,I'm a User Function!Nice to meet you!\n"; 18 | //printf(str); 19 | //test_fork(); 20 | my_shell(); 21 | /*while(1) 22 | { 23 | printf("user\n"); 24 | delay(1000000); 25 | }*/ 26 | 27 | } -------------------------------------------------------------------------------- /kernel/user/user_main.h: -------------------------------------------------------------------------------- 1 | #ifndef _USER_MAIN_H_ 2 | #define _USER_MAIN_H_ 3 | 4 | //__attribute__( (section(".user.text") ) ) 5 | void user_main(); 6 | 7 | #endif -------------------------------------------------------------------------------- /kernel/user/user_syscall.h: -------------------------------------------------------------------------------- 1 | #ifndef _USER_SYSCALL_H_ 2 | #define _USER_SYSCALL_H_ 3 | #include "../file/dir.h" 4 | #include "../file/fs.h" 5 | /* syscall number */ 6 | #define SYS_exit 1 7 | #define SYS_fork 2 8 | #define SYS_wait 3 9 | #define SYS_exec 4 10 | #define SYS_clone 5 11 | #define SYS_yield 10 12 | #define SYS_sleep 11 13 | #define SYS_kill 12 14 | #define SYS_gettime 17 15 | #define SYS_getpid 18 16 | #define SYS_brk 19 17 | #define SYS_mmap 20 18 | #define SYS_munmap 21 19 | #define SYS_shmem 22 20 | 21 | #define SYS_fdread 24 22 | 23 | #define SYS_pgdir 31 24 | 25 | #define SYS_print_char 36 26 | #define SYS_print_string 37 27 | #define SYS_print_num 38 28 | #define SYS_backtrace 39 29 | #define SYS_open 40 30 | #define SYS_close 41 31 | #define SYS_write 42 32 | #define SYS_lseek 43 33 | #define SYS_unlink 44 34 | #define SYS_mkdir 45 35 | #define SYS_rmdir 46 36 | #define SYS_rewinddir 47 37 | #define SYS_getcwd 48 38 | #define SYS_chdir 49 39 | #define SYS_stat 50 40 | #define SYS_opendir 51 41 | #define SYS_closedir 52 42 | #define SYS_readdir 53 43 | #define SYS_print_task 54 44 | #define SYS_malloc 55 45 | #define SYS_free 56 46 | #define SYS_mmap 57 47 | #define SYS_pipe 58 48 | #define SYS_socket 59 49 | #define SYS_bind 60 50 | #define SYS_listen 61 51 | #define SYS_accept 62 52 | #define SYS_connect 63 53 | //__attribute__( (section(".user.text") ) ) 54 | enum std_fd{ 55 | stdin_no, //0 标准输入 56 | stdout_no, //1 标准输出 57 | stderr_no //2 标准错误 58 | }; 59 | /* 60 | *__attribute__( (section(".user.text") ) )将其设置为特定的.user.text节 61 | *方便在链接脚本中区分kernel部分和user部分 62 | */ 63 | //__attribute__( (section(".user.text") ) ) 64 | static inline int user_syscall(int num, ...); 65 | //__attribute__( (section(".user.text") ) ) 66 | int user_sys_getpid(void); 67 | //__attribute__( (section(".user.text") ) ) 68 | void user_print_char(char c); 69 | //__attribute__( (section(".user.text") ) ) 70 | void user_print_string(char *str); 71 | //__attribute__( (section(".user.text") ) ) 72 | void user_print_num(int num,unsigned char base,char len,int flag); 73 | //__attribute__( (section(".user.text") ) ) 74 | void user_backtrace(); 75 | int read(int fd, void* buf, unsigned int count); 76 | int open(char* pathname, unsigned char flag); 77 | int close(int fd); 78 | unsigned int write(int fd, const void* buf, int count); 79 | int lseek(int fd, int offset, unsigned char whence) ; 80 | int unlink(const char* pathname); 81 | int mkdir(const char* pathname); 82 | int rmdir(const char* pathname); 83 | void rewinddir(struct dir* dir); 84 | char* getcwd(char* buf, unsigned int size); 85 | int chdir(const char* path); 86 | int stat(const char* path, struct stat* buf) ; 87 | struct dir* opendir(const char* name); 88 | int closedir(struct dir* dir); 89 | struct dir_entry* readdir(struct dir* dir); 90 | void ps(); 91 | unsigned int malloc(unsigned int bytes); 92 | void free(unsigned int addr,unsigned int size); 93 | int fork(); 94 | void mmap(unsigned int va_start,unsigned int va_end,unsigned pa_start); 95 | void exec(char *path,char **argv); 96 | int wait(int* status); 97 | void exit(int status); 98 | void pipe(int fd[2]); 99 | int socket(); 100 | int bind(int fd,char *addr); 101 | int listen(int fd); 102 | int accept(int fd,char *addr); 103 | int connect(int fd,char *addr); 104 | #endif -------------------------------------------------------------------------------- /kernel/user/va_list.h: -------------------------------------------------------------------------------- 1 | #ifndef _VA_LIST_H_ 2 | #define _VA_LIST_H_ 3 | /*可变参数宏定义*/ 4 | typedef char * user_va_list; 5 | //为了满足需要内存对齐的系统 6 | #define _INTSIZEOF(n) ((sizeof(n)+sizeof(int)-1)&~(sizeof(int) - 1) ) 7 | 8 | /* 9 | * va_start(ap,v):ap指向第一个变参的位置,即将第一个变参的地址赋予ap 10 | * va_arg(ap,t):获取变参的具体内容,t为变参的类型,如有多个参数, 11 | * 则通过移动ap的指针来获得变参的地址,从而获得内容 12 | * va_end(ap):清空va_list,即结束变参的获取,防止野指针 13 | */ 14 | #define user_va_start(ap,v) ( ap = (user_va_list)&v + _INTSIZEOF(v) ) 15 | #define user_va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) ) 16 | #define user_va_end(ap) ( ap = (user_va_list)0 ) 17 | #endif -------------------------------------------------------------------------------- /kernel/vga/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #设置项目名 2 | project (vga) 3 | 4 | add_library(${PROJECT_NAME} OBJECT vga.c) 5 | target_include_directories(${PROJECT_NAME} 6 | PUBLIC 7 | ${FreeFlyOS_SOURCE_DIR}/kernel/asm 8 | ${FreeFlyOS_SOURCE_DIR}/kernel/keyboard 9 | ${FreeFlyOS_SOURCE_DIR}/kernel/serial 10 | ${FreeFlyOS_SOURCE_DIR}/kernel/vga 11 | ) 12 | 13 | -------------------------------------------------------------------------------- /kernel/vga/readme.md: -------------------------------------------------------------------------------- 1 | ## vga.c 2 | 3 | vga即显示屏幕初始化,包含清空屏幕,打印字符,从键盘和串口接收字符等。 4 | 5 | 关于VGA显示的问题,详见我的博客https://blog.csdn.net/cy295957410/article/details/108436730 -------------------------------------------------------------------------------- /kernel/vga/vga.h: -------------------------------------------------------------------------------- 1 | #ifndef _VGA_H_ 2 | #define _VGA_H_ 3 | 4 | //the max of unsigned char is 255 in dec(3 character) 5 | #define uchar_max 3 6 | //the max of unsigned short is 65535 in dec(5 character) 7 | #define ushort_max 5 8 | //the max of unsigned int is 4294967295 in dec(10 character) 9 | #define int_max 10 10 | //the max of unsigned long long is 18446744073709551615 in dec(20 character) 11 | #define ulonglong_max 20 12 | 13 | 14 | #define dec 10 //Decimal 15 | #define hex 16 //Hexadecimal 16 | 17 | #define display_bits 1 //display x bits number ex. 100->00100 18 | #define display_num 0 //display only number bits ex. 100->100 19 | 20 | #define VGA_register 0x3d4 21 | #define VGA_data 0x3d5 22 | #define register_cursor_x 14 23 | #define register_cursor_y 15 24 | 25 | /*可变参数宏定义*/ 26 | typedef char * va_list; 27 | //为了满足需要内存对齐的系统 28 | #define _INTSIZEOF(n) ((sizeof(n)+sizeof(int)-1)&~(sizeof(int) - 1) ) 29 | 30 | /* 31 | * va_start(ap,v):ap指向第一个变参的位置,即将第一个变参的地址赋予ap 32 | * va_arg(ap,t):获取变参的具体内容,t为变参的类型,如有多个参数, 33 | * 则通过移动ap的指针来获得变参的地址,从而获得内容 34 | * va_end(ap):清空va_list,即结束变参的获取,防止野指针 35 | */ 36 | #define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v) ) 37 | #define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) ) 38 | #define va_end(ap) ( ap = (va_list)0 ) 39 | 40 | /* 系统默认的背景色和字体颜色,可根据喜好更改 */ 41 | #define default_background black 42 | #define default_foreground green 43 | 44 | typedef enum color { 45 | black = 0, 46 | blue = 1, 47 | green = 2, 48 | cyan = 3, 49 | red = 4, 50 | magenta = 5, 51 | brown = 6, 52 | light_grey = 7, 53 | dark_grey = 8, 54 | light_blue = 9, 55 | light_green = 10, 56 | light_cyan = 11, 57 | light_red = 12, 58 | light_magenta = 13, 59 | light_brown = 14, // yellow 60 | white = 15 61 | }color_type; 62 | 63 | void print_cursor(unsigned char x,unsigned char y); 64 | void print_char(char c,color_type background,color_type foreground); 65 | void clear(); 66 | void print_string(char *str,color_type background,color_type foreground); 67 | void print_num(unsigned long long num,color_type background,color_type foreground,unsigned char base,char len,int flag); 68 | void printk(char *fmt,...); 69 | void cons_putc(int c); 70 | int cons_getc(void); 71 | void backtrace(); 72 | #endif -------------------------------------------------------------------------------- /readme.assets/image-20201228212745678.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/readme.assets/image-20201228212745678.png -------------------------------------------------------------------------------- /readme.assets/image-20201228213055895.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/readme.assets/image-20201228213055895.png -------------------------------------------------------------------------------- /readme.assets/image-20201228213344675.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/readme.assets/image-20201228213344675.png -------------------------------------------------------------------------------- /readme.assets/image-20201228222144608.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/readme.assets/image-20201228222144608.png -------------------------------------------------------------------------------- /readme.assets/image-20201228223246325.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/readme.assets/image-20201228223246325.png -------------------------------------------------------------------------------- /readme.assets/image-20201228223255211.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/readme.assets/image-20201228223255211.png -------------------------------------------------------------------------------- /readme.assets/image-20201228223304979.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dashanji/FreeFlyOS/cbd9b83cedb3d930a6bc38d77e24ae7cf9df3da5/readme.assets/image-20201228223304979.png -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | ## FreeFlyOS 2 | 3 | A simple OS for learing! Here we go! Ale, ale, ale!Go, go, go! Ale, ale, ale!Let's do it together! 4 | 5 | You can do memory management、multi-progress、file system and so on. 6 | 7 | ## Environment 8 | 9 | Why choose x86_64-elf-toolchain? 10 | 11 | Because FreeFlyOS compiled and linked by this toolchain has nothing to do with the system. In fact, you can also use gcc under linux to compile the operating system, but there will be more system-related program sections, resulting in MBR exceeding 512B, so use x86_64-elf-toolchain to Minimize the OS. 12 | 13 | I only test in my Mac OS(x86-64) and Ubuntu(x86-64).It takes a long time to set up the environment, please be patient. 14 | 15 | #### Mac OS 16 | 17 | you need to do : 18 | 19 | 1、install curl and git 20 | 21 | 2、install brew,you can see how to install it in https://brew.sh,the command is: 22 | 23 | ```bash 24 | /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)" 25 | ``` 26 | 27 | 3、install x86_64-elf-binutils 28 | 29 | ``` 30 | brew install x86_64-elf-binutils 31 | ``` 32 | 33 | 4、install x86_64-elf-gcc 34 | 35 | ``` 36 | brew install x86_64-elf-gcc 37 | ``` 38 | 39 | 5、install cmake 40 | 41 | ``` 42 | brew install cmake 43 | ``` 44 | 45 | 6、install qemu 46 | 47 | ``` 48 | brew install qemu 49 | ``` 50 | 51 | #### Linux(Ubuntu-20.04.1-amd64) 52 | 53 | you need to do: 54 | 55 | 1、install curl and git 56 | 57 | ``` 58 | sudo apt install curl git 59 | ``` 60 | 61 | 2、install brew,you can see how to install it in https://brew.sh,the command is: 62 | 63 | ```bash 64 | /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)" 65 | ``` 66 | 67 | 3、install x86_64-elf-binutils 68 | 69 | ``` 70 | brew install x86_64-elf-binutils 71 | ``` 72 | 73 | 4、install x86_64-elf-gcc 74 | 75 | ``` 76 | brew install x86_64-elf-gcc 77 | ``` 78 | 79 | 5、install cmake 80 | 81 | ``` 82 | brew install cmake 83 | sudo ln -s (cmake安装目录)/bin/cmake /usr/bin/cmake //cmake一般没有直接装在/usr/bin下 84 | ``` 85 | 86 | 6、install qemu 87 | 88 | ``` 89 | sudo apt install qemu-sysetm-i386 90 | ``` 91 | 92 | ## Run 93 | 94 | ``` 95 | sh run.sh 96 | ``` 97 | 98 | In Mac OS,the result is: 99 | 100 | ![image-20201228213055895](readme.assets/image-20201228213055895.png) 101 | 102 | ![image-20201228213344675](readme.assets/image-20201228213344675.png) 103 | 104 | ![image-20201228222144608](readme.assets/image-20201228222144608.png) 105 | 106 | In Linux,the result is: 107 | 108 | ![image-20201228223246325](readme.assets/image-20201228223246325.png) 109 | 110 | ![image-20201228223255211](readme.assets/image-20201228223255211.png) 111 | 112 | ![image-20201228223304979](readme.assets/image-20201228223304979.png) 113 | 114 | -------------------------------------------------------------------------------- /run.sh: -------------------------------------------------------------------------------- 1 | #查看当前系统,目前只支持x86架构的类UNIX系统(Linux和MAC OS) 2 | OS=`uname -s` 3 | if [ "${OS}" == "Linux" ]; then 4 | toolchain="./cmake/linux_x86_toolchain.cmake" 5 | else if [ "${OS}" == "Darwin" ]; then 6 | toolchain="./cmake/mac_x86_toolchain.cmake" 7 | fi 8 | fi 9 | 10 | # 重新编译 11 | mkdir -p ./build/ 12 | rm -rf ./build/* 13 | cd ./build 14 | cmake -DCMAKE_TOOLCHAIN_FILE=${toolchain} .. 15 | make 16 | cd ../ -------------------------------------------------------------------------------- /rundocker.sh: -------------------------------------------------------------------------------- 1 | docker run -t -i dashanji/freeflyos:0.1 /bin/sh -c "qemu-system-i386 -curses -m 2048 -net nic,model=rtl8139 -smp 2 -hda FreeFlyOS.img" 2 | 3 | -------------------------------------------------------------------------------- /test_ap/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #设置项目名 2 | project (test_ap CXX ASM) 3 | 4 | add_library(${PROJECT_NAME} OBJECT start_ap.S ) 5 | target_include_directories(${PROJECT_NAME} 6 | PUBLIC 7 | ${FreeFlyOS_SOURCE_DIR}/kernel/ap 8 | ${FreeFlyOS_SOURCE_DIR}/test_ap 9 | ) 10 | set(test_name "start_ap") 11 | add_custom_command(OUTPUT ${test_name} 12 | DEPENDS 13 | ${PROJECT_NAME} 14 | COMMAND 15 | echo "ap start!" 16 | COMMAND 17 | x86_64-elf-ld -T ../../test_ap/ap_ld.ld -m elf_i386 -e apstart 18 | ../../build/test_ap/CMakeFiles/test_ap.dir/start_ap.S.o -o test_cpp 19 | COMMAND 20 | x86_64-elf-objdump -d test_cpp > ../../disassembly/test_cpp_disass.md 21 | COMMAND 22 | dd if=../test_ap/test_ap of=../../FreeFlyOS.img bs=512 count=30 seek=650 conv=notrunc 23 | COMMAND 24 | echo "ap down!" 25 | COMMAND 26 | qemu-system-i386 -m 2048 -smp 2 -hda ../../FreeFlyOS.img 27 | ) 28 | add_custom_target(ap_tar ALL DEPENDS ${test_name}) -------------------------------------------------------------------------------- /test_ap/ap_ld.ld: -------------------------------------------------------------------------------- 1 | /* 2 | ** 链接脚本 3 | */ 4 | OUTPUT_FORMAT(elf32-i386) 5 | OUTPUT_ARCH(i386) 6 | ENTRY(apstart) 7 | /* 8 | * ld有多种方法设置进程入口地址, 按以下顺序: (编号越前, 优先级越高) 9 | * 1, ld命令行的-e选项 10 | * 2, 连接脚本的ENTRY(SYMBOL)命令 11 | * 3, 如果定义了start 符号, 使用start符号值 12 | * 4, 如果存在 .text section , 使用.text section的第一字节的位置值 13 | * 5, 使用值0 14 | * 15 | * 16 | */ 17 | 18 | SECTIONS 19 | { 20 | . = 0x9000; 21 | 22 | .text : { *(.text) } 23 | 24 | .rodata : { *(.rodata) } 25 | .data : { *(.data) } 26 | 27 | .bss : { *(.bss) } 28 | } -------------------------------------------------------------------------------- /test_ap/start_ap.S: -------------------------------------------------------------------------------- 1 | #include "../kernel/ap/ap.h" 2 | .text 3 | .code16 4 | .global apstart 5 | apstart: 6 | cli 7 | 8 | xorw %ax, %ax 9 | movw %ax, %ds 10 | movw %ax, %es 11 | movw %ax, %ss 12 | 13 | lgdt gdt_ptr 14 | movl %cr0, %eax 15 | orl $CR0_PE, %eax 16 | movl %eax, %cr0 17 | 18 | ljmpl $(SEG_KCODE<<3), $(apstart32) 19 | 20 | .code32 21 | apstart32: 22 | movw $(SEG_KDATA<<3), %ax 23 | movw %ax, %ds 24 | movw %ax, %es 25 | movw %ax, %ss 26 | xorw %ax, %ax 27 | movw %ax, %fs 28 | movw %ax, %gs 29 | 30 | # setup page directory 31 | movl (AP_PGDIR), %eax 32 | movl %eax, %cr3 33 | 34 | # turn on paging 35 | movl %cr0, %eax 36 | orl $(CR0_PG), %eax 37 | movl %eax, %cr0 38 | 39 | # set a new stack 40 | movl (AP_KSTACK), %esp 41 | pushl (AP_INDEX) 42 | 43 | # jump to main 44 | movl (AP_MAIN), %eax 45 | call *%eax 46 | 47 | 1: 48 | jmp 1b 49 | 50 | 51 | 52 | .align 2 53 | gdt: 54 | .quad 0x0000000000000000 55 | .quad 0x00cf9a000000ffff 56 | .quad 0x00cf92000000ffff 57 | gdt_ptr: 58 | .word (gdt_ptr - gdt - 1) 59 | .long gdt 60 | 61 | -------------------------------------------------------------------------------- /test_cat/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #设置项目名 2 | project (test_cat C ASM) 3 | 4 | add_library(${PROJECT_NAME} OBJECT test.c start.S) 5 | #add_executable(${PROJECT_NAME} test.c ) 6 | target_include_directories(${PROJECT_NAME} 7 | PUBLIC 8 | ${FreeFlyOS_SOURCE_DIR}/kernel/user/ 9 | ${FreeFlyOS_SOURCE_DIR}/test_cat 10 | ) 11 | set(test_name "cat") 12 | add_custom_command(OUTPUT ${test_name} 13 | DEPENDS 14 | ${PROJECT_NAME} 15 | COMMAND 16 | x86_64-elf-ld -T ../../test_cat/test.ld -m elf_i386 -e _start ../../build/kernel/user/CMakeFiles/user.dir/stdio.c.o 17 | ../../build/kernel/user/CMakeFiles/user.dir/user_syscall.c.o 18 | ../../build/kernel/user/CMakeFiles/user.dir/string.c.o 19 | ../../build/test_cat/CMakeFiles/test_cat.dir/test.c.o 20 | ../../build/test_cat/CMakeFiles/test_cat.dir/start.S.o -o test_cat 21 | COMMAND 22 | x86_64-elf-objdump -d test_cat > ../../disassembly/test_cat_disass.md 23 | COMMAND 24 | dd if=../test_cat/test_cat of=../../FreeFlyOS.img bs=512 count=40 seek=530 conv=notrunc 25 | COMMAND 26 | echo "cat down!" 27 | ) 28 | add_custom_target(cat_tar ALL DEPENDS ${test_name}) -------------------------------------------------------------------------------- /test_cat/readme.md: -------------------------------------------------------------------------------- 1 | cat命令实现,外部命令 -------------------------------------------------------------------------------- /test_cat/start.S: -------------------------------------------------------------------------------- 1 | .text 2 | .code32 3 | .extern main 4 | .extern exit 5 | .global _start 6 | _start: 7 | push %ebx 8 | push %ecx 9 | call main 10 | 11 | push %eax 12 | call exit -------------------------------------------------------------------------------- /test_cat/test.c: -------------------------------------------------------------------------------- 1 | #include "../kernel/user/stdio.h" 2 | #include "../kernel/user/user_syscall.h" 3 | #include "../kernel/user/string.h" 4 | #define NULL ((void *)0) 5 | void main(int argc,char **argv){ 6 | /*printf("hello nice to meet you\n"); 7 | while(1);*/ 8 | if (argc > 2 || argc == 1) { 9 | printf("cat: only support 1 argument.\neg: cat filename\n"); 10 | exit(-2); 11 | } 12 | int buf_size = 1024; 13 | char abs_path[512] = {0}; 14 | void* buf = malloc(buf_size); 15 | if (buf == NULL) { 16 | printf("cat: malloc memory failed\n"); 17 | return -1; 18 | } 19 | if (argv[1][0] != '/') { 20 | getcwd(abs_path, 512); 21 | user_strcat(abs_path, "/"); 22 | user_strcat(abs_path, argv[1]); 23 | } else { 24 | user_strcpy(abs_path, argv[1]); 25 | } 26 | int fd = open(abs_path, O_RDONLY); 27 | if (fd == -1) { 28 | printf("cat: open: open %s failed\n", argv[1]); 29 | return -1; 30 | } 31 | int read_bytes= 0; 32 | while (1) { 33 | read_bytes = read(fd, buf, buf_size); 34 | if (read_bytes == -1) { 35 | break; 36 | } 37 | write(1, buf, read_bytes); 38 | } 39 | free(buf,buf_size); 40 | close(fd); 41 | return 66; 42 | } -------------------------------------------------------------------------------- /test_cat/test.ld: -------------------------------------------------------------------------------- 1 | /* 2 | ** 链接脚本 3 | */ 4 | OUTPUT_FORMAT(elf32-i386) 5 | OUTPUT_ARCH(i386) 6 | ENTRY(_start) 7 | /* 8 | * ld有多种方法设置进程入口地址, 按以下顺序: (编号越前, 优先级越高) 9 | * 1, ld命令行的-e选项 10 | * 2, 连接脚本的ENTRY(SYMBOL)命令 11 | * 3, 如果定义了start 符号, 使用start符号值 12 | * 4, 如果存在 .text section , 使用.text section的第一字节的位置值 13 | * 5, 使用值0 14 | * 15 | * 16 | */ 17 | 18 | SECTIONS 19 | { 20 | /* 将定位器符号置为0x7c00 */ 21 | . = 0x80000000; 22 | 23 | .text : { *(.text) } 24 | 25 | .rodata : { *(.rodata) } 26 | .data : { *(.data) } 27 | 28 | .bss : { *(.bss) } 29 | 30 | 31 | 32 | } -------------------------------------------------------------------------------- /test_cpp/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #设置项目名 2 | project (test_cpp CXX) 3 | 4 | add_library(${PROJECT_NAME} OBJECT test.cpp ) 5 | target_include_directories(${PROJECT_NAME} 6 | PUBLIC 7 | ${FreeFlyOS_SOURCE_DIR}/kernel/user/ 8 | ${FreeFlyOS_SOURCE_DIR}/test_cpp 9 | ) 10 | set(test_name "hellp_cpp") 11 | add_custom_command(OUTPUT ${test_name} 12 | DEPENDS 13 | ${PROJECT_NAME} 14 | COMMAND 15 | echo "cpp start!" 16 | COMMAND 17 | x86_64-elf-ld -T ../../test_cpp/test.ld -m elf_i386 -e main ../../build/kernel/user/CMakeFiles/user.dir/stdio.c.o 18 | ../../build/kernel/user/CMakeFiles/user.dir/user_syscall.c.o 19 | ../../build/kernel/user/CMakeFiles/user.dir/string.c.o 20 | ../../build/test_cpp/CMakeFiles/test_cpp.dir/test.cpp.o -o test_cpp 21 | COMMAND 22 | x86_64-elf-objdump -d test_cpp > ../../disassembly/test_cpp_disass.md 23 | COMMAND 24 | dd if=../test_cpp/test_cpp of=../../FreeFlyOS.img bs=512 count=50 seek=600 conv=notrunc 25 | COMMAND 26 | echo "cpp down!" 27 | ) 28 | add_custom_target(cpp_tar ALL DEPENDS ${test_name}) -------------------------------------------------------------------------------- /test_cpp/test.cpp: -------------------------------------------------------------------------------- 1 | #include "test.hpp" 2 | extern "C"{ 3 | #include "../kernel/user/stdio.h" 4 | #include "../kernel/user/user_syscall.h" 5 | } 6 | int main() 7 | { 8 | 9 | int nArr[5] = {1,2,3,4,5}; 10 | auto s=2; 11 | A aa; 12 | aa.a=10; 13 | aa.setb(20); 14 | printf("a:%d",aa.a); 15 | printf("b:%d",aa.getb()); 16 | for(int &x : nArr) 17 | { 18 | x *=2; //数组中每个元素倍乘 19 | printf("%d ",x); 20 | } 21 | printf("sizeof(s):%d",sizeof(s)); 22 | while(1); 23 | return 0; 24 | } -------------------------------------------------------------------------------- /test_cpp/test.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _TEST_HPP_ 2 | #define _TEST_HPP_ 3 | class A{ 4 | public: 5 | int a; 6 | private: 7 | int b; 8 | public: 9 | void setb(int m); 10 | int getb(); 11 | }; 12 | void A::setb(int m){ 13 | b=m; 14 | } 15 | int A::getb(){ 16 | return b; 17 | } 18 | #endif -------------------------------------------------------------------------------- /test_cpp/test.ld: -------------------------------------------------------------------------------- 1 | /* 2 | ** 链接脚本 3 | */ 4 | OUTPUT_FORMAT(elf32-i386) 5 | OUTPUT_ARCH(i386) 6 | ENTRY(_start) 7 | /* 8 | * ld有多种方法设置进程入口地址, 按以下顺序: (编号越前, 优先级越高) 9 | * 1, ld命令行的-e选项 10 | * 2, 连接脚本的ENTRY(SYMBOL)命令 11 | * 3, 如果定义了start 符号, 使用start符号值 12 | * 4, 如果存在 .text section , 使用.text section的第一字节的位置值 13 | * 5, 使用值0 14 | * 15 | * 16 | */ 17 | 18 | SECTIONS 19 | { 20 | /* 将定位器符号置为0x7c00 */ 21 | . = 0x80000000; 22 | 23 | .text : { *(.text) } 24 | 25 | .rodata : { *(.rodata) } 26 | .data : { *(.data) } 27 | 28 | .bss : { *(.bss) } 29 | 30 | 31 | 32 | } -------------------------------------------------------------------------------- /test_exec/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #设置项目名 2 | project (test_exec C ASM) 3 | 4 | add_library(${PROJECT_NAME} OBJECT test.c start.S) 5 | #add_executable(${PROJECT_NAME} test.c ) 6 | target_include_directories(${PROJECT_NAME} 7 | PUBLIC 8 | ${FreeFlyOS_SOURCE_DIR}/kernel/user/ 9 | ${FreeFlyOS_SOURCE_DIR}/test_exec 10 | ) 11 | set(test_name "exec") 12 | add_custom_command(OUTPUT ${test_name} 13 | DEPENDS 14 | ${PROJECT_NAME} 15 | COMMAND 16 | x86_64-elf-ld -T ../../test_exec/test.ld -m elf_i386 -e _start ../../build/kernel/user/CMakeFiles/user.dir/stdio.c.o 17 | ../../build/kernel/user/CMakeFiles/user.dir/user_syscall.c.o 18 | ../../build/test_exec/CMakeFiles/test_exec.dir/test.c.o 19 | ../../build/test_exec/CMakeFiles/test_exec.dir/start.S.o -o test_exec 20 | COMMAND 21 | x86_64-elf-objdump -d test_exec > ../../disassembly/test_exec_disass.md 22 | COMMAND 23 | dd if=../test_exec/test_exec of=../../FreeFlyOS.img bs=512 count=30 seek=500 conv=notrunc 24 | COMMAND 25 | echo "exec down!" 26 | ) 27 | add_custom_target(exec_tar ALL DEPENDS ${test_name}) -------------------------------------------------------------------------------- /test_exec/readme.md: -------------------------------------------------------------------------------- 1 | 测试exec是否能执行prog程序 -------------------------------------------------------------------------------- /test_exec/start.S: -------------------------------------------------------------------------------- 1 | .text 2 | .code32 3 | .extern main 4 | .extern exit 5 | .global _start 6 | _start: 7 | push %ebx 8 | push %ecx 9 | call main 10 | 11 | -------------------------------------------------------------------------------- /test_exec/test.c: -------------------------------------------------------------------------------- 1 | #include "../kernel/user/stdio.h" 2 | #include "../kernel/user/user_syscall.h" 3 | #define NULL ((void *)0) 4 | void main(int argc,char **argv){ 5 | int arg_idx = 0; 6 | while(arg_idx < argc) { 7 | printf("argv[%d] is %s\n", arg_idx, argv[arg_idx]); 8 | arg_idx++; 9 | } 10 | printf("Nice to meet you! It's all! See You! Goodbye!\n"); 11 | while(1); 12 | } -------------------------------------------------------------------------------- /test_exec/test.ld: -------------------------------------------------------------------------------- 1 | /* 2 | ** 链接脚本 3 | */ 4 | OUTPUT_FORMAT(elf32-i386) 5 | OUTPUT_ARCH(i386) 6 | ENTRY(_start) 7 | /* 8 | * ld有多种方法设置进程入口地址, 按以下顺序: (编号越前, 优先级越高) 9 | * 1, ld命令行的-e选项 10 | * 2, 连接脚本的ENTRY(SYMBOL)命令 11 | * 3, 如果定义了start 符号, 使用start符号值 12 | * 4, 如果存在 .text section , 使用.text section的第一字节的位置值 13 | * 5, 使用值0 14 | * 15 | * 16 | */ 17 | 18 | SECTIONS 19 | { 20 | /* 将定位器符号置为0x7c00 */ 21 | . = 0x80000000; 22 | 23 | .text : { *(.text) } 24 | 25 | .rodata : { *(.rodata) } 26 | .data : { *(.data) } 27 | 28 | .bss : { *(.bss) } 29 | 30 | 31 | 32 | } -------------------------------------------------------------------------------- /test_pipe/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #设置项目名 2 | project (test_pipe C ASM) 3 | 4 | add_library(${PROJECT_NAME} OBJECT test.c start.S) 5 | #add_executable(${PROJECT_NAME} test.c ) 6 | target_include_directories(${PROJECT_NAME} 7 | PUBLIC 8 | ${FreeFlyOS_SOURCE_DIR}/kernel/user 9 | ${FreeFlyOS_SOURCE_DIR}/test_pipe 10 | ) 11 | set(test_name "pip") 12 | add_custom_command(OUTPUT ${test_name} 13 | DEPENDS 14 | ${PROJECT_NAME} 15 | COMMAND 16 | x86_64-elf-ld -T ../../test_pipe/test.ld -m elf_i386 -e _start ../../build/kernel/user/CMakeFiles/user.dir/stdio.c.o 17 | ../../build/kernel/user/CMakeFiles/user.dir/user_syscall.c.o 18 | ../../build/test_pipe/CMakeFiles/test_pipe.dir/test.c.o 19 | ../../build/test_pipe/CMakeFiles/test_pipe.dir/start.S.o -o test_pipe 20 | COMMAND 21 | x86_64-elf-objdump -d test_pipe > ../../disassembly/test_pipe_disass.md 22 | COMMAND 23 | dd if=../test_pipe/test_pipe of=../../FreeFlyOS.img bs=512 count=30 seek=570 conv=notrunc 24 | COMMAND 25 | echo "pipe down!" 26 | ) 27 | add_custom_target(test_pi ALL DEPENDS ${test_name}) -------------------------------------------------------------------------------- /test_pipe/readme.md: -------------------------------------------------------------------------------- 1 | 测试管道用的程序 -------------------------------------------------------------------------------- /test_pipe/start.S: -------------------------------------------------------------------------------- 1 | .text 2 | .code32 3 | .extern main 4 | .extern exit 5 | .global _start 6 | _start: 7 | push %ebx 8 | push %ecx 9 | call main 10 | 11 | push %eax 12 | call exit -------------------------------------------------------------------------------- /test_pipe/test.c: -------------------------------------------------------------------------------- 1 | #include "../kernel/user/stdio.h" 2 | #include "../kernel/user/user_syscall.h" 3 | int main(int argc, char** argv) { 4 | int fd[2] = {-1}; 5 | pipe(fd); 6 | int pid = fork(); 7 | if(pid) { // 父进程 8 | close(fd[0]); // 关闭输入 9 | write(fd[1], "Hi, my son, I love you!", 24); 10 | printf("\nI`m father, my pid is %d\n", user_sys_getpid()); 11 | return 8; 12 | } else { 13 | close(fd[1]); // 关闭输出 14 | char buf[32] = {0}; 15 | read(fd[0], buf, 24); 16 | printf("\nI`m child, my pid is %d\n", user_sys_getpid()); 17 | printf("I`m child, my father said to me: \"%s\"\n", buf); 18 | return 9; 19 | } 20 | } -------------------------------------------------------------------------------- /test_pipe/test.ld: -------------------------------------------------------------------------------- 1 | /* 2 | ** 链接脚本 3 | */ 4 | OUTPUT_FORMAT(elf32-i386) 5 | OUTPUT_ARCH(i386) 6 | ENTRY(_start) 7 | /* 8 | * ld有多种方法设置进程入口地址, 按以下顺序: (编号越前, 优先级越高) 9 | * 1, ld命令行的-e选项 10 | * 2, 连接脚本的ENTRY(SYMBOL)命令 11 | * 3, 如果定义了start 符号, 使用start符号值 12 | * 4, 如果存在 .text section , 使用.text section的第一字节的位置值 13 | * 5, 使用值0 14 | * 15 | * 16 | */ 17 | 18 | SECTIONS 19 | { 20 | /* 将定位器符号置为0x7c00 */ 21 | . = 0x80000000; 22 | 23 | .text : { *(.text) } 24 | 25 | .rodata : { *(.rodata) } 26 | .data : { *(.data) } 27 | 28 | .bss : { *(.bss) } 29 | 30 | 31 | 32 | } -------------------------------------------------------------------------------- /test_socket/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #设置项目名 2 | project (test_socket C ASM) 3 | 4 | add_library(${PROJECT_NAME} OBJECT test.c start.S) 5 | #add_executable(${PROJECT_NAME} test.c ) 6 | target_include_directories(${PROJECT_NAME} 7 | PUBLIC 8 | ${FreeFlyOS_SOURCE_DIR}/kernel/user 9 | ${FreeFlyOS_SOURCE_DIR}/test_socket 10 | ) 11 | set(test_name "testso") 12 | add_custom_command(OUTPUT ${test_name} 13 | DEPENDS 14 | ${PROJECT_NAME} 15 | COMMAND 16 | x86_64-elf-ld -T ../../test_socket/test.ld -m elf_i386 -e _start ../../build/kernel/user/CMakeFiles/user.dir/stdio.c.o 17 | ../../build/kernel/user/CMakeFiles/user.dir/user_syscall.c.o 18 | ../../build/test_socket/CMakeFiles/test_socket.dir/test.c.o 19 | ../../build/test_socket/CMakeFiles/test_socket.dir/start.S.o -o test_socket 20 | COMMAND 21 | x86_64-elf-objdump -d test_socket > ../../disassembly/test_socket_disass.md 22 | COMMAND 23 | dd if=../test_socket/test_socket of=../../FreeFlyOS.img bs=512 count=50 seek=650 conv=notrunc 24 | COMMAND 25 | echo "testsocket down!" 26 | COMMAND 27 | qemu-system-i386 -m 2048 -net nic,model=rtl8139 -smp 2 -hda ../../FreeFlyOS.img 28 | ) 29 | add_custom_target(endsocket ALL DEPENDS ${test_name}) -------------------------------------------------------------------------------- /test_socket/start.S: -------------------------------------------------------------------------------- 1 | .text 2 | .code32 3 | .extern main 4 | .extern exit 5 | .global _start 6 | _start: 7 | push %ebx 8 | push %ecx 9 | call main 10 | 11 | push %eax 12 | call exit -------------------------------------------------------------------------------- /test_socket/test.c: -------------------------------------------------------------------------------- 1 | #include "../kernel/user/stdio.h" 2 | #include "../kernel/user/user_syscall.h" 3 | int main(int argc, char** argv) { 4 | int pid = fork(); 5 | char serveraddr[4]={192,168,0,1}; 6 | char clientaddr[4]={192,168,0,2}; 7 | if(pid) { // 父进程,服务器端 8 | 9 | int serverfd=socket(); 10 | bind(serverfd,serveraddr); 11 | listen(serverfd); 12 | int clientfd=accept(serverfd,clientaddr); 13 | while(1); 14 | } else { //子进程,客户端 15 | int clientfd=socket(); 16 | int serverfd=connect(clientfd,serveraddr); 17 | while(1); 18 | } 19 | } -------------------------------------------------------------------------------- /test_socket/test.ld: -------------------------------------------------------------------------------- 1 | /* 2 | ** 链接脚本 3 | */ 4 | OUTPUT_FORMAT(elf32-i386) 5 | OUTPUT_ARCH(i386) 6 | ENTRY(_start) 7 | /* 8 | * ld有多种方法设置进程入口地址, 按以下顺序: (编号越前, 优先级越高) 9 | * 1, ld命令行的-e选项 10 | * 2, 连接脚本的ENTRY(SYMBOL)命令 11 | * 3, 如果定义了start 符号, 使用start符号值 12 | * 4, 如果存在 .text section , 使用.text section的第一字节的位置值 13 | * 5, 使用值0 14 | * 15 | * 16 | */ 17 | 18 | SECTIONS 19 | { 20 | /* 将定位器符号置为0x7c00 */ 21 | . = 0x80000000; 22 | 23 | .text : { *(.text) } 24 | 25 | .rodata : { *(.rodata) } 26 | .data : { *(.data) } 27 | 28 | .bss : { *(.bss) } 29 | 30 | 31 | 32 | } -------------------------------------------------------------------------------- /xxd.sh: -------------------------------------------------------------------------------- 1 | #usage: sh xxd.sh 文件 起始地址 长度 2 | xxd -u -a -g 1 -s $2 -l $3 $1 3 | 4 | #-u use upper case hex letters. Default is lower case. 5 | # 6 | #-a | -autoskip 7 | # toggle autoskip: A single ’*’ replaces nul-lines. Default off. 8 | # 9 | #-g bytes | -groupsize bytes 10 | # separate the output of every bytes (two hex characters or eight bit-digits each) by a whitespace. Specify -g 0 to 11 | # suppress grouping. defaults to 2 in normal mode and 1 in bits mode. Grouping does not apply to postscript or 12 | # include style. 13 | # 14 | #-c cols | -cols cols 15 | # format octets per line. Default 16 (-i: 12, -ps: 30, -b: 6). Max 256. 16 | # 17 | #-s [+][-]seek 18 | # start at bytes abs. (or rel.) infile offset. + indicates that the seek is relative to the current stdin file position 19 | # (meaningless when not reading from stdin). - indicates that the seek should be that many characters from the end of 20 | # the input (or if combined with +: before the current stdin file position). 21 | # Without -s option, xxd starts at the current file position. 22 | -------------------------------------------------------------------------------- /体会.md: -------------------------------------------------------------------------------- 1 | 截止到2020年底,FreeFlyOS项目基本结束了,因为之前对OS比较感兴趣并且有一定的了解,再加上暑期参加了一个开源OS的内存优化,感觉自己实现起来也并不算太难,所以从9月起开始写这个项目,直到12月底才基本完成,期间遇到了很多问题,但最后都解决了,说明我行,你也行!如果你有写OS的想法的,并且有时间完成它,那么为何不自己实现一个呢,不去造轮子怎么理解轮子的本质呢? 2 | 3 | 这也算实现了自己的小目标了,以后看有没有时间继续更新了! 4 | 5 | 项目地址:https://github.com/dashanji/FreeFlyOS 6 | 7 | 该项目基本包含一个简单OS的功能,大约5000行代码左右(C+ASM),其余语言均是由构建脚本(CMake)或者反汇编(x86_64-elf-objdump)或查看elf文件信息(x86_64-elf-x64-readelf)生成, 8 | 9 | ![image-20201228110949237](/Users/caoy/Library/Application Support/typora-user-images/image-20201228110949237.png) 10 | 11 | 说一下开发OS的感受吧: 12 | 13 | 整体下来,感觉对Linux的一些基本原理了解更多了,但是说实话,写时一时爽,调试火葬场。 14 | 15 | 所以要写好一个OS的代码,必须先学会调试,不然有BUG的话,你就会很难受。目前我觉得最多的BUG就是缺页异常,所以对于页表的操作需要格外小心,此外最难发现的BUG就是内核栈和用户栈问题,栈的内容说不定会在不经意间更改。 16 | 17 | --------------------------------------------------------------------------------