├── LICENSE
├── README.md
├── imgfile
└── myos.iso
└── src
├── Makefile
├── arch
├── gdt.c
├── gdt.s
├── idt.c
├── idt.s
└── pic.c
├── boot.s
├── drivers
├── keyboard.c
├── keymap.c
└── terminal.c
├── include
├── do_read.h
├── do_write.h
├── gdt.h
├── get_ksize.h
├── get_mmap.h
├── idt.h
├── inb_outb.h
├── init_pmemory.h
├── init_vmemory.h
├── interrupt.h
├── kernel.h
├── keyboard.h
├── multiboot.h
├── pic.h
├── pmalloc.h
├── syscall.h
├── syscallnum.h
├── terminal.h
└── vga.h
├── isodir
└── boot
│ └── grub
│ └── grub.cfg
├── kernel
├── do_read.c
├── do_write.c
├── interrupt.c
├── interrupt.s
├── kernel.c
└── syscall.c
├── linker.ld
├── memory
├── get_ksize.c
├── get_mmap.c
├── init_pmemory.c
├── init_vmemory.c
├── paging.s
└── pmalloc.c
└── sh_libc
├── include
├── io.h
├── math.h
├── stdio.h
├── stdlib.h
├── string.h
└── sysdep.h
├── io.c
├── math.c
├── stdio.c
├── stdlib.c
├── string.c
└── sysdep.c
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU GENERAL PUBLIC LICENSE
2 | Version 2, June 1991
3 |
4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
6 | Everyone is permitted to copy and distribute verbatim copies
7 | of this license document, but changing it is not allowed.
8 |
9 | Preamble
10 |
11 | The licenses for most software are designed to take away your
12 | freedom to share and change it. By contrast, the GNU General Public
13 | License is intended to guarantee your freedom to share and change free
14 | software--to make sure the software is free for all its users. This
15 | General Public License applies to most of the Free Software
16 | Foundation's software and to any other program whose authors commit to
17 | using it. (Some other Free Software Foundation software is covered by
18 | the GNU Lesser General Public License instead.) You can apply it to
19 | your programs, too.
20 |
21 | When we speak of free software, we are referring to freedom, not
22 | price. Our General Public Licenses are designed to make sure that you
23 | have the freedom to distribute copies of free software (and charge for
24 | this service if you wish), that you receive source code or can get it
25 | if you want it, that you can change the software or use pieces of it
26 | in new free programs; and that you know you can do these things.
27 |
28 | To protect your rights, we need to make restrictions that forbid
29 | anyone to deny you these rights or to ask you to surrender the rights.
30 | These restrictions translate to certain responsibilities for you if you
31 | distribute copies of the software, or if you modify it.
32 |
33 | For example, if you distribute copies of such a program, whether
34 | gratis or for a fee, you must give the recipients all the rights that
35 | you have. You must make sure that they, too, receive or can get the
36 | source code. And you must show them these terms so they know their
37 | rights.
38 |
39 | We protect your rights with two steps: (1) copyright the software, and
40 | (2) offer you this license which gives you legal permission to copy,
41 | distribute and/or modify the software.
42 |
43 | Also, for each author's protection and ours, we want to make certain
44 | that everyone understands that there is no warranty for this free
45 | software. If the software is modified by someone else and passed on, we
46 | want its recipients to know that what they have is not the original, so
47 | that any problems introduced by others will not reflect on the original
48 | authors' reputations.
49 |
50 | Finally, any free program is threatened constantly by software
51 | patents. We wish to avoid the danger that redistributors of a free
52 | program will individually obtain patent licenses, in effect making the
53 | program proprietary. To prevent this, we have made it clear that any
54 | patent must be licensed for everyone's free use or not licensed at all.
55 |
56 | The precise terms and conditions for copying, distribution and
57 | modification follow.
58 |
59 | GNU GENERAL PUBLIC LICENSE
60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
61 |
62 | 0. This License applies to any program or other work which contains
63 | a notice placed by the copyright holder saying it may be distributed
64 | under the terms of this General Public License. The "Program", below,
65 | refers to any such program or work, and a "work based on the Program"
66 | means either the Program or any derivative work under copyright law:
67 | that is to say, a work containing the Program or a portion of it,
68 | either verbatim or with modifications and/or translated into another
69 | language. (Hereinafter, translation is included without limitation in
70 | the term "modification".) Each licensee is addressed as "you".
71 |
72 | Activities other than copying, distribution and modification are not
73 | covered by this License; they are outside its scope. The act of
74 | running the Program is not restricted, and the output from the Program
75 | is covered only if its contents constitute a work based on the
76 | Program (independent of having been made by running the Program).
77 | Whether that is true depends on what the Program does.
78 |
79 | 1. You may copy and distribute verbatim copies of the Program's
80 | source code as you receive it, in any medium, provided that you
81 | conspicuously and appropriately publish on each copy an appropriate
82 | copyright notice and disclaimer of warranty; keep intact all the
83 | notices that refer to this License and to the absence of any warranty;
84 | and give any other recipients of the Program a copy of this License
85 | along with the Program.
86 |
87 | You may charge a fee for the physical act of transferring a copy, and
88 | you may at your option offer warranty protection in exchange for a fee.
89 |
90 | 2. You may modify your copy or copies of the Program or any portion
91 | of it, thus forming a work based on the Program, and copy and
92 | distribute such modifications or work under the terms of Section 1
93 | above, provided that you also meet all of these conditions:
94 |
95 | a) You must cause the modified files to carry prominent notices
96 | stating that you changed the files and the date of any change.
97 |
98 | b) You must cause any work that you distribute or publish, that in
99 | whole or in part contains or is derived from the Program or any
100 | part thereof, to be licensed as a whole at no charge to all third
101 | parties under the terms of this License.
102 |
103 | c) If the modified program normally reads commands interactively
104 | when run, you must cause it, when started running for such
105 | interactive use in the most ordinary way, to print or display an
106 | announcement including an appropriate copyright notice and a
107 | notice that there is no warranty (or else, saying that you provide
108 | a warranty) and that users may redistribute the program under
109 | these conditions, and telling the user how to view a copy of this
110 | License. (Exception: if the Program itself is interactive but
111 | does not normally print such an announcement, your work based on
112 | the Program is not required to print an announcement.)
113 |
114 | These requirements apply to the modified work as a whole. If
115 | identifiable sections of that work are not derived from the Program,
116 | and can be reasonably considered independent and separate works in
117 | themselves, then this License, and its terms, do not apply to those
118 | sections when you distribute them as separate works. But when you
119 | distribute the same sections as part of a whole which is a work based
120 | on the Program, the distribution of the whole must be on the terms of
121 | this License, whose permissions for other licensees extend to the
122 | entire whole, and thus to each and every part regardless of who wrote it.
123 |
124 | Thus, it is not the intent of this section to claim rights or contest
125 | your rights to work written entirely by you; rather, the intent is to
126 | exercise the right to control the distribution of derivative or
127 | collective works based on the Program.
128 |
129 | In addition, mere aggregation of another work not based on the Program
130 | with the Program (or with a work based on the Program) on a volume of
131 | a storage or distribution medium does not bring the other work under
132 | the scope of this License.
133 |
134 | 3. You may copy and distribute the Program (or a work based on it,
135 | under Section 2) in object code or executable form under the terms of
136 | Sections 1 and 2 above provided that you also do one of the following:
137 |
138 | a) Accompany it with the complete corresponding machine-readable
139 | source code, which must be distributed under the terms of Sections
140 | 1 and 2 above on a medium customarily used for software interchange; or,
141 |
142 | b) Accompany it with a written offer, valid for at least three
143 | years, to give any third party, for a charge no more than your
144 | cost of physically performing source distribution, a complete
145 | machine-readable copy of the corresponding source code, to be
146 | distributed under the terms of Sections 1 and 2 above on a medium
147 | customarily used for software interchange; or,
148 |
149 | c) Accompany it with the information you received as to the offer
150 | to distribute corresponding source code. (This alternative is
151 | allowed only for noncommercial distribution and only if you
152 | received the program in object code or executable form with such
153 | an offer, in accord with Subsection b above.)
154 |
155 | The source code for a work means the preferred form of the work for
156 | making modifications to it. For an executable work, complete source
157 | code means all the source code for all modules it contains, plus any
158 | associated interface definition files, plus the scripts used to
159 | control compilation and installation of the executable. However, as a
160 | special exception, the source code distributed need not include
161 | anything that is normally distributed (in either source or binary
162 | form) with the major components (compiler, kernel, and so on) of the
163 | operating system on which the executable runs, unless that component
164 | itself accompanies the executable.
165 |
166 | If distribution of executable or object code is made by offering
167 | access to copy from a designated place, then offering equivalent
168 | access to copy the source code from the same place counts as
169 | distribution of the source code, even though third parties are not
170 | compelled to copy the source along with the object code.
171 |
172 | 4. You may not copy, modify, sublicense, or distribute the Program
173 | except as expressly provided under this License. Any attempt
174 | otherwise to copy, modify, sublicense or distribute the Program is
175 | void, and will automatically terminate your rights under this License.
176 | However, parties who have received copies, or rights, from you under
177 | this License will not have their licenses terminated so long as such
178 | parties remain in full compliance.
179 |
180 | 5. You are not required to accept this License, since you have not
181 | signed it. However, nothing else grants you permission to modify or
182 | distribute the Program or its derivative works. These actions are
183 | prohibited by law if you do not accept this License. Therefore, by
184 | modifying or distributing the Program (or any work based on the
185 | Program), you indicate your acceptance of this License to do so, and
186 | all its terms and conditions for copying, distributing or modifying
187 | the Program or works based on it.
188 |
189 | 6. Each time you redistribute the Program (or any work based on the
190 | Program), the recipient automatically receives a license from the
191 | original licensor to copy, distribute or modify the Program subject to
192 | these terms and conditions. You may not impose any further
193 | restrictions on the recipients' exercise of the rights granted herein.
194 | You are not responsible for enforcing compliance by third parties to
195 | this License.
196 |
197 | 7. If, as a consequence of a court judgment or allegation of patent
198 | infringement or for any other reason (not limited to patent issues),
199 | conditions are imposed on you (whether by court order, agreement or
200 | otherwise) that contradict the conditions of this License, they do not
201 | excuse you from the conditions of this License. If you cannot
202 | distribute so as to satisfy simultaneously your obligations under this
203 | License and any other pertinent obligations, then as a consequence you
204 | may not distribute the Program at all. For example, if a patent
205 | license would not permit royalty-free redistribution of the Program by
206 | all those who receive copies directly or indirectly through you, then
207 | the only way you could satisfy both it and this License would be to
208 | refrain entirely from distribution of the Program.
209 |
210 | If any portion of this section is held invalid or unenforceable under
211 | any particular circumstance, the balance of the section is intended to
212 | apply and the section as a whole is intended to apply in other
213 | circumstances.
214 |
215 | It is not the purpose of this section to induce you to infringe any
216 | patents or other property right claims or to contest validity of any
217 | such claims; this section has the sole purpose of protecting the
218 | integrity of the free software distribution system, which is
219 | implemented by public license practices. Many people have made
220 | generous contributions to the wide range of software distributed
221 | through that system in reliance on consistent application of that
222 | system; it is up to the author/donor to decide if he or she is willing
223 | to distribute software through any other system and a licensee cannot
224 | impose that choice.
225 |
226 | This section is intended to make thoroughly clear what is believed to
227 | be a consequence of the rest of this License.
228 |
229 | 8. If the distribution and/or use of the Program is restricted in
230 | certain countries either by patents or by copyrighted interfaces, the
231 | original copyright holder who places the Program under this License
232 | may add an explicit geographical distribution limitation excluding
233 | those countries, so that distribution is permitted only in or among
234 | countries not thus excluded. In such case, this License incorporates
235 | the limitation as if written in the body of this License.
236 |
237 | 9. The Free Software Foundation may publish revised and/or new versions
238 | of the General Public License from time to time. Such new versions will
239 | be similar in spirit to the present version, but may differ in detail to
240 | address new problems or concerns.
241 |
242 | Each version is given a distinguishing version number. If the Program
243 | specifies a version number of this License which applies to it and "any
244 | later version", you have the option of following the terms and conditions
245 | either of that version or of any later version published by the Free
246 | Software Foundation. If the Program does not specify a version number of
247 | this License, you may choose any version ever published by the Free Software
248 | Foundation.
249 |
250 | 10. If you wish to incorporate parts of the Program into other free
251 | programs whose distribution conditions are different, write to the author
252 | to ask for permission. For software which is copyrighted by the Free
253 | Software Foundation, write to the Free Software Foundation; we sometimes
254 | make exceptions for this. Our decision will be guided by the two goals
255 | of preserving the free status of all derivatives of our free software and
256 | of promoting the sharing and reuse of software generally.
257 |
258 | NO WARRANTY
259 |
260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
268 | REPAIR OR CORRECTION.
269 |
270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
278 | POSSIBILITY OF SUCH DAMAGES.
279 |
280 | END OF TERMS AND CONDITIONS
281 |
282 | How to Apply These Terms to Your New Programs
283 |
284 | If you develop a new program, and you want it to be of the greatest
285 | possible use to the public, the best way to achieve this is to make it
286 | free software which everyone can redistribute and change under these terms.
287 |
288 | To do so, attach the following notices to the program. It is safest
289 | to attach them to the start of each source file to most effectively
290 | convey the exclusion of warranty; and each file should have at least
291 | the "copyright" line and a pointer to where the full notice is found.
292 |
293 | {description}
294 | Copyright (C) {year} {fullname}
295 |
296 | This program is free software; you can redistribute it and/or modify
297 | it under the terms of the GNU General Public License as published by
298 | the Free Software Foundation; either version 2 of the License, or
299 | (at your option) any later version.
300 |
301 | This program is distributed in the hope that it will be useful,
302 | but WITHOUT ANY WARRANTY; without even the implied warranty of
303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
304 | GNU General Public License for more details.
305 |
306 | You should have received a copy of the GNU General Public License along
307 | with this program; if not, write to the Free Software Foundation, Inc.,
308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
309 |
310 | Also add information on how to contact you by electronic and paper mail.
311 |
312 | If the program is interactive, make it output a short notice like this
313 | when it starts in an interactive mode:
314 |
315 | Gnomovision version 69, Copyright (C) year name of author
316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
317 | This is free software, and you are welcome to redistribute it
318 | under certain conditions; type `show c' for details.
319 |
320 | The hypothetical commands `show w' and `show c' should show the appropriate
321 | parts of the General Public License. Of course, the commands you use may
322 | be called something other than `show w' and `show c'; they could even be
323 | mouse-clicks or menu items--whatever suits your program.
324 |
325 | You should also get your employer (if you work as a programmer) or your
326 | school, if any, to sign a "copyright disclaimer" for the program, if
327 | necessary. Here is a sample; alter the names:
328 |
329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program
330 | `Gnomovision' (which makes passes at compilers) written by James Hacker.
331 |
332 | {signature of Ty Coon}, 1 April 1989
333 | Ty Coon, President of Vice
334 |
335 | This General Public License does not permit incorporating your program into
336 | proprietary programs. If your program is a subroutine library, you may
337 | consider it more useful to permit linking proprietary applications with the
338 | library. If this is what you want to do, use the GNU Lesser General
339 | Public License instead of this License.
340 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 自作OS(仮称)
2 | x86 32bit なOSです。
3 |
4 | ## 開発環境
5 | OS : Linux(CentOS7.1)
6 | 使用プログラミング言語 : C, GNU Assembler
7 | GCC バージョン : gcc version 6.3.0
8 |
9 | 記事毎に使用したソースコードと解説記事は[Releases](https://github.com/Shadow5523/osdev/releases)から参照することができる。
10 |
11 | ## コンパイル
12 | ※クロスコンパイラの導入方法は下記記事を参照。
13 | [OSを自作してみる1 ~Linuxで自作OSを作る環境を構築する~](https://zeus.shadow-net.jp/?p=118)
14 |
15 | 1.osdevレポジトリをcloneする。
16 | git clone https://github.com/Shadow5523/osdev.git
17 |
18 | 2.ソースコードのディレクトリへ移動
19 | cd osdev/src
20 |
21 | 3.makeを使用してコンパイルする。同じディレクトリに出来る"myos.iso"がOSのイメージファイルとなる。
22 | make
23 |
24 | 4.make cleanでオブジェクトファイルを消すことが出来る。
25 | make clean
26 |
27 |
28 | ## コンパイル済イメージファイル
29 | 最新版のイメージファイルを以下に配置しておきます。
30 | [myos.iso](/imgfile)
31 |
32 |
33 | ## 参考資料
34 | [OSDev.org](http://wiki.osdev.org/Main_Page)
35 | [0から作るソフトウェア開発](http://softwaretechnique.jp/OS_Development/scratchbuild.html)
36 | [30日でできる! OS自作入門](https://books.google.co.jp/books/about/30%E6%97%A5%E3%81%A7%E3%81%A7%E3%81%8D%E3%82%8B_OS%E8%87%AA%E4%BD%9C%E5%85%A5%E9%96%80.html?id=ilSvAgAAQBAJ&source=kp_cover&redir_esc=y)
37 | [OSのようなもの](http://d.hatena.ne.jp/wocota/searchdiary?word=%2A%5B%BC%AB%BA%EEOS%5D)
38 | [システムコールの呼び出し方メモ](https://qiita.com/kure/items/5a1a114f9a37aeab255c)
39 | [x86_64環境でシステムコールを発行する](http://sugawarayusuke.hatenablog.com/entry/2016/04/22/213251)
40 |
41 |
--------------------------------------------------------------------------------
/imgfile/myos.iso:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Shadow5523/osdev/8b74fb110f8dea006d232ecd87547d31852c9d6e/imgfile/myos.iso
--------------------------------------------------------------------------------
/src/Makefile:
--------------------------------------------------------------------------------
1 | all: create
2 | OBJ = kernel.o terminal.o boot.o inb_outb.o keyboard.o \
3 | keymap.o gdt.o idt.o pic.o interrupt.o stdio.o \
4 | stdlib.o string.o math.o get_mmap.o io.o sysdep.o \
5 | syscall.o getksize.o do_write.o do_read.o init_pmemory.o pmalloc.o\
6 | init_vmemory.o
7 |
8 | OBJAS = interruptas.o idts.o gdts.o boot.o paging.o
9 |
10 |
11 | CC = i686-elf-gcc
12 | CCAS = i686-elf-as
13 | CFLAGS = -ffreestanding -O2 -Wall
14 |
15 |
16 | INCLUDEDIR = include/
17 | ARCHDIR = arch/
18 | DRVDIR = drivers/
19 | KRNDIR = kernel/
20 | SHLIBC = sh_libc/
21 | SHLIBCINC = sh_libc/include/
22 | MEMDIR = memory/
23 |
24 |
25 | interruptas.o: $(KRNDIR)interrupt.s
26 | $(CCAS) $< -o interruptas.o
27 |
28 | idts.o: $(ARCHDIR)idt.s
29 | $(CCAS) $< -o idts.o
30 |
31 | gdts.o: $(ARCHDIR)gdt.s
32 | $(CCAS) $< -o gdts.o
33 |
34 | boot.o: boot.s
35 | $(CCAS) $< -o boot.o
36 |
37 | paging.o: $(MEMDIR)paging.s
38 | $(CCAS) $< -o paging.o
39 |
40 | interrupt.o: $(KRNDIR)interrupt.c $(INCLUDEDIR)interrupt.h
41 | $(CC) -c $^ -std=gnu99 $(CFLAGS) -Wextra
42 |
43 | pic.o: $(ARCHDIR)pic.c $(INCLUDEDIR)pic.h
44 | $(CC) -c $^ -std=gnu99 $(CFLAGS) -Wextra
45 |
46 | idt.o: $(ARCHDIR)idt.c $(INCLUDEDIR)idt.h
47 | $(CC) -c $^ -std=gnu99 $(CFLAGS) -Wextra
48 |
49 | gdt.o: $(ARCHDIR)gdt.c $(INCLUDEDIR)gdt.h
50 | $(CC) -c $^ -std=gnu99 $(CFLAGS) -Wextra
51 |
52 | inb_outb.o: $(INCLUDEDIR)inb_outb.h
53 | $(CC) -c $^ -std=gnu99 $(CFLAGS) -Wextra
54 |
55 | keymap.o: $(DRVDIR)keymap.c $(INCLUDEDIR)keyboard.h
56 | $(CC) -c $^ -std=gnu99 $(CFLAGS) -Wextra
57 |
58 | keyboard.o: $(DRVDIR)keyboard.c $(INCLUDEDIR)keyboard.h
59 | $(CC) -c $^ -std=gnu99 $(CFLAGS) -Wextra
60 |
61 | terminal.o: $(DRVDIR)terminal.c $(INCLUDEDIR)terminal.h $(INCLUDEDIR)vga.h
62 | $(CC) -c $^ -std=gnu99 $(CFLAGS) -Wextra
63 |
64 | kernel.o: $(KRNDIR)kernel.c $(INCLUDEDIR)kernel.h $(INCLUDEDIR)multiboot.h
65 | $(CC) -c $^ -std=gnu99 $(CFLAGS) -Wextra
66 |
67 | syscall.o: $(KRNDIR)syscall.c $(INCLUDEDIR)syscall.h $(INCLUDEDIR)syscallnum.h
68 | $(CC) -c $^ -std=gnu99 $(CFLAGS) -Wextra
69 |
70 | do_write.o: $(KRNDIR)do_write.c $(INCLUDEDIR)do_write.h
71 | $(CC) -c $^ -std=gnu99 $(CFLAGS) -Wextra
72 |
73 | do_read.o: $(KRNDIR)do_read.c $(INCLUDEDIR)do_read.h
74 | $(CC) -c $^ -std=gnu99 $(CFLAGS) -Wextra
75 |
76 | stdio.o: $(SHLIBC)stdio.c $(SHLIBCINC)stdio.h
77 | $(CC) -c $^ -std=gnu99 $(CFLAGS) -Wextra
78 |
79 | stdlib.o: $(SHLIBC)stdlib.c $(SHLIBCINC)stdlib.h
80 | $(CC) -c $^ -std=gnu99 $(CFLAGS) -Wextra
81 |
82 | string.o: $(SHLIBC)string.c $(SHLIBCINC)string.h
83 | $(CC) -c $^ -std=gnu99 $(CFLAGS) -Wextra
84 |
85 | math.o: $(SHLIBC)math.c $(SHLIBCINC)math.h
86 | $(CC) -c $^ -std=gnu99 $(CFLAGS) -Wextra
87 |
88 | io.o: $(SHLIBC)io.c $(SHLIBCINC)io.h
89 | $(CC) -c $^ -std=gnu99 $(CFLAGS) -Wextra
90 |
91 | sysdep.o: $(SHLIBC)sysdep.c $(SHLIBCINC)sysdep.h
92 | $(CC) -c $^ -std=gnu99 $(CFLAGS) -Wextra
93 |
94 | get_mmap.o: $(MEMDIR)get_mmap.c $(INCLUDEDIR)get_mmap.h
95 | $(CC) -c $^ -std=gnu99 $(CFLAGS) -Wextra
96 |
97 | getksize.o: $(MEMDIR)get_ksize.c $(INCLUDEDIR)get_ksize.h
98 | $(CC) -c $^ -std=gnu99 $(CFLAGS) -Wextra
99 |
100 | init_pmemory.o: $(MEMDIR)init_pmemory.c $(INCLUDEDIR)init_pmemory.h
101 | $(CC) -c $^ -std=gnu99 $(CFLAGS) -Wextra
102 |
103 | init_vmemory.o: $(MEMDIR)init_vmemory.c $(INCLUDEDIR)init_vmemory.h
104 | $(CC) -c $^ -std=gnu99 $(CFLAGS) -Wextra
105 |
106 | pmalloc.o: $(MEMDIR)pmalloc.c $(INCLUDEDIR)pmalloc.h
107 | $(CC) -c $^ -std=gnu99 $(CFLAGS) -Wextra
108 |
109 | create: $(OBJAS) $(OBJ)
110 | $(CC) -T linker.ld -o myos.bin $(CFLAGS) -nostdlib *.o -lgcc
111 | grub2-file --is-x86-multiboot myos.bin
112 | \cp -f myos.bin isodir/boot/myos.bin
113 | grub2-mkrescue -o myos.iso isodir
114 |
115 | clean:
116 | rm -f *.o myos.bin myos.iso isodir/boot/myos.bin
117 | rm -f ./*~ $(ARCHDIR)*~ $(INCLUDEDIR)*~ $(SHLIBCINC)*~ $(MEMDIR)*~ \
118 | $(KRNDIR)*~
119 | rm -f $(SHLIBCINC)*gch $(INCLUDEDIR)*gch
120 |
--------------------------------------------------------------------------------
/src/arch/gdt.c:
--------------------------------------------------------------------------------
1 | #include "../include/gdt.h"
2 |
3 | void gdt_init(void){
4 | gdtr gdt;
5 | terminal_writestring("Initialize GDT...");
6 | for (size_t i = 0; i < GDT_LEN; i++) {
7 | set_segment_desc(i, 0, 0, 0, 0);
8 | }
9 | set_segment_desc(1, 0, 0xffffffff, 0x9a, 0xcf);
10 | set_segment_desc(2, 0, 0xffffffff, 0x92, 0xcf);
11 | set_segment_desc(3, 0, 0xffffffff, 0xfa, 0xcf);
12 | set_segment_desc(4, 0, 0xffffffff, 0xf2, 0xcf);
13 |
14 | gdt.gdt_size = GDT_LEN * sizeof(gdt_desc) - 1;
15 | gdt.base = (uint32_t)gdt_entries;
16 | load_gdtr((uint32_t)(&gdt));
17 | terminal_writestring(" OK!\n");
18 | }
19 |
20 |
21 | void set_segment_desc(uint32_t index, uint32_t base, uint32_t limit, uint8_t s_access, uint8_t gran){
22 | gdt_desc * sd = &gdt_entries[index];
23 | sd -> base_high = (base >> 24 & 0xff);
24 | sd -> base_low = base & 0xffff;
25 | sd -> base_mid = (base >> 16) & 0xff;
26 | sd -> s_access = s_access;
27 | sd -> limit_low = limit & 0xffff;
28 | sd -> limit_high = ((limit >> 16) & 0x0f) | (gran & 0xf0);
29 | }
30 |
--------------------------------------------------------------------------------
/src/arch/gdt.s:
--------------------------------------------------------------------------------
1 | .global load_gdtr
2 |
3 | load_gdtr:
4 | movl 4(%esp), %eax
5 | lgdt (%eax)
6 |
7 | mov %cr0, %eax
8 | or $1, %eax
9 | mov %eax, %cr0
10 |
11 | mov $0x10, %ax
12 | mov %ax, %ds
13 | mov %ax, %es
14 | mov %ax, %fs
15 | mov %ax, %gs
16 | mov %ax, %ss
17 |
18 | jmp $0x08, $gdt_flush
19 | gdt_flush:
20 | ret
21 |
--------------------------------------------------------------------------------
/src/arch/idt.c:
--------------------------------------------------------------------------------
1 | #include "../include/idt.h"
2 |
3 | void idt_init(void){
4 | idtr idt;
5 | terminal_writestring("Initialize IDT...");
6 | for (size_t i = 0; i < IDT_LEN; i++) {
7 | set_gate_desc(i, 0, 0, 0);
8 | }
9 |
10 | set_gate_desc(33, (uint32_t)as_keyboard_interrupt, 0x08, 0x8e);
11 | set_gate_desc(128, (uint32_t)as_software_interrupt, 0x08, 0x8f);
12 |
13 | idt.idt_size = IDT_LEN * sizeof(gate_desc) - 1;
14 | idt.base = (uint32_t)idt_entries;
15 | load_idtr((uint32_t)&(idt));
16 | terminal_writestring(" OK!\n");
17 | }
18 |
19 |
20 | void set_gate_desc(uint32_t index, uint32_t offset, uint32_t selector, uint8_t ar){
21 | gate_desc *gd = &idt_entries[index];
22 | gd -> offset_low = offset & 0xffff;
23 | gd -> offset_high = (offset >> 16) & 0xffff;
24 | gd -> dw_count = 0;
25 | gd -> selector = selector;
26 | gd -> s_access = ar | 0x60;
27 | }
28 |
--------------------------------------------------------------------------------
/src/arch/idt.s:
--------------------------------------------------------------------------------
1 | .global load_idtr
2 |
3 | load_idtr:
4 | mov 4(%esp), %eax
5 | lidt (%eax)
6 | ret
7 |
--------------------------------------------------------------------------------
/src/arch/pic.c:
--------------------------------------------------------------------------------
1 | #include "../include/pic.h"
2 |
3 | void pic_init(void){
4 | terminal_writestring("Initialize PIC...");
5 |
6 | outb(MASTER_PIC_MASK_DATA, CLEAR_MASK);
7 | outb(SLAVE_PIC_MASK_DATA, CLEAR_MASK);
8 |
9 | outb(MASTER_PIC_CMD_STAT, WRITE_ICW1);
10 | outb(SLAVE_PIC_CMD_STAT, WRITE_ICW1);
11 |
12 | outb(MASTER_PIC_MASK_DATA, WRITE_ICW2_M);
13 | outb(SLAVE_PIC_MASK_DATA, WRITE_ICW2_S);
14 |
15 | outb(MASTER_PIC_MASK_DATA, WRITE_ICW3_M);
16 | outb(SLAVE_PIC_MASK_DATA, WRITE_ICW3_S);
17 |
18 | outb(MASTER_PIC_MASK_DATA, WRITE_ICW4_X86MODE);
19 | outb(SLAVE_PIC_MASK_DATA, WRITE_ICW4_X86MODE);
20 |
21 | outb(MASTER_PIC_MASK_DATA, 0xf9);
22 | outb(SLAVE_PIC_MASK_DATA, 0xef);
23 |
24 | terminal_writestring(" OK!\n");
25 | }
26 |
--------------------------------------------------------------------------------
/src/boot.s:
--------------------------------------------------------------------------------
1 | .set ALIGN, 1<<0
2 | .set MEMINFO, 1<<1
3 | .set FLAGS, ALIGN | MEMINFO
4 | .set MAGIC, 0x1BADB002
5 | .set CHECKSUM, -(MAGIC + FLAGS)
6 |
7 | .set KERNEL_VBASE, 0xC0000000
8 | .set KERNEL_PNUM, (KERNEL_VBASE >> 22)
9 |
10 | //初期のカーネルスタックサイズを確保する(16KB)
11 | .set STACKSIZE, 0x4000
12 |
13 | .section .data
14 | .balign 0x1000
15 |
16 | //ページディレクトリ作成
17 | _boot_pd:
18 | .long 0x00000083
19 | .fill (KERNEL_PNUM - 1), 4, 0x00000000
20 |
21 | .long 0x00000083
22 | .fill (1024 - KERNEL_PNUM - 1), 4, 0x00000000
23 |
24 | .section .multiboot
25 | .balign 4
26 | .long MAGIC
27 | .long FLAGS
28 | .long CHECKSUM
29 |
30 | .section .text
31 | .global _loader
32 |
33 | _loader:
34 | movl $(_boot_pd - KERNEL_VBASE), %ecx
35 | movl %ecx, %cr3
36 |
37 | // pse bit set
38 | movl %cr4, %ecx
39 | orl $0x00000010, %ecx
40 | movl %ecx, %cr4
41 |
42 | // enable paging
43 | movl %cr0, %ecx
44 | orl $0x80000000, %ecx
45 | movl %ecx, %cr0
46 |
47 | leal (_start), %ecx
48 | jmp *%ecx
49 |
50 | .type _start, @function
51 | _start:
52 | movl $0, (_boot_pd)
53 |
54 | // TLB Flush
55 | invlpg (0)
56 |
57 | movl $stack_top, %esp
58 | addl $KERNEL_VBASE, %ebx
59 | pushl %eax
60 | pushl %ebx
61 |
62 | call kernel_main
63 | cli
64 |
65 | 1: hlt
66 | jmp 1b
67 |
68 | .size _start, . - _start
69 |
70 | .section .bss
71 | .balign 32
72 | stack_bottom:
73 | .skip STACKSIZE
74 | stack_top:
75 |
--------------------------------------------------------------------------------
/src/drivers/keyboard.c:
--------------------------------------------------------------------------------
1 | #include "../include/keyboard.h"
2 | #include "../include/inb_outb.h"
3 |
4 | key_buf kb;
5 |
6 | void key_init(void){
7 | change_trate_delay(TYPEMATICDELEY_SET11);
8 | if (enable_keyboard() == 0xFA) {
9 | terminal_writestring("Keyboard enable OK\n");
10 | }
11 | if (!ps2_kerboard_init()) {
12 | terminal_writestring("PS/2 Keyboard init OK\n");
13 | }
14 | }
15 |
16 |
17 | uint8_t ps2_kerboard_init(void){
18 | uint8_t scodeset = getscodeset();
19 | if (scodeset == 0x43) {
20 | terminal_writestring("Current Scan code set 1\nCorrection to Scan code set2\n");
21 | change_codeset(SCAN_CODE_SET2);
22 | } else if (scodeset == 0x41) {
23 | terminal_writestring("Scan code set 2\n");
24 | } else if (scodeset == 0x3f) {
25 | terminal_writestring("Current Scan code set 3\nCorrection to Scan code set2\n");
26 | change_codeset(SCAN_CODE_SET2);
27 | } else {
28 | terminal_writestring("Unknown scan code set\nPS/2 Emulation?\n");
29 | return 1;
30 | }
31 | return 0;
32 | }
33 |
34 |
35 | void select_keymode(uint8_t scan_code){
36 | if (kb.len < 128) {
37 | if (scan_code == L_SHIFT || scan_code == R_SHIFT) {
38 | ks.shift_enable = true;
39 | } else if (scan_code == CAPS_LOCK && !ks.caps_lock) {
40 | ks.caps_lock = true;
41 | ks.led_stat += SET_CAPSLOCK_LED;
42 | switch_kb_led(ks.led_stat);
43 | } else if (scan_code == CAPS_LOCK && ks.caps_lock) {
44 | ks.caps_lock = false;
45 | ks.led_stat -= SET_CAPSLOCK_LED;
46 | switch_kb_led(ks.led_stat);
47 | } else if (scan_code == NUM_LOCK && !ks.num_lock) {
48 | ks.num_lock = true;
49 | ks.led_stat += SET_NUMLOCK_LED;
50 | switch_kb_led(ks.led_stat);
51 | } else if (scan_code == NUM_LOCK && ks.num_lock) {
52 | ks.num_lock = false;
53 | ks.led_stat -= SET_NUMLOCK_LED;
54 | switch_kb_led(ks.led_stat);
55 | } else if (scan_code == SCROLL_LOCK && !ks.scr_lock) {
56 | ks.scr_lock = true;
57 | ks.led_stat += SET_SCROLLLOCK_LED;
58 | switch_kb_led(ks.led_stat);
59 | } else if (scan_code == SCROLL_LOCK && ks.scr_lock) {
60 | ks.scr_lock = false;
61 | ks.led_stat -= SET_SCROLLLOCK_LED;
62 | switch_kb_led(ks.led_stat);
63 | } else {
64 | input_bufdata(scan_code);
65 | ++kb.len;
66 | if (kb.write == 128) { kb.write = 0; }
67 | }
68 | }
69 | }
70 |
71 |
72 | void keyboard_input_int(uint8_t scan_code){
73 | if (scan_code == 0xE0) {
74 | if (!ext_input) {
75 | ext_input = true;
76 | } else {
77 | ext_input = false;
78 | }
79 | }
80 | if (scan_code <= 0x80) {
81 | select_keymode(scan_code);
82 | } else {
83 | scan_code -= 0x80;
84 | if (scan_code == L_SHIFT || scan_code == R_SHIFT) {
85 | ks.shift_enable = false;
86 | }
87 | }
88 | }
89 |
90 |
91 | void switch_kb_led(uint8_t set_led){
92 | while (inb(PORTMAP_KEYBOARD2) & 0x02);
93 | outb(PORTMAP_KEYBOARD1, SWITCH_LED);
94 | while (inb(PORTMAP_KEYBOARD2) & 0x02);
95 | outb(PORTMAP_KEYBOARD1, set_led);
96 | }
97 |
98 |
99 | uint8_t enable_keyboard(void){
100 | outb(PORTMAP_KEYBOARD1, ENABLE_KEYBOARD);
101 | return getscode();
102 | }
103 |
104 |
105 | uint8_t getscodeset(void){
106 | while (inb(PORTMAP_KEYBOARD2) & 0x02);
107 | outb(PORTMAP_KEYBOARD1, SET_SCANCODESET);
108 | if (getscode() == 0xFA) {
109 | while (inb(PORTMAP_KEYBOARD2) & 0x02);
110 | outb(PORTMAP_KEYBOARD1, 0x00);
111 | return getscode();
112 | } else {
113 | return 0x00;
114 | }
115 | }
116 |
117 |
118 | uint8_t getscode(void){
119 | uint8_t c = 0;
120 | do {
121 | if (inb(PORTMAP_KEYBOARD1) != c) {
122 | c = inb(PORTMAP_KEYBOARD1);
123 | if (c > 0) return c;
124 | }
125 | } while (1);
126 | }
127 |
128 |
129 | void change_codeset(uint8_t set){
130 | outb(PORTMAP_KEYBOARD1, SET_SCANCODESET);
131 | outb(PORTMAP_KEYBOARD1, set);
132 | }
133 |
134 |
135 | void change_trate_delay(uint8_t set){
136 | while (inb(PORTMAP_KEYBOARD2) & 0x02);
137 | outb(PORTMAP_KEYBOARD1, SET_TYPEMATIC_RATE);
138 | while (inb(PORTMAP_KEYBOARD2) & 0x02);
139 | outb(PORTMAP_KEYBOARD1, set);
140 | }
141 |
142 |
143 | void input_bufdata(uint8_t scan_code){
144 | const keymap *key = &key_code;
145 | uint8_t numpad_data = 0;
146 |
147 | if (ks.num_lock) {
148 | numpad_data = key -> numlock[scan_code];
149 | ext_input = false;
150 | }
151 |
152 | if (!numpad_data) {
153 | if (ext_input && scan_code == 0x35) {
154 | kb.pdata[kb.write++] = '\0';
155 | } else if (ks.shift_enable && !ks.caps_lock) {
156 | kb.pdata[kb.write++] = key -> shift[scan_code];
157 | } else if (!ks.shift_enable && ks.caps_lock) {
158 | if ((numpad_data = key -> base[scan_code]) >= 'a' && numpad_data <= 'z') {
159 | kb.pdata[kb.write++] = key -> shift[scan_code];
160 | } else {
161 | kb.pdata[kb.write++] = key -> base[scan_code];
162 | }
163 | } else if (ks.shift_enable && ks.caps_lock) {
164 | if ((numpad_data = key -> base[scan_code]) >= 'a' && numpad_data <= 'z') {
165 | kb.pdata[kb.write++] = key -> base[scan_code];
166 | } else {
167 | kb.pdata[kb.write++] = key -> shift[scan_code];
168 | }
169 | } else {
170 | kb.pdata[kb.write++] = key -> base[scan_code];
171 | }
172 | } else {
173 | kb.pdata[kb.write++] = numpad_data;
174 | }
175 | }
176 |
--------------------------------------------------------------------------------
/src/drivers/keymap.c:
--------------------------------------------------------------------------------
1 | #include "../include/keyboard.h"
2 |
3 | const keymap key_code = {
4 | .base = {
5 | '0', '0', '1', '2', '3', '4', '5', '6', '7', '8',
6 | '9', '0', '-', '=', '\b', '\t', 'q', 'w', 'e', 'r',
7 | 't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n', '0',
8 | 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';',
9 | '\'', '`', '0', '\\', 'z', 'x', 'c', 'v', 'b', 'n',
10 | 'm', ',', '.', '/', '0', '\0', '0', ' ', '0', '0',
11 | '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
12 | '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
13 | '\0', '\0', '0', '\0', '0', '0', '0', '0', '0', '0',
14 | '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
15 | '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
16 | '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
17 | '0', '0', '0', '0', '0', '0', '0', '0'},
18 |
19 | .shift = {
20 | '0', '0', '!', '@', '#', '$', '%', '^', '&', '*',
21 | '(', ')', '_', '+', '\b', '\t', 'Q', 'W', 'E', 'R',
22 | 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', '\n', '0',
23 | 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':',
24 | '"', '~', '0', '|', 'Z', 'X', 'C', 'V', 'B', 'N',
25 | 'M', '<', '>', '?', '0', '\0', '0', ' ', '0', '0',
26 | '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
27 | '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
28 | '\0', '\0', '0', '\0', '0', '0', '0', '0', '0', '0',
29 | '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
30 | '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
31 | '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
32 | '0', '0', '0', '0', '0', '0', '0', '0'},
33 |
34 | .numlock = {
35 | [0x4F] = '1', [0x50] = '2', [0x51] = '3',
36 | [0x4B] = '4', [0x4C] = '5', [0x4D] = '6',
37 | [0x47] = '7', [0x48] = '8', [0x49] = '9',
38 | [0x52] = '0', [0x4A] = '-', [0x4E] = '+',
39 | [0x37] = '*', [0x53] = '.'
40 | }
41 | };
42 |
--------------------------------------------------------------------------------
/src/drivers/terminal.c:
--------------------------------------------------------------------------------
1 | #include "../include/terminal.h"
2 | #include "../include/vga.h"
3 |
4 | extern size_t pmstr_len;
5 |
6 | void terminal_initialize(void){
7 | t_row = 0;
8 | t_column = 0;
9 | t_color = vga_entry_color(VGA_COLOR_LIGHT_GREEN, VGA_COLOR_BLACK);
10 | t_buffer = (uint16_t*) 0xC00B8000; //テキストバッファはこのアドレスから始まる
11 | for (size_t y = 0; y < VGA_HEIGHT; ++y) {
12 | for (size_t x = 0; x < VGA_WIDTH; ++x) {
13 | const size_t index = y * VGA_WIDTH + x;
14 | t_buffer[index] = vga_entry(' ', t_color);
15 | }
16 | }
17 | }
18 |
19 |
20 | void terminal_setcolor(uint8_t color){
21 | t_color = color;
22 | }
23 |
24 |
25 | void terminal_putentryat(uint8_t c, uint8_t color, size_t x, size_t y){
26 | const size_t index = y * VGA_WIDTH + x;
27 | t_buffer[index] = vga_entry(c, color);
28 | }
29 |
30 |
31 | void terminal_uponerow(void){
32 | for (size_t y = 1; y < VGA_HEIGHT; y++) {
33 | for (size_t x = 0; x < VGA_WIDTH; x++) {
34 | const size_t index = y * VGA_WIDTH + x;
35 | t_buffer[(y - 1) * VGA_WIDTH + x] = t_buffer[index];
36 | if (y == (VGA_HEIGHT - 1)) {
37 | t_buffer[index] = vga_entry(' ', t_color);
38 | }
39 | }
40 | }
41 | }
42 |
43 |
44 | void terminal_putchar(uint8_t c){
45 | if (c == '\n') {
46 | c = 0;
47 | if (++t_row >= VGA_HEIGHT) {
48 | terminal_uponerow();
49 | --t_row;
50 | t_column = -1;
51 | } else {
52 | t_column = -1;
53 | }
54 | } else if (c == '\t') {
55 | c = 0;
56 | t_column += 4;
57 | } else if(c == '\b') {
58 | c = 0;
59 | t_buffer[(t_row * VGA_WIDTH + t_column) - 1] = vga_entry(' ', t_color);
60 | if ( t_column > pmstr_len + 2 ) {
61 | if (--t_column <= pmstr_len) {
62 | t_column = pmstr_len;
63 |
64 |
65 | /*プロンプト時は以下は無効
66 | t_column = VGA_WIDTH
67 |
68 | if (--t_row < 2) {
69 | t_row = 2;
70 | t_column = 0;
71 | }
72 | */
73 | }
74 | }
75 | return;
76 | }
77 | terminal_putentryat(c, t_color, t_column, t_row);
78 | if (++t_column >= VGA_WIDTH) {
79 | t_column = 0;
80 | if (++t_row >= VGA_HEIGHT) {
81 | terminal_uponerow();
82 | --t_row;
83 | }
84 | }
85 | }
86 |
87 |
88 | void terminal_write(const uint8_t* data, size_t size){
89 | for (size_t i = 0; i < size; ++i)
90 | terminal_putchar(data[i]);
91 | }
92 |
93 |
94 | void terminal_writestring(const uint8_t* data){
95 | terminal_write(data, sh_strlen(data));
96 | }
97 |
--------------------------------------------------------------------------------
/src/include/do_read.h:
--------------------------------------------------------------------------------
1 | #ifndef _DO_READ_H_
2 | #define _DO_READ_H_
3 |
4 | #include
5 |
6 | size_t do_read(int, void*, size_t);
7 |
8 | #endif _DO_READ_H
9 |
--------------------------------------------------------------------------------
/src/include/do_write.h:
--------------------------------------------------------------------------------
1 | #ifndef _DO_WRITE_H_
2 | #define _DO_WRITE_H_
3 |
4 | #include
5 |
6 | size_t do_write(int, const void*, size_t);
7 |
8 | #endif _DO_WRITE_H
9 |
--------------------------------------------------------------------------------
/src/include/gdt.h:
--------------------------------------------------------------------------------
1 | #ifndef _GDT_H_
2 | #define _GDT_H_
3 |
4 | #include
5 | #include
6 |
7 | #ifdef __cplusplus
8 | extern "C" void load_gdtr(uint32_t);
9 | #else
10 | extern void load_gdtr(uint32_t);
11 | #endif
12 |
13 | typedef struct{
14 | uint16_t limit_low;
15 | uint16_t base_low;
16 | uint8_t base_mid;
17 | uint8_t s_access;
18 | uint8_t limit_high;
19 | uint8_t base_high;
20 | }__attribute__((packed)) gdt_desc;
21 |
22 | typedef struct{
23 | uint16_t gdt_size;
24 | uint32_t base;
25 | }__attribute__((packed)) gdtr;
26 |
27 | #define GDT_LEN 8192
28 | gdt_desc gdt_entries[GDT_LEN];
29 |
30 | void gdt_init();
31 | void set_segment_desc(uint32_t, uint32_t, uint32_t, uint8_t, uint8_t);
32 |
33 | #endif _GDT_H_
34 |
--------------------------------------------------------------------------------
/src/include/get_ksize.h:
--------------------------------------------------------------------------------
1 | #ifndef _GET_KSIZE_H_
2 | #define _GET_KSIZE_H_
3 |
4 | #include
5 |
6 | extern uint32_t __kernel_start;
7 | extern uint32_t __kernel_end;
8 |
9 | uint32_t get_ksize(void);
10 |
11 | #endif _GET_KSIZE_H_
12 |
--------------------------------------------------------------------------------
/src/include/get_mmap.h:
--------------------------------------------------------------------------------
1 | #ifndef _GETMMAP_H_
2 | #define _GETMMAP_H_
3 |
4 | #include "multiboot.h"
5 |
6 | uint32_t getmmap(multiboot_info_t*);
7 |
8 | #define VBASE 0xC0000000
9 |
10 | #endif _GETMMAP_H_
11 |
--------------------------------------------------------------------------------
/src/include/idt.h:
--------------------------------------------------------------------------------
1 | #ifndef _IDT_H_
2 | #define _IDT_H_
3 |
4 | #include
5 | #include
6 | #include "interrupt.h"
7 |
8 | #ifdef __cplusplus
9 | extern "C" void load_idtr(uint32_t);
10 | #else
11 | extern void load_idtr(uint32_t);
12 | #endif
13 |
14 | extern as_keyboard_interrupt(void);
15 | extern as_software_interrupt(void);
16 |
17 | typedef struct{
18 | uint16_t offset_low;
19 | uint16_t selector;
20 | uint8_t dw_count;
21 | uint8_t s_access;
22 | uint16_t offset_high;
23 | }__attribute__((packed)) gate_desc;
24 |
25 | typedef struct{
26 | uint16_t idt_size;
27 | uint32_t base;
28 | }__attribute__((packed)) idtr;
29 |
30 | #define LIDT 0x000007ff
31 | #define IDT_LEN 256
32 | gate_desc idt_entries[IDT_LEN];
33 |
34 | void idt_init(void);
35 | void set_gate_desc(uint32_t, uint32_t, uint32_t, uint8_t);
36 |
37 | #endif _IDT_H_
38 |
--------------------------------------------------------------------------------
/src/include/inb_outb.h:
--------------------------------------------------------------------------------
1 | #ifndef _INB_OUT_H_
2 | #define _INB_OUT_H_
3 |
4 | #include
5 |
6 | static inline uint8_t inb(uint16_t port){
7 | uint8_t ret;
8 | asm volatile("inb %1, %0"
9 | : "=a"(ret)
10 | : "Nd"(port));
11 | return ret;
12 | }
13 |
14 |
15 | static inline uint8_t outb(uint16_t port, uint8_t val){
16 | asm volatile("outb %0, %1" : : "a"(val), "Nd"(port));
17 | }
18 |
19 |
20 | #endif _INB_OUT_H_
21 |
--------------------------------------------------------------------------------
/src/include/init_pmemory.h:
--------------------------------------------------------------------------------
1 | #ifndef _INIT_PMEMORY_H_
2 | #define _INIT_PMEMORY_H_
3 |
4 | #include
5 | #include
6 |
7 | #include "multiboot.h"
8 | #include "get_ksize.h"
9 | #include "get_mmap.h"
10 | #include "../sh_libc/include/stdio.h"
11 | #include "../sh_libc/include/string.h"
12 |
13 | typedef struct{
14 | uint32_t system_msize; //システムメモリサイズ
15 | uint32_t system_mbloks; //システムメモリブロック数
16 | uint32_t allocated_blocks; //割り当て済のブロック数
17 | uint32_t free_blocks; //フリーブロック数
18 | uint32_t* mmap; //ビットマップ
19 | uint32_t mmap_size; //ビットマップのサイズ
20 | }p_memory_info;
21 |
22 | p_memory_info pm_info;
23 |
24 | void get_system_mblocks(uint32_t);
25 | void setmemory(int);
26 | void clearmemory(int);
27 | void pbitmap_free(uint32_t, uint32_t);
28 | void pbitmap_alloc(uint32_t, uint32_t);
29 |
30 | #endif _INIT_PMEMORY_H_
31 |
--------------------------------------------------------------------------------
/src/include/init_vmemory.h:
--------------------------------------------------------------------------------
1 | #ifndef _INIT_VMEMORY_H_
2 | #define _INIT_VMEMORY_H_
3 |
4 | #include
5 | #include
6 |
7 | #include "init_pmemory.h"
8 | #include "pmalloc.h"
9 |
10 | #define PE_PFLAG 0x00000001
11 | #define PE_RWFLAG 0x00000002
12 |
13 | //pte & pdeの形を定義
14 | typedef uint32_t page_table_entry;
15 | typedef uint32_t page_dir_entry;
16 | extern p_memory_info pm_info;
17 |
18 | extern void enable_paging(page_dir_entry *);
19 | int init_paging(void);
20 | int init_vmemory(void);
21 |
22 | #endif _INIT_PMEMORY_H_
23 |
--------------------------------------------------------------------------------
/src/include/interrupt.h:
--------------------------------------------------------------------------------
1 | #ifndef _INETRRUPT_H_
2 | #define _INETRRUPT_H_
3 |
4 | #include "pic.h"
5 |
6 | #include
7 | #include
8 |
9 | void interrupt_done(void);
10 |
11 | //irq
12 | void keyboard_interrupt(void);
13 |
14 | //irqnum
15 | #define irq1 0x61
16 |
17 | #endif _INETRRUPT_H_
18 |
--------------------------------------------------------------------------------
/src/include/kernel.h:
--------------------------------------------------------------------------------
1 | #ifndef _KERNEL_H_
2 | #define _KERNEL_H_
3 |
4 |
5 | #if !defined(__cplusplus)
6 | #include
7 | #endif
8 |
9 | #include
10 | #include
11 |
12 | /* コンパイラが正しいターゲットを認識しているかの確認 */
13 | #if defined(__linux__)
14 | #error "You are not using a cross-compiler, you will most certainly run into trouble"
15 | #endif
16 |
17 | /* 32-bit x86ターゲット以外のコンパイラを使用するとエラーになる */
18 | #if !defined(__i386__)
19 | #error "This tutorial needs to be compiled with a ix86-elf compiler"
20 | #endif
21 |
22 | #include "terminal.h"
23 | #include "keyboard.h"
24 | #include "inb_outb.h"
25 | #include "gdt.h"
26 | #include "pic.h"
27 | #include "idt.h"
28 | #include "multiboot.h"
29 | #include "get_mmap.h"
30 | #include "get_ksize.h"
31 | #include "init_pmemory.h"
32 | #include "init_vmemory.h"
33 | #include "pmalloc.h"
34 |
35 | #include "../sh_libc/include/stdio.h"
36 | #include "../sh_libc/include/math.h"
37 | #include "../sh_libc/include/io.h"
38 |
39 | int input_line(char*, char*);
40 | void prompt(void);
41 | int executing(char*);
42 |
43 | #endif _KERNEL_H_
44 |
--------------------------------------------------------------------------------
/src/include/keyboard.h:
--------------------------------------------------------------------------------
1 | #ifndef _KEYBOARD_H_
2 | #define _KEYBOARD_H_
3 |
4 | #include
5 | #include
6 | #include
7 |
8 | //command
9 | #define SWITCH_LED 0xED
10 | #define ENABLE_KEYBOARD 0xF4
11 | #define SET_SCANCODESET 0xF0
12 | #define SET_TYPEMATIC_RATE 0xF3
13 |
14 | //options
15 | #define SCAN_CODE_SET1 0x01
16 | #define SCAN_CODE_SET2 0x02
17 | #define SCAN_CODE_SET3 0x03
18 | #define GET_SCAN_CODE_SET 0x00
19 |
20 | #define TYPEMATICDELAY_SET01 0x01
21 | #define TYPEMATICDELAY_SET02 0x02
22 | #define TYPEMATICDELEY_SET11 0x0B
23 |
24 | #define PORTMAP_KEYBOARD1 0x60
25 | #define PORTMAP_KEYBOARD2 0x64
26 |
27 | //keyled
28 | #define SET_CAPSLOCK_LED 0x04
29 | #define SET_NUMLOCK_LED 0x02
30 | #define SET_SCROLLLOCK_LED 0x01
31 |
32 | //scan_code
33 | #define L_SHIFT 0x2A
34 | #define R_SHIFT 0x36
35 | #define CAPS_LOCK 0x3A
36 | #define NUM_LOCK 0x45
37 | #define SCROLL_LOCK 0x46
38 |
39 | typedef struct{
40 | uint8_t pdata[128];
41 | size_t write;
42 | size_t read;
43 | size_t len;
44 | }key_buf;
45 |
46 | typedef struct{
47 | uint8_t base[0x80];
48 | uint8_t shift[0x80];
49 | uint8_t numlock[0x80];
50 | }keymap;
51 |
52 | typedef struct{
53 | bool shift_enable:1;
54 | bool relese_enable:1;
55 | bool caps_lock:1;
56 | bool num_lock:1;
57 | bool scr_lock:1;
58 | uint8_t led_stat;
59 | }kb_stat;
60 |
61 | kb_stat ks;
62 | const keymap key_code;
63 | bool ext_input;
64 |
65 | void key_init(void);
66 | uint8_t ps2_kerboard_init(void);
67 | void keyboard_input_int(uint8_t);
68 | void switch_kb_led(uint8_t);
69 | uint8_t enable_keyboard(void);
70 | uint8_t getscode(void);
71 | uint8_t getscodeset(void);
72 | void change_codeset(uint8_t);
73 | void change_trate_delay(uint8_t);
74 | void input_bufdata(uint8_t);
75 |
76 | #endif _KEYBOARD_H_
77 |
--------------------------------------------------------------------------------
/src/include/multiboot.h:
--------------------------------------------------------------------------------
1 | #ifndef _MULTIBOOT_H_
2 | #define _MULTIBOOT_H_
3 |
4 | #include
5 | #include
6 |
7 | typedef struct {
8 | uint32_t num;
9 | uint32_t size;
10 | uint32_t addr;
11 | uint32_t shndx;
12 | } multiboot_elf_section_header_table_t;
13 |
14 | typedef struct {
15 | uint32_t tab_size;
16 | uint32_t str_size;
17 | uint32_t addr;
18 | uint32_t reserved;
19 | } aout_symbol_table_t;
20 |
21 | typedef struct {
22 | uint32_t flag;
23 | uint32_t mem_lower;
24 | uint32_t mem_upper;
25 | uint32_t boot_device;
26 | uint32_t cmdline;
27 | uint32_t module_count;
28 | uint32_t module_addr;
29 |
30 | union {
31 | aout_symbol_table_t aout_sym;
32 | multiboot_elf_section_header_table_t elf_sec;
33 | } u;
34 |
35 | uint32_t mmap_length;
36 | uint32_t mmap_addr;
37 | } multiboot_info_t;
38 |
39 | typedef struct{
40 | uint32_t size;
41 | uint32_t base_addr_low;
42 | uint32_t base_addr_high;
43 | uint32_t length_low;
44 | uint32_t length_high;
45 | uint32_t type;
46 | } multiboot_memory_t;
47 |
48 | #endif _MULTIBOOT_H_
49 |
--------------------------------------------------------------------------------
/src/include/pic.h:
--------------------------------------------------------------------------------
1 | #ifndef _PIC_H_
2 | #define _PIC_H_
3 |
4 | #include
5 | #include "inb_outb.h"
6 |
7 | //PICマスター/スレーブのポートアドレス
8 | #define MASTER_PIC_CMD_STAT 0x20
9 | #define MASTER_PIC_MASK_DATA 0x21
10 | #define SLAVE_PIC_CMD_STAT 0xA0
11 | #define SLAVE_PIC_MASK_DATA 0xa1
12 |
13 | //ICWコマンド
14 | #define WRITE_ICW1 0x11
15 | #define WRITE_ICW2_M 0x20
16 | #define WRITE_ICW2_S 0x28
17 | #define WRITE_ICW3_M 0x04
18 | #define WRITE_ICW3_S 0x02
19 | #define WRITE_ICW4_X86MODE 0x01
20 | #define CLEAR_MASK 0xff
21 |
22 | //OCW1
23 | #define PIC_MASK_IRQ0 0x01
24 | #define PIC_MASK_IRQ1 0x02
25 | #define PIC_MASK_IRQ2 0x04
26 | #define PIC_MASK_IRQ3 0x08
27 | #define PIC_MASK_IRQ4 0x10
28 | #define PIC_MASK_IRQ5 0x20
29 | #define PIC_MASK_IRQ6 0x40
30 | #define PIC_MASK_IRQ7 0x80
31 | #define PIC_MASK_IRQA 0x00
32 |
33 | //EOI
34 | #define PIC_EOI 0x20
35 |
36 | void pic_init(void);
37 |
38 | #endif _PIC_H_
39 |
--------------------------------------------------------------------------------
/src/include/pmalloc.h:
--------------------------------------------------------------------------------
1 | #ifndef _PMALLOC_H_
2 | #define _PMALLOC_H_
3 |
4 | #include
5 | #include
6 |
7 | #include "init_pmemory.h"
8 | #include "../sh_libc/include/stdio.h"
9 |
10 | extern p_memory_info pm_info;
11 |
12 | int findfreememory(unsigned int*);
13 | void* malloc4kb(void);
14 | void free4kb(void*);
15 |
16 | #endif _PMALLOC_H_
17 |
--------------------------------------------------------------------------------
/src/include/syscall.h:
--------------------------------------------------------------------------------
1 | #ifndef _SYSCALL_H_
2 | #define _SYSCALL_H_
3 |
4 | #include
5 | #include "syscallnum.h"
6 |
7 | uint32_t syscall_interrupt(uint32_t, uint32_t, uint32_t,
8 | uint32_t, uint32_t, uint32_t);
9 |
10 | #endif _SYSCALL_H_
11 |
--------------------------------------------------------------------------------
/src/include/syscallnum.h:
--------------------------------------------------------------------------------
1 | #ifndef _SYSCALLNUM_H_
2 | #define _SYSCALLNUM_H_
3 |
4 | #define SYSCALL_WRITE 0
5 | #define SYSCALL_READ 1
6 |
7 | #endif _SYSCALLNUM_H_
8 |
--------------------------------------------------------------------------------
/src/include/terminal.h:
--------------------------------------------------------------------------------
1 | #ifndef _TERMINAL_H_
2 | #define _TERMINAL_H_
3 |
4 | #include
5 | #include
6 |
7 | static const size_t VGA_WIDTH = 80;
8 | static const size_t VGA_HEIGHT = 25;
9 | static size_t t_row;
10 | static size_t t_column;
11 | static uint8_t t_color;
12 | static uint16_t* t_buffer;
13 |
14 | void terminal_initialize(void);
15 | void terminal_setcolor(uint8_t);
16 | void terminal_putentryat(uint8_t, uint8_t, size_t, size_t);
17 | void terminal_uponerow(void);
18 | void terminal_putchar(uint8_t c);
19 | void terminal_write(const uint8_t*, size_t);
20 | void terminal_writestring(const uint8_t*);
21 |
22 | #endif _TERMINAL_H_
23 |
--------------------------------------------------------------------------------
/src/include/vga.h:
--------------------------------------------------------------------------------
1 | #ifndef _VGA_H_
2 | #define _VGA_H_
3 |
4 | #include
5 |
6 | enum vga_color {
7 | VGA_COLOR_BLACK = 0,
8 | VGA_COLOR_BLUE = 1,
9 | VGA_COLOR_GREEN = 2,
10 | VGA_COLOR_CYAN = 3,
11 | VGA_COLOR_RED = 4,
12 | VGA_COLOR_MAGENTA = 5,
13 | VGA_COLOR_BROWN = 6,
14 | VGA_COLOR_LIGHT_GREY = 7,
15 | VGA_COLOR_DARK_GREY = 8,
16 | VGA_COLOR_LIGHT_BLUE = 9,
17 | VGA_COLOR_LIGHT_GREEN = 10,
18 | VGA_COLOR_LIGHT_CYAN = 11,
19 | VGA_COLOR_LIGHT_RED = 12,
20 | VGA_COLOR_LIGHT_MAGENTA = 13,
21 | VGA_COLOR_LIGHT_BROWN = 14,
22 | VGA_COLOR_WHITE = 15,
23 | };
24 |
25 | static inline uint8_t vga_entry_color(enum vga_color fg, enum vga_color bg){
26 | return fg | bg << 4;
27 |
28 | }
29 |
30 |
31 |
32 | static inline uint16_t vga_entry(unsigned char uc, uint8_t color){
33 | return (uint16_t)uc | (uint16_t)color << 8;
34 |
35 | }
36 |
37 |
38 | #endif _VGA_H_
39 |
--------------------------------------------------------------------------------
/src/isodir/boot/grub/grub.cfg:
--------------------------------------------------------------------------------
1 | menuentry "myos" {
2 | multiboot /boot/myos.bin
3 | }
--------------------------------------------------------------------------------
/src/kernel/do_read.c:
--------------------------------------------------------------------------------
1 | #include "../include/do_read.h"
2 |
3 | size_t do_read(int fd, void* buffer, size_t byte){
4 | if (!byte) { return 0;}
5 | if (fd < 0) { return -1; }
6 | if (buffer == NULL) { return -1; }
7 |
8 | sh_printf("sh_read() ok\n");
9 | #
10 |
11 | return byte;
12 | }
13 |
--------------------------------------------------------------------------------
/src/kernel/do_write.c:
--------------------------------------------------------------------------------
1 | #include "../include/do_write.h"
2 |
3 | size_t do_write(int fd, const void* buffer, size_t byte){
4 | if (!byte) { return 0;}
5 | if (fd < 0) { return -1; }
6 | if (buffer == NULL) { return -1; }
7 |
8 | #
9 |
10 | return byte;
11 | }
12 |
--------------------------------------------------------------------------------
/src/kernel/interrupt.c:
--------------------------------------------------------------------------------
1 | #include "../include/interrupt.h"
2 |
3 | void interrupt_done(void){
4 | outb(MASTER_PIC_CMD_STAT, PIC_EOI);
5 | outb(SLAVE_PIC_CMD_STAT, PIC_EOI);
6 | }
7 |
8 |
9 | void keyboard_interrupt(void){
10 | outb(MASTER_PIC_CMD_STAT, irq1);
11 | keyboard_input_int(sh_getchar());
12 | interrupt_done();
13 | }
14 |
--------------------------------------------------------------------------------
/src/kernel/interrupt.s:
--------------------------------------------------------------------------------
1 | .global as_keyboard_interrupt
2 | .global as_software_interrupt
3 |
4 | .extern keyboard_interrupt
5 | .extern syscall_interrupt
6 |
7 | as_keyboard_interrupt:
8 | push %es
9 | push %ds
10 | pushal
11 | mov %esp, %eax
12 | push %eax
13 | mov %ss, %ax
14 | mov %ax, %ds
15 | mov %ax, %es
16 | call keyboard_interrupt
17 | pop %eax
18 | popal
19 | pop %ds
20 | pop %es
21 | sti
22 | iretl
23 |
24 |
25 | as_software_interrupt:
26 | pushl %esp
27 | pushl %ebp
28 | pushl %esi
29 | pushl %edi
30 | pushl %edx
31 | pushl %ecx
32 | pushl %ebx
33 | pushl %eax
34 | call syscall_interrupt
35 | popl %eax
36 | popl %ebx
37 | popl %ecx
38 | popl %edx
39 | popl %edi
40 | popl %esi
41 | popl %ebp
42 | popl %esp
43 | iretl
44 |
45 |
--------------------------------------------------------------------------------
/src/kernel/kernel.c:
--------------------------------------------------------------------------------
1 | #include "../include/kernel.h"
2 |
3 | extern key_buf kb;
4 | extern size_t pmstr_len;
5 | size_t pmstr_len;
6 | static size_t i;
7 |
8 | void kernel_main(multiboot_info_t* mbt, uint32_t magic){
9 | terminal_initialize();
10 |
11 | //memory
12 | //init_pmemory(mbt, getmmap(mbt));
13 | //sh_printf("physical memory init... OK!\n");
14 | //init_vmemory();
15 | //sh_printf("virtual memory init... OK!\n");
16 |
17 | //multiboot
18 | sh_printf("multiboot magic number 0x%x\n", magic);
19 | getmmap(mbt);
20 |
21 | //cr0レジスタの値を確認
22 | uint32_t cr0_data;
23 | asm volatile(
24 | "pop %%eax \n"
25 | "mov %%cr0, %%eax \n"
26 | : "=a"(cr0_data) : : );
27 | sh_printf("cr0 registar=0x%x\n", cr0_data);
28 |
29 | gdt_init();
30 | pic_init();
31 | idt_init();
32 | key_init();
33 |
34 | sh_printf("Hello, kernel World! \n\n");
35 | prompt();
36 | }
37 |
38 |
39 | void prompt(void){
40 | int result = -1;
41 | char cmdline[1024];
42 | char *prompt_name = "prompt";
43 | pmstr_len = sh_strlen(prompt_name);
44 | sh_printf("\n%s> ", prompt_name);
45 |
46 | kb.len = 0;
47 | kb.write = 0;
48 | kb.read = 0;
49 | i = 0;
50 |
51 | for (;;) {
52 | if ((result = input_line(prompt_name, cmdline)) != -1) {
53 | if (i) {
54 | if (executing(cmdline) == -1) {
55 | sh_printf("\nCommand not found!");
56 | }
57 | }
58 | sh_printf("\n%s> ", prompt_name);
59 | result = -1;
60 | i = 0;
61 | }
62 | }
63 | }
64 |
65 |
66 | int input_line(char* prompt_name, char* cmdline){
67 | asm volatile("cli");
68 | if (!kb.len) {
69 | asm volatile("sti");
70 | } else {
71 | char c = kb.pdata[kb.read];
72 | --kb.len;
73 | ++kb.read;
74 | if (kb.read == 128) { kb.read = 0; }
75 | asm volatile("sti");
76 |
77 | if (c == '\n') {
78 | cmdline[i] = '\0';
79 | return 0;
80 | } else if (c == '\b') {
81 | cmdline[i] == '\0';
82 | if (i > 0) { --i; }
83 | } else {
84 | cmdline[i++] = c;
85 | }
86 | sh_printf("%c", c);
87 | }
88 | return -1;
89 | }
90 |
91 |
92 | int executing(char* cmdline){
93 | if (!sh_strcmp(cmdline, "clear")) {
94 | terminal_initialize();
95 | return 0;
96 | } else if (!sh_strcmp(cmdline, "reboot")){
97 | outb(0x64, 0xFE);
98 | return 0;
99 | } else {
100 | return -1;
101 | }
102 | }
103 |
--------------------------------------------------------------------------------
/src/kernel/syscall.c:
--------------------------------------------------------------------------------
1 | #include "../include/syscall.h"
2 | #include "../sh_libc/include/stdio.h"
3 |
4 | uint32_t syscall_interrupt(uint32_t syscall_num,
5 | uint32_t arg1,
6 | uint32_t arg2,
7 | uint32_t arg3,
8 | uint32_t arg4,
9 | uint32_t arg5){
10 | switch (syscall_num) {
11 | case SYSCALL_WRITE:
12 | return do_write(arg1, arg2, arg3);
13 | break;
14 | case SYSCALL_READ:
15 | return do_read(arg1, arg2, arg3);
16 | break;
17 | }
18 | return 0;
19 | }
20 |
--------------------------------------------------------------------------------
/src/linker.ld:
--------------------------------------------------------------------------------
1 | ENTRY(_loader)
2 | OUTPUT_FORMAT(elf32-i386)
3 |
4 | SECTIONS{
5 | . = 0xC0100000;
6 |
7 | .text ALIGN(4K) : AT(ADDR(.text) - 0xC0000000) {
8 | __kernel_start = .;
9 | *(.multiboot)
10 | *(.text)
11 | }
12 |
13 | .rodata ALIGN(4K) : AT(ADDR(.rodata) - 0xC0000000) {
14 | *(.rodata*)
15 | }
16 |
17 | .data ALIGN(4K) : AT(ADDR(.data) - 0xC0000000) {
18 | *(.data)
19 | }
20 |
21 | .bss ALIGN(4K) : AT(ADDR(.bss) - 0xC0000000) {
22 | *(COMMON)
23 | *(.bss)
24 | __kernel_end = .;
25 | }
26 | }
27 |
28 |
29 |
--------------------------------------------------------------------------------
/src/memory/get_ksize.c:
--------------------------------------------------------------------------------
1 | #include "../include/get_ksize.h"
2 |
3 | uint32_t get_ksize(void){
4 | return &__kernel_end - &__kernel_start;
5 | }
6 |
--------------------------------------------------------------------------------
/src/memory/get_mmap.c:
--------------------------------------------------------------------------------
1 | #include "../include/get_mmap.h"
2 |
3 | uint32_t getmmap(multiboot_info_t* mbt){
4 | multiboot_memory_t* mmap = mbt -> mmap_addr | VBASE;
5 |
6 | char type_str[32];
7 | uint32_t total_mem_size;
8 |
9 | sh_printf("\n\n================get memory map=====================\n");
10 |
11 | for (mmap; mmap < (mbt -> mmap_addr + mbt -> mmap_length | VBASE); mmap++) {
12 | switch (mmap -> type) {
13 | case 0x1:;
14 | sh_strcpy(type_str, "available RAM");
15 | break;
16 | case 0x2:;
17 | sh_strcpy(type_str, "reserved RAM");
18 | break;
19 | case 0x03:;
20 | sh_strcpy(type_str, "ACPI reclaimable RAM");
21 | break;
22 | case 0x04:;
23 | sh_strcpy(type_str, "ACPI non-volatile storage RAM");
24 | break;
25 | case 0x05:;
26 | sh_strcpy(type_str, "Usage prohibited RAM");
27 | break;
28 | }
29 |
30 | if (mmap -> base_addr_high == 0x0) {
31 | sh_printf("base_addr = 0x%x: ", mmap -> base_addr_low);
32 | } else {
33 | sh_printf("base_addr = 0x%x%08x: ", mmap -> base_addr_high, mmap -> base_addr_low);
34 | }
35 |
36 | if (mmap -> length_high == 0x0) {
37 | sh_printf("length = 0x%x: ", mmap -> length_low);
38 | } else {
39 | sh_printf("length = 0x%x%08x: ", mmap -> length_high, mmap -> length_low);
40 | }
41 | sh_printf("type = %s\n", type_str);
42 |
43 | }
44 |
45 |
46 | total_mem_size = (mbt -> mem_lower + mbt -> mem_upper + 1024) / 1024;
47 | sh_printf("Total memory %dMB\n", total_mem_size);
48 | sh_printf("===================================================\n\n");
49 |
50 | return total_mem_size;
51 | }
52 |
--------------------------------------------------------------------------------
/src/memory/init_pmemory.c:
--------------------------------------------------------------------------------
1 | #include "../include/init_pmemory.h"
2 |
3 | void get_system_mblocks(uint32_t msize){
4 | pm_info.system_msize = msize;
5 | pm_info.system_mbloks = msize / 4096;
6 | pm_info.allocated_blocks = pm_info.system_mbloks;
7 | pm_info.free_blocks = 0;
8 | pm_info.mmap = &__kernel_end;
9 | pm_info.mmap_size = pm_info.system_mbloks / sizeof(uint32_t) * 8;
10 | sh_memset((void *)pm_info.mmap, 0xff, pm_info.mmap_size);
11 | }
12 |
13 |
14 | void setmemory(int bnum){
15 | pm_info.mmap[bnum / 32] |= (1 << (bnum % 32));
16 | }
17 |
18 |
19 | void clearmemory(int bnum){
20 | pm_info.mmap[bnum / 32] &= ~(1 << (bnum % 32));
21 | }
22 |
23 |
24 | void pbitmap_free(uint32_t address, uint32_t size){
25 | address /= 4096;
26 | size /= 4096;
27 |
28 | for (size_t i = address; i <= size; i++) {
29 | clearmemory(address);
30 | address++;
31 | pm_info.allocated_blocks--;
32 | pm_info.free_blocks++;
33 | }
34 | }
35 |
36 |
37 | void pbitmap_alloc(uint32_t address, uint32_t size){
38 | address /= 4096;
39 | size = (size / 4096) == 0 ? 1 : size / 4096;
40 |
41 | for (size_t i = address; i <= size; i++) {
42 | setmemory(address);
43 | address++;
44 | pm_info.allocated_blocks++;
45 | pm_info.free_blocks--;
46 | }
47 | }
48 |
49 |
50 | void init_pmemory(multiboot_info_t *mbt, uint32_t total_msize){
51 | uint32_t send_addr;
52 | uint32_t send_length;
53 | multiboot_memory_t* mmap = mbt -> mmap_addr | VBASE;
54 |
55 | get_system_mblocks(total_msize * 1024 * 1024);
56 |
57 | for (mmap; mmap < (mbt -> mmap_addr + mbt -> mmap_length | VBASE); mmap++) {
58 | send_addr = (mmap -> base_addr_high << 8) | mmap -> base_addr_low;
59 | send_length = (mmap -> length_high << 8 ) | mmap -> length_low;
60 |
61 | if (mmap -> type == 0x1 || mmap -> type == 0x3) {
62 | if (send_addr == &__kernel_start) {
63 | pbitmap_alloc(send_addr, get_ksize() + pm_info.mmap_size);
64 | pbitmap_free(&__kernel_end, send_length - (get_ksize() + pm_info.mmap_size));
65 | } else {
66 | pbitmap_free(send_addr, send_length);
67 | }
68 | } else {
69 | pbitmap_alloc(send_addr, send_length);
70 | }
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/src/memory/init_vmemory.c:
--------------------------------------------------------------------------------
1 |
2 | #include "../include/init_vmemory.h"
3 |
4 | int init_paging(void){
5 | page_dir_entry* page_directory = (page_dir_entry*)malloc4kb();
6 | page_table_entry* page_table = (page_table_entry*)malloc4kb();
7 |
8 | for (size_t i = 0, address = 0x0; i < 1024; i++, address += 0x1000) {
9 | page_directory[i] = PE_RWFLAG;
10 | page_table[i] = address | (PE_RWFLAG | PE_PFLAG);
11 | }
12 |
13 | page_directory[0] = (page_dir_entry)page_table | (PE_RWFLAG | PE_PFLAG);
14 | enable_paging(page_directory);
15 |
16 | return 0;
17 | }
18 |
19 |
20 | int init_vmemory(void){
21 | if (!init_paging()) {
22 | sh_printf("Initialize paging init... OK!\n");
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/memory/paging.s:
--------------------------------------------------------------------------------
1 | .text
2 | .global enable_paging
3 |
4 | enable_paging:
5 | push %ebp
6 | mov %esp, %ebp
7 |
8 | //writing cr3
9 | mov 8(%esp), %eax
10 | mov %eax, %cr3
11 |
12 | //writing cr0
13 | mov %cr0, %eax
14 | or $0x80000000, %eax
15 | mov %eax, %cr0
16 |
17 | mov %ebp, %esp
18 | pop %ebp
19 | ret
20 |
--------------------------------------------------------------------------------
/src/memory/pmalloc.c:
--------------------------------------------------------------------------------
1 | #include "../include/pmalloc.h"
2 |
3 | int findfreememory(unsigned int *bnum){
4 | for (size_t b_index = 0; b_index < pm_info.mmap_size; b_index++) {
5 | if (pm_info.mmap[b_index] != 0xFFFFFFFF) {
6 | for (size_t b_count = 0; b_count < 32; b_count++) {
7 | if (!(pm_info.mmap[b_index] & (1 << (b_count % 32)))) {
8 | *bnum = b_index * sizeof(unsigned int) * 8 + b_count;
9 | return 0;
10 | }
11 | }
12 | }
13 | }
14 | return -1;
15 | }
16 |
17 |
18 | void* malloc4kb(void){
19 | unsigned int b_number;
20 | void* p_address;
21 | int status;
22 | if (pm_info.free_blocks <= 0) { return NULL; }
23 | if (findfreememory(&b_number)) { return NULL; }
24 | setmemory(b_number);
25 |
26 | p_address = (void *)(b_number * 4096);
27 |
28 | pm_info.allocated_blocks++;
29 | pm_info.free_blocks--;
30 |
31 | return p_address;
32 | }
33 |
34 |
35 | void free4kb(void* p_address){
36 | unsigned int b_number;
37 | b_number = (unsigned int)p_address / 4096;
38 |
39 | clearmemory(b_number);
40 |
41 | pm_info.allocated_blocks--;
42 | pm_info.free_blocks++;
43 | }
44 |
--------------------------------------------------------------------------------
/src/sh_libc/include/io.h:
--------------------------------------------------------------------------------
1 | #ifndef _IO_H_
2 | #define _IO_H_
3 |
4 | #include
5 | #include "../../include/syscall.h"
6 | #include "sysdep.h"
7 |
8 | size_t sh_write(int, const void*, size_t);
9 | size_t sh_read(int, void*, size_t);
10 |
11 | #endif _IO_H_
12 |
--------------------------------------------------------------------------------
/src/sh_libc/include/math.h:
--------------------------------------------------------------------------------
1 | #ifndef _MATH_H_
2 | #define _MATH_H_
3 |
4 | #include
5 |
6 | double sh_pow(double, double);
7 |
8 | #endif _MATH_H_
9 |
--------------------------------------------------------------------------------
/src/sh_libc/include/stdio.h:
--------------------------------------------------------------------------------
1 | #ifndef _STDIO_H_
2 | #define _STDIO_H_
3 |
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 |
10 | #include "../../include/terminal.h"
11 |
12 | bool PRINTF_LEN_FLAG;
13 |
14 | #define NULL ((void *)0)
15 |
16 | int sh_printf(const unsigned char*, ...);
17 | int sh_vprintf(const unsigned char*, va_list);
18 | void numeral_formatting(int, int, int);
19 | static bool print(const unsigned char*, size_t);
20 | int sh_putchar(int);
21 | unsigned char sh_getchar(void);
22 |
23 | #endif _STDIO_H_
24 |
--------------------------------------------------------------------------------
/src/sh_libc/include/stdlib.h:
--------------------------------------------------------------------------------
1 | #ifndef _STDLIB_H_
2 | #define _STDLIB_H_
3 |
4 | #include
5 |
6 | void sh_itoa(unsigned long, unsigned char*, unsigned int);
7 |
8 | #endif _STDLIB_H_
9 |
--------------------------------------------------------------------------------
/src/sh_libc/include/string.h:
--------------------------------------------------------------------------------
1 | #ifndef _STRING_H_
2 | #define _STRING_H_
3 |
4 | #include
5 | #include
6 |
7 | size_t sh_strlen(const uint8_t*);
8 | void sh_strrev(unsigned char*);
9 | char* sh_strcpy(char*, const char*);
10 | char* sh_strcat(char*, const char*);
11 | int sh_strcmp(const char*, const char*);
12 | void* sh_memcpy(void* restrict, const void* restrict, size_t);
13 | void* sh_memset(void *, int, size_t);
14 |
15 | #endif _STRING_H_
16 |
--------------------------------------------------------------------------------
/src/sh_libc/include/sysdep.h:
--------------------------------------------------------------------------------
1 | #ifndef _SYSDEP_H_
2 | #define _SYSDEP_H_
3 |
4 | #include
5 |
6 | #define GET_MACRO(_1, _2, _3, _4, _5, _6, NAME, ...) NAME
7 | #define system_call(...) GET_MACRO(__VA_ARGS__, system_call5, system_call4, system_call3, \
8 | system_call2, system_call1)(__VA_ARGS__)
9 |
10 | uint32_t system_call5(uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t);
11 | uint32_t system_call4(uint32_t, uint32_t, uint32_t, uint32_t, uint32_t);
12 | uint32_t system_call3(uint32_t, uint32_t, uint32_t, uint32_t);
13 | uint32_t system_call2(uint32_t, uint32_t, uint32_t);
14 | uint32_t system_call1(uint32_t, uint32_t);
15 |
16 | #endif _SYSDEP_H_
17 |
--------------------------------------------------------------------------------
/src/sh_libc/io.c:
--------------------------------------------------------------------------------
1 | #include "include/io.h"
2 |
3 | size_t sh_write(int fd, const void* buffer, size_t byte){
4 | return system_call(SYSCALL_WRITE, fd, buffer, byte);
5 | }
6 |
7 | size_t sh_read(int fd, void* buffer, size_t byte){
8 | return system_call(SYSCALL_READ, fd, buffer, byte);
9 | }
10 |
--------------------------------------------------------------------------------
/src/sh_libc/math.c:
--------------------------------------------------------------------------------
1 | #include "include/math.h"
2 |
3 | double sh_pow(double x, double y){
4 | int i = 1;
5 | int j = 1;
6 | double p = 1;
7 |
8 | if (!y) { return 1; }
9 |
10 | if (y > 0) {
11 | while (i <= y) {
12 | p *= x;
13 | ++i;
14 | }
15 | return p;
16 | }
17 |
18 | if (y < 0) {
19 | y = - y;
20 | while (j <= y) {
21 | p *= x;
22 | ++j;
23 | }
24 | }
25 | return (1 / p);
26 | }
27 |
--------------------------------------------------------------------------------
/src/sh_libc/stdio.c:
--------------------------------------------------------------------------------
1 | #include "include/stdio.h"
2 |
3 | int sh_printf(const unsigned char* format, ...){
4 | va_list parameter;
5 | va_start(parameter, format);
6 | sh_vprintf(format, parameter);
7 | va_end(format);
8 | return 0;
9 | }
10 |
11 |
12 | int sh_vprintf(const unsigned char* format, va_list parameter){
13 | unsigned long num = 0;
14 | size_t amount = 0;
15 |
16 | while (*format != '\0') {
17 | if (format[0] != '%' || format[1] == '%') {
18 | if (format[0] == '%') { ++format; }
19 | amount = 1;
20 | while (format[amount] && format[amount] != '%') { ++amount; }
21 | if (!print(format, amount)) { return -1; }
22 | format += amount;
23 | continue;
24 | }
25 |
26 | const char* format_begun_at = format++;
27 | unsigned int length = 0;
28 |
29 | //length
30 | if (*format == '0'){
31 | PRINTF_LEN_FLAG = true;
32 | format++;
33 | while(*format >= '0' && *format <= '9'){
34 | length = (length * 10) + (*format - '0');
35 | format++;
36 | }
37 | }
38 |
39 | //type
40 | switch (*format) {
41 | case 's':
42 | ++format;
43 | const char* string = va_arg(parameter, const char*);
44 | if (!print(string, sh_strlen(string))) { return -1; }
45 | break;
46 |
47 | case 'c':
48 | ++format;
49 | unsigned char chardata[2];
50 | chardata[0] = (char)va_arg(parameter, int);
51 | chardata[1] = '\0';
52 | if (!print(chardata, sh_strlen(chardata))) { return -1; }
53 | break;
54 |
55 | case 'i':
56 | case 'd':
57 | ++format;
58 | num = va_arg(parameter, int);
59 | numeral_formatting(num, length, 10);
60 | break;
61 |
62 | case 'x':
63 | ++format;
64 | num = va_arg(parameter, unsigned long);
65 | numeral_formatting(num, length, 16);
66 | break;
67 |
68 | default:
69 | format = format_begun_at;
70 | if (!print(format, sh_strlen(format))) { return -1; }
71 | format += sh_strlen(format);
72 | }
73 | num = 0;
74 | }
75 | return 0;
76 |
77 | }
78 |
79 |
80 | void numeral_formatting(int num, int length, int redix){
81 | char pading[255];
82 | unsigned char data[255];
83 | pading[length - 1] = '\0';
84 | sh_itoa(num, data, redix);
85 | if (PRINTF_LEN_FLAG && sh_strlen(data) - 1 < length) {
86 | for (int i = 0; i < length - sh_strlen(data); i++) {
87 | pading[i] = '0';
88 | }
89 | sh_strcat(pading, data);
90 | if (!print(pading, sh_strlen(pading))) { return -1; }
91 | PRINTF_LEN_FLAG = false;
92 | } else {
93 | if (!print(data, sh_strlen(data))) { return -1; }
94 | }
95 | }
96 |
97 |
98 | static bool print(const unsigned char* data, size_t length){
99 | const unsigned char* bytes = (const unsigned char*) data;
100 | for (size_t i = 0; i < length; i++) {
101 | if (sh_putchar(bytes[i]) == '\0') { return false; }
102 | }
103 | return true;
104 | }
105 |
106 |
107 | int sh_putchar(int intchar){
108 | char ch = (char) intchar;
109 | terminal_write(&ch, sizeof(ch));
110 | return intchar;
111 | }
112 |
113 |
114 | unsigned char sh_getchar(void){
115 | return getscode();
116 | }
117 |
--------------------------------------------------------------------------------
/src/sh_libc/stdlib.c:
--------------------------------------------------------------------------------
1 | #include "include/stdlib.h"
2 |
3 | void sh_itoa(unsigned long data, unsigned char* str, unsigned int base){
4 | size_t i = 0;
5 | unsigned long num = data;
6 | unsigned long copynum = data;
7 | unsigned long lorder;
8 | do {
9 | if(base == 16) {
10 | lorder = num & 0xF;
11 | num >>= 4;
12 | } else {
13 | lorder = num;
14 | copynum >>= 27;
15 | }
16 | copynum >>= 4;
17 | do {
18 | data = lorder % base;
19 | if (data < 0x0A) {
20 | str[i++] = '0' + data;
21 | } else {
22 | str[i++] = 'A' + data - 0x0A;
23 | }
24 | lorder /= base;
25 | } while (lorder);
26 | } while (copynum);
27 | str[i] = '\0';
28 |
29 | sh_strrev(str);
30 | }
31 |
--------------------------------------------------------------------------------
/src/sh_libc/string.c:
--------------------------------------------------------------------------------
1 | #include "include/string.h"
2 |
3 | size_t sh_strlen(const uint8_t* str){
4 | size_t len = 0;
5 | while (str[len]) { ++len; }
6 | return len;
7 | }
8 |
9 |
10 | void sh_strrev(unsigned char* str){
11 | unsigned char tmp;
12 | size_t len = sh_strlen(str);
13 | for (size_t i = 0, j = len - 1; i < j; i++, j--) {
14 | tmp = str[i];
15 | str[i] = str[j];
16 | str[j] = tmp;
17 | }
18 | }
19 |
20 |
21 | char* sh_strcpy(char *dest, const char *src){
22 | return sh_memcpy(dest, src, sh_strlen(src) + 1);
23 | }
24 |
25 |
26 |
27 | char* sh_strcat(char *s1, const char *s2){
28 | size_t i = 0, j = 0;
29 | for (i = 0; s1[i] != '\0'; i++);
30 | for (j = 0; s2[j] != '\0'; j++) {
31 | s1[i + j] = s2[j];
32 | }
33 | s1[i + j] = '\0';
34 | return s1;
35 | }
36 |
37 |
38 | int sh_strcmp(const char* s1, const char* s2){
39 | const unsigned char *p1 = (const unsigned char *)s1;
40 | const unsigned char *p2 = (const unsigned char *)s2;
41 | unsigned char c1, c2;
42 | do {
43 | c1 = (unsigned char)*p1++;
44 | c2 = (unsigned char)*p2++;
45 | if (c1 == '\0') { return c1 - c2; }
46 | } while (c1 == c2);
47 | return c1 - c2;
48 | }
49 |
50 |
51 | void* sh_memcpy(void* restrict dst_ptr,
52 | const void* restrict src_ptr,
53 | size_t size){
54 | unsigned char* dst = (unsigned char*)dst_ptr;
55 | const unsigned char* src = (const unsigned char*)src_ptr;
56 | for (size_t i = 0; i < size; i++) { dst[i] = src[i]; }
57 | return dst_ptr;
58 | }
59 |
60 |
61 | void* sh_memset(void *s, int c, size_t n){
62 | unsigned char* ptr = (unsigned char *)s;
63 | if (n) {
64 | while (n-- > 0) { *ptr++ = c; }
65 | }
66 | return s;
67 | }
68 |
--------------------------------------------------------------------------------
/src/sh_libc/sysdep.c:
--------------------------------------------------------------------------------
1 | #include "include/sysdep.h"
2 |
3 | uint32_t system_call5(uint32_t syscall_num, uint32_t arg1, uint32_t arg2,
4 | uint32_t arg3, uint32_t arg4, uint32_t arg5){
5 | uint32_t ret;
6 | asm volatile("\tint $0x80\n"
7 | :"=a"(ret)
8 | : "a"(syscall_num), "b"(arg1), "c"(arg2), "d"(arg3), "D"(arg4), \
9 | "S"(arg5));
10 | return ret;
11 | }
12 |
13 |
14 | uint32_t system_call4(uint32_t syscall_num, uint32_t arg1, uint32_t arg2,
15 | uint32_t arg3, uint32_t arg4){
16 | uint32_t ret;
17 | asm volatile("\tint $0x80\n"
18 | :"=a"(ret)
19 | : "a"(syscall_num), "b"(arg1), "c"(arg2), "d"(arg3), "D"(arg4));
20 | return ret;
21 | }
22 |
23 |
24 | uint32_t system_call3(uint32_t syscall_num, uint32_t arg1, uint32_t arg2,
25 | uint32_t arg3){
26 | uint32_t ret;
27 | asm volatile("\tint $0x80\n"
28 | :"=a"(ret)
29 | : "a"(syscall_num), "b"(arg1), "c"(arg2), "d"(arg3));
30 | return ret;
31 | }
32 |
33 |
34 | uint32_t system_call2(uint32_t syscall_num, uint32_t arg1, uint32_t arg2){
35 | uint32_t ret;
36 | asm volatile("\tint $0x80\n"
37 | :"=a"(ret)
38 | : "a"(syscall_num), "b"(arg1), "c"(arg2));
39 | return ret;
40 | }
41 |
42 |
43 | uint32_t system_call1(uint32_t syscall_num, uint32_t arg1){
44 | uint32_t ret;
45 | asm volatile("\tint $0x80\n"
46 | :"=a"(ret)
47 | : "a"(syscall_num), "b"(arg1));
48 | return ret;
49 | }
50 |
--------------------------------------------------------------------------------