]> Zhao Yanbai Git Server - kernel.git/commitdiff
import the kernel code to use the new repository with some modifies: 1. add install...
authorAceVest <zhaoyanbai@126.com>
Wed, 2 Apr 2014 16:39:24 +0000 (00:39 +0800)
committerAceVest <zhaoyanbai@126.com>
Wed, 2 Apr 2014 16:39:24 +0000 (00:39 +0800)
112 files changed:
LICENSE [new file with mode: 0644]
Makefile [new file with mode: 0644]
README [new file with mode: 0644]
bin/Makefile [new file with mode: 0644]
bin/helloworld.S [new file with mode: 0644]
bin/helloworld.c [new file with mode: 0644]
bin/shell.S [new file with mode: 0644]
bin/shell.c [new file with mode: 0644]
boot/Makefile [new file with mode: 0644]
boot/boot.c [new file with mode: 0644]
boot/cmdline.c [new file with mode: 0644]
boot/multiboot.S [new file with mode: 0644]
boot/reboot.S [new file with mode: 0644]
copy.sh [new file with mode: 0755]
drivers/Makefile [new file with mode: 0644]
drivers/hd.c [new file with mode: 0644]
drivers/hd.h [new file with mode: 0644]
drivers/keyboard.c [new file with mode: 0644]
drivers/keyboard.c.bake [new file with mode: 0644]
drivers/vga.c [new file with mode: 0644]
fs/Makefile [new file with mode: 0644]
fs/ext2.c [new file with mode: 0644]
fs/fs.c [new file with mode: 0644]
fs/open.c [new file with mode: 0644]
fs/read.c [new file with mode: 0644]
fs/stat.c [new file with mode: 0644]
fs/write.c [new file with mode: 0644]
include/assert.h [new file with mode: 0644]
include/bits.h [new file with mode: 0644]
include/boot/bootparam.h [new file with mode: 0644]
include/boot/multiboot.h [new file with mode: 0644]
include/elf.h [new file with mode: 0644]
include/errno.h [new file with mode: 0644]
include/ext2.h [new file with mode: 0644]
include/fcntl.h [new file with mode: 0644]
include/fs.h [new file with mode: 0644]
include/global.h [new file with mode: 0644]
include/i8259.h [new file with mode: 0644]
include/init.h [new file with mode: 0644]
include/io.h [new file with mode: 0644]
include/irq.h [new file with mode: 0644]
include/linkage.h [new file with mode: 0644]
include/list.h [new file with mode: 0644]
include/mm.h [new file with mode: 0644]
include/msr.h [new file with mode: 0644]
include/page.h [new file with mode: 0644]
include/pci.h [new file with mode: 0644]
include/printk.h [new file with mode: 0644]
include/processor.h [new file with mode: 0644]
include/sched.h [new file with mode: 0644]
include/stat.h [new file with mode: 0644]
include/stdio.h [new file with mode: 0644]
include/stdlib.h [new file with mode: 0644]
include/string.h [new file with mode: 0644]
include/syscall.h [new file with mode: 0644]
include/system.h [new file with mode: 0644]
include/task.h [new file with mode: 0644]
include/types.h [new file with mode: 0644]
include/unistd.h [new file with mode: 0644]
include/wait.h [new file with mode: 0644]
kernel.mk [new file with mode: 0644]
kernel/Makefile [new file with mode: 0644]
kernel/clock.c [new file with mode: 0644]
kernel/entry.S [new file with mode: 0644]
kernel/exec.c [new file with mode: 0644]
kernel/exit.c [new file with mode: 0644]
kernel/fork.c [new file with mode: 0644]
kernel/i8259.c [new file with mode: 0644]
kernel/init.c [new file with mode: 0644]
kernel/innerint.c [new file with mode: 0644]
kernel/interrupts.S [new file with mode: 0644]
kernel/irq.c [new file with mode: 0644]
kernel/printk.c [new file with mode: 0644]
kernel/processor.c [new file with mode: 0644]
kernel/sched.c [new file with mode: 0644]
kernel/syscall.S [new file with mode: 0644]
kernel/syscall.c [new file with mode: 0644]
kernel/system.c [new file with mode: 0644]
kernel/test.c [new file with mode: 0644]
kernel/test_task.c [new file with mode: 0644]
kernel/wait.c [new file with mode: 0644]
lib/Makefile [new file with mode: 0644]
lib/assert.c [new file with mode: 0644]
lib/errno.c [new file with mode: 0644]
lib/exec.c [new file with mode: 0644]
lib/exit.c [new file with mode: 0644]
lib/fork.c [new file with mode: 0644]
lib/keyboard.c [new file with mode: 0644]
lib/lib.c [new file with mode: 0644]
lib/open.c [new file with mode: 0644]
lib/read.c [new file with mode: 0644]
lib/stat.c [new file with mode: 0644]
lib/string.c [new file with mode: 0644]
lib/vsprintf.c [new file with mode: 0644]
lib/write.c [new file with mode: 0644]
mm/Makefile [new file with mode: 0644]
mm/kmalloc.c [new file with mode: 0644]
mm/mm.c [new file with mode: 0644]
mm/page.c [new file with mode: 0644]
pci/Makefile [new file with mode: 0644]
pci/setuppci.c [new file with mode: 0644]
scripts/bochscompile [new file with mode: 0644]
scripts/grub.cfg [new file with mode: 0644]
scripts/init.sh [new file with mode: 0755]
scripts/link.ld [new file with mode: 0644]
scripts/mnthd.sh [new file with mode: 0755]
setup/Makefile [new file with mode: 0644]
setup/cpuid.c [new file with mode: 0644]
setup/logo.c [new file with mode: 0644]
setup/setup.c [new file with mode: 0644]
setup/system.c [new file with mode: 0644]
setup/version.c [new file with mode: 0644]

diff --git a/LICENSE b/LICENSE
new file mode 100644 (file)
index 0000000..22fbe5d
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,339 @@
+GNU GENERAL PUBLIC LICENSE
+                       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc., <http://fsf.org/>
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+                            NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    {description}
+    Copyright (C) {year}  {fullname}
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  {signature of Ty Coon}, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
\ No newline at end of file
diff --git a/Makefile b/Makefile
new file mode 100644 (file)
index 0000000..5009e7f
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,45 @@
+############################################################################
+CF             = -c -I include -fno-builtin
+CC             = $(_CC) $(CF) -o
+SYSTEMMAP      = System.map
+KERNELBIN      = KERNEL.BIN
+LINKSCRIPT     = scripts/link.ld
+OBJS = boot/multiboot.S.o boot/boot.o boot/reboot.S.o  boot/cmdline.o\
+       setup/*.o mm/*.o kernel/*.o fs/*.o pci/*.o lib/*.o \
+       drivers/*.o
+#BINS#######################################################################
+$(KERNELBIN):
+       cd boot && make
+       cd setup && make
+       cd mm && make
+       cd kernel && make
+       cd fs && make
+       cd pci && make
+       cd lib && make
+       cd drivers && make
+       ld -M -T$(LINKSCRIPT) -o $@ $(OBJS) > $(SYSTEMMAP)
+       ld -T$(LINKSCRIPT) -o $@ $(OBJS)
+       cd bin && make
+       md5sum $(KERNELBIN)
+       #./scripts/grub2-debug.sh
+       #mv $@ KRNL.ELF
+.PHONY:real
+real:
+
+.PHONY:clean
+clean:
+       cd boot && make clean
+       cd setup && make clean
+       cd mm && make clean
+       cd kernel && make clean
+       cd fs && make clean
+       cd pci && make clean
+       cd lib && make clean
+       cd drivers && make clean
+       cd bin && make clean
+       rm -f $(KERNELBIN) System.map snapshot.txt log.txt
+       rm -f KRNL.ELF
+
+.PHONY:copy
+copy:
+       ./copy.sh
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..19ba022
--- /dev/null
+++ b/README
@@ -0,0 +1,10 @@
+kernel
+======
+
+I can't find a satisfactory name for my kernel.
+
+### HOW TO GET THE LATEST SOURCECODE?
+    git clone https://github.com/acevest/kernel
+### WHEN DID YOU START TO DO THIS WORK?
+    Maybe 2006.12
+### HOW TO COMPILE THIS KERNEL?
diff --git a/bin/Makefile b/bin/Makefile
new file mode 100644 (file)
index 0000000..12a8eee
--- /dev/null
@@ -0,0 +1,20 @@
+CC = gcc
+CFLAGS = -c -I../include -fno-builtin
+LDOBJS = ../lib/errno.o ../lib/fork.o ../lib/lib.o ../lib/open.o \
+       ../lib/stat.o ../lib/string.o ../lib/write.o ../lib/exec.o \
+       ../lib/vsprintf.o ../lib/read.o \
+       ../lib/keyboard.o ../lib/exit.o
+all:
+       gcc -c shell.S -o shell.S.o
+       gcc $(CFLAGS) shell.c -o shell.o
+       ld $(LDOBJS) shell.S.o shell.o -o sh
+       gcc -c helloworld.S -o helloworld.S.o
+       gcc $(CFLAGS) helloworld.c -o helloworld.o
+       ld $(LDOBJS) helloworld.S.o helloworld.o -o hw 
+
+.PHONY:clean
+clean:
+       rm sh hw helloworld.o -f
+.PHONY:c
+c:
+       make clean
diff --git a/bin/helloworld.S b/bin/helloworld.S
new file mode 100644 (file)
index 0000000..1e469e8
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:        helloworld.S
+ * 
+ *      Author:        Zhao Yanbai [zhaoyanbai@126.com]
+ *                     Tue Feb 23 20:15:27 2010
+ * 
+ * Description:        none
+ * 
+ *--------------------------------------------------------------------------
+ */
+#define        ASM
+#include<syscall.h>
+.global        _start
+_start:
+       nop
+       nop
+       nop
+       #xchg %bx, %bx
+loop:
+       #jmp    loop
+       call    hw
+       
+       nop
+       nop
+       nop
+       nop
+       nop
+die:
+       jmp     die
diff --git a/bin/helloworld.c b/bin/helloworld.c
new file mode 100644 (file)
index 0000000..a204a65
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:        helloworld.c
+ * 
+ *      Author:        Zhao Yanbai [zhaoyanbai@126.com]
+ *                     Tue Feb 23 22:44:40 2010
+ * 
+ * Description:        none
+ * 
+ *--------------------------------------------------------------------------
+ */
+#include<unistd.h>
+#include<stdio.h>
+
+int hw()
+{
+       printf("hello world\n");
+       //syscall3(SYSC_WRITE, 0, "fuck", 5);
+       //write(0, "hello world", sizeof("hello world"));
+       //write(0, "hello world", 12);
+       
+       exit(0);
+
+       return 0;
+}
diff --git a/bin/shell.S b/bin/shell.S
new file mode 100644 (file)
index 0000000..fe91cbe
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:        shell.S
+ * 
+ *      Author:        Zhao Yanbai [zhaoyanbai@126.com]
+ *                     Wed Feb 24 17:47:27 2010
+ * 
+ * Description:        none
+ * 
+ *--------------------------------------------------------------------------
+ */
+.global        _start
+_start:
+       nop
+       nop
+       nop
+loop:
+       #jmp    loop
+       call    shell
+       nop
+       nop
+       nop
+       nop
+       nop
+       nop
+       nop
+       nop
+die:
+       jmp     die
diff --git a/bin/shell.c b/bin/shell.c
new file mode 100644 (file)
index 0000000..a14e736
--- /dev/null
@@ -0,0 +1,153 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:        shell.c
+ * 
+ *      Author:        Zhao Yanbai [zhaoyanbai@126.com]
+ *                     Wed Feb 24 17:47:22 2010
+ * 
+ * Description:        none
+ * 
+ *--------------------------------------------------------------------------
+ */
+#include<stdio.h>
+#include<types.h>
+#include<string.h>
+#define        CMD_SIZE        256
+char cmd[CMD_SIZE];
+
+void get_cmd()
+{
+       int i;
+
+       i=0;
+       printf("#");
+       while(1)
+       {
+               int k;
+               char ch;
+               extern char ParseKbdInput(int k);
+               extern unsigned char read_kbd();
+reinput:
+               k = read_kbd();
+               ch = ParseKbdInput(k);
+               if(ch == -1)
+                       continue;
+               
+               if(ch == '\b')
+               {
+            i = --i < 0 ? 0 : i;
+                       cmd[i] = 0;
+                       continue;
+               }
+
+               if(ch == '\n')
+               {
+                       cmd[i++] = 0;
+                       break;
+               }
+
+               cmd[i++] = ch;
+
+               if(i == CMD_SIZE - 1)
+               {
+                       printf("shell buffer is full..."
+                               "reset buffer...\n");
+                       i = 0;
+               }
+       }
+
+    int len = strlen(cmd);
+    int j;
+    int flag = 0;
+    for(j = len - 1; j>=0; j--) {
+        if(cmd[j] != '\n') {
+            flag = 1;
+            break;
+        }
+    }
+
+    if(flag == 0) {
+        i = 0;
+        goto reinput;
+    }
+
+       cmd[CMD_SIZE-1] = 0;
+}
+
+int shell()
+{
+       char buf[CMD_SIZE];
+
+       while(1)
+       {
+               get_cmd();
+
+               //printf("\nCMD: %s\n", cmd);
+
+               if(cmd[0] == 0) continue;
+               if(cmd[0] != '/')
+               {
+                       strcpy(buf, cmd);
+                       strcpy(cmd, "/bin/");
+                       strcat(cmd, buf);
+               }
+               
+               pid_t pid;
+               pid = fork();
+
+               if(pid<0)
+               {
+                       printf("shit happens in shell\n");
+                       while(1);
+               }
+               else if(pid == 0)
+               {
+                       execv(cmd, NULL);
+               }
+
+               int  i = 100000;
+               while(i--);
+       }
+
+
+
+       return 0;
+}
+
+#if 0
+int shell()
+{
+       pid_t pid;
+
+       pid = fork();
+
+       if(pid<0)
+       {
+               printf("shit happens in shell\n");
+               while(1);
+       }
+       else if(pid == 0)
+       {
+               execv("/bin/hw", NULL);
+       }
+       else
+       {
+
+               while(1)
+               {
+                       int k;
+                       char ch;
+                       extern char ParseKbdInput(int k);
+                       extern unsigned char read_kbd();
+                       //asm("xchg %bx, %bx");
+                       k = read_kbd();
+                       ch = ParseKbdInput(k);
+                       if(ch != -1)
+                       printf("<%c>",ch);
+               }
+       }
+
+
+       return 0;
+}
+#endif
diff --git a/boot/Makefile b/boot/Makefile
new file mode 100644 (file)
index 0000000..10ffe92
--- /dev/null
@@ -0,0 +1,23 @@
+include ../kernel.mk
+CC = gcc
+CFLAGS = $(CF)
+
+CSOUCE_FILES = $(wildcard *.c)
+SSOUCE_FILES = $(wildcard *.S)
+OBJS  = $(patsubst %.c,%.o,$(CSOUCE_FILES))
+OBJS += $(patsubst %.S,%.S.o,$(SSOUCE_FILES))
+
+%.o : %.c *.h ../include/*.h
+       $(CC) $(CFLAGS) $< -o $@
+%.S.o : %.S ../include/*.h
+       $(CC) $(CFLAGS) $< -o $@
+
+
+all:$(OBJS)
+
+.PHONY:clean
+clean:
+       $(RM) $(OBJS)
+.PHONY:c
+c:
+       make clean
diff --git a/boot/boot.c b/boot/boot.c
new file mode 100644 (file)
index 0000000..fe64161
--- /dev/null
@@ -0,0 +1,279 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:        boot.c
+ * 
+ *      Author:        Zhao Yanbai [zhaoyanbai@126.com]
+ *                     Wed Dec 30 21:55:29 2009
+ * 
+ * Description:        none
+ * 
+ *--------------------------------------------------------------------------
+ */
+
+
+#include<system.h>
+#include<boot/multiboot.h>
+#include<boot/bootparam.h>
+#include<page.h>
+#include<bits.h>
+#include<assert.h>
+
+extern void    parse_cmdline(const char *cmdline);
+void   init_free_area(u32 base, u32 len);
+
+
+struct boot_params boot_params __attribute__((aligned(32)));
+
+void init_boot_params(multiboot_info_t *p)
+{
+    boot_params.cmdline = (char *) p->cmdline;
+
+    // KB to Bytes
+    // no need to concern about 64bit
+    boot_params.mem_lower = p->mem_lower << 10;
+    boot_params.mem_upper = p->mem_upper << 10;
+
+    boot_params.boot_device = p->boot_device;
+
+    memory_map_t *mmap = (memory_map_t *) pa2va(p->mmap_addr);
+
+    unsigned int i;
+    boot_params.e820map.map_cnt = p->mmap_length / sizeof(memory_map_t);
+    for(i=0; i<boot_params.e820map.map_cnt; ++i, ++mmap)
+    {
+        boot_params.e820map.map[i].addr = mmap->base_addr_low;
+        boot_params.e820map.map[i].size = mmap->length_low;
+        boot_params.e820map.map[i].type = mmap->type;
+    }
+}
+
+extern void init_bootmem();
+
+void CheckKernel(unsigned long addr, unsigned long magic)
+{
+       if(magic != MULTIBOOT_BOOTLOADER_MAGIC)
+       {
+               printk("Your boot loader does not support multiboot.\n");
+               while(1);
+       }
+
+    multiboot_info_t *mbi = (multiboot_info_t *) addr;
+
+       if( (mbi->flags & 0x47) != 0x47)
+       {
+               printk("Kernel Need More Information\n");
+               while(1);
+       }
+
+    init_boot_params(mbi);
+
+    init_bootmem();
+
+    while(1);
+}
+
+#if 0
+{
+       int i, mmapCount;
+       pmmapItem pMPI;
+
+       pMultiBootInfo pMBI = (pMultiBootInfo) addr;
+
+
+    
+    {
+        printk("mmap_addr %x mmap_length %x\n", pMBI->mmap_addr, pMBI->mmap_length);
+               while(1);
+
+    }
+
+
+       system.boot_device      = pMBI->boot_device;
+
+       /* 分析命令行参数 */
+       parse_cmdline((const char *)pMBI->cmdline);
+
+       system.mmap_addr= pMBI->mmap_addr;
+       system.mmap_size= pMBI->mmap_length;
+       system.mm_lower = pMBI->mem_lower;
+       system.mm_upper = pMBI->mem_upper;
+       system.mm_size          = 0x100000 + (system.mm_upper<<10);
+       // 最大只管理1G的内存
+       if(system.mm_size > MAX_SUPT_PHYMM_SIZE)
+               system.mm_size = MAX_SUPT_PHYMM_SIZE;
+
+       // 重新进行页映射
+       system.page_count       = (system.mm_size >> PAGE_SHIFT);
+       system.pgd              = (unsigned long *) &krnl_end;
+       system.pte_start        = system.pgd + PAGE_ITEMS;
+
+       unsigned long *pde = system.pgd;
+       unsigned long *pte = system.pte_start;
+       unsigned long pde_count = system.page_count/PAGE_ITEMS + 
+                                 (system.page_count%PAGE_ITEMS != 0);
+
+       unsigned long pde_base = KRNLADDR>>22;
+       pde[pde_base] = 7 + va2pa(pte);
+       for(i=pde_base+1; i<(pde_base+pde_count); i++)
+               pde[i] = pde[i-1] + 0x1000;
+       pte[0] = 7;
+       for(i=1; i<system.page_count; i++)
+               pte[i] = pte[i-1] + 0x1000;
+
+       //asm("xchg %bx,%bx");
+       asm("movl %%edx, %%cr3"::"d"(va2pa(pde)));
+
+       system.pte_end          = pte+i;
+       system.pte_end          = (u32*) PAGE_UP(system.pte_end);
+
+       system.page_map         = (pPage)system.pte_end;
+       system.page_bitmap      = PAGE_UP((system.page_map +
+                                       system.page_count));
+       memset((u32)system.page_map, 0,
+               system.page_bitmap-(u32)system.page_map);
+
+       // 初始化伙伴系统的位图
+       unsigned int    bmSize = system.page_count>>1;//bitmap size
+       u32             bmaddr = system.page_bitmap;
+       for(i=0; i<MAX_ORDER; i++)
+       {
+               freeArea[i].map = (unsigned char *)bmaddr;
+               bmSize = (bmSize>>1) + (bmSize%8 != 0);
+               bmaddr += bmSize;
+               bmaddr = ALIGN(bmaddr, sizeof(long));
+       }
+       memset(system.page_bitmap, 0x00, bmaddr - system.page_bitmap);
+
+       system.kernel_end       = PAGE_UP(bmaddr);
+       
+
+
+       mmapCount = system.mmap_size/sizeof(mmapItem);
+       pMPI    = (pmmapItem) system.mmap_addr;
+
+#if 1
+       printk("mm_size: %d MB\n", system.mm_size>>20);
+       printk("page_count:%d page_map:%08x page_bitmap:%08x\n",
+               system.page_count, system.page_map, system.page_bitmap);
+       printk("boot device: %x\n", (unsigned int)system.boot_device);
+       printk("CmdLine: %s\n", system.cmdline);
+       printk("mmap count: %d\n", mmapCount);
+#endif
+
+
+       // 初始化空闲页链表头
+       for(i=0; i<MAX_ORDER; i++)
+               INIT_LIST_HEAD(&freeArea[i].freeList);
+
+       // 初始化描述每个页的结构体
+       for(i=0; i<system.page_count; i++)
+       {
+               INIT_LIST_HEAD(&pgmap[i].list);
+               pgmap[i].mapNR = i;
+               pgmap[i].count = 0;
+       }
+
+       for(i=0; i<mmapCount; i++, pMPI++)
+       {
+               // unsupport high part
+               u32 base        = pMPI->base_addr_low;
+               u32 length      = pMPI->length_low;
+               u32 type        = pMPI->type;
+
+
+               printk("--%08x %08x %02x\n", base, length, type);
+
+
+               if(type == E820_RAM)
+               {
+                       if((base+length)>MAX_SUPT_PHYMM_SIZE)
+                       {
+                               length = MAX_SUPT_PHYMM_SIZE - base;
+                       }
+
+                       if(base < va2pa(system.kernel_end)
+                       && va2pa(system.kernel_end) < base+length)
+                       {
+                               unsigned int offset;
+                               offset = va2pa(PAGE_UP(system.kernel_end)) - base;
+                               base += offset;
+                               length -= offset;
+                       }
+                       if(base == 0)
+                       {
+                               if(length < 0x1000)
+                                       continue;
+                               base += 0x1000;
+                               length -= 0x1000;
+                       }
+                       printk("base:%08x length:%08x addr:%08x\n",
+                       base, length, base+length);
+
+                       init_free_area(base, length);
+               }
+       }
+}
+
+int get_order(unsigned int min_pfn, unsigned int max_pfn)
+{
+       int i, order, size;
+
+       assert(min_pfn<=max_pfn);
+       for(i=order=0; i<MAX_ORDER; i++)
+       {
+               if(min_pfn % (1UL<<i) == 0)
+                       order = i;
+       }
+
+       size = 1UL<<order;
+
+       while(min_pfn+size>max_pfn)
+       {
+               order--;
+               size >>= 1;
+       }
+
+       return order;
+}
+
+void   init_free_area(u32 base, u32 len)
+{
+       unsigned int max_pfn, min_pfn;
+       unsigned int i,order,size;
+
+       min_pfn = get_pfn(base);
+       max_pfn = get_pfn(base+len);
+/*
+       printk("%08x\t%08x\t%x\t%x\t%x\t%d\n",base, base+len, 
+                                       min_pfn, max_pfn,
+                                       max_pfn-min_pfn,
+                                       max_pfn-min_pfn);
+*/
+       assert(min_pfn<=system.page_count);
+       assert(max_pfn<=system.page_count);
+
+       while(min_pfn != max_pfn)
+       {
+               order = get_order(min_pfn, max_pfn);
+               //printk("min:%05d end:%05d max:%05d order:%02d\n",
+               //      min_pfn, min_pfn+(1<<order), max_pfn, order);
+
+               //order = (order>=MAX_ORDER)? MAX_ORDER-1: order;
+               assert(0<=order && order<MAX_ORDER);
+
+               size = 1<<order;
+
+               pgmap[min_pfn].order = order;
+               list_add(&pgmap[min_pfn].list, &freeArea[order].freeList);
+
+               change_bit(pgmap[min_pfn].mapNR>>(order+1),
+                               (unsigned long *)freeArea[order].map);
+
+               //printk("%d\t%08x %d\t",pgmap[min_pfn].mapNR>>(order+1),
+               //                      freeArea[order].map, min_pfn);
+               min_pfn += size;
+               //printk("%d\t%d\t%d\t%d\n",min_pfn, max_pfn, order, size);
+               //int j=3000000;while(j--);
+       }
+}
+#endif
diff --git a/boot/cmdline.c b/boot/cmdline.c
new file mode 100644 (file)
index 0000000..39d9c12
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:        cmdline.c
+ * 
+ *      Author:        Zhao Yanbai [zhaoyanbai@126.com]
+ *                     Wed Feb 17 17:11:37 2010
+ * 
+ * Description:        none
+ * 
+ *--------------------------------------------------------------------------
+ */
+#include<fs.h>
+#include<printk.h>
+#include<system.h>
+#include<string.h>
+#include<stdlib.h>
+
+void get_variable_value(const char *name, char *value);
+
+void parse_root_dev()
+{
+       char    value[128];
+       int     n;
+       get_variable_value("root", value);
+
+       /* 目前只支持通道一的一个硬盘 */
+    /*
+    printk("D:%s\n", value);
+       assert( value[0] == '(' &&
+               value[1] == 'h' &&
+               value[2] == 'd' &&
+               value[3] == '0' &&
+               value[4] == ',');
+    */
+    value[0] = '(';
+    value[1] = 'h';
+    value[2] = 'd';
+    value[3] = '0';
+    value[4] = ')';
+    value[5] = ',';
+    value[6] = '0';
+    value[7] = '\0';
+       n = atoi(value+5);
+
+       system.root_dev = MAKE_DEV(DEV_MAJOR_HD, n+1);
+}
+void parse_debug()
+{
+       char value[128];
+       int n;
+       get_variable_value("debug", value);
+       n = atoi(value);
+
+       system.debug = (n != 0);
+}
+
+
+void parse_cmdline(char *cmdline)
+{
+       system.cmdline = cmdline;
+       printk("cmdline: %s\n", system.cmdline);
+       parse_root_dev();
+       parse_debug();
+#if 0
+       get_variable_value("root", value);
+       printk("root : %s\n", value, n);
+       get_variable_value("debug", value);
+       n = atoi(value);
+       printk("debug : %s %d\n", value, n);
+       while(1);
+#endif
+}
+
+
+void get_variable_value(const char *name, char *value)
+{
+       char *p = system.cmdline;
+       char buf[256];
+       int  i;
+       *value = 0;
+
+       while(*p)
+       {
+               while(*p != ' ')
+               {
+                       if(*p++ == 0)
+                               return;
+               }
+               p++;
+               i = 0;
+               while(*p != '=' && *p != 0)
+                       buf[i++] = *p++;
+               if(*p++ == 0)
+                       return;
+               buf[i] = 0;
+               //printk("%s %s %d\n",buf, name, strcmp(buf, name));
+
+               if(strcmp(buf, name) != 0)
+               {
+                       while(*p != ' ' && *p != 0)
+                               p++;
+                       continue;
+               }
+
+               i = 0;
+               while(*p != ' ' && *p != 0)
+                       value[i++] = *p++;
+               value[i] = 0;
+               //printk("DD %s", value);
+               return ;
+       }
+
+}
diff --git a/boot/multiboot.S b/boot/multiboot.S
new file mode 100644 (file)
index 0000000..b64d8fc
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:        reboot.S
+ * 
+ * Description:        none
+ * 
+ * 
+ *      Author:        Zhao Yanbai [zhaoyanbai@126.com]
+ * 
+ *     Version:        1.0
+ * Create Date: Mon Nov 10 15:58:46 2008
+ * Last Update: Tue Feb 10 22:39:24 2009
+ * 
+ *--------------------------------------------------------------------------
+ */
+#define ASM
+#include"boot/multiboot.h"
+#include"system.h"
+.global        _start
+.extern CheckKernel
+.extern SetupKernel
+.extern        KernelEntry
+.extern init_pgd
+.extern init_pgt
+
+.section .multiboot_header
+.align 32
+       # Multiboot Header
+       # Align 32 bits boundary
+       .align  4
+       # Magic
+       .long   MULTIBOOT_HEADER_MAGIC
+       # Flags
+       .long   MULTIBOOT_HEADER_FLAGS
+       # Checksum
+       .long   -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)
+
+.text
+.code32
+.align 32
+_start:
+       # Reset EFLAGS
+       pushl   $0
+       popf
+
+       # Load GDT's Information To GDTR
+       lgdt    GDTR-KRNLADDR
+
+       mov     $0x10, %dx
+       mov     %dx,%ds
+       mov     %dx,%es
+       mov     %dx,%ss
+       mov     %dx,%fs
+       mov     %dx,%gs
+
+       movl    $(stack + MULTIBOOT_STACK_SIZE - KRNLADDR), %esp
+
+
+       # Save Multiboot Infomation...
+       pushl   %eax
+       addl    $KRNLADDR,%ebx
+       pushl   %ebx
+
+       # Setup Page 
+       movl    $init_pgd-KRNLADDR,%ebx
+       movl    %ebx,%edi
+       movl    $1024,%ecx
+       xorl    %eax,%eax
+       cld
+       rep
+       stosl
+
+       movl    %ebx,%edi
+       movl    %ebx,%eax
+       movl    %ebx,%ecx
+       addl    $7,%eax
+       addl    $0x1000,%eax
+       movl    %eax, 0000(%edi)
+       movl    %eax, 3072(%edi)
+       addl    $0x1000,%eax
+       movl    %eax, 0004(%edi)
+       movl    %eax, 3076(%edi)
+
+       movl    $init_pgt-KRNLADDR,%ebx
+       movl    %ebx,%edi
+       #addl   $0x1000,%edi
+       movl    $2048,%ecx
+       movl    $0x07,%eax
+       cld
+1:
+       stosl
+       addl    $0x1000,%eax
+       loop    1b
+
+       movl    $init_pgd-KRNLADDR,%ebx
+       movl    %ebx,%cr3
+
+       # enable PG
+       movl    %cr0,%eax
+       orl     $0x80000000,%eax
+       movl    %eax,%cr0
+
+
+       jmp     2f
+2:
+
+       ljmp    $0x08,$Label
+Label:
+       call    CheckKernel
+       addl    $8,%esp
+       call    KernelEntry
+
+Die:   jmp     Die     # Should never come to here.
+
+.align 32
+BootGDT:
+EMPT:  .long   0x00000000,0x00000000
+Code:  .long   0x0000FFFF,0x00CF9B00
+Data:  .long   0x0000FFFF,0x00CF9300
+BootGDTEnd:
+GDTR:
+       GDTRLimit:      .word   BootGDTEnd-BootGDT
+       GDTRBase:       .long   BootGDT-KRNLADDR
+
+       .comm   stack, MULTIBOOT_STACK_SIZE
diff --git a/boot/reboot.S b/boot/reboot.S
new file mode 100644 (file)
index 0000000..72a30cc
--- /dev/null
@@ -0,0 +1,149 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:        reboot.S
+ * 
+ * Description:        none
+ * 
+ * 
+ *      Author:        Zhao Yanbai [zhaoyanbai@126.com]
+ * 
+ *     Version:        1.0
+ * Create Date: Sat Jul 11 19:16:42 2009
+ * Last Update: Sat Jul 11 19:16:42 2009
+ * 
+ *--------------------------------------------------------------------------
+ */
+#define        ASM
+#include<system.h>
+.global do_restart
+.global        do_reboot
+.global        do_poweroff
+.extern        printk
+.text
+.code32
+.align 32
+do_restart:
+do_reboot:
+       movl    $REBOOT_RESTART,RebootFlag
+       pushl   $msgReboot
+       call    printk
+       addl    $4,%esp
+       jmp     _do_reboot
+msgReboot:     .asciz  "Rebooting ..........."
+do_poweroff:
+       movl    $REBOOT_POWEROFF,RebootFlag
+       pushl   $msgPowerOff
+       call    printk
+       addl    $4,%esp
+       jmp     _do_reboot
+msgPowerOff:   .asciz  "Shutdown System......"
+
+_do_reboot:
+       # Disable All Interrupts
+       cli
+
+       # Write to CMOS
+       movb    $0x8F,%al
+       movw    $0x70,%dx
+       outb    %al,%dx
+       movb    $0x00,%al
+       movw    $0x71,%dx
+       outb    %al,%dx
+
+
+       # Prepare Paging For Reboot 
+       movl    $256,%ecx
+       movl    $0x100C00,%esi
+       movl    $0x100000,%edi
+       rep
+       movsl
+
+
+       # Modify 'jmp' Instruction In Real Mode Code
+       cmpl    $REBOOT_POWEROFF,RebootFlag
+       je      1f
+       cmpl    $REBOOT_RESTART,RebootFlag
+       je      2f
+1:
+       movl    $JUMPEND,%ecx
+       subl    $JUMPBEGIN,%ecx
+       movl    $JUMPBEGIN,%edi
+       movb    $0x90,%al
+       rep
+       stosb
+
+2:
+       # Copy The Real Mode Code to Low Memory
+       movl    $Code16End,%ecx
+       subl    $Code16,%ecx
+       movl    $Code16,%esi
+       movl    $0x1000,%edi
+       rep
+       movsb
+
+       # Reload CR3
+       #movl   $0x100000,%eax
+       #movl   %eax,%cr3
+
+       # Set Reboot Mode
+       # 0x1234 For Warm Reboot
+       # 0x0000 For Cold Reboot
+       movw    $0x1234,(0x472)
+
+       lidt    IDTR
+       lgdt    GDTR
+
+       movl    $0x10,%eax
+       movw    %ax,%ds
+       movw    %ax,%es
+       movw    %ax,%fs
+       movw    %ax,%gs
+       movw    %ax,%ss
+
+       # Jump to Real Mode Code
+       ljmp    $0x0008,$0x1000
+
+RebootGDT:
+EMPT:  .long   0x00000000,0x00000000
+Code:  .long   0x0000FFFF,0x00009A00
+Data:  .long   0x0000FFFF,0x00009200
+RebootGDTEnd:
+GDTR:
+       GDTRLimit:      .word   RebootGDTEnd-RebootGDT
+       GDTRBase:       .long   RebootGDT
+IDTR:
+       IDTRLimit:      .word   0x3FF
+       IDTRBase:       .long   0x0
+RebootFlag:    .long   REBOOT_RESTART
+.align 16
+.code16
+Code16:
+       movl    %cr0,%eax
+       andl    $0x00000011,%eax
+       orl     $0x60000000,%eax
+       movl    %eax,%cr0
+       movl    %eax,%cr3
+       movl    %cr0,%ebx
+       andl    $0x60000000,%ebx
+       jz      1f
+       invd
+1:
+       andb    $0x10,%al
+       movl    %eax,%cr0
+
+       # The Jump Instruction Will be Set 'nop' If Need Reboot.
+JUMPBEGIN:
+       jmp     REBOOT
+JUMPEND:
+
+SHUTDOWN:
+       movw    $0x1000,%ax
+       movw    %ax,%ss
+       movw    $0xF000,%sp
+       movw    $0x5307,%ax
+       movw    $0x0001,%bx
+       movw    $0x0003,%cx
+       int     $0x15
+REBOOT:
+       ljmp    $0xFFFF,$0x0000
+Code16End:
diff --git a/copy.sh b/copy.sh
new file mode 100755 (executable)
index 0000000..8a6d398
--- /dev/null
+++ b/copy.sh
@@ -0,0 +1,27 @@
+#!/bin/bash
+#set -x
+
+HDIMG=./HD.IMG
+lodev=`losetup -f --show $HDIMG`
+
+partx -a ${lodev}
+
+PART=${lodev}p1
+#sleep 1
+
+mount $PART /mnt/
+
+cp ./KERNEL.BIN /mnt/boot/Kernel
+cp scripts/grub.cfg /mnt/boot/grub2/
+
+md5sum /mnt/boot/Kernel
+
+mkdir -p /mnt/bin/
+cp ./bin/hw /mnt/bin/
+cp ./bin/sh /mnt/bin/
+
+umount /mnt/
+
+partx -d ${lodev}p1
+
+losetup -d ${lodev}
diff --git a/drivers/Makefile b/drivers/Makefile
new file mode 100644 (file)
index 0000000..23675f3
--- /dev/null
@@ -0,0 +1,23 @@
+include ../kernel.mk
+CC = gcc
+CFLAGS = $(CF)
+
+CSOUCE_FILES = $(wildcard *.c)
+SSOUCE_FILES = $(wildcard *.S)
+OBJS  = $(patsubst %.c,%.o,$(CSOUCE_FILES))
+OBJS += $(patsubst %.S,%.S.o,$(SSOUCE_FILES))
+
+%.o : %.c ../include/*.h ./*.h
+       $(CC) $(CFLAGS) $< -o $@
+%.S.o : %.S  ../include/*.h ./*.h
+       $(CC) $(CFLAGS) $< -o $@
+
+
+all:$(OBJS)
+
+.PHONY:clean
+clean:
+       $(RM) $(OBJS)
+.PHONY:c
+c:
+       make clean
diff --git a/drivers/hd.c b/drivers/hd.c
new file mode 100644 (file)
index 0000000..0e47b48
--- /dev/null
@@ -0,0 +1,407 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:        hd.c
+ * 
+ *      Author:        Zhao Yanbai [zhaoyanbai@126.com]
+ *                     Mon Feb  1 15:26:55 2010
+ * 
+ * Description:        none
+ * 
+ *--------------------------------------------------------------------------
+ */
+#include<io.h>
+#include<hd.h>
+#include<irq.h>
+#include<system.h>
+//void hd_handler(pPtRegs regs, unsigned int irq)
+void   hd_handler(unsigned int irq, pPtRegs regs, void *dev_id)
+{
+       printk("hd_handler:%d ", irq);
+}
+
+int    hd_controller_ready(Dev dev)
+{
+       int retries = 0x1000;
+
+       do
+       {
+               if(hd_rdy(dev))
+                       return 1;
+       }while(--retries);
+
+       return 0;
+}
+
+void   hd_controller_reset(unsigned int dev)
+{
+       outb(HD_CTL_RESET,      REG_CTL(dev));
+/*
+       //outb(HD_CTL_RESET,    REG_CTL(dev));
+       while(1)
+       {
+               printk("%02x ", inb(REG_STATUS(dev)));
+       }
+       while(hd_bsy(dev))
+       {
+               printk("bsy");
+       }
+*/
+}
+
+void   hd_out(Dev dev, u32 nsect, u64 sect_nr, u32 cmd)
+{
+       assert(nsect > 0);
+       assert(HD_GET_DEV(dev) < 2);    // 0: ata-master 1:ata-slave
+
+       unsigned char device = 0xE0;
+       device |= ((HD_GET_DEV(dev)) << 4);
+
+       if(!hd_controller_ready(dev))
+       {
+               return ;
+       }
+
+       if(system.debug)
+       {
+               hd_controller_reset(dev);
+       }
+
+       outb(0x00,                              REG_CTL(dev));
+       outb(0x00,                              REG_FEATURES(dev));
+       outb((u8)nsect,                         REG_NSECTOR(dev));
+#ifdef USE_LBA_48
+       /* 
+        * LBA-48 bit
+        * 先写高位.再写低位.
+        */
+       outb((u8)((sect_nr>>0x18)&0xFF),        REG_LBAL(dev));
+       outb((u8)((sect_nr>>0x20)&0xFF),        REG_LBAM(dev));
+       outb((u8)((sect_nr>>0x28)&0xFF),        REG_LBAH(dev));
+
+       outb((u8)((sect_nr>>0x00)&0xFF),        REG_LBAL(dev));
+       outb((u8)((sect_nr>>0x08)&0xFF),        REG_LBAM(dev));
+       outb((u8)((sect_nr>>0x10)&0xFF),        REG_LBAH(dev));
+#else
+       outb((u8)((sect_nr>>0x00)&0xFF),        REG_LBAL(dev));
+       outb((u8)((sect_nr>>0x08)&0xFF),        REG_LBAM(dev));
+       outb((u8)((sect_nr>>0x10)&0xFF),        REG_LBAH(dev));
+#endif 
+       outb((u8)device,                        REG_DEVICE(dev));
+       outb((u8)cmd,                           REG_CMD(dev));
+}
+
+void   _hd_read(Dev dev, u64 sect_nr, void *buf, u32 count, u32 cmd)
+{
+       u32     device;
+       u32     nsect;
+       u32     retires = 100;
+
+       nsect   = (count + SECT_SIZE -1)/SECT_SIZE;
+
+       do
+       {
+               hd_out(dev, nsect,  sect_nr, cmd);
+
+               int drq_retires = 100000;
+               while(!hd_drq(dev) && --drq_retires)
+                       /* do nothing */;
+
+               if(drq_retires != 0)
+                       break;
+       }while(--retires);
+
+       if(retires == 0)
+               panic("hard disk is not ready");
+
+       hd_rd_data(dev, buf, count);
+}
+
+
+void   hd_read(Dev dev, u64 sect_nr, void *buf, u32 count)
+{
+       _hd_read(dev, sect_nr, buf, count, HD_CMD_READ_EXT);
+}
+
+void   hd_read_identify(Dev dev, void *buf)
+{
+       _hd_read(dev, 0, buf, SECT_SIZE, HD_CMD_IDENTIFY);
+}
+
+void   hd_print_identify(const char *buf)
+{
+       char    *p;
+       short   *ident;
+       int     i;
+
+       ident = (short *) buf;
+
+       char    hd_sn[32];      /* 20 bytes */
+       char    hd_model[64];   /* 40 bytes */
+       short   hd_capabilites = ident[49];
+       short   hd_supt_inst_set = ident[83];
+
+       p = (char *) (ident+10);
+       for(i=0; i<20; i++)
+       {
+               hd_sn[i] = p[i];
+       }
+       hd_sn[i] = 0;
+
+       p = (char *) (ident+27);
+       for(i=0; i<40; i++)
+       {
+               hd_model[i] = p[i];
+       }
+       hd_model[i] = 0;
+
+
+       printk("Hard Disk Vendor: %s\n", hd_sn);
+       printk("Hard Disk Model: %s\n", hd_model);
+       printk("Hard Disk Support LBA: %s\n",
+               (hd_capabilites & 0x0200) ? "Yes" : "No");
+       printk("Hard Disk Support LBA-48bit: %s\n",
+               (hd_supt_inst_set & 0x0400) ? "Yes" : "No");
+
+       if(!(hd_supt_inst_set & 0x0400))
+               panic("Your hard disk ");
+}
+
+void   setup_hd()
+{
+       if(!system.debug)
+               hd_controller_reset(ROOT_DEV);
+       //hd_controller_reset(1);
+       //return ;
+
+       char *buf;
+       buf = (unsigned char *) get_virt_pages(1);
+       assert(buf != NULL);
+
+#if 1
+       hd_read_identify(ROOT_DEV, buf);
+#else
+       outb(0x00, 0x1F1);
+       outb(0x01, 0x1F2);
+       outb(0x00, 0x1F3);
+       outb(0x00, 0x1F4);
+       outb(0x00, 0x1F5);
+       outb(0xE0, 0x1F6);
+       outb(0xEC, 0x1F7);
+       while(!(inb(0x1F7) & 0x08)){}
+       asm("cld;rep;insw;"::"c"(256), "d"(0x1F0), "D"(buf));
+#endif
+       hd_print_identify(buf);
+
+       free_virt_pages(buf);
+}
+
+
+
+
+#if 0
+int    hd_controller_ready(unsigned int channel)
+{
+       int retries = 0x1000;
+
+       do
+       {
+               if(hd_rdy(channel))
+                       return 1;
+       }while(--retries);
+
+       return 0;
+}
+
+void   hd_controller_reset(unsigned int channel)
+{
+       outb(HD_CTL_RESET,      REG_CTL(channel));
+}
+
+void   hd_out(u32 channel, u32 device, u32 nsect, u64 sect_nr, u32 cmd)
+{
+       assert(device < 2);     // 0: ata-master 1: ata-slave
+       assert(channel < 2);    // PC only support 2 IDE channels
+       assert(nsect > 0);
+
+       unsigned char dev = (device)?0x10 : 0x00;
+       dev |= 0xE0;
+
+       if(!hd_controller_ready(channel))
+               return ;
+
+       outb(0x00,                              REG_CTL(channel));
+       outb(0x00,                              REG_FEATURES(channel));
+       outb((u8)nsect,                         REG_NSECTOR(channel));
+#ifdef USE_LBA_48
+       /* 
+        * LBA-48 bit
+        * 先写高位.再写低位.
+        */
+       outb((u8)((sect_nr>>0x18)&0xFF),        REG_LBAL(channel));
+       outb((u8)((sect_nr>>0x20)&0xFF),        REG_LBAM(channel));
+       outb((u8)((sect_nr>>0x28)&0xFF),        REG_LBAH(channel));
+
+       outb((u8)((sect_nr>>0x00)&0xFF),        REG_LBAL(channel));
+       outb((u8)((sect_nr>>0x08)&0xFF),        REG_LBAM(channel));
+       outb((u8)((sect_nr>>0x10)&0xFF),        REG_LBAH(channel));
+#else
+       outb((u8)((sect_nr>>0x00)&0xFF),        REG_LBAL(channel));
+       outb((u8)((sect_nr>>0x08)&0xFF),        REG_LBAM(channel));
+       outb((u8)((sect_nr>>0x10)&0xFF),        REG_LBAH(channel));
+#endif 
+       outb((u8)dev,                           REG_DEVICE(channel));
+       outb((u8)cmd,                           REG_CMD(channel));
+}
+
+void   _hd_read(u32 dev, u64 sect_nr, void *buf, u32 count, u32 cmd)
+{
+       u32     channel, device;
+       u32     nsect;
+       u32     retires = 100;
+
+       channel = device = 0;   //
+
+       nsect   = (count + SECT_SIZE -1)/SECT_SIZE;
+
+       do
+       {
+               hd_out(channel, device, nsect,  sect_nr, cmd);
+
+               int drq_retires = 100000;
+               while(!hd_drq(channel) && --drq_retires)
+                       /* do nothing */;
+
+               if(drq_retires != 0)
+                       break;
+       }while(--retires);
+
+       if(retires == 0)
+               panic("hard disk is not ready");
+
+       hd_rd_data(channel, buf, count);
+}
+
+
+void   hd_read(u32 dev, u64 sect_nr, void *buf, u32 count)
+{
+       _hd_read(dev, sect_nr, buf, count, HD_CMD_READ_EXT);
+}
+
+void   hd_read_identify(u32 dev, void *buf)
+{
+       _hd_read(dev, 0, buf, SECT_SIZE, HD_CMD_IDENTIFY);
+}
+
+void   hd_print_identify(const char *buf)
+{
+       char    *p;
+       short   *ident;
+       int     i;
+
+       ident = (short *) buf;
+
+       char    hd_sn[32];      /* 20 bytes */
+       char    hd_model[64];   /* 40 bytes */
+       short   hd_capabilites = ident[49];
+       short   hd_supt_inst_set = ident[83];
+
+       p = (char *) (ident+10);
+       for(i=0; i<20; i++)
+       {
+               hd_sn[i] = p[i];
+       }
+       hd_sn[i] = 0;
+
+       p = (char *) (ident+27);
+       for(i=0; i<40; i++)
+       {
+               hd_model[i] = p[i];
+       }
+       hd_model[i] = 0;
+
+
+       printk("Hard Disk SN: %s\n", hd_sn);
+       printk("Hard Disk Model: %s\n", hd_model);
+       printk("Hard Disk Support LBA: %s\n",
+               (hd_capabilites & 0x0200) ? "Yes" : "No");
+       printk("Hard Disk Support LBA-48bit: %s\n",
+               (hd_supt_inst_set & 0x0400) ? "Yes" : "No");
+
+       if(!(hd_supt_inst_set & 0x0400))
+               panic("Your hard disk ");
+}
+
+void   setup_hd()
+{
+       //hd_controller_reset(0);
+       //hd_controller_reset(1);
+       //return ;
+
+       char *buf;
+       buf = (unsigned char *) get_virt_pages(1);
+       assert(buf != NULL);
+
+#if 1
+       hd_read_identify(ROOT_DEV, buf);
+#else
+       outb(0x00, 0x1F1);
+       outb(0x01, 0x1F2);
+       outb(0x00, 0x1F3);
+       outb(0x00, 0x1F4);
+       outb(0x00, 0x1F5);
+       outb(0xE0, 0x1F6);
+       outb(0xEC, 0x1F7);
+       while(!(inb(0x1F7) & 0x08)){}
+       asm("cld;rep;insw;"::"c"(256), "d"(0x1F0), "D"(buf));
+#endif
+       hd_print_identify(buf);
+
+       free_virt_pages(buf);
+}
+#endif
+
+
+#if 0
+void   hd_rd_sect(u64 sn, char *buf)
+{
+       int chl = 0;
+       unsigned char dev = 0xE0;
+
+       outb(HD_CTL_RESET,      REG_CTL(chl));
+       outb(HD_CTL_DISABLE_INT,REG_CTL(chl));
+       outb(0x00,              REG_FEATURES(chl));
+       outb(0x01,              REG_NSECTOR(chl));
+#if 0
+       outb((sn>>0x00)&0xFF,   REG_LBAL(chl));
+       outb((sn>>0x08)&0xFF,   REG_LBAM(chl));
+       outb((sn>>0x10)&0xFF,   REG_LBAH(chl));
+#endif
+#if 0
+       outb(0x00,      REG_LBAL(chl));
+       outb(0x00,      REG_LBAL(chl));
+       outb(0x00,      REG_LBAM(chl));
+       outb(0x00,      REG_LBAM(chl));
+       outb(0x00,      REG_LBAH(chl));
+       outb(0x00,      REG_LBAH(chl));
+#endif
+#if 1
+       /* 
+        * LBA-48 bit
+        * 先写高位.再写低位.
+        */
+       outb(0x00,                      REG_LBAL(chl));
+       outb(0x00,                      REG_LBAM(chl));
+       outb(0x00,                      REG_LBAH(chl));
+
+       outb(0x00,                      REG_LBAL(chl)); outb(0x00,                      REG_LBAM(chl));
+       outb(0x00,                      REG_LBAH(chl));
+#endif
+
+       outb(dev,                       REG_DEVICE(chl));
+       outb(HD_CMD_READ_EXT,           REG_CMD(chl));
+
+       while(!hd_drq(chl));
+
+       hd_rd_data(chl, buf, SECT_SIZE);
+}
+#endif
diff --git a/drivers/hd.h b/drivers/hd.h
new file mode 100644 (file)
index 0000000..4da59c2
--- /dev/null
@@ -0,0 +1,218 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:        hd.h
+ * 
+ * Description:        none
+ * 
+ * 
+ *      Author:        Zhao Yanbai [zhaoyanbai@126.com]
+ * 
+ *     Version:        1.0
+ * Create Date: Tue Feb 10 15:17:57 2009
+ * Last Update: Mon Feb 01 21:07:31 2010
+ * 
+ *--------------------------------------------------------------------------
+ */
+
+#ifndef        _HD_H
+#define        _HD_H
+
+#include<types.h>
+#include<printk.h>
+#include<assert.h>
+
+#if 0
+#define        HD_CHL0_DATA            0x1F0
+#define        HD_CHL0_ERR             0x1F1
+#define        HD_CHL0_NSECTOR 0x1F2
+#define        HD_CHL0_SECTOR  0x1F3
+#define        HD_CHL0_CYLL            0x1F4
+#define        HD_CHL0_CYLH            0x1F5
+#define        HD_CHL0_CURRENT 0x1F6   /*101nhhhh
+                                n:0--First Hardisk, 1--Second Hardisk.
+                                hhhh: head*/
+#define        HD_STATUS       0x1F7
+#define        HD_CMD          HD_STATUS
+#endif
+
+
+/* 命令寄存器的起始值 */
+#define        HD_CHL0_CMD_BASE        0x1F0
+#define        HD_CHL1_CMD_BASE        0x170
+
+#define        HD_DATA                 0
+#define        HD_ERR                  1
+#define                HD_ERR_BB               0x80
+#define                HD_ERR_ECC              0x40
+#define                HD_ERR_ID               0x10
+#define                HD_ERR_AC               0x04
+#define                HD_ERR_TK               0x02
+#define                HD_ERR_DM               0x01
+#define        HD_NSECTOR              2
+#define        HD_LBAL                 3
+#define        HD_LBAM                 4
+#define        HD_LBAH                 5
+#define        HD_DEVICE               6
+#define        HD_STATUS               7               /* controller status */
+#define                HD_STATUS_BSY           0x80    /* controller busy */
+#define                HD_STATUS_RDY           0x40    /* drive ready */
+#define                HD_STATUS_WF            0x20    /* write fault */
+#define                HD_STATUS_SC            0x10    /* seek complete */
+#define                HD_STATUS_DRQ           0x08    /* data transfer request */
+#define                HD_STATUS_CRD           0x04    /* correct data */
+#define                HD_STATUS_IDX           0x02    /* index pulse */
+#define                HD_STATUS_ERR           0x01    /* error */
+#define        HD_FEATURES             HD_ERR
+#define        HD_CMD                  HD_STATUS
+#define                HD_CMD_IDLE             0x00
+#define                HD_CMD_RECALIBRATE      0x10
+#define                HD_CMD_READ             0x20    /* read data */
+#define                HD_CMD_READ_EXT         0x24    /* read data (LBA-48 bit)*/
+#define                HD_CMD_WRITE            0x30
+#define                HD_CMD_WRITE_EXT        0x34
+#define                HD_CMD_READ_VERIFY      0x40
+#define                HD_CMD_FORMAT           0x50
+#define                HD_CMD_SEEK             0x70
+#define                HD_CMD_DIAG             0x90
+#define                HD_CMD_SPECIFY          0x91
+#define                HD_CMD_IDENTIFY         0xEC
+
+/* 硬盘控制寄存器 */
+#define        HD_CHL0_CTL_BASE        0x3F6
+#define        HD_CHL1_CTL_BASE        0x376
+
+#define        HD_CTL                  0
+#define                HD_CTL_NORETRY          0x80    /* disable access retry */
+#define                HD_CTL_NOECC            0x40    /* disable ecc retry */
+#define                HD_CTL_EIGHTHEADS       0x08    /* more than 8 heads */
+#define                HD_CTL_RESET            0x04    /* reset controller */
+#define                HD_CTL_DISABLE_INT      0x02    /* disable interrupts */
+
+#define                HD_GET_CHL(dev)         (0)     /* 暂时还是只支持通道0 */
+#define                HD_GET_DEV(dev)         (0)     /* 暂时还是只支持一个硬盘 */
+
+#define        REG_CMD_BASE(dev, offset)                       \
+       (HD_GET_CHL(dev)?(HD_CHL1_CMD_BASE+offset)      \
+       :                                               \
+       (HD_CHL0_CMD_BASE+offset))
+
+#define        REG_CTL_BASE(dev, offset)                       \
+       (HD_GET_CHL(dev)?(HD_CHL1_CTL_BASE+offset)      \
+       :                                               \
+       (HD_CHL0_CTL_BASE+offset))
+
+#if 1
+#define        REG_DATA(dev)           REG_CMD_BASE(dev, HD_DATA)
+#define        REG_ERR(dev)            REG_CMD_BASE(dev, HD_ERR)
+#define        REG_NSECTOR(dev)        REG_CMD_BASE(dev, HD_NSECTOR)
+#define        REG_LBAL(dev)           REG_CMD_BASE(dev, HD_LBAL)
+#define        REG_LBAM(dev)           REG_CMD_BASE(dev, HD_LBAM)
+#define        REG_LBAH(dev)           REG_CMD_BASE(dev, HD_LBAH)
+#define        REG_DEVICE(dev)         REG_CMD_BASE(dev, HD_DEVICE)
+#define        REG_STATUS(dev)         REG_CMD_BASE(dev, HD_STATUS)
+#define        REG_FEATURES(dev)       REG_CMD_BASE(dev, HD_FEATURES)
+#define        REG_CMD(dev)            REG_CMD_BASE(dev, HD_CMD)
+
+#define        REG_CTL(dev)            REG_CTL_BASE(dev, HD_CTL)
+#else  
+#define        REG_DATA        REG_CMD_BASE(0, HD_DATA)
+#define        REG_ERR         REG_CMD_BASE(0, HD_ERR)
+#define        REG_NSECTOR     REG_CMD_BASE(0, HD_NSECTOR)
+#define        REG_LBAL        REG_CMD_BASE(0, HD_LBAL)
+#define        REG_LBAM        REG_CMD_BASE(0, HD_LBAM)
+#define        REG_LBAH        REG_CMD_BASE(0, HD_LBAH)
+#define        REG_DEVICE      REG_CMD_BASE(0, HD_DEVICE)
+#define        REG_STATUS      REG_CMD_BASE(0, HD_STATUS)
+#define        REG_FEATURES    REG_CMD_BASE(0, HD_FEATURES)
+#define        REG_CMD         REG_CMD_BASE(0, HD_CMD)
+
+#define        REG_CTL         REG_CTL_BASE(0, HD_CTL)
+#endif
+
+/* 一个扇区包含的字节数 */
+#define        SECT_SIZE       512
+
+
+static inline void hd_rd_port(int port, void *buf, unsigned long count)
+{
+       unsigned char *p =(unsigned char *)buf;
+       unsigned char value[4];
+       int i, n;
+       n = (count & 3UL);
+       if(n == 0)
+       {
+               insl(port, p, count>>2);
+       }
+       else
+       {
+               insl(port, p, (count>>2));
+               insl(port, value, 1);
+
+               count -= n;
+               for(i=0; i<n; i++)
+                       p[count+i] = value[i];
+       }
+
+#if 0  
+       unsigned char *p =(unsigned char *)buf;
+       int l, w, b;
+       l = count & (~3UL);
+       w = count - l;
+       b = w & 0x01;
+       w = w - b;
+       printk("l:%d w:%d b:%d\n", l, w, b);
+       if(l)
+       {
+               insl(port, p, l);
+               p += l;
+       }
+       if(w)
+       {
+               insw(port, p+l, w);
+               p += w;
+       }
+       if(b)
+       {
+               insb(port, p+l+w, b);
+       }
+#endif
+#if 0
+       int i, rest;
+       unsigned char *p =(unsigned char *)buf;
+
+       rest = count & 3UL;
+       count-= rest;
+
+       printk("count:%d rest:%d\n", count, rest);
+
+       insl(port, p, count>>2);
+
+       for(i=0; i<rest; i++)
+               insb(port, p+count+i, 1);
+#endif
+#if 0
+       if(!(count & 0x3UL))
+       {
+               count >>= 2;
+               insl(port, buf, count-2);
+       }
+       else if(!(count & 0x1UL))
+       {
+               count >>= 1;
+               insw(port, buf, count);
+       }
+#endif
+}
+
+/* 从硬盘数据端口读取数据 */
+#define        hd_rd_data(dev, buf, count) hd_rd_port(REG_DATA(dev), buf, count)
+
+#define        hd_bsy(dev) ((inb(REG_STATUS(dev)) & HD_STATUS_BSY))
+#define        hd_rdy(dev) ((inb(REG_STATUS(dev)) & HD_STATUS_RDY))
+#define        hd_drq(dev) ((inb(REG_STATUS(dev)) & HD_STATUS_DRQ))
+#define        hd_err(dev) ((inb(REG_STATUS(dev)) & HD_STATUS_ERR))
+
+
+#define        USE_LBA_48      /* 使用LBA-48bit 模式操作硬盘 */
+
+#endif //_HD_H
diff --git a/drivers/keyboard.c b/drivers/keyboard.c
new file mode 100644 (file)
index 0000000..09fcee4
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:        keyboard.h
+ * 
+ * Description:        none
+ * 
+ * 
+ *      Author:        Zhao Yanbai [zhaoyanbai@126.com]
+ * 
+ *     Version:        1.0
+ * Create Date: Thu Jul 16 18:39:57 2009
+ * Last Update: Thu Jul 16 18:39:57 2009
+ * 
+ *--------------------------------------------------------------------------
+ */
+#include<printk.h>
+#include<system.h>
+#include<syscall.h>
+#include<stdio.h>
+#include<io.h>
+
+#define        KBD_BUF_SIZE    256
+static struct
+{
+       unsigned int count;
+       unsigned int head,tail;
+       unsigned char buf[KBD_BUF_SIZE];
+} kbd_buf;
+#define        count   kbd_buf.count
+#define        head    kbd_buf.head
+#define        tail    kbd_buf.tail
+#define        buf     kbd_buf.buf
+
+
+
+extern void reboot();
+extern void poweroff();
+void   kbd_handler(unsigned int irq, pPtRegs regs, void *dev_id)
+{
+       unsigned char ScanCode;
+       //printk("%s\n", dev_id);
+       ScanCode = inb(0x60);
+       //printk("%02x", ScanCode);
+       if(count < KBD_BUF_SIZE)
+       {
+               count++;
+               buf[tail++] = ScanCode;
+               tail %= KBD_BUF_SIZE;
+       }
+}
+
+inline int getScanCode()
+{
+       unsigned int ScanCode;
+       
+       //while(count <= 0);
+       if(count <= 0) return -1;
+
+       ScanCode = buf[head++];
+       head %= KBD_BUF_SIZE;
+       count--;        //很明显这是临界资源但现在只能这样了
+
+       return (0xFF & ScanCode);
+}
+
+
+int    sysc_read_kbd()
+{
+       return getScanCode();
+}
diff --git a/drivers/keyboard.c.bake b/drivers/keyboard.c.bake
new file mode 100644 (file)
index 0000000..0dd77d9
--- /dev/null
@@ -0,0 +1,265 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:        keyboard.h
+ * 
+ * Description:        none
+ * 
+ * 
+ *      Author:        Zhao Yanbai [zhaoyanbai@126.com]
+ * 
+ *     Version:        1.0
+ * Create Date: Thu Jul 16 18:39:57 2009
+ * Last Update: Thu Jul 16 18:39:57 2009
+ * 
+ *--------------------------------------------------------------------------
+ */
+#include<printk.h>
+#include<system.h>
+#include<syscall.h>
+#include<stdio.h>
+#include<io.h>
+#define        EXT_KEY         0x80000000      /* None Print Key */
+#define        L_SHIFT_DOWN    0x00000100
+#define        R_SHIFT_DOWN    0x00000200
+#define        L_CTRL_DOWN     0x00000400
+#define        R_CTRL_DOWN     0x00000800
+#define        L_ALT_DOWN      0x00001000
+#define        R_ALT_DOWN      0x00002000
+#define        L_SHIFT_UP      (~L_SHIFT_DOWN)
+#define        R_SHIFT_UP      (~R_SHIFT_DOWN)
+#define        L_CTRL_UP       (~L_CTRL_DOWN)
+#define        R_CTRL_UP       (~R_CTRL_DOWN)
+#define        L_ALT_UP        (~L_ALT_DOWN)
+#define        R_ALT_UP        (~R_ALT_DOWN)
+#define        SET_L_SHIFT_DOWN(key)   (key |= L_SHIFT_DOWN)
+#define        SET_R_SHIFT_DOWN(key)   (key |= R_SHIFT_DOWN)
+#define        SET_L_CTRL_DOWN(key)    (key |= L_CTRL_DOWN)
+#define        SET_R_CTRL_DOWN(key)    (key |= R_CTRL_DOWN)
+#define        SET_L_ALT_DOWN(key)     (key |= L_ALT_DOWN)
+#define        SET_R_ALT_DOWN(key)     (key |= R_ALT_DOWN)
+#define        SET_L_SHIFT_UP(key)     (key &= L_SHIFT_UP)
+#define        SET_R_SHIFT_UP(key)     (key &= R_SHIFT_UP)
+#define        SET_L_CTRL_UP(key)      (key &= L_CTRL_UP)
+#define        SET_R_CTRL_UP(key)      (key &= R_CTRL_UP)
+#define        SET_L_ALT_UP(key)       (key &= L_ALT_UP)
+#define        SET_R_ALT_UP(key)       (key &= R_ALT_UP)
+#define        IS_L_SHIFT_DOWN(key)    (key & L_SHIFT_DOWN)
+#define        IS_R_SHIFT_DOWN(key)    (key & R_SHIFT_DOWN)
+#define        IS_L_CTRL_DOWN(key)     (key & L_CTRL_DOWN)
+#define        IS_R_CTRL_DOWN(key)     (key & R_CTRL_DOWN)
+#define        IS_L_ALT_DOWN(key)      (key & L_ALT_DOWN)
+#define        IS_R_ALT_DOWN(key)      (key & R_ALT_DOWN)
+
+const unsigned char kbdCharTable[]={0,0,
+'1','2','3','4','5','6','7','8','9','0','-','=','\b',0,
+'q','w','e','r','t','y','u','i','o','p','[',']','\n',0,
+'a','s','d','f','g','h','j','k','l',';','\'','`',0,'\\',
+'z','x','c','v','b','n','m',',','.','/',0,0,0,' ',
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+};
+const unsigned char kbdShiftCharTable[]={0,0,
+'!','@','#','$','%','^','&','*','(',')','_','+','\b',0,
+'Q','W','E','R','T','Y','U','I','O','P','{','}','\n',0,
+'A','S','D','F','G','H','J','K','L',':','"','~',0,'|',
+'Z','X','C','V','B','N','M','<','>','?',0,0,0,' ',
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+};
+
+/* Make Code */
+#define        MC_BACKSPACE    0x0E
+#define        MC_CTRL         0x1D
+#define        MC_L_SHIFT      0x2A
+#define        MC_R_SHIFT      0x36
+#define        MC_ALT          0x38
+#define        MC_CAPSLOCK     0x3A
+#define        MC_DELETE       0x53
+#define        BC_BACKSPACE    (0x80 | MC_BACKSPACE)
+#define        BC_CTRL         (0x80 | MC_CTRL)
+#define        BC_L_SHIFT      (0x80 | MC_L_SHIFT)
+#define        BC_R_SHIFT      (0x80 | MC_R_SHIFT)
+#define        BC_ALT          (0x80 | MC_ALT)
+#define        BC_DELETE       (0x80 | MC_DELETE)
+#define        BC_CAPSLOCK     (0x80 | MC_CAPSLOCK)
+
+#define        KBD_BUF_SIZE    256
+static struct
+{
+       unsigned int count;
+       unsigned int head,tail;
+       unsigned char buf[KBD_BUF_SIZE];
+} kbd_buf;
+#define        count   kbd_buf.count
+#define        head    kbd_buf.head
+#define        tail    kbd_buf.tail
+#define        buf     kbd_buf.buf
+
+void   kbd_handler(unsigned int irq, pPtRegs regs, void *dev_id)
+{
+       unsigned char ScanCode;
+       //printk("%s\n", dev_id);
+       ScanCode = inb(0x60);
+       //printk("%02x", ScanCode);
+       if(count < KBD_BUF_SIZE)
+       {
+               count++;
+               buf[tail++] = ScanCode;
+               tail %= KBD_BUF_SIZE;
+       }
+}
+
+inline int getScanCode()
+{
+       unsigned int ScanCode;
+       
+       //while(count <= 0);
+       if(count <= 0) return -1;
+
+       ScanCode = buf[head++];
+       head %= KBD_BUF_SIZE;
+       count--;        //很明显这是临界资源但现在只能这样了
+
+       return (0xFF & ScanCode);
+}
+
+
+unsigned char read_kbd()
+{
+       char    k;
+       int ret = -1;
+
+       while(ret == -1)
+       {
+               syscall0(SYSC_READ_KBD);
+               asm("":"=a"(ret));
+       }
+
+       k = (unsigned char) ret;
+
+       return k;
+}
+
+unsigned int _parse_kbd()
+{
+       int ScanCode;
+       static unsigned int key;
+       static unsigned char E0Flag = 0;
+       ScanCode = read_kbd();
+
+       if(ScanCode == 0xE0)
+       {
+               E0Flag = 1;
+               ScanCode = read_kbd();
+       }
+
+       if(ScanCode & 0x80)     // Make Or Break Code ?
+               goto    BreakCode;
+       
+       // Ctrl + Alt + Del
+       if( IS_L_CTRL_DOWN(key) && IS_L_ALT_DOWN(key))
+       {
+               if(E0Flag == 1 && ScanCode == MC_DELETE)
+               {
+                       extern  void reboot();
+                       printf("Reboot System Now ...\n");
+                       int i = 100000;
+                       while(i--);
+                       reboot();
+               }
+               if(ScanCode ==  MC_BACKSPACE)
+               {
+                       extern  void poweroff();
+                       printf("Shutdown System Now ...\n");
+                       int i = 100000;
+                       while(i--);
+                       poweroff();
+               }
+       }
+
+
+       switch(ScanCode)
+       {
+       case    MC_L_SHIFT:     SET_L_SHIFT_DOWN(key);  goto End;
+       case    MC_R_SHIFT:     SET_R_SHIFT_DOWN(key);  goto End;
+
+       case    MC_CTRL:
+               E0Flag?SET_R_CTRL_DOWN(key):SET_L_CTRL_DOWN(key);
+               goto End;
+       case    MC_ALT:
+
+               E0Flag?SET_R_ALT_DOWN(key):SET_L_ALT_DOWN(key);
+               goto End;
+       }
+               
+       goto    End;
+
+BreakCode:
+       switch(ScanCode)
+       {
+       case    BC_L_SHIFT:     SET_L_SHIFT_UP(key);    goto End;
+       case    BC_R_SHIFT:     SET_R_SHIFT_UP(key);    goto End;
+       case    BC_CTRL:
+               E0Flag?SET_R_CTRL_UP(key):SET_L_CTRL_UP(key);
+               goto End;
+       case    BC_ALT:
+               E0Flag?SET_R_ALT_UP(key):SET_L_ALT_UP(key);
+               goto End;
+       }
+
+End:
+
+       key &= 0xFFFFFF00;
+       key |= (((E0Flag)?0x00:ScanCode) & 0xFF);
+
+       E0Flag = 0;
+
+       return key;
+
+}
+
+
+
+void ParseKbdInput()
+{
+       unsigned int k;
+       unsigned int inx;
+       unsigned char chr;
+       static unsigned char CapsLock;
+
+       k = _parse_kbd();
+
+       if(k == -1) return ;
+
+       inx = k & 0xFF;
+       chr = 0;
+
+       if(inx >= sizeof(kbdCharTable)) goto End;
+
+       // CapsLock ON OR OFF
+       if(inx == MC_CAPSLOCK)
+               CapsLock = (CapsLock)?0:1;
+
+
+       //if((!IS_L_SHIFT_DOWN(k) && !IS_R_SHIFT_DOWN(k) && CapsLock == 0)
+       //|| ((IS_L_SHIFT_DOWN(k) || IS_R_SHIFT_DOWN(k)) && CapsLock ==1))
+       if(!IS_L_SHIFT_DOWN(k) && !IS_R_SHIFT_DOWN(k))
+       {
+               chr = kbdCharTable[inx];
+               if(CapsLock ==1 && chr >= 'a' && chr <= 'z')
+                       chr -= 32;
+       }
+       else
+       {
+               chr = kbdShiftCharTable[inx];
+               if(CapsLock ==1 && chr >= 'A' && chr <= 'Z')
+                       chr += 32;
+       }
+
+End:
+       if(chr != 0)
+               printf("%c", chr);
+}
+
+int    sysc_read_kbd()
+{
+       return getScanCode();
+}
diff --git a/drivers/vga.c b/drivers/vga.c
new file mode 100644 (file)
index 0000000..c27d820
--- /dev/null
@@ -0,0 +1,137 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:        vga.c
+ * 
+ *      Author:        Zhao Yanbai [zhaoyanbai@126.com]
+ *                     Sat Jul 18 23:01:18 2009
+ * 
+ * Description:        none
+ * 
+ *--------------------------------------------------------------------------
+ */
+
+#include<io.h>
+
+#define        VGA_CRTC_ADDR   0x3D4
+#define        VGA_CRTC_DATA   0x3D5
+#define        VGA_CRTC_START_ADDR_H   0xC
+#define        VGA_CRTC_START_ADDR_L   0xD
+#define        VGA_CRTC_CURSOR_H       0xE
+#define        VGA_CRTC_CURSOR_L       0xF
+
+
+#define        LINES_PER_SCREEN        24      //25
+#define        CHARS_PER_LINE          80
+#define        BYTES_PER_LINE          (CHARS_PER_LINE<<1)
+#define        MAX_LINES               (LINES_PER_SCREEN<<1)
+#define        VIDEO_ADDR              0xC00B8000
+
+static unsigned int xpos, ypos;
+
+void   setCursorPos(unsigned int x, unsigned int y);
+void   printString(const char *buf, unsigned char color);
+void   printChar(const unsigned char c, const unsigned char color);
+void   ScrollUp();
+
+void   setCursorPos(unsigned int x, unsigned int y)
+{
+       unsigned short  offset = x +  y * CHARS_PER_LINE;
+       outb(VGA_CRTC_CURSOR_H, VGA_CRTC_ADDR);
+       outb((offset>>8) & 0xFF,VGA_CRTC_DATA);
+       outb(VGA_CRTC_CURSOR_L, VGA_CRTC_ADDR);
+       outb(offset & 0xFF,     VGA_CRTC_DATA);
+}
+
+void   printChar(const unsigned char c, const unsigned char color)
+{
+       unsigned short * const pv = (unsigned short * const) VIDEO_ADDR;
+
+       switch(c)
+       {
+       case '\r':
+               xpos = 0;
+               break;
+       case '\n':
+               xpos = 0; ypos++;
+               break;
+       case '\t':
+               xpos &= (~0x07);
+               xpos += 8;
+               if(xpos >= CHARS_PER_LINE)
+               {
+                       xpos = 0;
+                       ypos ++;
+               }
+               break;
+       case '\b':
+               if(xpos > 0)
+                       xpos--;
+               else if(ypos > 0)
+               {
+                       xpos = CHARS_PER_LINE - 1;
+                       ypos --;
+               }
+               *(pv + xpos + ypos*CHARS_PER_LINE) = ' ' | (color << 8);
+               break;
+       default:
+               *(pv + xpos + ypos*CHARS_PER_LINE) = c | (color << 8);
+               xpos ++;
+               if(xpos == CHARS_PER_LINE)
+               {
+                       xpos = 0;
+                       ypos ++;
+               }
+               break;
+       }
+
+       ScrollUp();
+
+       setCursorPos(xpos, ypos);
+}
+
+void   ScrollUp()
+{
+       static unsigned int last_ypos;
+       unsigned short topline;
+       if((ypos >= LINES_PER_SCREEN) && (ypos > last_ypos))
+       {
+               topline = ypos - LINES_PER_SCREEN;
+
+               if(topline == MAX_LINES)
+               {
+
+                       memcpy( VIDEO_ADDR,
+                               VIDEO_ADDR+MAX_LINES*BYTES_PER_LINE,
+                               LINES_PER_SCREEN*BYTES_PER_LINE);
+
+                       unsigned char *p;
+                       const unsigned char *pend;
+                       p=(unsigned char *)
+                       VIDEO_ADDR+LINES_PER_SCREEN*BYTES_PER_LINE;
+                       while(p <=(unsigned char *) VIDEO_ADDR 
+                       + (LINES_PER_SCREEN+MAX_LINES)*BYTES_PER_LINE)
+                       {
+                               *p++ = ' ';
+                               *p++ = 0x0F;
+                       }
+                       ypos -= topline;
+                       topline = 0;
+               }
+               outb(VGA_CRTC_START_ADDR_H,VGA_CRTC_ADDR);
+               outb(((topline*CHARS_PER_LINE)>>8)&0xFF,VGA_CRTC_DATA);
+               outb(VGA_CRTC_START_ADDR_L,VGA_CRTC_ADDR);
+               outb((topline*CHARS_PER_LINE)&0xFF,VGA_CRTC_DATA);
+       }
+       last_ypos = ypos;
+}
+
+void   printString(const char *buf, unsigned char color)
+{
+       char *p = (char *) buf;
+
+       while(*p)
+       {
+               printChar(*p, color);
+               p++;
+       }
+}
diff --git a/fs/Makefile b/fs/Makefile
new file mode 100644 (file)
index 0000000..23675f3
--- /dev/null
@@ -0,0 +1,23 @@
+include ../kernel.mk
+CC = gcc
+CFLAGS = $(CF)
+
+CSOUCE_FILES = $(wildcard *.c)
+SSOUCE_FILES = $(wildcard *.S)
+OBJS  = $(patsubst %.c,%.o,$(CSOUCE_FILES))
+OBJS += $(patsubst %.S,%.S.o,$(SSOUCE_FILES))
+
+%.o : %.c ../include/*.h ./*.h
+       $(CC) $(CFLAGS) $< -o $@
+%.S.o : %.S  ../include/*.h ./*.h
+       $(CC) $(CFLAGS) $< -o $@
+
+
+all:$(OBJS)
+
+.PHONY:clean
+clean:
+       $(RM) $(OBJS)
+.PHONY:c
+c:
+       make clean
diff --git a/fs/ext2.c b/fs/ext2.c
new file mode 100644 (file)
index 0000000..a9f96f2
--- /dev/null
+++ b/fs/ext2.c
@@ -0,0 +1,317 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:        ext2.c
+ * 
+ *      Author:        Zhao Yanbai [zhaoyanbai@126.com]
+ *                     Sun Feb 14 15:52:01 2010
+ * 
+ * Description:        none
+ * 
+ *--------------------------------------------------------------------------
+ */
+
+#include<fs.h>
+#include<system.h>
+#include<string.h>
+#include<stat.h>
+
+unsigned int ext2_start_sect;
+Inode  ext2_root_inode;
+
+extern void hd_read(Dev dev, u64 sect_nr, void *buf, u32 count);
+void   ext2_read_block(int block_id, char *buf);
+static void ext2_print_group_descriptor(pGroupDesc p);
+static void ext2_print_inode(pInode p);
+int ext2_search_file(const char *file, const pInode in, pInode out);
+//char *ext2_loadfile(const char *path, size_t *file_size);
+
+/* ext2 super block */
+SuperBlock ext2_sb
+       __attribute__((__aligned__(PAGE_SIZE)));
+Inode  inode_table[NR_INODES]
+       __attribute__((__aligned__(PAGE_SIZE))) = {{0,},};
+/* 
+ * ext2 group descriptor table
+ * 其大小为一个EXT2_BLOCK_SIZE
+ */
+static pGroupDesc gdesc;
+
+void   setup_ext2()
+{
+       int i;
+
+       hd_read(ROOT_DEV, ext2_start_sect+2, EXT2_SB, sizeof(SuperBlock));
+       printk("EXT2 SB:%x\n", sizeof(SuperBlock));
+       printk("inodes count: %d\n", EXT2_SB->s_inodes_count);
+       printk("blocks count: %d\n", EXT2_SB->s_blocks_count);
+       printk("s_magic: %x\n", EXT2_SB->s_magic);
+       printk("LOG BLOCK SIZE:%x\n", EXT2_SB->s_log_block_size);
+       printk("Block Size:%d %x\n", EXT2_BLOCK_SIZE, EXT2_BLOCK_SIZE);
+
+
+       if(EXT2_SB->s_magic != 0xEF53)
+               panic("Only Support Ext2 File System...");
+
+       /* 分配group descriptor table 的内存 */
+       gdesc = (pGroupDesc) kmalloc(EXT2_BLOCK_SIZE);
+       if(gdesc == NULL)
+               panic("out of memory for ext2 group descritpor table");
+       /* 初始化ext2 group descriptor table */
+       ext2_read_block(EXT2_FIRST_BLOCK_ID+1, (char *)gdesc);
+#if 0
+       printk("-------%d %d %d",
+               EXT2_BLOCK_SIZE, EXT2_INODE_SIZE, EXT2_INODES_PER_BLOCK);
+       for(i=0; i<12; i++)
+               ext2_print_group_descriptor(gdesc+i);
+#endif
+
+       ext2_read_inode(2, &ext2_root_inode);
+#if 1
+       ext2_print_inode(&ext2_root_inode);
+#endif
+
+#if 0
+       Inode   boot_ino, grub_ino, grubconf_ino;
+       int     boot_n, grub_n, grubconf_n;
+       boot_n = ext2_search_file("boot", &ext2_root_inode, &boot_ino);
+       printk("boot_n:%d size:%d\n", boot_n, boot_ino.i_size);
+       grub_n = ext2_search_file("grub", &boot_ino, &grub_ino);
+       printk("grub_n:%d size:%d\n", grub_n, grub_ino.i_size);
+       grubconf_n = ext2_search_file("grub.conf",
+                                       &grub_ino, &grubconf_ino);
+       printk("grubconf_n:%d size:%d\n", grubconf_n, grubconf_ino.i_size);
+#endif
+#if 0
+       size_t filesz;
+       char *buf=ext2_loadfile("/boot/grub/grub.conf", &filesz);
+
+       for(i=0; i<filesz; i++)
+               printk("%c", buf[i]);
+#endif
+#if 0
+       unsigned char *p = (char *)kmalloc(EXT2_BLOCK_SIZE);
+       ext2_read_block(0, p);
+
+       for(i=0; i<512; i++)
+               printk("%02x ", p[i]);
+#endif
+#if 0
+       int dly = 0xF000000;
+       while(dly--);
+#endif
+}
+
+void   ext2_read_block(int block_id, char *buf)
+{
+       u64 sect = EXT2_SECT;
+       sect += block_id*EXT2_SECT_PER_BLOCK;
+
+       //printk("block id: %d sect:%d\n", block_id, sect);
+
+       hd_read(ROOT_DEV, sect, buf, EXT2_BLOCK_SIZE);
+}
+
+
+/*
+ * 写这版ext2_read_inode的时候我想起了2008.12.16在0.2.1中写的
+ * 那个 GetInode. 这两个函数完成的是同样的功能.但是很明显
+ * 之前的那个版本写得那是相当的滑稽幼稚.甚至还有大大的BUG.
+ * 但是正是这些点滴见证着我的内核的成长.
+ */
+int    ext2_read_inode(unsigned int n, pInode ino)
+{
+       assert(1<=n && n <= EXT2_INODES_COUNT);
+       if(n == EXT2_BAD_INO) return 0;
+
+       unsigned int    gnr;    /* inode 所在的group的号 */
+       unsigned int    gidx;   /* inode 所在的group的偏移 */
+       unsigned int    inotbl; /* inode table 的 block id */
+
+
+       gnr     = (n-1) / EXT2_INODES_PER_GROUP;
+       gidx    = (n-1) % EXT2_INODES_PER_GROUP;
+
+       inotbl  = (gdesc+gnr)->bg_inode_table;
+
+       // 跳过完整的BLOCK
+       inotbl += (gidx/EXT2_INODES_PER_BLOCK);
+       gidx   %= EXT2_INODES_PER_BLOCK;
+
+
+       char *buf = kmalloc(EXT2_BLOCK_SIZE);
+       if(buf == NULL)
+               panic("faild read inode. out of memory");
+       ext2_read_block(inotbl, buf);
+
+       memcpy((void *)ino,(void*)(((pInode)buf)+gidx), EXT2_INODE_SIZE);
+
+       kfree(buf);
+
+       return n;
+}
+int ext2_read_file(const pInode ino, void *buf, size_t count)
+{
+       int i, blks;
+       void *p;
+
+       blks = (ino->i_size+EXT2_BLOCK_SIZE-1)/EXT2_BLOCK_SIZE;
+       assert(blks>0);
+
+       if(blks > EXT2_NDIR_BLOCKS)
+               panic("file too large to read");
+
+       p = kmalloc(blks*EXT2_BLOCK_SIZE);
+
+       if(p == NULL)
+               panic("out of memory when search inode in directory");
+
+       for(i=0; i<blks; i++)
+       {
+               ext2_read_block(ino->i_block[i],
+                       (char *)(i*EXT2_BLOCK_SIZE + (unsigned long)p));
+       }
+
+       memcpy(buf, p, count);
+
+       kfree(p);
+
+       return count;
+}
+#if 0
+char *load_inode_content(const pInode ino)
+{
+       int i, blks;
+       char *buf;
+
+       blks = (ino->i_size+EXT2_BLOCK_SIZE-1)/EXT2_BLOCK_SIZE;
+       assert(blks>0);
+       if(blks > EXT2_NDIR_BLOCKS)
+               panic("unsupport file large than 12KB");
+
+
+       buf = kmalloc(blks*EXT2_BLOCK_SIZE);
+       if(buf == NULL)
+               panic("out of memory when search inode in directory");
+       for(i=0; i<blks; i++)
+       {
+               ext2_read_block(ino->i_block[i], buf + i*EXT2_BLOCK_SIZE);
+       }
+
+       return buf;
+}
+#endif
+
+/*
+ * 从in中查找file从out返回
+ * int 型的函数返回值的意思是inode号
+ * 失败则返回的是EXT2_BAD_INO
+ */
+int ext2_search_file(const char *file, const pInode in, pInode out)
+{
+       assert(file != NULL);
+       assert(in != NULL);
+       assert(S_ISDIR(in->i_mode));
+
+       char *buf;
+#if 0
+       buf = load_inode_content(in);
+#else
+       buf = kmalloc(in->i_size);
+       ext2_read_file(in, buf, in->i_size);
+#endif
+
+       pDirEnt ent = (pDirEnt)buf;
+       int len = strlen(file);
+       int inode_n = EXT2_BAD_INO;
+       while(ent < (pDirEnt)(buf + in->i_size))
+       {
+               if(ent->name_len == len)
+               {
+                       if(strncmp(file, ent->name, ent->name_len) == 0)
+                       {
+                               inode_n = ent->inode;
+#if 0
+                               printk("file: %s\n", ent->name);
+#endif
+                               break;
+                       }
+               }
+
+
+               ent = (pDirEnt)(ent->rec_len + (unsigned long)ent);
+       }
+       kfree(buf);
+
+       ext2_read_inode(inode_n, out);
+
+       return inode_n;
+}
+
+
+static int get_filename_from_path(const char *path, char *filename)
+{
+       int i = 0;
+
+       while(*path != '/' && *path != '\0')
+       {
+               filename[i++] = *path++;
+       }
+       filename[i] = 0;
+
+
+       return i; // file name len
+}
+
+
+int ext2_get_file_inode_nr(const char *path)
+{
+       assert(*path++ == '/'); /* 目前只支持从根目录开始的路径 */
+       Inode   ino = ext2_root_inode;
+       int     ino_nr, len;
+       char file[EXT2_NAME_LEN];
+
+       while((len=get_filename_from_path(path, file)) != 0)
+       {
+#if 0
+               printk("file: %s ", file);
+#endif
+               ino_nr = ext2_search_file(file, &ino, &ino);
+
+               path += len;
+
+               if(*path != 0)
+                       path++;
+       }
+#if 0
+       printk("ino_nr:%d\n", ino_nr);
+#endif
+       return ino_nr;
+}
+
+#if 0
+/*
+ * 需要自己释放内存
+ */
+char *ext2_loadfile(const char *path, size_t *file_size)
+{
+       char *buf;
+       buf = load_inode_content(&inode);
+       *file_size = inode.i_size;
+
+       return buf;
+}
+#endif
+
+static void ext2_print_group_descriptor(pGroupDesc p)
+{
+       printk("block bitmap:%d inode bitmap:%d inode table:%d\n",
+               p->bg_block_bitmap,
+               p->bg_inode_bitmap,
+               p->bg_inode_table);
+}
+
+static void ext2_print_inode(pInode p)
+{
+       printk("i_mode:%04x i_size:%d i_blocks:%d\n",
+               p->i_mode, p->i_size, p->i_blocks);
+}
diff --git a/fs/fs.c b/fs/fs.c
new file mode 100644 (file)
index 0000000..3348586
--- /dev/null
+++ b/fs/fs.c
@@ -0,0 +1,198 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:        fs.c
+ * 
+ *      Author:        Zhao Yanbai [zhaoyanbai@126.com]
+ *                     Fri Feb 12 20:48:50 2010
+ * 
+ * Description:        none
+ * 
+ *--------------------------------------------------------------------------
+ */
+#include<fs.h>
+#include<io.h>
+#include<printk.h>
+#include<system.h>
+#define        SECT_SIZE       512
+
+File   file_table[NR_FILES]
+       __attribute__ ((__aligned__(PAGE_SIZE))) = {{0,},};
+extern unsigned int ext2_start_sect;
+void   hd_read(Dev dev, u64 sect_nr, void *buf, u32 count);
+void   init_file_table();
+void   save_boot_part(int n, pPartition p, u32 base_sect);
+void   read_ext_part(u32 base, u32 offset);
+
+void   setup_fs()
+{
+       int i, minor;
+       pPartition p;
+       unsigned char *buf;
+
+
+       init_file_table();
+
+
+       minor = DEV_MINOR(ROOT_DEV);
+       buf = (unsigned char *) get_virt_pages(1);
+       hd_read(ROOT_DEV, 0, buf, SECT_SIZE);
+
+
+       for(i=0; i<4; i++)
+       {
+               p = (pPartition)(buf+PARTS_POS) + i;
+               if(p->Type == 0)
+                       continue;
+
+               //save_boot_part(i+1, p, p->AbsoluteSectNo);
+               save_boot_part(i, p, p->AbsoluteSectNo);
+
+               printk("hd%d\tbase: %08x size: %08x type:%02x",
+                       i, p->AbsoluteSectNo, p->PartitionSize, p->Type);
+               if(p->Type == 0x05)
+               {
+                       printk("\tExtend\n");
+                       //read_ext_part(p->AbsoluteSectNo, 0);
+               }
+               else
+                       printk("\n");
+       }
+
+
+       printk("ext2_start_sect: %x\n", ext2_start_sect);
+
+
+       return ;
+       //int j = 0xF0000000;
+       //while(j--);
+       
+
+/*
+       minor = 5;      
+       if(minor >= 5)
+       {
+               for(i=0; i<4; i++)
+               {
+                       p = (pPartition)(buf+PARTS_POS) + i;
+                       if(p->Type == 0x05)
+                               break;
+               }
+               assert(i<4);
+               //read_ext_part(0, p->AbsoluteSectNo);
+               read_ext_part(p->AbsoluteSectNo, 0);
+       }
+*/
+#if 0
+       outb(0x00, 0x1F1);
+       outb(1, 0x1F2);
+       outb(0x00, 0x1F3);
+       outb(0x00, 0x1F4);
+       outb(0x00, 0x1F5);
+       outb(0xE0, 0x1F6);
+       outb(0xEC, 0x1F7);
+       while(!(inb(0x1F7) & 0x08)){}
+       /*
+       while(1)
+       {
+               printk("%02x ", inb(0x1F7));
+       }*/
+       asm("cld;rep;insw;"::"c"(256), "d"(0x1F0), "D"(buf));
+
+       for(i=0; i<512; i++)
+               printk("%02x ", buf[i]);
+#endif
+
+#if 0
+#define        SZ      512
+       hd_read(ROOT_DEV, 0, buf, SZ);
+       //hd_read(0, 1, buf+512, 512);
+       //hd_read(0,0,buf, 1023);
+       pPartition p;
+#if 0
+       for(i=0; i<SZ; i++)
+               printk("%02x ", buf[i]);
+       while(1);
+#endif
+#endif
+#if 0
+       for(i=0; i<4; i++)
+       {
+               p = (pPartition)(buf+PARTS_POS)+i;
+               printk( "State:%02x Head:%d StartSC:%d Type:%02x "
+                       "EndHead:%d EndSC:%d AboluteSectNo:%d "
+                       "PartitionSize:%d\n",
+               p->State, p->Head, p->StartSC, p->Type,
+               p->EndHead, p->EndSC, p->AbsoluteSectNo, p->PartitionSize);
+       }
+#endif
+
+#if 0
+       int j, k;
+       j = 0x10000;
+       while(j--)
+       {
+               k = 0x10000;
+               while(k--);
+       }
+#endif
+}
+
+void   init_file_table()
+{
+       int i;
+
+       for(i=0; i<NR_FILES; i++)
+       {
+               file_table[i].count     = 0;
+               file_table[i].ino_nr    = 0;
+               file_table[i].inode     = NULL;
+       }
+}
+
+void   save_boot_part(int n, pPartition p, u32 base_sect)
+{
+       if(p->Type == 0x05)
+               panic("partition should not be extended");
+
+       int minor = DEV_MINOR(ROOT_DEV);
+
+       if(minor-1 == n)
+               ext2_start_sect = base_sect;
+}
+
+static unsigned int ext_part = 5;
+void   read_ext_part(u32 base, u32 offset)
+{
+       unsigned char *buf;
+       pPartition p;
+       buf = get_virt_pages(1);
+
+       //printk("^^^^^^^^^:%08x\n", base+offset);
+       hd_read(ROOT_DEV, base+offset, buf, SECT_SIZE);
+       int i;
+
+       for(i=0; i<4; i++)
+       {
+               p = (pPartition)(buf+PARTS_POS) + i;
+               if(p->Type == 0x00)
+                       continue;
+
+               if(p->Type != 0x05)
+               {
+
+                       //save_boot_part(ext_part, p, 0);
+                       printk("  hd%d\tbase: %08x size: %08x type:%02x\n",
+                               ext_part++, base+p->AbsoluteSectNo,
+                               p->PartitionSize, p->Type);
+               }
+               else
+               {
+                       read_ext_part(base, p->AbsoluteSectNo);
+               }
+       }
+
+       printk("\n");
+
+       free_virt_pages(buf);
+}
+
diff --git a/fs/open.c b/fs/open.c
new file mode 100644 (file)
index 0000000..564c7ea
--- /dev/null
+++ b/fs/open.c
@@ -0,0 +1,93 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:        open.c
+ * 
+ *      Author:        Zhao Yanbai [zhaoyanbai@126.com]
+ *                     Sat Feb 20 18:53:47 2010
+ * 
+ * Description:        none
+ * 
+ *--------------------------------------------------------------------------
+ */
+
+#include<fs.h>
+#include<errno.h>
+#include<types.h>
+#include<sched.h>
+#include<fcntl.h>
+#include<assert.h>
+#include<syscall.h>
+
+int sysc_open(const char *path, int flags, mode_t mode)
+{
+       assert(mode == 0); // unsupport now...
+       assert(flags == O_RDONLY);      // support only...
+
+       int ino_nr, i, fd;
+       pInode inode;
+
+       /* 先获取文件的i节点号 */
+       ino_nr = get_inode_nr(path);
+       if(ino_nr == EXT2_BAD_INO)
+               return -ENOENT;
+
+       /* 找到空的文件描述符句柄 */
+       for(i=0; i<NR_OPENS; i++)
+               if(current->fps[i] == NULL)
+                       break;
+       if(i == NR_OPENS)
+               return -EMFILE;
+       fd = i;
+
+
+       /* 找到空的描述符或已经打开的描述符 */
+       int empt_nr, fdt_nr;
+       pFile pf;
+       empt_nr = fdt_nr = -1;
+       for(i=0, pf=file_table; i<NR_FILES; i++, pf++)
+       {
+               if(pf->ino_nr == ino_nr)
+               {
+                       fdt_nr = i;
+                       break;
+               }
+               else if(pf->ino_nr == 0)
+               {
+                       empt_nr = i;
+               }
+       }
+
+       if(fdt_nr != -1)
+       {
+               pf = file_table+fdt_nr;
+       }
+       else if(empt_nr != -1)
+       {
+               pf = file_table+empt_nr;
+       }
+       else
+       {
+               return -EMFILE;
+       }
+
+
+       if(pf->ino_nr == ino_nr)
+       {
+               pf->count++;
+               current->fps[fd] = pf;
+               return fd;
+       }
+
+       inode = find_empty_inode();
+       if(inode == NULL)
+               return -ENOMEM;
+
+       get_inode(ino_nr, inode);
+       
+       pf->count = 1;
+       pf->ino_nr = ino_nr;
+       pf->inode = inode;
+       current->fps[fd] = pf;
+
+       return fd;
+}
diff --git a/fs/read.c b/fs/read.c
new file mode 100644 (file)
index 0000000..873d3b8
--- /dev/null
+++ b/fs/read.c
@@ -0,0 +1,33 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:        read.c
+ * 
+ *      Author:        Zhao Yanbai [zhaoyanbai@126.com]
+ *                     Tue Feb 23 18:53:47 2010
+ * 
+ * Description:        none
+ * 
+ *--------------------------------------------------------------------------
+ */
+#include<types.h>
+#include<assert.h>
+#include<fs.h>
+#include<errno.h>
+#include<sched.h>
+
+int sysc_read(int fd, void *buf, size_t count)
+{
+       if(fd<0 || fd>=NR_OPENS)
+               return -EBADF;
+
+       pFile fp = current->fps[fd];
+       assert(fp != NULL);
+
+       pInode  inode = fp->inode;
+       assert(inode->i_size > 0);      // 目前只能这样支持
+       if(inode->i_size > MAX_SUPT_FILE_SIZE)
+               return -EFAULT;
+
+
+       return read_file(inode, buf, count);
+}
diff --git a/fs/stat.c b/fs/stat.c
new file mode 100644 (file)
index 0000000..5373949
--- /dev/null
+++ b/fs/stat.c
@@ -0,0 +1,44 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:        stat.c
+ * 
+ *      Author:        Zhao Yanbai [zhaoyanbai@126.com]
+ *                     Tue Feb 23 19:56:08 2010
+ * 
+ * Description:        none
+ * 
+ *--------------------------------------------------------------------------
+ */
+#include<types.h>
+#include<stat.h>
+#include<errno.h>
+#include<fs.h>
+#include<sched.h>
+#include<memory.h>
+int sysc_stat(int fd, struct stat *stat)
+{
+       if(fd<0 || fd>=NR_OPENS)
+               return -EBADF;
+
+       pFile fp = current->fps[fd];
+       assert(fp != NULL);
+
+       pInode  inode = fp->inode;
+       assert(inode->i_size > 0);      // 目前只能这样支持
+       if(inode->i_size > MAX_SUPT_FILE_SIZE)
+               return -EFAULT;
+
+       memset((void*)stat, 0, sizeof(struct stat));
+
+       stat->st_ino    = fp->ino_nr;
+       stat->st_mode   = inode->i_mode;
+       stat->st_uid    = inode->i_uid;
+       stat->st_gid    = inode->i_gid;
+       stat->st_size   = inode->i_size;
+       stat->st_blocks = inode->i_blocks;
+       stat->st_atime  = inode->i_atime;
+       stat->st_mtime  = inode->i_mtime;
+       stat->st_ctime  = inode->i_ctime;
+
+       return 0;
+}
diff --git a/fs/write.c b/fs/write.c
new file mode 100644 (file)
index 0000000..89e7c15
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:        write.c
+ * 
+ * Description:        none
+ * 
+ * 
+ *      Author:        Zhao Yanbai [zhaoyanbai@126.com]
+ * 
+ *     Version:        1.0
+ * Create Date: Sun Mar  8 11:05:12 2009
+ * Last Update: Sun Mar  8 11:05:12 2009
+ * 
+ *--------------------------------------------------------------------------
+ */
+
+
+extern void    printString(const char *buf, unsigned char color);
+int sysc_write(int fd, const char *buf, unsigned long size)
+{
+       if(size < 0) return -1;
+
+       switch(fd)
+       {
+       case 0:
+               printString(buf, 0xF);
+               break;
+       default:
+               return -1;
+       }
+
+       return size;
+}
diff --git a/include/assert.h b/include/assert.h
new file mode 100644 (file)
index 0000000..e157a7e
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:        assert.h
+ * 
+ *      Author:        Zhao Yanbai [zhaoyanbai@126.com]
+ *                     Sat Jan 23 14:02:00 2010
+ * 
+ * Description:        none
+ * 
+ *--------------------------------------------------------------------------
+ */
+
+#ifndef        _ASSERT_H
+#define        _ASSERT_H
+
+#include<global.h>
+
+#define        assert(exp)                                                     \
+( (exp)                                                                        \
+? (void) (0)                                                           \
+: assert_fail(__STRING(exp), __FILE__, __LINE__, __PRETTY_FUNCTION__))
+
+#endif //_ASSERT_H
diff --git a/include/bits.h b/include/bits.h
new file mode 100644 (file)
index 0000000..b73d895
--- /dev/null
@@ -0,0 +1,203 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:        bits.h
+ * 
+ * Description:        none
+ * 
+ * 
+ *      Author:        Zhao Yanbai [zhaoyanbai@126.com]
+ * 
+ *     Version:        1.0
+ * Create Date: Wed Mar  4 20:56:29 2009
+ * Last Update: Wed Mar  4 20:56:29 2009
+ * 
+ *--------------------------------------------------------------------------
+ */
+
+#ifndef        _BITS_H
+#define        _BITS_H
+
+//#define      SET_BIT(bit) (1UL<<bit)
+//#define      CLR_BIT(bit) (~(1UL<<bit))
+//#define      ISSET_BIT(val,bit) ((val) & SET_BIT(bit))
+#define        SET_BIT(val, bit)       (val |= (1UL<<bit))
+#define        CLR_BIT(val, bit)       (val &= (~(1UL<<bit)))
+#define        XOR_BIT(val, bit)       (btc((unsigned int *)&val, bit), val)
+#define        ISSET_BIT(val, bit)     (val & (1UL<<bit))
+#define        ISCLR_BIT(val, bit)     (!ISSET_BIT(val, bit))
+
+#define BITS_PER_LONG (sizeof(unsigned long)*8)
+
+static inline void btc(unsigned int *v, unsigned int b)
+{
+       asm ("btc %1,%0":"=m"(*v): "Ir"(b));
+}
+
+static inline int test_and_set_bit(long nr, volatile unsigned long *addr)
+{
+    int oldbit;
+
+    asm("bts %2,%1\n\t"
+        "sbb %0,%0"
+        : "=r" (oldbit), "+m" (*(volatile long *) (addr))
+        : "Ir" (nr));
+    return oldbit;
+}
+
+static inline int test_and_clear_bit(int nr, volatile unsigned long *addr)
+{
+       int oldbit;
+
+       asm volatile("btr %2,%1\n\t"
+                    "sbb %0,%0"
+                    : "=r" (oldbit), "+m" (*(volatile long *) (addr)) 
+                    : "Ir" (nr) : "memory");
+
+       return oldbit;
+}
+/**
+ * test_and_change_bit - Change a bit and return its old value
+ * @nr: Bit to change
+ * @addr: Address to count from
+ *
+ * This operation is atomic and cannot be reordered.
+ * It also implies a memory barrier.
+ */
+static inline int test_and_change_bit(int nr, volatile unsigned long *addr)
+{
+       int oldbit;
+
+       asm volatile("btc %2,%1\n\t"
+                    "sbb %0,%0"
+                    : "=r" (oldbit), "+m" (*(volatile long *) (addr)) 
+                    : "Ir" (nr) : "memory");
+
+       return oldbit;
+}
+
+/**
+ * change_bit - Toggle a bit in memory
+ * @nr: the bit to change
+ * @addr: the address to start counting from
+ *
+ * Unlike change_bit(), this function is non-atomic and may be reordered.
+ * If it's called on the same region of memory simultaneously, the effect
+ * may be that only one operation succeeds.
+ */
+static inline void change_bit(int nr, volatile unsigned long *addr)
+{
+       asm volatile("btc %1,%0": "+m" (*(volatile long *) (addr)) 
+                               : "Ir" (nr));
+}
+
+static inline int constant_test_bit(unsigned int nr, const volatile unsigned long *addr)
+{
+   return ((1UL << (nr % BITS_PER_LONG)) &
+       (((unsigned long *)addr)[nr / BITS_PER_LONG])) != 0;
+}
+
+/**
+ * find_first_bit - find the first set bit in a memory region
+ * @addr: The address to start the search at
+ * @size: The maximum size to search
+ *
+ * Returns the bit-number of the first set bit, not the number of the byte
+ * containing a bit.
+ */
+static inline int find_first_bit(const unsigned long *addr, unsigned size)
+{
+       int d0, d1;
+       int res;
+
+       /* This looks at memory. Mark it volatile to tell gcc not to move it around */
+       __asm__ __volatile__(
+               "xorl %%eax,%%eax\n\t"
+               "repe; scasl\n\t"
+               "jz 1f\n\t"
+               "leal -4(%%edi),%%edi\n\t"
+               "bsfl (%%edi),%%eax\n"
+               "1:\tsubl %%ebx,%%edi\n\t"
+               "shll $3,%%edi\n\t"
+               "addl %%edi,%%eax"
+               :"=a" (res), "=&c" (d0), "=&D" (d1)
+               :"1" ((size + 31) >> 5), "2" (addr), "b" (addr) : "memory");
+       return res;
+}
+
+/**
+ * find_first_zero_bit - find the first zero bit in a memory region
+ * @addr: The address to start the search at
+ * @size: The maximum size to search
+ *
+ * Returns the bit-number of the first zero bit, not the number of the byte
+ * containing a bit.
+ */
+static inline int find_first_zero_bit(const unsigned long *addr, unsigned size)
+{
+       int d0, d1, d2;
+       int res;
+
+       if (!size)
+               return 0;
+       /* This looks at memory. Mark it volatile to tell gcc not to move it around */
+       __asm__ __volatile__(
+               "movl $-1,%%eax\n\t"
+               "xorl %%edx,%%edx\n\t"
+               "repe; scasl\n\t"
+               "je 1f\n\t"
+               "xorl -4(%%edi),%%eax\n\t"
+               "subl $4,%%edi\n\t"
+               "bsfl %%eax,%%edx\n"
+               "1:\tsubl %%ebx,%%edi\n\t"
+               "shll $3,%%edi\n\t"
+               "addl %%edi,%%edx"
+               :"=d" (res), "=&c" (d0), "=&D" (d1), "=&a" (d2)
+               :"1" ((size + 31) >> 5), "2" (addr), "b" (addr) : "memory");
+       return res;
+}
+
+/**
+ * find_next_zero_bit - find the first zero bit in a memory region
+ * @addr: The address to base the search on
+ * @offset: The bitnumber to start searching at
+ * @size: The maximum size to search
+ */
+static inline int find_next_zero_bit(const unsigned long *addr, int size, int offset)
+{
+       unsigned long * p = ((unsigned long *) addr) + (offset >> 5);
+       int set = 0, bit = offset & 31, res;
+
+       if (bit) {
+               /*
+                * Look for zero in the first 32 bits.
+                */
+               __asm__("bsfl %1,%0\n\t"
+                       "jne 1f\n\t"
+                       "movl $32, %0\n"
+                       "1:"
+                       : "=r" (set)
+                       : "r" (~(*p >> bit)));
+               if (set < (32 - bit))
+                       return set + offset;
+               set = 32 - bit;
+               p++;
+       }
+       /*
+        * No zero yet, search remaining full bytes for a zero
+        */
+       res = find_first_zero_bit (p, size - 32 * (p - (unsigned long *) addr));
+       return (offset + set + res);
+}
+
+static inline int variable_test_bit(int nr, volatile const unsigned long *addr)
+{
+       int oldbit;
+
+       asm volatile("bt %2,%1\n\t"
+                    "sbb %0,%0"
+                    : "=r" (oldbit)
+                    : "m" (*(unsigned long *)addr), "Ir" (nr));
+
+       return oldbit;
+}
+#endif //_BITS_H
diff --git a/include/boot/bootparam.h b/include/boot/bootparam.h
new file mode 100644 (file)
index 0000000..494df90
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * ------------------------------------------------------------------------
+ *   File Name: bootparam.h
+ *      Author: Zhao Yanbai
+ *              Sat Mar 29 09:02:21 2014
+ * Description: none
+ * ------------------------------------------------------------------------
+ */
+
+#pragma once
+
+#include "multiboot.h"
+
+#define        E820_RAM        1
+#define        E820_RESERVED   2
+#define        E820_ACPI       3
+#define        E820_NVS        4
+#define E820_UNUSABLE 5
+
+#define E820_MAP_CNT 128
+
+struct e820_entry {
+    unsigned long addr;
+    unsigned long size;
+    unsigned long type;
+};
+
+struct e820map {
+    unsigned long map_cnt;
+    struct e820_entry map[E820_MAP_CNT];
+};
+
+struct boot_params {
+    char *cmdline;
+    unsigned long boot_device;
+    unsigned long root_device;
+
+    unsigned long mem_lower; // in bytes
+    unsigned long mem_upper; 
+
+    struct e820map e820map;
+};
+
+extern struct boot_params boot_params;
diff --git a/include/boot/multiboot.h b/include/boot/multiboot.h
new file mode 100644 (file)
index 0000000..2b751d1
--- /dev/null
@@ -0,0 +1,124 @@
+/* multiboot.h - the header for Multiboot */
+/* Copyright (C) 1999, 2001  Free Software Foundation, Inc.
+   
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+/* Macros.  */
+#pragma once
+
+/* The magic number for the Multiboot header.  */
+#define MULTIBOOT_HEADER_MAGIC         0x1BADB002
+
+/* The flags for the Multiboot header.  */
+#ifdef __ELF__
+# define MULTIBOOT_HEADER_FLAGS                0x00000003
+#else
+# define MULTIBOOT_HEADER_FLAGS                0x00010003
+#endif
+
+/* The magic number passed by a Multiboot-compliant boot loader.  */
+#define MULTIBOOT_BOOTLOADER_MAGIC     0x2BADB002
+
+/* The size of our stack (16KB).  */
+#define MULTIBOOT_STACK_SIZE           0x4000
+
+/* C symbol format. HAVE_ASM_USCORE is defined by configure.  */
+#ifdef HAVE_ASM_USCORE
+# define EXT_C(sym)                    _ ## sym
+#else
+# define EXT_C(sym)                    sym
+#endif
+
+#ifndef ASM
+/* Do not include here in boot.S.  */
+
+/* Types.  */
+
+/* The Multiboot header.  */
+typedef struct multiboot_header
+{
+  unsigned long magic;
+  unsigned long flags;
+  unsigned long checksum;
+  unsigned long header_addr;
+  unsigned long load_addr;
+  unsigned long load_end_addr;
+  unsigned long bss_end_addr;
+  unsigned long entry_addr;
+} multiboot_header_t;
+
+/* The symbol table for a.out.  */
+typedef struct aout_symbol_table
+{
+  unsigned long tabsize;
+  unsigned long strsize;
+  unsigned long addr;
+  unsigned long reserved;
+} aout_symbol_table_t;
+
+/* The section header table for ELF.  */
+typedef struct elf_section_header_table
+{
+  unsigned long num;
+  unsigned long size;
+  unsigned long addr;
+  unsigned long shndx;
+} elf_section_header_table_t;
+
+/* The Multiboot information.  */
+typedef struct multiboot_info
+{
+  unsigned long flags;
+  unsigned long mem_lower;
+  unsigned long mem_upper;
+  unsigned long boot_device;
+  unsigned long cmdline;
+  unsigned long mods_count;
+  unsigned long mods_addr;
+  union
+  {
+    aout_symbol_table_t aout_sym;
+    elf_section_header_table_t elf_sec;
+  } u;
+  unsigned long mmap_length;
+  unsigned long mmap_addr;
+} multiboot_info_t;
+
+
+/* The module structure.  */
+typedef struct module
+{
+  unsigned long mod_start;
+  unsigned long mod_end;
+  unsigned long string;
+  unsigned long reserved;
+} module_t;
+
+/* The memory map. Be careful that the offset 0 is base_addr_low
+   but no size.  */
+typedef struct memory_map
+{
+  unsigned long size;
+  unsigned long base_addr_low;
+  unsigned long base_addr_high;
+  unsigned long length_low;
+  unsigned long length_high;
+  unsigned long type;
+} memory_map_t;
+
+typedef multiboot_info_t MultiBootInfo, *pMultiBootInfo;
+typedef memory_map_t mmapItem, *pmmapItem;
+
+#endif /* ! ASM */
diff --git a/include/elf.h b/include/elf.h
new file mode 100644 (file)
index 0000000..ea6eb2f
--- /dev/null
@@ -0,0 +1,187 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:        elf.h
+ * 
+ *      Author:        Zhao Yanbai [zhaoyanbai@126.com]
+ *                     Sat Jan 30 19:36:15 2010
+ * 
+ * Description:        none
+ * 
+ *--------------------------------------------------------------------------
+ */
+
+#ifndef        _ELF_H
+#define        _ELF_H
+
+typedef        u16     Elf32_Half;
+typedef        u32     Elf32_Word;
+typedef        s32     Elf32_Sword;
+typedef        u64     Elf32_Xword;
+typedef        s64     Elf32_Sxword;
+typedef        u32     Elf32_Addr;
+typedef        u32     Elf32_Off;
+typedef        u16     Elf32_Section;
+typedef        Elf32_Half      Elf32_Versym;
+
+/*
+ *--------------------------------------------------------------------------
+ * ELF file Header.
+ * This appears at the start of every ELF file.
+ *--------------------------------------------------------------------------
+ */
+
+#define        EI_NIDENT       (16)
+typedef        struct
+{
+       unsigned char   e_ident[EI_NIDENT];
+       Elf32_Half      e_type;
+       Elf32_Half      e_machine;
+       Elf32_Word      e_version;
+       Elf32_Addr      e_entry;
+       Elf32_Off       e_phoff;
+       Elf32_Off       e_shoff;
+       Elf32_Word      e_flags;
+       Elf32_Half      e_ehsize;       // ELF Header Size in bytes 
+       Elf32_Half      e_phentsize;    // Program header table entry size
+       Elf32_Half      e_phnum;
+       Elf32_Half      e_shentsize;
+       Elf32_Half      e_shnum;
+       Elf32_Half      e_shstrndx;     //Section Header String Table Index
+}Elf32_Ehdr, *pElf32_Ehdr;
+
+#define        ELFMAG                  "\177ELF"
+#define        SELFMAG                 4
+
+#define        EI_MAG0                 0
+#define                ELFMAG0         0x7F
+
+#define        EI_MAG1                 1
+#define                ELFMAG1         'E'
+
+#define        EI_MAG2                 2
+#define                ELFMAG2         'L'
+
+#define        EI_MAG3                 3
+#define                ELFMAG3         'F'
+
+#define        EI_CLASS                4
+#define                ELFCLASSNONE    0
+#define                ELFCLASS32      1
+#define                ELFCLASS64      2
+#define                ELFCLASSNUM     3
+
+#define        EI_DATA                 5
+#define                ELFDATANONE     0
+#define                ELFDATA2LSB     1       /* 2's complement, little endian */
+#define                ELFDATA2MSB     2       /* 2's complement, big endian */
+#define                ELFDATANUM      3
+
+#define        EI_VERSION              6       /* value must be EV_CURRENT */
+
+#define        EI_OSABI                7       
+#define        ELFOSABI_NONE           0       /* UNIX System V ABI */
+#define        ELFOSABI_SYSV           0       /* Alias.  */
+#define        ELFOSABI_HPUX           1       /* HP-UX */
+#define        ELFOSABI_NETBSD         2       /* NetBSD.  */
+#define        ELFOSABI_LINUX          3       /* Linux.  */
+#define        ELFOSABI_SOLARIS        6       /* Sun Solaris.  */
+#define        ELFOSABI_AIX            7       /* IBM AIX.  */
+#define        ELFOSABI_IRIX           8       /* SGI Irix.  */
+#define        ELFOSABI_FREEBSD        9       /* FreeBSD.  */
+#define        ELFOSABI_TRU64          10      /* Compaq TRU64 UNIX.  */
+#define        ELFOSABI_MODESTO        11      /* Novell Modesto.  */
+#define        ELFOSABI_OPENBSD        12      /* OpenBSD.  */
+#define        ELFOSABI_ARM            97      /* ARM */
+#define        ELFOSABI_STANDALONE     255     /* Standalone (embedded) application */
+
+#define        EI_ABIVERSION           8
+
+#define        EI_PAD                  9
+
+
+/* values for e_type (object file type). */
+#define        ET_NONE         0       /* No file type */
+#define        ET_REL          1       /* Relocatable file */
+#define        ET_EXEC         2       /* Executable file */
+#define        ET_DYN          3       /* Shared object file */
+#define        ET_CORE         4       /* Core file */
+#define        ET_NUM          5       /* Number of defined types */
+#define        ET_LOOS         0xFE00  /* OS-Specific range start */
+#define        ET_HIOS         0xFEFF  /* OS-Specific range end */
+#define        ET_LOPROC       0xFF00  /* Processor-Specific range start */
+#define        ET_HIPROC       0xFFFF  /* Processor-Specific range end */
+
+#define        EM_NONE         0       /* No Machine */
+#define        EM_386          3       /* Intel 80386 */
+#define        EM_MIPS         8       /* MIPS R3000 big endian*/
+#define        EM_MIPS_RS3_LE  8       /* MIPS R3000 little endian*/
+#define        EM_PPC          20      /* Power PC */
+#define        EM_ARM          40      /* ARM */
+#define        EM_NUM          95
+
+
+/* values for e_version */
+#define        EV_NONE         0
+#define        EV_CURRENT      1
+#define        EV_NUM          2
+/*
+ *--------------------------------------------------------------------------
+ * Section header
+ *--------------------------------------------------------------------------
+ */
+typedef        struct
+{
+       Elf32_Word      sh_name;        /* Section name(string tbl index) */
+       Elf32_Word      sh_type;        /* Section type */
+       Elf32_Word      sh_flags;       /* Section flags */
+       Elf32_Addr      sh_addr;        /* virtual addr at execution */
+       Elf32_Off       sh_offset;      /* Section file offset */
+       Elf32_Word      sh_size;        /* Section size in bytes */
+       Elf32_Word      sh_link;        /* Link to another section */
+       Elf32_Word      sh_info;        /* Additional section infomation */
+       Elf32_Word      sh_addralign;   /* Section alignment */
+       Elf32_Word      sh_entsize;     /* Entry size if section holds tbl*/
+} Elf32_Shdr, *pElf32_Shdr;
+
+
+/*
+ *--------------------------------------------------------------------------
+ * Program segment header
+ *--------------------------------------------------------------------------
+ */
+
+typedef struct
+{
+       Elf32_Word      p_type;
+       Elf32_Off       p_offset;
+       Elf32_Addr      p_vaddr;
+       Elf32_Addr      p_paddr;
+       Elf32_Word      p_filesz;
+       Elf32_Word      p_memsz;
+       Elf32_Word      p_flags;
+       Elf32_Word      p_align;
+} Elf32_Phdr,*pElf32_Phdr;
+
+/* p_type */
+#define        PT_NULL         0       /* Program header table entry unused */
+#define        PT_LOAD         1       /* Loadable program segment */
+#define        PT_DYNAMIC      2       /* Dynamic linking information */
+#define        PT_INTERP       3       /* Program interpreter */
+#define        PT_NOTE         4       /* Auxiliary information */
+#define        PT_SHLIB        5       /* Reserved */
+#define        PT_PHDR         6       /* Entry for header table itself */
+#define        PT_TLS          7       /* Thread-local storage segment */
+#define        PT_NUM          8       /* Number of defined types */
+#define        PT_LOOS         0x60000000      /* Start of OS-Specific */
+#define        PT_GNU_EH_FRAME 0x6474E550      /* GCC .eh_frame_hdr segment */
+#define        PT_GNU_STACK    0x6474E551      /* Indicates stack executability */
+#define        PT_GNU_RELRO    0x6474E552      /* Read-only after relocation */
+#define        PT_LOSUNW       0x6FFFFFFA
+#define        PT_SHNWBSS      0x6FFFFFFA      /* Sun Specific Segment */
+#define        PT_SUNWSTACK    0x6FFFFFFB      /* Stack segment */
+#define        PT_HISUNW       0x6FFFFFFF
+#define        PT_HIOS         0x6FFFFFFF      /* End of OS-Specific */
+#define        PT_LOPROC       0x70000000      /* Start of processor-specific */
+#define        PT_HIPROC       0x7FFFFFFF      /* End of processor-specific */
+
+#endif //_ELF_H
diff --git a/include/errno.h b/include/errno.h
new file mode 100644 (file)
index 0000000..03e0371
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:        errno.h
+ * 
+ *      Author:        Zhao Yanbai [zhaoyanbai@126.com]
+ *                     Mon Feb  1 17:07:06 2010
+ * 
+ * Description:        none
+ * 
+ *--------------------------------------------------------------------------
+ */
+
+#ifndef        _ERRNO_H
+#define        _ERRNO_H
+
+#define        EPERM            1      /* Operation not permitted */
+#define        ENOENT           2      /* No such file or directory */
+#define        ESRCH            3      /* No such process */
+#define        EINTR            4      /* Interrupted system call */
+#define        EIO              5      /* I/O error */
+#define        ENXIO            6      /* No such device or address */
+#define        E2BIG            7      /* Argument list too long */
+#define        ENOEXEC          8      /* Exec format error */
+#define        EBADF            9      /* Bad file number */
+#define        ECHILD          10      /* No child processes */
+#define        EAGAIN          11      /* Try again */
+#define        ENOMEM          12      /* Out of memory */
+#define        EACCES          13      /* Permission denied */
+#define        EFAULT          14      /* Bad address */
+#define        ENOTBLK         15      /* Block device required */
+#define        EBUSY           16      /* Device or resource busy */
+#define        EEXIST          17      /* File exists */
+#define        EXDEV           18      /* Cross-device link */
+#define        ENODEV          19      /* No such device */
+#define        ENOTDIR         20      /* Not a directory */
+#define        EISDIR          21      /* Is a directory */
+#define        EINVAL          22      /* Invalid argument */
+#define        ENFILE          23      /* File table overflow */
+#define        EMFILE          24      /* Too many open files */
+#define        ENOTTY          25      /* Not a typewriter */
+#define        ETXTBSY         26      /* Text file busy */
+#define        EFBIG           27      /* File too large */
+#define        ENOSPC          28      /* No space left on device */
+#define        ESPIPE          29      /* Illegal seek */
+#define        EROFS           30      /* Read-only file system */
+#define        EMLINK          31      /* Too many links */
+#define        EPIPE           32      /* Broken pipe */
+#define        EDOM            33      /* Math argument out of domain of func */
+#define        ERANGE          34      /* Math result not representable */
+
+extern int errno;
+
+#endif //_ERRNO_H
diff --git a/include/ext2.h b/include/ext2.h
new file mode 100644 (file)
index 0000000..26e86e1
--- /dev/null
@@ -0,0 +1,238 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:        ext2.h
+ * 
+ * Description:        当然.几乎来自Linux 内核.
+ * 
+ * 
+ *      Author:        Zhao Yanbai [zhaoyanbai@126.com]
+ * 
+ *     Version:        1.0
+ * Create Date: Fri Dec 26 22:43:43 2008
+ * Last Update: Fri Dec 26 22:43:43 2008
+ * 
+ *--------------------------------------------------------------------------
+ */
+
+#ifndef        _EXT2_H
+#define        _EXT2_H
+
+#include<types.h>
+
+#define        EXT2_BAD_INO            1
+#define        EXT2_ROOT_INO           2
+#define        EXT2_BOOT_LOADER_INO    5
+#define        EXT2_UNDEL_DIR_INO      6
+
+#define        EXT2_MIN_BLOCK_SIZE     1024
+#define        EXT2_MAX_BLOCK_SIZE     4096
+#define        EXT2_MIN_BLOCK_LOG_SIZE 10
+
+#define        EXT2_SB                 (&ext2_sb)
+#define        EXT2_SECT               (ext2_start_sect)
+
+#ifndef        EXT2_SB
+#error "Please define EXT2_SB"
+#endif
+
+#define        EXT2_BLOCK_SIZE         (EXT2_MIN_BLOCK_SIZE <<         \
+                               (EXT2_SB)->s_log_block_size)
+
+#define        EXT2_SECT_PER_BLOCK     (EXT2_BLOCK_SIZE/512)
+
+#define        EXT2_BLOCK_SIZE_BITS    ((EXT2_SB)->s_log_block_size + 10)
+#define        EXT2_INODE_SIZE         ((EXT2_SB)->s_inode_size)
+#define        EXT2_INODES_PER_BLOCK   (EXT2_BLOCK_SIZE/EXT2_INODE_SIZE)
+#define        EXT2_FIRST_INO          ((EXT2_SB)->s_first_ino)
+/* 
+ * 表示第一个块号. 因为SuperBlock总是从第三个扇区开始的所以如果块的大小
+ * 是1024的话SuperBlock的块号是1.而如果块的大小是2048或4096则SuperBlock
+ * 的块号是0
+ */
+#define        EXT2_FIRST_BLOCK_ID     (EXT2_BLOCK_SIZE == 1024)
+
+#define        EXT2_BLOCKS_PER_GROUP   ((EXT2_SB)->s_blocks_per_group)
+#define        EXT2_DESC_PER_BLOCK     ((EXT2_SB)->s_desc_per_block)
+#define        EXT2_INODES_PER_GROUP   ((EXT2_SB)->s_inodes_per_group)
+#define        EXT2_INODES_COUNT       ((EXT2_SB)->s_inodes_count)
+
+/*
+ * ------------------------------------------------------------------------
+ *  EXT2 FILE SYSTEM PART
+ * ------------------------------------------------------------------------
+ */
+typedef struct ext2_superblock
+{
+/*
+       u32     s_inodes_count;
+       u32     s_blocks_count;
+       u32     s_r_blocks_count;
+       u32     s_free_blocks_count;
+       u32     s_free_inodes_count;
+       u32     s_first_data_block;
+       u32     s_log_block_size;
+       u32     s_log_frag_size;
+       u32     s_blocks_per_group;
+       u32     s_frags_per_group;
+       u32     s_inodes_per_group;
+
+       // So Much Items
+       // I do not want to write down ...
+*/
+       u32     s_inodes_count;         /* Inodes count */
+       u32     s_blocks_count;         /* Blocks count */
+       u32     s_r_blocks_count;       /* Reserved blocks count */
+       u32     s_free_blocks_count;    /* Free blocks count */
+       u32     s_free_inodes_count;    /* Free inodes count */
+       u32     s_first_data_block;     /* First Data Block */
+       u32     s_log_block_size;       /* Block size */
+       u32     s_log_frag_size;        /* Fragment size */
+       u32     s_blocks_per_group;     /* # Blocks per group */
+       u32     s_frags_per_group;      /* # Fragments per group */
+       u32     s_inodes_per_group;     /* # Inodes per group */
+       u32     s_mtime;                /* Mount time */
+       u32     s_wtime;                /* Write time */
+       u16     s_mnt_count;            /* Mount count */
+       u16     s_max_mnt_count;        /* Maximal mount count */
+       u16     s_magic;                /* Magic signature */
+       u16     s_state;                /* File system state */
+       u16     s_errors;       /* Behaviour when detecting errors */
+       u16     s_minor_rev_level;      /* minor revision level */
+       u32     s_lastcheck;            /* time of last check */
+       u32     s_checkinterval;        /* max. time between checks */
+       u32     s_creator_os;           /* OS */
+       u32     s_rev_level;            /* Revision level */
+       u16     s_def_resuid;   /* Default uid for reserved blocks */
+       u16     s_def_resgid;   /* Default gid for reserved blocks */
+       /*
+        * These fields are for EXT2_DYNAMIC_REV superblocks only.
+        *
+        * Note: the difference between the compatible feature set and
+        * the incompatible feature set is that if there is a bit set
+        * in the incompatible feature set that the kernel doesn't
+        * know about, it should refuse to mount the filesystem.
+        * 
+        * e2fsck's requirements are more strict; if it doesn't know
+        * about a feature in either the compatible or incompatible
+        * feature set, it must abort and not try to meddle with
+        * things it doesn't understand...
+        */
+       u32     s_first_ino;            /* First non-reserved inode */
+       u16     s_inode_size;           /* size of inode structure */
+       u16     s_block_group_nr; /* block group # of this superblock */
+       u32     s_feature_compat;       /* compatible feature set */
+       u32     s_feature_incompat;     /* incompatible feature set */
+       u32     s_feature_ro_compat; /* readonly-compatible feature set */
+       u8      s_uuid[16];             /* 128-bit uuid for volume */
+       char    s_volume_name[16];      /* volume name */
+       char    s_last_mounted[64];     /* directory where last mounted */
+       u32     s_algorithm_usage_bitmap; /* For compression */
+       /*
+        * Performance hints.  Directory preallocation should only
+        * happen if the EXT2_COMPAT_PREALLOC flag is on.
+        */
+       u8      s_prealloc_blocks;/* Nr of blocks to try to preallocate*/
+       u8      s_prealloc_dir_blocks;/* Nr to preallocate for dirs */
+       u16     s_padding1;
+       /*
+        * Journaling support valid if EXT3_FEATURE_COMPAT_HAS_JOURNAL set.
+        */
+       u8      s_journal_uuid[16];     /* uuid of journal superblock */
+       u32     s_journal_inum;         /* inode number of journal file */
+       u32     s_journal_dev;          /* device number of journal file */
+       u32     s_last_orphan;  /* start of list of inodes to delete */
+       u32     s_hash_seed[4];         /* HTREE hash seed */
+       u8      s_def_hash_version;     /* Default hash version to use */
+       u8      s_reserved_char_pad;
+       u16     s_reserved_word_pad;
+       u32     s_default_mount_opts;
+       u32     s_first_meta_bg;        /* First metablock block group */
+       u32     s_reserved[190];/* Padding to the end of the block */
+} SuperBlock,*pSuperBlock;
+
+extern SuperBlock ext2_sb;
+
+
+typedef struct ext2_group_descriptor
+{
+       u32     bg_block_bitmap;
+       u32     bg_inode_bitmap;
+       u32     bg_inode_table;
+       u16     bg_free_blocks_count;
+       u16     bg_free_inodes_count;
+       u16     bg_used_dirs_count;
+       u16     bg_pad;
+       u32     bg_reserved[3];
+} GroupDesc,*pGroupDesc;
+
+#define        EXT2_NDIR_BLOCKS        (12)
+#define        EXT2_IND_BLOCK          (EXT2_NDIR_BLOCKS)
+#define        EXT2_DIND_BLOCK         (EXT2_IND_BLOCK + 1)
+#define        EXT2_TIND_BLOCK         (EXT2_DIND_BLOCK + 1)
+#define        EXT2_N_BLOCKS           (EXT2_TIND_BLOCK + 1)
+
+
+typedef struct ext2_inode
+{
+       u16     i_mode;
+       u16     i_uid;
+       u32     i_size;
+       u32     i_atime;
+       u32     i_ctime;
+       u32     i_mtime;
+       u32     i_dtime;
+       u16     i_gid;
+       u16     i_links_count;
+       u32     i_blocks;
+       u32     i_flags;
+       u32     i_osd1;
+       u32     i_block[EXT2_N_BLOCKS];
+       u32     i_generation;
+       u32     i_file_acl;
+       u32     i_dir_acl;
+       u32     i_faddr;
+       u8      i_osd2[12];
+} Inode,*pInode;
+
+
+#define        EXT2_NAME_LEN   255
+typedef struct ext2_dir_ent
+{
+       u32     inode;
+       u16     rec_len;
+       u8      name_len;
+       u8      file_type;              /* 目录类型 */
+       char    name[EXT2_NAME_LEN];
+} DirEnt, *pDirEnt;
+
+/*
+ * Ext2 目录类型.
+ * 到目前为止只有低3位有效.
+ */
+enum
+{
+       EXT2_FT_UNKNOWN,
+       EXT2_FT_REG_FILE,
+       EXT2_FT_DIR,
+       EXT2_FT_CHRDEV,
+       EXT2_FT_BLKDEV,
+       EXT2_FT_FIFO,
+       EXT2_FT_SOCK,
+       EXT2_FT_SYMLINK,
+       EXT2_FT_MAX
+};
+
+
+#define        EXT2_DIR_PAD                    4
+#define        EXT2_DIR_ROUND                  (EXT2_DIR_PAD-1)
+#define        EXT2_DIR_REC_LEN(name_len)      (((name_len)+8+EXT2_DIR_ROUND) & \
+                                               ~EXT2_DIR_ROUND)
+#define        EXT2_MAX_REC_LEN                ((1<<16)-1)
+
+
+extern int ext2_read_inode(unsigned int n, pInode inode);
+extern int ext2_get_file_inode(const char *path, pInode inode);
+extern int ext2_read_file(const pInode ino, void *buf, size_t count);
+
+
+#endif //_EXT2_H
diff --git a/include/fcntl.h b/include/fcntl.h
new file mode 100644 (file)
index 0000000..fb871c7
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:        fcntl.h
+ * 
+ *      Author:        Zhao Yanbai [zhaoyanbai@126.com]
+ *                     Tue Feb 23 16:24:15 2010
+ * 
+ * Description:        none
+ * 
+ *--------------------------------------------------------------------------
+ */
+
+#ifndef        _FCNTL_H
+#define        _FCNTL_H
+
+#define O_ACCMODE         0003
+#define O_RDONLY            00
+#define O_WRONLY            01
+#define O_RDWR              02
+#define O_CREAT                   0100 /* not fcntl */
+#define O_EXCL            0200 /* not fcntl */
+#define O_NOCTTY          0400 /* not fcntl */
+#define O_TRUNC                  01000 /* not fcntl */
+#define O_APPEND         02000
+#define O_NONBLOCK       04000
+#define O_NDELAY       O_NONBLOCK
+#define O_SYNC          010000
+#define O_FSYNC                 O_SYNC
+#define O_ASYNC                 020000
+
+
+#endif //_FCNTL_H
diff --git a/include/fs.h b/include/fs.h
new file mode 100644 (file)
index 0000000..0240f86
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:        fs.h
+ * 
+ *      Author:        Zhao Yanbai [zhaoyanbai@126.com]
+ *                     Fri Feb 12 22:29:59 2010
+ * 
+ * Description:        none
+ * 
+ *--------------------------------------------------------------------------
+ */
+
+#ifndef        _FS_H
+#define        _FS_H
+
+#include<types.h>
+#include<page.h>
+#include<ext2.h>
+
+typedef struct partition
+{
+       u8      State;
+       u8      Head;
+       u16     StartSC;
+       u8      Type;
+       u8      EndHead;
+       u16     EndSC;
+       u32     AbsoluteSectNo;
+       u32     PartitionSize;
+} Partition, *pPartition;
+
+
+/* 分区表开始的位置 */
+#define        PARTS_POS       0x1BE
+
+/* 设备的主设备号. 占用两个字节. */
+#define        DEV_MAJOR_UNUSED        0x0000
+#define        DEV_MAJOR_MEM           0x0001
+#define        DEV_MAJOR_TTY           0x0002
+#define        DEV_MAJOR_IDE0          0x0003
+#define        DEV_MAJOR_HD            DEV_MAJOR_IDE0
+#define        DEV_MAJOR_IDE1          0x0004
+#define        DEV_MAJOR_SCSI0         0x0005
+#define        DEV_MAJOR_SCSI2         0x0006
+
+#define        DEV_MAJOR_BITS          (16)
+#define        DEV_MINOR_MASK          ((1UL << DEV_MAJOR_BITS) - 1)
+
+#define        MAKE_DEV(major, minor)  ((major) << DEV_MAJOR_BITS | minor)
+
+#define        DEV_MAJOR(dev)          ((unsigned int)((dev) >> DEV_MAJOR_BITS))
+#define        DEV_MINOR(dev)          ((unsigned int)((dev) &  DEV_MINOR_MASK))
+
+
+
+typedef struct
+{
+       int     count;
+       int     ino_nr;
+       pInode  inode;
+} File, *pFile;
+
+#define        MAX_SUPT_FILE_SIZE      (EXT2_IND_BLOCK*EXT2_BLOCK_SIZE)
+#define        NR_FILES        (PAGE_SIZE/sizeof(File))
+#define        NR_INODES       (2*NR_FILES)
+#define        NR_OPENS        (2)     /* 一个进程同时打开文件的限制数 */
+extern File file_table[NR_FILES];
+extern Inode inode_table[NR_INODES];
+
+
+
+
+static inline int get_inode_nr(const char *path)
+{
+       return ext2_get_file_inode_nr(path);
+}
+
+static inline int get_inode(unsigned int n, pInode inode)
+{
+       return ext2_read_inode(n, inode);
+}
+
+static inline int read_file(const pInode inode, void *buf, size_t count)
+{
+       return ext2_read_file(inode, buf, count);
+}
+
+/* 在多进程下这样肯定不行 
+ * 管不了这么多了,先这样写吧
+ */
+static inline pInode find_empty_inode()
+{
+       int i;
+       pInode p = inode_table;
+       for(i=0; i<NR_FILES; i++, p++)
+       {
+               if(p->i_size == 0)
+               {
+                       p->i_size = 1;
+                       return p;
+               }
+       }
+
+       return NULL;
+}
+
+#endif //_FS_H
diff --git a/include/global.h b/include/global.h
new file mode 100644 (file)
index 0000000..e2d02f2
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:        global.h
+ * 
+ *      Author:        Zhao Yanbai [zhaoyanbai@126.com]
+ *                     Sat Jan 23 14:12:40 2010
+ * 
+ * Description:        none
+ * 
+ *--------------------------------------------------------------------------
+ */
+
+#ifndef        _GLOBAL_H
+#define        _GLOBAL_H
+
+
+#ifndef        __STRING
+#define        __STRING(x)     #x
+#endif
+
+#endif //_GLOBAL_H
diff --git a/include/i8259.h b/include/i8259.h
new file mode 100644 (file)
index 0000000..009906d
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:        i8259.h
+ * 
+ * Description:        none
+ * 
+ * 
+ *      Author:        Zhao Yanbai [zhaoyanbai@126.com]
+ * 
+ *     Version:        1.0
+ * Create Date: Sun Nov  9 11:37:09 2008
+ *     Version: 1.1
+ * Last Update: Tue Feb 10 20:28:47 2009
+ * 
+ *--------------------------------------------------------------------------
+ */
+
+#ifndef        _I8259_H
+#define        _I8259_H
+
+#include "irq.h"
+#include "io.h"
+
+#define        PIC_MASTER_CMD  0x20
+#define        PIC_MASTER_IMR  0x21
+#define        PIC_SLAVER_CMD  0xA0
+#define        PIC_SLAVER_IMR  0xA1
+
+#define        PIC_MASTER_ISR  PIC_MASTER_CMD
+#define        PIC_SLAVER_ISR  PIC_SLAVER_CMD
+
+#define        PIC_CASCADE_IR  0x2     //The IR2 on Master Connect to Slaver.
+
+extern void init_i8259();
+extern void mask_i8259();
+
+static inline int enable_i8259_irq(unsigned int irq)
+{
+       unsigned char mask = ~(1 << irq);
+       if(irq & 8)
+       {
+               mask &= inb(PIC_SLAVER_IMR);
+               outb( mask, PIC_SLAVER_IMR);
+       }
+       else
+       {
+               mask &= inb(PIC_MASTER_IMR);
+               outb_p( mask, PIC_MASTER_IMR);
+       }
+}
+static inline int disable_i8259_irq(unsigned int irq)
+{
+       unsigned char mask = 1 << irq;
+       if(irq & 8)
+       {
+               mask |= inb(PIC_SLAVER_IMR);
+               outb( mask, PIC_SLAVER_IMR);
+       }
+       else
+       {
+               mask |= inb(PIC_MASTER_IMR);
+               outb( mask, PIC_MASTER_IMR);
+       }
+}
+
+static inline void mask_ack_i8259_irq(unsigned int irq)
+{
+       unsigned int mask = 1 << irq;
+
+       if(irq & 8)
+       {
+               mask |= inb(PIC_SLAVER_IMR);
+               // Mask
+               outb(mask, PIC_SLAVER_IMR);
+               // Specific EOI to slave
+               outb(0x60 + (irq & 0x07), PIC_SLAVER_CMD);
+               // Specific EOI to master
+               outb(0x60 + (PIC_CASCADE_IR & 0x07), PIC_MASTER_CMD);
+       }
+       else
+       {
+               mask |= inb(PIC_MASTER_IMR);
+               // Mask
+               outb(mask, PIC_MASTER_IMR);
+               // Specific EOI to master
+               outb(0x60 + irq, PIC_MASTER_CMD);
+       }
+
+/*
+       // None Specific EOI
+       outb(0x20, PIC_MASTER_CMDA);
+       outb(0x20, PIC_SLAVER_CMDA);
+*/
+}
+
+
+static inline void do_i8259_IRQ(pPtRegs regs, unsigned int irq)
+{
+}
+
+
+
+#endif //_I8259_H
diff --git a/include/init.h b/include/init.h
new file mode 100644 (file)
index 0000000..a23c6c8
--- /dev/null
@@ -0,0 +1,14 @@
+/*
+ * ------------------------------------------------------------------------
+ *   File Name: init.h
+ *      Author: Zhao Yanbai
+ *              Sat Mar 29 15:47:03 2014
+ * Description: none
+ * ------------------------------------------------------------------------
+ */
+
+#pragma once
+
+
+#define __initdata __attribute__ ((__section__ (".init.data")))
+
diff --git a/include/io.h b/include/io.h
new file mode 100644 (file)
index 0000000..ea21313
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:        io.h
+ * 
+ * Description:        none
+ * 
+ * 
+ *      Author:        Zhao Yanbai [zhaoyanbai@126.com]
+ * 
+ *     Version:        1.0
+ * Create Date: Mon Jun 18 23:25:23 2007
+ * Last Update: Mon Jun 18 23:25:23 2007
+ * 
+ *--------------------------------------------------------------------------
+ */
+
+#ifndef        _IO_H
+#define        _IO_H
+
+#include<types.h>
+
+#define outb_p(value,port)({                           \
+__asm__("outb  %%al,%%dx;nop;nop;nop;nop"              \
+:                                                      \
+:"a" (value),"d" (port));                              \
+})
+
+#define inb_p(port)({                                  \
+u8 _bt;                                                \
+__asm__("inb   %%dx,%%al;nop;nop;nop;nop"              \
+:"=a" (_bt)                                            \
+:"d" (port));                                          \
+_bt;                                                   \
+})
+
+
+#define outb(value,port)({                             \
+__asm__("outb  %%al,%%dx"                              \
+:                                                      \
+:"a" (value),"d" (port));                              \
+})
+
+#define outw(value,port)({                             \
+__asm__("outw  %%ax,%%dx"                              \
+:                                                      \
+:"a" (value),"d" (port));                              \
+})
+#define outl(value,port)({                             \
+__asm__("outl  %%eax,%%dx"                             \
+:                                                      \
+:"a" (value),"d" (port));                              \
+})
+
+#define inb(port)({                                    \
+u8 _bt;                                                \
+asm("inb       %%dx,%%al"                              \
+:"=a" (_bt)                                            \
+:"d" (port));                                          \
+_bt;                                                   \
+})
+
+#define inw(port)({                                    \
+u16 _bt;                                               \
+asm("inw       %%dx,%%ax"                              \
+:"=a" (_bt)                                            \
+:"d" (port));                                          \
+_bt;                                                   \
+})
+
+#define inl(port)({                                    \
+u16 _bt;                                               \
+asm("inl       %%dx,%%eax"                             \
+:"=a" (_bt)                                            \
+:"d" (port));                                          \
+_bt;                                                   \
+})
+
+
+#define        BUILDIO(bwl, type)                              \
+static inline void ins##bwl(int port, void *buf, unsigned long count)  \
+{                                                                      \
+       asm volatile(   "cld;rep;ins" #bwl                              \
+                       : "+c"(count), "+D"(buf) : "d"(port));          \
+}
+
+
+BUILDIO(b, char)
+BUILDIO(w, short)
+BUILDIO(l, int)
+
+#endif //_IO_H
diff --git a/include/irq.h b/include/irq.h
new file mode 100644 (file)
index 0000000..585d65c
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:        irq.h
+ * 
+ * Description:        none
+ * 
+ * 
+ *      Author:        Zhao Yanbai [zhaoyanbai@126.com]
+ * 
+ *     Version:        1.0
+ * Create Date: Fri Nov 28 16:38:25 2008
+ * Last Update: Fri Nov 28 16:38:25 2008
+ * 
+ *--------------------------------------------------------------------------
+ */
+
+#ifndef        _IRQ_H
+#define        _IRQ_H
+
+#include"system.h"
+
+#define        NR_IRQS         224
+#define        FIRST_IRQ_VECT  0x20
+
+typedef        struct
+{
+       const char *name;
+       int     (*enable)(unsigned int irq);
+       int     (*disable)(unsigned int irq);
+       void    (*ack)(unsigned int irq);
+} IrqChip, *pIrqChip;
+
+typedef struct irqaction
+{
+       //void (*handler)(pPtRegs regs, unsigned int irq);
+       void    (*handler)(unsigned int irq, pPtRegs regs, void *dev_id);
+       const char *dev_name;
+       void *dev_id;
+       struct irqaction *next; 
+} IrqAction, *pIrqAction;
+
+typedef        struct
+{
+       pIrqChip        chip;
+       pIrqAction      action;
+       unsigned int    status;
+       unsigned int    depth;
+} IrqDesc, *pIrqDesc;
+
+extern IrqChip i8259_chip;
+extern IrqDesc irq_desc[];
+extern IrqDesc no_irq_desc;
+int    request_irq(unsigned int irq,
+       //void (*handler)(pPtRegs, unsigned int),
+       void    (*handler)(unsigned int, pPtRegs, void *),
+       const char *devname,
+       void    *dev_id);
+
+static inline int enable_irq(unsigned int irq)
+{
+       return irq_desc[irq].chip->enable(irq);
+}
+static inline int disable_irq(unsigned int irq)
+{
+       return irq_desc[irq].chip->disable(irq);
+}
+#endif //_IRQ_H
diff --git a/include/linkage.h b/include/linkage.h
new file mode 100644 (file)
index 0000000..b40d5f0
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:        linkage.h
+ * 
+ * Description:        none
+ * 
+ * 
+ *      Author:        Zhao Yanbai [zhaoyanbai@126.com]
+ * 
+ *     Version:        1.0
+ * Create Date: Fri Jul  10 11:19:26 2009
+ * Last Update: Fri Jul  10 11:19:26 2009
+ * 
+ *--------------------------------------------------------------------------
+ */
+#ifndef        __LINKAGE_H
+#define        __LINKAGE_H
+
+#define        ALIGN           .align  0x04,0x90
+#define        ALIGN_STR       ".align 0x04,0x90"
+#define        ENTRY(symbol)   \
+       .global symbol; \
+       ALIGN;          \
+       symbol:
+
+
+
+#endif
diff --git a/include/list.h b/include/list.h
new file mode 100644 (file)
index 0000000..b25fdea
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:        list.h
+ * 
+ * Description:        none
+ * 
+ * 
+ *      Author:        Zhao Yanbai [zhaoyanbai@126.com]
+ * 
+ *     Version:        1.0
+ * Create Date: Mon Apr 20 20:52:05 2009
+ * Last Update: Mon Apr 20 20:52:05 2009
+ * 
+ *--------------------------------------------------------------------------
+ */
+
+#ifndef        _LIST_H
+#define        _LIST_H
+
+/* Allmost Copy From Linux */
+typedef struct list_head
+{
+       struct list_head *prev, *next;
+} ListHead, *pListHead;
+
+#define        LIST_HEAD_INIT(name) {&(name), &(name) }
+#define        LIST_HEAD(name) ListHead name = LIST_HEAD_INIT(name)
+#define        INIT_LIST_HEAD(ptr)             \
+do{                                    \
+       (ptr)->next = (ptr);            \
+       (ptr)->prev = (ptr);            \
+}while(0)
+
+#define        list_entry(ptr, type, member)   \
+       ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
+
+#define        list_for_each(pos, head)        \
+       for(pos = (head)->next; pos != (head); pos = pos->next)
+#define        list_for_each_safe(pos, tmp, head)              \
+       for(pos = (head)->next, tmp = pos->next;        \
+               pos != (head);                          \
+               pos = tmp, tmp = pos->next)
+
+static inline void _list_add(  pListHead newItem,
+                               pListHead prev,
+                               pListHead next)
+{
+       next->prev      = newItem;
+       newItem->next   = next;
+       newItem->prev   = prev;
+       prev->next      = newItem;
+}
+
+static inline void list_add(pListHead newItem, pListHead head)
+{
+       _list_add(newItem, head, head->next);
+}
+
+static inline void list_add_tail(pListHead newItem, pListHead head)
+{
+       _list_add(newItem, head->prev, head);
+}
+
+
+static inline void _list_del(pListHead prev, pListHead next)
+{
+       next->prev = prev;
+       prev->next = next;
+}
+
+static inline void list_del(pListHead entry)
+{
+       _list_del(entry->prev, entry->next);
+}
+
+static inline void list_del_init(pListHead entry)
+{
+       _list_del(entry->prev, entry->next);
+       INIT_LIST_HEAD(entry);
+}
+
+static inline int list_is_empty(pListHead head)
+{
+       return head->next == head;
+}
+
+
+#endif //_LIST_H
diff --git a/include/mm.h b/include/mm.h
new file mode 100644 (file)
index 0000000..ef81104
--- /dev/null
@@ -0,0 +1,13 @@
+/*
+ * ------------------------------------------------------------------------
+ *   File Name: mm.h
+ *      Author: Zhao Yanbai
+ *              Sun Mar 30 11:10:00 2014
+ * Description: none
+ * ------------------------------------------------------------------------
+ */
+
+#pragma once
+
+
+void *alloc_bootmem(unsigned long size, unsigned long align);
diff --git a/include/msr.h b/include/msr.h
new file mode 100644 (file)
index 0000000..319d8f5
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:        msr.h
+ * 
+ * Description:        none
+ * 
+ * 
+ *      Author:        Zhao Yanbai [zhaoyanbai@126.com]
+ * 
+ *     Version:        1.0
+ * Create Date: Fri Jan  2 19:54:18 2009
+ * Last Update: Fri Jan  2 19:54:18 2009
+ * 
+ *--------------------------------------------------------------------------
+ */
+
+#ifndef        _MSR_H
+#define        _MSR_H
+
+#define        MSR_SYSENTER_CS         0x174
+#define        MSR_SYSENTER_ESP        0x175
+#define        MSR_SYSENTER_EIP        0x176
+
+#define        wrmsr(msr, lowval, highval) do{\
+       asm("wrmsr;"::"c"(msr),"a"(lowval),"d"(highval));\
+}while(0);
+
+
+#endif //_MSR_H
diff --git a/include/page.h b/include/page.h
new file mode 100644 (file)
index 0000000..d45d9a8
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:        page.h
+ * 
+ * Description:        none
+ * 
+ * 
+ *      Author:        Zhao Yanbai [zhaoyanbai@126.com]
+ * 
+ *     Version:        1.0
+ * Create Date: Sat Feb  7 21:47:42 2009
+ * Last Update: Sat Feb  7 21:47:42 2009
+ * 
+ *--------------------------------------------------------------------------
+ */
+
+#ifndef        _PAGE_H
+#define        _PAGE_H
+
+
+
+#define        PAGE_P          0x0
+#define        PAGE_WR         0x1
+#define        PAGE_US         0x2
+
+#define        PAGE_SHIFT      (12)
+#define        PAGE_SIZE       (1UL << PAGE_SHIFT)
+#define        PAGE_MASK       (~((1UL << PAGE_SHIFT)-1))
+#define        PAGE_OFFSET     (0xC0000000)
+
+#ifndef        ASM
+#include<types.h>
+#define        get_npd(vaddr)  (((u32)(vaddr))>>22)
+#define        get_npt(vaddr)  ((((u32)(vaddr))>>12) & 0x3FF)
+
+#include<list.h>
+
+#define        PAGE_ITEMS      (PAGE_SIZE/sizeof(unsigned long))
+#define        PAGE_ALIGN(page)        (page & PAGE_MASK)
+#define        PAGE_UP(page)   (((unsigned long)page + PAGE_SIZE -1) & PAGE_MASK)
+#define        PAGE_DOWN       PAGE_ALIGN
+
+#define va2pa(x) (((unsigned long)(x)) - PAGE_OFFSET)
+#define pa2va(x) ((void *) (((unsigned long)(x)) + PAGE_OFFSET))
+
+// pfn: page frame number
+#define        pa2pfn(addr)    ((addr)>>PAGE_SHIFT)
+#define pfn2pa(pfn)     ((pfn)<<PAGE_SHIFT)
+
+#define va2pfn(addr)    pa2pfn(va2pa(addr))
+#define pfn2va(pfn)     pa2va(pfn2pa(pfn))
+
+
+#define PFN_UP(addr)     (((addr) + PAGE_SIZE - 1) >> PAGE_SHIFT)
+#define PFN_DW(addr)     ((addr) >> PAGE_SHIFT)
+
+#define        MAX_ORDER       (11)
+
+typedef struct page
+{
+       //struct page *prev, *next;
+       ListHead list;
+       unsigned int order;
+       unsigned int mapNR;
+       unsigned int count;
+} Page, *pPage;
+
+typedef struct free_area
+{
+       //struct page *prev, *next;
+       ListHead freeList;
+       unsigned char *map;
+       unsigned int mapSize;
+       unsigned int count;
+} FreeArea, *pFreeArea;
+
+
+extern FreeArea freeArea[MAX_ORDER];
+
+pPage  alloc_pages(unsigned int order);
+void   free_pages(pPage page);
+//void free_pages(pPage page, unsigned int order);
+void   disp_free_area();
+
+
+#endif // ASM
+
+#endif //_PAGE_H
diff --git a/include/pci.h b/include/pci.h
new file mode 100644 (file)
index 0000000..582cb38
--- /dev/null
@@ -0,0 +1,154 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:        pci.h
+ * 
+ * Description:        none
+ * 
+ * 
+ *      Author:        Zhao Yanbai [zhaoyanbai@126.com]
+ * 
+ *     Version:        1.0
+ * Create Date: Sun Mar  8 21:32:16 2009
+ * Last Update: Sun Mar  8 21:32:16 2009
+ * 
+ *--------------------------------------------------------------------------
+ */
+
+#ifndef        _PCI_H
+#define        _PCI_H
+
+#define        PCI_ADDR        0xCF8   // CONFIG_ADDRESS
+#define        PCI_DATA        0xCFC   // CONFIG_DATA
+
+// PCI Device
+/*
+ * 31                        16 15                         0
+ * +---------------------------+---------------------------+ 00H
+ * |         Device ID         |          Vendor ID        |
+ * +---------------------------+---------------------------+ 04H
+ * |           Status          |          Command          |
+ * +-----------------------------------------+-------------+ 08H
+ * |               Class Code                | Revision    |
+ * +-------------+-------------+-------------+-------------+ 0CH
+ * |    BIST     | Header Type |LatencyTimer |CacheLineSize|
+ * +-------------+-------------+-------------+-------------+ 10H
+ * |                Base Address Register 1                |
+ * +-------------------------------------------------------+ 14H
+ * |                Base Address Register 2                |
+ * +-------------------------------------------------------+ 18H
+ * |                Base Address Register 3                |
+ * +-------------------------------------------------------+ 1CH
+ * |                Base Address Register 4                |
+ * +-------------------------------------------------------+ 20H
+ * |                Base Address Register 5                |
+ * +-------------------------------------------------------+ 24H
+ * |                Base Address Register 6                |
+ * +-------------------------------------------------------+ 28H
+ * |                  CardBus CIS Pointer                  |
+ * +---------------------------+---------------------------+ 2CH 
+ * |        System ID          |        Subsystem ID       |
+ * +---------------------------+---------------------------+ 30H
+ * |               Expansion ROM Base Address              |
+ * +-----------------------------------------+-------------+ 34H
+ * |/////////////////////////////////////////|Capabilities |
+ * +-----------------------------------------+-------------+ 38H
+ * |///////////////////////////////////////////////////////|
+ * +-------------+------------+-------------+--------------+ 3CH
+ * |   Max_Lat   |   Min_Gnt  |Interrupt PIN|Interrupt Line|
+ * +-------------+------------+-------------+--------------+ 40H
+ */
+
+
+#define        PCI_VENDORID            0x00
+#define        PCI_DEVICEID            0x02
+#define        PCI_COMMAND             0x04
+#define        PCI_STATUS              0x06
+#define        PCI_REVISION            0x08
+#define        PCI_CLASSPROG           0x09
+#define        PCI_CLASSDEVICE         0x10
+#define        PCI_HDRTYPE             0x0E
+       #define PCI_HDRTYPE_MASK        0x7F
+       #define PCI_HDRTYPE_NORMAL      0x00
+       #define PCI_HDRTYPE_BRIDGE      0x01
+       #define PCI_HDRTYPE_CARDBUS     0x02
+#define        PCI_INTRLINE            0x3C
+#define        PCI_INTRPIN             0x3D
+#define        PCI_MINGNT              0x3E
+#define        PCI_MAXLAT              0x3F
+
+
+#define        PCI_CMD(bus, dev, devfn, reg) \
+(0x80000000 | (dev << 11) | (devfn << 8) | (reg & 0xFC))
+
+#define        PCI_CONFIG_CMD(cmd) (cmd & ~3)
+#define        PCI_GET_CMD_REG(cmd) (cmd & 0xFF)
+
+
+/*   PCI IDS   */
+// Display
+#define        PCI_BASE_CLASS_DISPLAY          0x03
+#define        PCI_CLASS_DISPLAY_VGA           0x0300
+// Bridge
+#define        PCI_BASE_CLASS_BRIDGE           0x06
+#define        PCI_CLASS_BRIDGE_HOST           0x0600
+#define        PCI_CLASS_BRIDGE_ISA            0x0601
+#define        PCI_CLASS_BRIDGE_PCI            0x0604
+#define        PCI_CLASS_BRIDGE_CARDBUS        0x0607
+
+/* Vendors*/
+#define        PCI_VENDORID_COMPAQ     0x0E11
+#define        PCI_VENDORID_INTEL      0x8086
+#define        PCI_VENDORID_ATI        0x1002
+#define        PCI_VENDORID_IBM        0x1014
+#define        PCI_VENDORID_AMD        0x1022
+#define        PCI_VENDORID_HP         0x103C
+#define        PCI_VENDORID_SONY       0x104D
+#define        PCI_VENDORID_MOTOROLA   0x1057
+#define        PCI_VENDORID_APPLE      0x106B
+#define        PCI_VENDORID_SUN        0x108E
+#define        PCI_VENDORID_NVIDIA     0x10DE
+#define        PCI_VENDORID_REALTEK    0x10EC
+
+
+// PCI Bridge
+// TODO
+/*
+ * 31                        16 15                         0
+ * +---------------------------+---------------------------+ 00H
+ * |         Device ID         |          Vendor ID        |
+ * +---------------------------+---------------------------+ 04H
+ * |           Status          |          Command          |
+ * +-----------------------------------------+-------------+ 08H
+ * |               Class Code                | Revision    |
+ * +-------------+-------------+-------------+-------------+ 0CH
+ * |    BIST     | Header Type |LatencyTimer |CacheLineSize|
+ * +-------------+-------------+-------------+-------------+ 10H
+ * |                Base Address Register 1                |
+ * +-------------------------------------------------------+ 14H
+ * |                Base Address Register 2                |
+ * +-------------------------------------------------------+ 18H
+ * |                Base Address Register 3                |
+ * +-------------------------------------------------------+ 1CH
+ * |                Base Address Register 4                |
+ * +-------------------------------------------------------+ 20H
+ * |                Base Address Register 5                |
+ * +-------------------------------------------------------+ 24H
+ * |                Base Address Register 6                |
+ * +-------------------------------------------------------+ 28H
+ * |                  CardBus CIS Pointer                  |
+ * +---------------------------+---------------------------+ 2CH 
+ * |        System ID          |        Subsystem ID       |
+ * +---------------------------+---------------------------+ 30H
+ * |               Expansion ROM Base Address              |
+ * +-----------------------------------------+-------------+ 34H
+ * |/////////////////////////////////////////|Capabilities |
+ * +-----------------------------------------+-------------+ 38H
+ * |///////////////////////////////////////////////////////|
+ * +-------------+------------+-------------+--------------+ 3CH
+ * |   Max_Lat   |   Min_Gnt  |Interrupt PIN|Interrupt Line|
+ * +-------------+------------+-------------+--------------+ 40H
+ */
+
+
+
+#endif //_PCI_H
diff --git a/include/printk.h b/include/printk.h
new file mode 100644 (file)
index 0000000..461cc66
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:        printk.h
+ * 
+ * Description:        none
+ * 
+ * 
+ *      Author:        Zhao Yanbai [zhaoyanbai@126.com]
+ * 
+ *     Version:        1.0
+ * Create Date: Wed Mar  4 21:49:19 2009
+ * Last Update: Wed Mar  4 21:49:19 2009
+ * 
+ *--------------------------------------------------------------------------
+ */
+
+#ifndef        _PRINTK_H
+#define        _PRINTK_H
+
+int    printk(char *fmtstr, ...);
+
+#endif //_PRINTK_H
diff --git a/include/processor.h b/include/processor.h
new file mode 100644 (file)
index 0000000..389f611
--- /dev/null
@@ -0,0 +1,216 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:        processor.h
+ * 
+ * Description:        none
+ * 
+ * 
+ *      Author:        Zhao Yanbai [zhaoyanbai@126.com]
+ * 
+ *     Version:        1.0
+ * Create Date: Sun Aug 03 21:37:34 2008
+ * Last Update: Sun Aug 03 21:37:34 2008
+ * 
+ *--------------------------------------------------------------------------
+ */
+
+
+
+#ifndef        _DESCRIPTOR_H
+#define _DESCRIPTOR_H 
+
+#include"types.h"
+#include"system.h"
+#include"string.h"
+
+//Descriptor Attrib.
+#define        DA_E    0x8     //Executable
+#define        DA_ED   0x4     //For Data SEG
+#define        DA_C    0x4     //For Code SEG
+#define        DA_W    0x2     //For Data SEG
+#define        DA_A    0x1     //Access. 1-Accessed.
+//we just need Accessed.
+//For Data Segment.
+#define        DSA_R   (DA_A)
+#define DSA_RW (DA_A | DA_W)
+#define        DSA_RD  (DA_A | DA_ED)          //down to ...
+#define        DSA_RWD (DA_A | DA_W | DA_ED)
+//For Code Segment.
+#define        CSA_E   (DA_E | DA_A)
+#define        CSA_ER  (DA_E | DA_A | DA_R)
+#define        CSA_EC  (DA_E | DA_A | DA_C)
+#define        CSA_ERC (DA_E | DA_A | DA_R | DA_C)
+
+
+//-------------------------------------------------------------------------
+// Code And Data Descriptor.
+// Program Segment Descriptor.
+//-------------------------------------------------------------------------
+typedef        struct
+{
+       unsigned short limitL;
+
+       unsigned short baseL;
+
+       unsigned char baseM;
+       unsigned char type:4;
+       unsigned char S:1;      //allways set to 0. NOT SYS SEG DESC
+       unsigned char DPL:2;
+       unsigned char P:1;      //allways set to 1.
+
+       unsigned char limitH:4;
+       unsigned char AVL:1;
+       unsigned char zero:1;   //should be set to 0
+       unsigned char DB:1;     //0--16bits,1--32bits
+       unsigned char G:1;      //set to 1. We just need 4K size.
+       unsigned char baseH;
+} Seg,*pSeg;
+
+
+//-------------------------------------------------------------------------
+// TSS State,LDT
+// And Gates(Call,Interrupt,Trap,Tss) Descriptor.
+//-------------------------------------------------------------------------
+typedef struct
+{
+       unsigned short  eaddrL;
+
+       unsigned short  selector;
+
+       unsigned char   parmeter:5;     //for call gate
+                                       //reserved by other gates.
+       unsigned char   zero:3;
+       unsigned char   type:4;
+       unsigned char   S:1;
+       unsigned char   DPL:2;
+       unsigned char   P:1;
+
+       unsigned short eaddrH;
+
+} Gate, *pGate;
+
+//just used for type...
+typedef union
+{
+       Seg     seg;
+       Gate    gate;
+} Desc, *pDesc;
+
+
+#define        NGDT    256
+#define        NIDT    256
+#define        NLDT    5
+extern Desc    idt[NIDT];
+extern Desc    gdt[NGDT];
+
+//-------------------------------------------------------------------------
+//Define Gate Types...
+//-------------------------------------------------------------------------
+#define        INTR_GATE       0x0E    //Clear 'IF' bit.---->Close Interrupt
+#define        TRAP_GATE       0x0F    //Keep  'IF' bit.
+#define        TSS_DESC        0x09
+
+static inline void _init_desc(pDesc desc)
+{
+       if(0xc010a1c8 == (unsigned long)desc)
+               asm("xchg %bx,%bx");
+       memset((char *)desc, 0, sizeof(Desc));
+}
+
+
+static inline Desc _create_seg(u8 type, u8 DPL)
+{
+       Desc    d;
+       pSeg    p=&d.seg;
+
+       _init_desc(&d);
+       p->limitL       = 0xFFFF;
+       p->limitH       = 0x0F; 
+       p->type         = type;
+       p->S            = 0x1;
+       p->DPL          = DPL;
+       p->P            = 0x1;
+       p->G            = 0x1;
+       p->DB           = 0x1;
+
+       return d;
+}
+
+
+
+
+
+static inline Desc _create_gate(u32 handler, u8 type, u8 DPL)
+{
+       Desc    d;
+       pGate   p = &d.gate;
+
+       _init_desc(&d);
+
+       p->eaddrL       = 0xFFFF & handler;
+       p->eaddrH       = 0xFFFF & (handler >> 16);
+       p->selector     = SELECTOR_KRNL_CS;
+       p->type         = type;
+       p->P            = 0x1;
+       p->DPL          = DPL;
+
+       return d;
+}
+static inline void set_idt_gate(u32 vec, u32 handler,u8 type, u8 DPL)
+{
+       idt[vec] = _create_gate(handler, type, DPL);
+}
+
+typedef        struct
+{
+       u16     backlink, _backlink;
+       u32     esp0;
+       u16     ss0, _ss0;
+       u32     esp1;
+       u16     ss1, _ss1;
+       u32     esp2;
+       u16     ss2, _ss2;
+       u32     cr3;
+       u32     eip;
+       u32     eflags;
+       u32     eax;
+       u32     ecx;
+       u32     edx;
+       u32     ebx;
+       u32     esp;
+       u32     ebp;
+       u32     esi;
+       u32     edi;
+       u16     es, _es;
+       u16     cs, _cs;
+       u16     ss, _ss;
+       u16     ds, _ds;
+       u16     fs, _fs;
+       u16     gs, _gs;
+       u16     ldt, _ldt;
+       u16     T:1, _T:15, iomap_base;
+} TSS, *pTSS;
+static inline void set_tss_gate(u32 vec, u32 addr)
+{
+#if 1
+       pSeg    p = (pSeg) (gdt+vec);
+       _init_desc((pDesc)p);
+       p->limitL = 0xFFFF & sizeof(TSS);
+       p->limitH = 0x0F   & (sizeof(TSS) >> 16);
+       p->baseL = 0xFFFF & addr;
+       p->baseM = 0xFF   & (addr>>16);
+       p->baseH = 0xFF   & (addr>>24);
+
+       p->P = 1;
+       p->DPL = PRIVILEGE_USER;
+       p->S = 0;
+
+       p->type = TSS_DESC;
+#endif
+}
+
+
+extern TSS     tss;
+
+
+#endif//_DESCRIPTOR_H
diff --git a/include/sched.h b/include/sched.h
new file mode 100644 (file)
index 0000000..89917b3
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:        sched.h
+ * 
+ * Description:        none
+ * 
+ * 
+ *      Author:        Zhao Yanbai [zhaoyanbai@126.com]
+ * 
+ *     Version:        1.0
+ * Create Date: Sat Feb  7 21:43:49 2009
+ * Last Update: Sat Feb  7 21:43:49 2009
+ * 
+ *--------------------------------------------------------------------------
+ */
+
+#ifndef        _SCHED_H
+#define        _SCHED_H
+
+#include<task.h>
+#define        NR_TASKS        3
+//pTask        tTasks[NR_TASKS];
+//void add_task();
+void   SetupTasks();
+//void test_taskA();
+//void test_taskB();
+//unsigned long schedule(pPtRegs       regs);
+unsigned long schedule();
+
+pid_t  get_next_pid();
+void   init_tsk_cr3(pTask);
+
+
+inline void wake_up(pWaitQueue wq);
+inline void sleep_on(pWaitQueue wq);
+
+#define TASK_CNT 64
+
+#endif //_SCHED_H
diff --git a/include/stat.h b/include/stat.h
new file mode 100644 (file)
index 0000000..7cb6147
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:        stat.h
+ * 
+ *      Author:        Zhao Yanbai [zhaoyanbai@126.com]
+ *                     Fri Feb 12 18:01:27 2010
+ * 
+ * Description:        none
+ * 
+ *--------------------------------------------------------------------------
+ */
+
+#ifndef        _STAT_H
+#define        _STAT_H
+
+typedef struct stat {
+       unsigned long  st_dev;
+       unsigned long  st_ino;
+       unsigned short st_mode;
+       unsigned short st_nlink;
+       unsigned short st_uid;
+       unsigned short st_gid;
+       unsigned long  st_rdev;
+       unsigned long  st_size;
+       unsigned long  st_blksize;
+       unsigned long  st_blocks;
+       unsigned long  st_atime;
+       unsigned long  st_atime_nsec;
+       unsigned long  st_mtime;
+       unsigned long  st_mtime_nsec;
+       unsigned long  st_ctime;
+       unsigned long  st_ctime_nsec;
+       unsigned long  __unused4;
+       unsigned long  __unused5;
+} Stat, *pStat;
+
+#define S_IFMT  00170000
+#define S_IFSOCK 0140000
+#define S_IFLNK         0120000
+#define S_IFREG  0100000
+#define S_IFBLK  0060000
+#define S_IFDIR  0040000
+#define S_IFCHR  0020000
+#define S_IFIFO  0010000
+#define S_ISUID  0004000
+#define S_ISGID  0002000
+#define S_ISVTX  0001000
+
+#define S_ISLNK(m)     (((m) & S_IFMT) == S_IFLNK)
+#define S_ISREG(m)     (((m) & S_IFMT) == S_IFREG)
+#define S_ISDIR(m)     (((m) & S_IFMT) == S_IFDIR)
+#define S_ISCHR(m)     (((m) & S_IFMT) == S_IFCHR)
+#define S_ISBLK(m)     (((m) & S_IFMT) == S_IFBLK)
+#define S_ISFIFO(m)    (((m) & S_IFMT) == S_IFIFO)
+#define S_ISSOCK(m)    (((m) & S_IFMT) == S_IFSOCK)
+
+
+#endif //_STAT_H
diff --git a/include/stdio.h b/include/stdio.h
new file mode 100644 (file)
index 0000000..05a2f15
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:        stdio.h
+ * 
+ * Description:        none
+ * 
+ * 
+ *      Author:        Zhao Yanbai [zhaoyanbai@126.com]
+ * 
+ *     Version:        1.0
+ * Create Date: Mon Mar  9 01:59:06 2009
+ * Last Update: Mon Mar  9 01:59:06 2009
+ * 
+ *--------------------------------------------------------------------------
+ */
+
+#ifndef        _STDIO_H
+#define        _STDIO_H
+#include<string.h>
+#include<syscall.h>
+extern int write(int fd, const char *buf, unsigned long size);
+char ptfbuf[1024];
+static inline int printf(const char *fmt, ...)
+{
+       char *args = (char*)(((char*)&fmt)+4);
+       vsprintf(ptfbuf, fmt, args);
+
+       //asm("xchg %bx,%bx;");
+       
+       return write(0, ptfbuf, strlen(ptfbuf));
+}
+
+#endif //_STDIO_H
diff --git a/include/stdlib.h b/include/stdlib.h
new file mode 100644 (file)
index 0000000..04afdd5
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:        stdlib.h
+ * 
+ *      Author:        Zhao Yanbai [zhaoyanbai@126.com]
+ *                     Wed Feb 17 19:01:02 2010
+ * 
+ * Description:        none
+ * 
+ *--------------------------------------------------------------------------
+ */
+
+#ifndef        _STDLIB_H
+#define        _STDLIB_H
+
+extern int atoi(const char *s);
+
+#endif //_STDLIB_H
diff --git a/include/string.h b/include/string.h
new file mode 100644 (file)
index 0000000..420db80
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:        string.h
+ * 
+ * Description:        none
+ * 
+ * 
+ *      Author:        Zhao Yanbai [zhaoyanbai@126.com]
+ * 
+ *     Version:        1.0
+ * Create Date: Wed Jul 30 16:03:27 2008
+ * Last Update: Wed Jul 30 16:03:27 2008
+ * 
+ *--------------------------------------------------------------------------
+ */
+
+#ifndef        _STRING_H
+#define        _STRING_H
+
+#include"types.h"
+char   *strcpy(char *dest, const char *src);
+size_t strlen(const char *str);
+int    strcmp(const char *a, const char *b);
+int    strncmp(const char *a, const char *b, size_t count);
+char   *strcat(char *dest, const char *src);
+
+
+void   *memcpy(void *dest, const void *src, size_t size);
+void   memset(char *dest, char ch, size_t size);
+
+#endif //_STRING_H
diff --git a/include/syscall.h b/include/syscall.h
new file mode 100644 (file)
index 0000000..df5ffab
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:        syscall.h
+ * 
+ * Description:        none
+ * 
+ * 
+ *      Author:        Zhao Yanbai [zhaoyanbai@126.com]
+ * 
+ *     Version:        1.0
+ * Create Date: Fri Jan  2 19:52:28 2009
+ * Last Update: Tue Feb 23 02:32:35 2010
+ * 
+ *--------------------------------------------------------------------------
+ */
+
+#ifndef        _SYSCALL_H
+#define        _SYSCALL_H
+
+#define        SYSC_NUM        256
+
+#ifndef        ASM
+
+#include "page.h"
+#include "errno.h"
+typedef        int     SyscReturn;
+typedef SyscReturn  (*pfSysc)();
+
+
+#define        SYSENTER                \
+       asm(                    \
+       "pushl  %ecx;"          \
+       "pushl  %edx;"          \
+       "pushl  %ebp;"          \
+       "pushl  $1f;"           \
+       "movl   %esp,%ebp;"     \
+       "sysenter;"             \
+       "1:"                    \
+       "addl   $4,%esp;"       \
+       "popl   %ebp;"          \
+       "popl   %edx;"          \
+       "popl   %ecx;");        \
+
+
+
+#define        sysenter(vect)({        \
+       asm(""::"a"(vect));     \
+       SYSENTER                \
+})
+#if 0
+#define        syscall0(vect)(({       \
+       sysenter(vect);         \
+}), ({int i;asm("":"=a"(i));i;}))
+#endif
+#define        _syscall0(vect)({       \
+       sysenter(vect);         \
+})
+
+#define        _syscall1(vect, a)({    \
+       asm(""::"b"(a));        \
+       sysenter(vect);         \
+})
+
+#define        _syscall2(vect, a, b)({ \
+       asm(""::"b"(a), "d"(b));\
+       sysenter(vect);         \
+})
+
+#define        _syscall3(vect, a, b, c)({      \
+       asm(""::"b"(a), "d"(b), "c"(c));\
+       sysenter(vect);                 \
+})
+
+#define        _syscall_ret()({        \
+       int ret;                \
+       asm("":"=a"(ret));      \
+       if(ret < 0)             \
+       {                       \
+               errno = -ret;   \
+               ret = -1;       \
+       }                       \
+       ret;})
+
+#define        syscall0(vect)          \
+       (({_syscall0(vect);}),          ({_syscall_ret();}))
+#define        syscall1(vect, a)       \
+       (({_syscall1(vect, a);}),       ({_syscall_ret();}))
+#define        syscall2(vect, a, b)    \
+       (({_syscall2(vect, a, b);}),    ({_syscall_ret();}))
+#define        syscall3(vect, a, b, c) \
+       (({_syscall3(vect, a, b, c);}), ({_syscall_ret();}))
+#if 1
+enum
+{
+       SYSC_WRITE,
+       SYSC_READ_KBD,
+       SYSC_REBOOT,
+       SYSC_FORK,
+       SYSC_EXEC,
+       SYSC_OPEN,
+       SYSC_READ,
+       SYSC_STAT,
+       SYSC_EXIT,
+    SYSC_PAUSE,
+       SYSC_TEST
+};
+#endif
+
+#endif // ASM
+
+#endif //_SYSCALL_H
diff --git a/include/system.h b/include/system.h
new file mode 100644 (file)
index 0000000..abd1355
--- /dev/null
@@ -0,0 +1,237 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:    system.h
+ * 
+ * Description:    none
+ * 
+ * 
+ *      Author:    Zhao Yanbai [zhaoyanbai@126.com]
+ * 
+ *     Version:    1.0
+ * Create Date: Sat Feb  7 18:57:58 2009
+ * Last Update: Sat Feb  7 18:57:58 2009
+ * 
+ *--------------------------------------------------------------------------
+ */
+
+#ifndef    _SYSTEM_H
+#define    _SYSTEM_H
+
+#include<page.h>
+#include<assert.h>
+#define    KRNLADDR    PAGE_OFFSET
+
+#ifndef    ASM
+#include "types.h"
+#include "printk.h"
+
+void    *kmalloc(size_t size);
+void    kfree(void *p);
+
+
+static inline void *get_virt_pages(unsigned int n)
+{
+    assert(n>0);
+    size_t    size = n << PAGE_SHIFT;
+    return (void*) kmalloc(size);
+}
+static inline void free_virt_pages(void *p)
+{
+    kfree((void *)p);
+}
+static inline void *get_phys_pages(unsigned int n)
+{
+/*
+    assert(n>0);
+    size_t    size = n << PAGE_SHIFT;
+    return (void*) va2pa(kmalloc(size));
+*/
+    return (void *)va2pa(get_virt_pages(n));
+}
+static inline void free_phys_pages(void *p)
+{
+    free_virt_pages((void*)va2pa(p));
+}
+
+extern inline void panic(char *msg);
+
+extern char etext, edata, end;
+
+char gdtr[6],idtr[6];
+#define lgdt()    __asm__    __volatile__("lgdt gdtr")
+#define    sgdt()    __asm__    __volatile__("sgdt gdtr")
+#define    lidt()    __asm__    __volatile__("lidt idtr")
+#define    sidt()    __asm__    __volatile__("sidt idtr")
+
+#define    cli()    __asm__    __volatile__("cli")
+#define    sti()    __asm__    __volatile__("sti")
+#define    disableIRQ()    cli()
+#define    enableIRQ()    sti()
+
+#define    ALIGN(x, a)    (((x)+(a)-1) & ~((a)-1))
+
+
+// 1 GB
+#define    MAX_SUPT_PHYMM_SIZE    (1UL<<30)
+
+#define    INT_STACK_SIZE    PAGE_SIZE
+
+
+enum GDTSelectorIndex
+{
+    INDEX_SPACE=0,
+    INDEX_KCODE,
+    INDEX_KDATA,
+    INDEX_UCODE,
+    INDEX_UDATA,
+    INDEX_EMP1,
+    INDEX_EMP2,
+    INDEX_EMP3,
+    INDEX_EMP4,
+    INDEX_EMP5,
+    INDEX_EMP6,
+    INDEX_EMP7,
+    INDEX_EMP8,
+    INDEX_TSS,
+};
+// pushad push eax, ecx, edx, ebx, esp, ebp, esi, edi
+typedef    struct
+{
+    u32    ebx;
+    u32    edx;
+    u32    ecx;
+    u32    edi;
+    u32    esi;
+    u32    ebp;
+    u32    eax;    // 因为在系统调用中用来带调用号,就无法传送参数
+            // 所以把eax放在这个位置
+    u16    ds, _ds;
+    u16    es, _es;
+    u16    fs, _fs;
+    u16    gs, _gs;
+    union
+    {
+        u32    sysc_nr;
+        u32    irq;
+        u32    errcode;
+    };
+    u32    eip;
+    u16    cs, _cs;
+    u32    eflags;
+    u32    esp;
+    u16    ss, _ss;
+} PtRegs, *pPtRegs;
+
+typedef    unsigned long    Dev, *pDev;
+
+typedef struct system
+{
+    u32    mmap_addr;
+    u32    mmap_size;    // Byte
+
+    u32    mm_lower;    // KB
+    u32    mm_upper;    // KB
+    u64    mm_size;    // Byte
+
+    u32    page_count;
+    pPage    page_map;
+    u32    page_bitmap;
+
+    u32 *page_dir;
+    u32    *pte_start;
+    u32    *pte_end;
+
+    u32    kernel_end;
+
+    // +-------+-------+-------+-------+
+    // | drive | part1 | part2 | part3 |
+    // +-------+-------+-------+-------+
+    // Partition numbers always start from zero.
+    // Unused partition bytes must be set to 0xFF.
+    // More Infomation see 'info multiboot'
+    u32    boot_device;
+
+    Dev    root_dev;
+#define    CMD_LINE_SIZE    128
+    char    *cmdline;
+
+    u32    debug;
+} System, *pSystem;
+
+extern    System system;
+
+#define    pgmap system.page_map
+
+#endif
+
+
+#define    SAVE_REGS   \
+    cld;            \
+    pushl    %gs;    \
+    pushl    %fs;    \
+    pushl    %es;    \
+    pushl    %ds;    \
+    pushl    %eax;    \
+    pushl    %ebp;    \
+    pushl    %esi;    \
+    pushl    %edi;    \
+    pushl    %ecx;    \
+    pushl    %edx;    \
+    pushl    %ebx;
+
+#define    RESTORE_REGS    \
+    popl    %ebx;    \
+    popl    %edx;    \
+    popl    %ecx;    \
+    popl    %edi;    \
+    popl    %esi;    \
+    popl    %ebp;    \
+    popl    %eax;    \
+    popl    %ds;    \
+    popl    %es;    \
+    popl    %fs;    \
+    popl    %gs;
+
+
+#define    PRIVILEGE_KRNL    0x0
+#define    PRIVILEGE_USER    0x3
+
+#define    INDEX_UCODE    3
+#define    INDEX_UDATA    4
+/* *8 == <<3 .但要用于汇编文件 <<3 不行. */
+#define    SELECTOR_KRNL_CS    (INDEX_KCODE*8)
+#define    SELECTOR_KRNL_DS    (INDEX_KDATA*8)
+#define    SELECTOR_KRNL_SS    SELECTOR_KRNL_DS
+#define    SELECTOR_USER_CS    ((INDEX_UCODE*8)|PRIVILEGE_USER)
+#define    SELECTOR_USER_DS    ((INDEX_UDATA*8)|PRIVILEGE_USER)
+#define    SELECTOR_USER_SS    SELECTOR_USER_DS
+
+
+#if 0
+#define    INT_VECT_DIVIDE          0x0
+#define    INT_VECT_DEBUG           0x1
+#define    INT_VECT_NMI             0x2
+#define    INT_VECT_BREAKPOINT      0x3    /* Break Point */
+#define    INT_VECT_OVERFLOW        0x4
+#define    INT_VECT_BOUNDS          0x5
+#define    INT_VECT_INVALOP         0x6
+#define    INT_VECT_COPROCNOT       0x7
+#define    INT_VECT_DOUBLEFAULT     0x8    /* Double Fault */
+#define    INT_VECT_COPROCSEG       0x9
+#define    INT_VECT_INVALTSS        0xA
+#define    INT_VECT_SEGNOT          0xB
+#define    INT_VECT_STACKFAULT      0xC    /* Stack Fault */
+#define    INT_VECT_PROTECTION      0xD
+#define    INT_VECT_PAGEFAULT       0xE
+#define    INT_VECT_COPROCERR       0x10
+#endif
+#define    INT_VECT_IRQ0    0x20
+#define    INT_VECT_IRQ8    0x28
+
+#define    REBOOT_RESTART   0x00
+#define    REBOOT_POWEROFF  0x01
+
+
+#define    ROOT_DEV    system.root_dev
+
+#endif //_SYSTEM_H
diff --git a/include/task.h b/include/task.h
new file mode 100644 (file)
index 0000000..3df9102
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:        task.h
+ * 
+ *      Author:        Zhao Yanbai [zhaoyanbai@126.com]
+ *                     Thu Dec 31 16:54:48 2009
+ * 
+ * Description:        none
+ * 
+ *--------------------------------------------------------------------------
+ */
+
+#ifndef        _TASK_H
+#define        _TASK_H
+
+#include <page.h>
+#include <list.h>
+#include <types.h>
+#include <processor.h>
+#include <system.h>
+#include <wait.h>
+#include <fs.h>
+#define        TASK_PAGES      (2)
+#define        TASK_SIZE       (TASK_PAGES<<PAGE_SHIFT)
+
+enum
+{
+    TASK_UNUSED,
+       TASK_RUNNING,
+       TASK_UNINTERRUPTIBLE,
+       TASK_INTERRUPTIBLE,
+       TASK_EXITING
+};
+
+typedef        union
+{
+       struct
+       {
+               PtRegs          regs;
+
+               unsigned long   esp0;   /* 指示发生在用户态的中断在进入
+                                          内核态后的栈位置 */
+
+               /* 进程切换时用 */
+               unsigned long   esp;
+               unsigned long   eip;
+
+               pid_t           pid;
+               pid_t           ppid;
+               unsigned int state;
+               long            exit_code;
+               void            *cr3;
+
+               long            tty;
+
+               ListHead        list;
+
+               WaitQueue       wait;
+
+               pFile           fps[NR_OPENS];
+
+       };
+
+       unsigned char stack[TASK_SIZE];
+} Task, *pTask;
+
+typedef Task task_struct;
+
+#define        ROOT_TSK_PID    (1)
+
+extern pTask           current;
+extern Task            RootTsk;
+extern ListHead        tsk_list;
+
+#define        add_tsk2list(tsk)       list_add_tail((&(tsk)->list), &tsk_list)
+#define        get_tsk_from_list(p)    list_entry((p), Task, list)
+#define        del_tsk_from_list(tsk)  list_del((&tsk->list))
+
+#endif //_TASK_H
diff --git a/include/types.h b/include/types.h
new file mode 100644 (file)
index 0000000..f125189
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:        types.h
+ * 
+ * Description:        none
+ * 
+ * 
+ *      Author:        Zhao Yanbai [zhaoyanbai@126.com]
+ * 
+ *     Version:        1.0
+ * Create Date: Wed Aug 13 23:06:22 2008
+ * Last Update: Wed Aug 13 23:06:22 2008
+ * 
+ *--------------------------------------------------------------------------
+ */
+
+#ifndef        _TYPES_H
+#define        _TYPES_H
+
+typedef                unsigned int            size_t;
+typedef                int                     ssize_t;
+
+typedef                signed char             s8;
+typedef                signed short            s16;
+typedef                signed long             s32;
+typedef                signed long long        s64;
+
+typedef                unsigned char           u8;
+typedef        unsigned short          u16;
+typedef                unsigned long           u32;
+typedef                unsigned long long      u64;
+
+typedef                unsigned long           pid_t;
+typedef                unsigned long           mode_t;
+
+
+#define        NULL ((void*)0)
+
+
+//=========================================================================
+//Define kinds of function's type ...
+//=========================================================================
+typedef        void    (*pf_intr)();
+
+#endif //_TYPES_H
diff --git a/include/unistd.h b/include/unistd.h
new file mode 100644 (file)
index 0000000..cf7ee37
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:        unistd.h
+ * 
+ *      Author:        Zhao Yanbai [zhaoyanbai@126.com]
+ *                     Sun Feb  7 13:24:11 2010
+ * 
+ * Description:        none
+ * 
+ *--------------------------------------------------------------------------
+ */
+
+#ifndef        _UNISTD_H
+#define        _UNISTD_H
+
+#include<types.h>
+
+extern pid_t   fork();
+extern int     exit(int status);
+
+#endif //_UNISTD_H
diff --git a/include/wait.h b/include/wait.h
new file mode 100644 (file)
index 0000000..b3f40fe
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:        wait.h
+ * 
+ *      Author:        Zhao Yanbai [zhaoyanbai@126.com]
+ *                     Mon Feb 22 20:50:56 2010
+ * 
+ * Description:        none
+ * 
+ *--------------------------------------------------------------------------
+ */
+
+#ifndef        _WAIT_H
+#define        _WAIT_H
+
+#include<list.h>
+
+typedef        struct
+{
+       ListHead wait;
+} WaitQueueHead, *pWaitQueueHead;
+
+typedef        ListHead WaitQueue, *pWaitQueue;
+
+void init_wait_queue(pWaitQueueHead wqh);
+
+
+#endif //_WAIT_H
diff --git a/kernel.mk b/kernel.mk
new file mode 100644 (file)
index 0000000..e9ab7a4
--- /dev/null
+++ b/kernel.mk
@@ -0,0 +1 @@
+CF             = -g -c -I. -Iinclude -I../include -fno-builtin
diff --git a/kernel/Makefile b/kernel/Makefile
new file mode 100644 (file)
index 0000000..2aaf358
--- /dev/null
@@ -0,0 +1,23 @@
+include ../kernel.mk
+CC = gcc
+CFLAGS = $(CF)
+
+CSOUCE_FILES = $(wildcard *.c)
+SSOUCE_FILES = $(wildcard *.S)
+OBJS  = $(patsubst %.c,%.o,$(CSOUCE_FILES))
+OBJS += $(patsubst %.S,%.S.o,$(SSOUCE_FILES))
+
+%.o : %.c ../include/*.h
+       $(CC) $(CFLAGS) $< -o $@
+%.S.o : %.S  ../include/*.h
+       $(CC) $(CFLAGS) $< -o $@
+
+
+all:$(OBJS)
+
+.PHONY:clean
+clean:
+       $(RM) $(OBJS)
+.PHONY:c
+c:
+       make clean
diff --git a/kernel/clock.c b/kernel/clock.c
new file mode 100644 (file)
index 0000000..1d6dc4a
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:        clock.c
+ * 
+ *      Author:        Zhao Yanbai [zhaoyanbai@126.com]
+ *                     Tue Jan  5 09:51:54 2010
+ * 
+ * Description:        none
+ * 
+ *--------------------------------------------------------------------------
+ */
+
+#include<printk.h>
+#include<system.h>
+//void clk_handler(pPtRegs regs, unsigned int irq)
+void   clk_handler(unsigned int irq, pPtRegs regs, void *dev_id)
+{
+       //printk("^");
+       //printk("%s ", dev_id);
+}
diff --git a/kernel/entry.S b/kernel/entry.S
new file mode 100644 (file)
index 0000000..da8d993
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:        entry.S
+ * 
+ * Description:        none
+ * 
+ * 
+ *      Author:        Zhao Yanbai [zhaoyanbai@126.com]
+ * 
+ *     Version:        1.0
+ * Create Date: Thu Jul 09 19:56:40 2009
+ * Last Update: Thu Jul 09 19:56:40 2009
+ * 
+ *--------------------------------------------------------------------------
+ */
+#define        ASM
+#include<system.h>
+#include<linkage.h>
+
+/*
+ * 陷阱门不会自动清除IF位.所以必需先关中断.
+ * 这个bug我调了很久很久......
+ */
+#define        EC_ENTRY(name)      \
+       .extern do##name;       \
+       ENTRY(name)             \
+       cli; /* 非常重要 */
+
+#define        EC_CALLDO(name)     \
+       SAVE_REGS                           \
+       call    do##name;               \
+       RESTORE_REGS;                   \
+       addl    $4,%esp;                \
+       iret;
+
+
+/*
+ * 不会自动压入错误码的,调用此宏压入一个
+ * 零来占据错误码的位置.以保持代码风格的
+ * 一致性.
+ */
+#define        NOERRCODE(name)     \
+       EC_ENTRY(name)          \
+       pushl   $0;             \
+       EC_CALLDO(name)
+
+#define        ERRORCODE(name)     \
+       EC_ENTRY(name)          \
+       EC_CALLDO(name)
+
+
+NOERRCODE      (DivideError)
+NOERRCODE      (Debug)
+NOERRCODE      (NMI)
+NOERRCODE      (BreakPoint)
+NOERRCODE      (OverFlow)
+NOERRCODE      (BoundsCheck)
+NOERRCODE      (InvalidOpcode)
+NOERRCODE      (DeviceNotAvailable)
+NOERRCODE      (DoubleFault)
+NOERRCODE      (CoprocSegOverRun)
+ERRORCODE      (InvalidTss)
+ERRORCODE      (SegNotPresent)
+ERRORCODE      (StackFault)
+ERRORCODE      (GeneralProtection)
+ERRORCODE      (PageFault)
+NOERRCODE      (CoprocError)
+
diff --git a/kernel/exec.c b/kernel/exec.c
new file mode 100644 (file)
index 0000000..06ff350
--- /dev/null
@@ -0,0 +1,201 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:        exec.c
+ * 
+ *      Author:        Zhao Yanbai [zhaoyanbai@126.com]
+ *                     Sat Feb 20 21:12:30 2010
+ * 
+ * Description:        none
+ * 
+ *--------------------------------------------------------------------------
+ */
+
+#include<syscall.h>
+#include<types.h>
+#include<fcntl.h>
+#include<assert.h>
+#include<stat.h>
+#include<sched.h>
+#include<memory.h>
+#include<elf.h>
+
+int sysc_exec(const char *path, char *const argv[])
+{
+       assert(argv == NULL);   // unsupport now
+
+       int fd;
+       int i;
+
+       fd = sysc_open(path, O_RDONLY, 0);
+       if(fd == -1)
+       {
+               panic("can not find file");
+       }
+
+       int     filesz;
+       Stat    stat;
+       char    *buf;
+
+       sysc_stat(fd, &stat);
+       filesz  = stat.st_size;
+       if(stat.st_size <=0 || stat.st_size>MAX_SUPT_FILE_SIZE)
+       {
+               printk("file %s is not exist\n", path);
+               return -ENOENT;
+       }
+       buf = (void*)kmalloc(filesz);
+       sysc_read(fd, buf, filesz);
+
+#if 0  
+       for(i=0; i<filesz; i++)
+               printk("%02x ", (unsigned char)buf[i]);
+#endif
+
+       pElf32_Ehdr ehdr = (pElf32_Ehdr) buf;
+       //assert(strncmp(ELFMAG, ehdr->e_ident, sizeof(ELFMAG)-1) == 0);
+       if(strncmp(ELFMAG, ehdr->e_ident, sizeof(ELFMAG)-1) != 0)
+       {
+               printk("file %s can not execute\n", path);
+               kfree(buf);
+               return -ENOEXEC;
+       }
+       //printk("Entry: %08x phnum:%d\n", ehdr->e_entry, ehdr->e_phnum);
+       
+       int size = 0;
+       char *pv = NULL;        // phdr 中第一个的VirtAddr
+       for(i=0; i<ehdr->e_phnum; i++)
+       {
+               pElf32_Phdr phdr;
+               phdr = (pElf32_Phdr)(buf+ehdr->e_phoff+(i*ehdr->e_phentsize));
+               //printk(" %d %08x\n", i, phdr->p_type);
+               if(phdr->p_type == PT_LOAD)
+               {
+                       size += phdr->p_memsz;
+                       if(i==0)
+                               pv = (char *)phdr->p_vaddr;
+               }
+       }
+
+       char *exe = (char *) kmalloc(size);
+       for(i=0; i<ehdr->e_phnum; i++)
+       {
+               pElf32_Phdr phdr;
+               phdr = (pElf32_Phdr)(buf+ehdr->e_phoff+(i*ehdr->e_phentsize));
+               if(phdr->p_type != PT_LOAD)
+                       continue;
+#if 0
+               printk("%08x ", exe+phdr->p_vaddr-pv);
+               printk("p_offset:%d\n", phdr->p_offset);
+
+               int j;
+               for(j=0; j<100;/*phdr->p_filesz*/ j++)
+                       printk("%02x ", *((char *)(buf+phdr->p_offset)+j));
+#endif
+               if(phdr->p_filesz != 0)
+               {
+                       memcpy((void*)(exe+phdr->p_vaddr-pv),
+                               (void*)(buf+phdr->p_offset),
+                               phdr->p_filesz);
+               }
+
+
+#if 0
+               u32     *pd =(u32*)pa2va(current->cr3);
+               u32     *pt;
+               u32     npd_min, npd_max, npt;
+               u32     pde, pte;
+               u32     vaddr = phdr->p_vaddr;
+               npd_min = get_npd(vaddr);
+               npd_max = get_npd(vaddr+phdr->p_memsz);
+               u32     npd;
+
+               for(npd=npd_min; npd<=npd_max; npd++)
+               {
+                       void *tmp = get_phys_pages(1);
+                       pd[npd] = tmp | 7;
+               }
+#endif
+       }
+
+
+       /*
+        *  因为目前文件支持最大为12*EXT2_BLOCK_SIZE
+        *  即12K~48K之间
+        *  所以就以一个页目录项来简化处理
+        */
+       u32     *pd = (u32*) pa2va(current->cr3);
+       u32     *pt;
+       u32     pa_exe;
+       u32     npd, npt;
+       
+       pa_exe  = va2pa(exe);
+       npd     = get_npd(ehdr->e_entry);
+       pt      = get_phys_pages(1);
+       if(pt == NULL)
+               panic("out of memory");
+       //printk("npd: %d pt:%08x\n", npd, pt);
+       memset(pa2va(pt), 0, PAGE_SIZE);
+       pd[npd] = (u32) pt | 7;
+       pt = pa2va(pt);
+       for(i=0; i<ehdr->e_phnum; i++)
+       {
+               pElf32_Phdr phdr;
+               phdr = (pElf32_Phdr)(buf+ehdr->e_phoff+(i*ehdr->e_phentsize));
+               if(phdr->p_type != PT_LOAD)
+                       continue;
+
+               u32     npt_min, npt_max;
+
+               npt_min = get_npt(phdr->p_vaddr);
+               npt_max = get_npt(phdr->p_vaddr+phdr->p_memsz);
+               //printk("npt_min:%d npt_max:%d\n", npt_min, npt_max);
+               int j;
+               for(j=npt_min; j<=npt_max; j++)
+               {
+                       pt[j] = (u32)(pa_exe | 7);      // 对于.text不能这样
+                       //printk("pt[j] :%08x\n", pt[j]);
+                       pa_exe = PAGE_SIZE+pa_exe;
+               }
+       }
+       
+       //printk("exe : %08x cr3:%08x\n", exe, pd);
+
+
+       /* 准备内核栈的数据并从ret_from_fork返回 */
+       pPtRegs regs    = ((pPtRegs)(TASK_SIZE+(unsigned long)current)) - 1;
+       extern void ret_from_fork();
+       memset((void*)regs, 0, sizeof(PtRegs));
+       regs->ss        = SELECTOR_USER_DS;
+       regs->ds        = SELECTOR_USER_DS;
+       regs->es        = SELECTOR_USER_DS;
+       regs->fs        = SELECTOR_USER_DS;
+       regs->gs        = SELECTOR_USER_DS;
+       regs->esp       = (KRNLADDR-4*sizeof(unsigned long));
+       regs->eflags    = 0x200;
+       regs->cs        = SELECTOR_USER_CS;
+       regs->eip       = (unsigned long)ehdr->e_entry;
+       current->esp    = (unsigned long) regs;
+       current->eip    = (unsigned long)ret_from_fork;
+
+#if 0  /* 写完之后发现貌似不用 */
+       /* 准备用户栈数据 */
+       /* 先找到用户栈的位置 */
+       u32 pde = pd[get_npd(KRNLADDR)-1] & PAGE_MASK;
+       pt = pa2va(pde);
+       u32 *stack = (u32*)pa2va(pt[1023]);
+       stack[1023] = 0x00;
+       stack[1022] = 0x00;     /* ebp */
+       stack[1021] = 0x00;     /* edx */
+       stack[1020] = 0x00;     /* ecx */
+       printk("stack pt: %08x pde:%08x %08x %08x\n",
+               pt, pde, pd[get_npd(KRNLADDR)-1]);
+#endif
+       kfree(buf);
+
+
+       //printk("eip: %08x \n", regs->eip);
+
+       load_cr3(current);
+
+       return 0;
+}
diff --git a/kernel/exit.c b/kernel/exit.c
new file mode 100644 (file)
index 0000000..812e63b
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:        exit.c
+ * 
+ *      Author:        Zhao Yanbai [zhaoyanbai@126.com]
+ *                     Thu Mar  4 10:03:57 2010
+ * 
+ * Description:        none
+ * 
+ *--------------------------------------------------------------------------
+ */
+
+#include<sched.h>
+#include<system.h>
+
+int sysc_exit(int status)
+{
+
+       if(current == &RootTsk)
+               panic("Root Task is Exiting...");
+
+       /* 先简要实现 */
+       current->state = TASK_EXITING;
+
+       
+       schedule();
+
+       return 0;
+}
diff --git a/kernel/fork.c b/kernel/fork.c
new file mode 100644 (file)
index 0000000..6a2975b
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:        fork.c
+ * 
+ *      Author:        Zhao Yanbai [zhaoyanbai@126.com]
+ *                     Sun Feb  7 13:25:28 2010
+ * 
+ * Description:        none
+ * 
+ *--------------------------------------------------------------------------
+ */
+
+#include<sched.h>
+#if 1
+int sysc_fork()
+{
+       // 先分配一个进程控制结构
+       task_struct *tsk;
+       // TODO tsk = get_unused_task_pcb();
+       if(tsk == NULL)
+               panic("can not malloc PCB");
+
+       //printk("CHILD:%08x\n", tsk);
+
+       memcpy(tsk, current, sizeof(task_struct));
+
+       tsk->pid        = get_next_pid();
+       tsk->ppid       = current->pid;
+
+       init_tsk_cr3(tsk);
+
+       int i, j;
+       u32 *p_pd  = (u32 *) current->cr3; // parent's page dir
+       u32 p_pde; // parent's page dir entry
+       u32 *p_pt  = NULL;
+       u32 *c_pd  = (u32 *) tsk->cr3;
+       u32 c_pde;
+       u32 *c_pt  = NULL;
+
+       p_pd = pa2va(p_pd);
+       c_pd = pa2va(c_pd);
+
+       for(i = (KRNLADDR>>22); i>=0; i--)
+       {
+               p_pde = p_pd[i] & 0xFFFFF000;
+               if(p_pde == 0)
+                       continue;
+
+               //printk("i:%d p_pde:%08x ", i, p_pde);
+
+               // 分配页表
+               c_pde = (u32) get_phys_pages(1);
+
+               //printk("c_pde:%08x ", c_pde);
+
+               c_pt  = pa2va(c_pde);
+               p_pt  = pa2va(p_pde);
+
+               //printk("c_pt:%08x p_pt:%08x\n", c_pt, p_pt);
+
+               for(j=0; j<PAGE_ITEMS; j++)
+               {
+                       p_pt[j] &= (~2UL);
+                       c_pt[j] = p_pt[j];
+                       /* 增加此页的共享计数 */
+                       pgmap[p_pt[j]>>PAGE_SHIFT].count++;
+               }
+
+               c_pd[i] = c_pde | 7;
+       }
+
+
+       load_cr3(current);
+
+       //pPtRegs       regs    = ((pPtRegs)(TASK_SIZE+(unsigned long) current))-1;
+       //tsk->regs     = *regs;
+       //tsk->regs.eax = 0x00;
+       //tsk->regs.eflags |= 0x200; //enable IF
+       pPtRegs regs    = ((pPtRegs)(TASK_SIZE+(unsigned long) tsk))-1;
+       extern  void ret_from_fork();
+       regs->eax       = 0x00;
+       tsk->esp0       = TASK_SIZE + (unsigned long) tsk;
+       tsk->esp        = (unsigned long) regs;
+       tsk->eip        = (unsigned long) ret_from_fork;
+
+
+       //printk("FORK:%08x\n", tsk);
+
+    tsk->state = TASK_RUNNING;
+
+       return (int)tsk->pid;
+}
+#endif
diff --git a/kernel/i8259.c b/kernel/i8259.c
new file mode 100644 (file)
index 0000000..eb46952
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:        i8259.c
+ * 
+ * Description:        none
+ * 
+ * 
+ *      Author:        Zhao Yanbai [zhaoyanbai@126.com]
+ * 
+ *     Version:        1.0
+ * Create Date: Sun Nov  9 11:35:22 2008
+ * Last Update: Tue Feb 10 22:37:15 2009
+ * 
+ *--------------------------------------------------------------------------
+ */
+
+
+#include "io.h"
+#include "i8259.h"
+#include "irq.h"
+
+IrqChip        i8259_chip =
+{
+       .name           = "XT-PIC",
+       .enable         = enable_i8259_irq,
+       .disable        = disable_i8259_irq,
+       .ack            = mask_ack_i8259_irq,
+};
+#if 0
+void enable_i8259_irq(unsigned int irq)
+{
+       unsigned int mask = ~(1 << irq);
+       cached_irq_mask &= mask;
+       if(irq & 8)
+               outb_p(cached_slaver_mask, PIC_SLAVER_IMR);
+       else
+               outb_p(cached_master_mask, PIC_MASTER_IMR);
+}
+
+void disable_i8259_irq(unsigned int irq)
+{
+       unsigned int mask = 1 << irq;
+       cached_irq_mask |= mask;
+       if(irq & 8)
+               outb_p(cached_slaver_mask, PIC_SLAVER_IMR);
+       else
+               outb_p(cached_master_mask, PIC_MASTER_IMR);
+}
+#endif
+void mask_i8259()
+{
+       //mask all of 8259
+       outb_p(0xFF, PIC_MASTER_IMR);
+       outb_p(0xFF, PIC_SLAVER_IMR);
+}
+void init_i8259()
+{
+#if 0
+       outb_p(0x11,0x20);
+       outb_p(0x11,0xA0);
+
+       outb_p(0x20,0x21);
+       outb_p(0x28,0xA1);
+
+       outb_p(0x04,0x21);
+       outb_p(0x02,0xA1);
+
+       outb_p(0x01,0x21);
+       outb_p(0x01,0xA1);
+
+       outb_p(0xFF,0x21);
+       outb_p(0xFF,0xA1);
+#else
+       //Master...
+       outb_p(0x11, PIC_MASTER_CMD); // ICW1
+       outb_p(0x20, PIC_MASTER_IMR); // ICW2: IR0-7 mapped to 0x20-0x27
+       outb_p(1U<<PIC_CASCADE_IR, PIC_MASTER_IMR); //IR2 Connect Slaver.
+       outb_p(0x01, PIC_MASTER_IMR);   // Normal EOI
+       //Auto EOI:outb_p(0x03, PIC_MASTER_CMDB);
+       
+       //Slaver...
+       outb_p(0x11, PIC_SLAVER_CMD);
+       outb_p(0x28, PIC_SLAVER_IMR); // IR0-7 mapped to 0x28-0x2F
+       outb_p(PIC_CASCADE_IR, PIC_SLAVER_IMR);
+       outb_p(0x01, PIC_SLAVER_IMR);
+       //Auto EOI:outb_p(0x01, PIC_SLAVER_CMDB);
+       mask_i8259();
+#endif
+}
diff --git a/kernel/init.c b/kernel/init.c
new file mode 100644 (file)
index 0000000..e60c3c3
--- /dev/null
@@ -0,0 +1,184 @@
+#include<io.h>
+#include<sched.h>
+#include<types.h>
+#include<page.h>
+#include<stdio.h>
+#include<system.h>
+#include<syscall.h>
+#include<processor.h>
+#include<irq.h>
+#include<fcntl.h>
+#include<stat.h>
+
+#define        KRNL_STACK_SIZE 4096
+
+extern void    root_task();
+extern void    setup_kernel();
+
+TSS    tss;
+System system;
+
+static char    kernel_stack[KRNL_STACK_SIZE] __attribute__ ((__aligned__(PAGE_SIZE)));
+
+int KernelEntry()
+{
+       asm(    "movl $kernel_stack,%%esp;"
+               "addl %%eax,%%esp;"
+               ::"a"(KRNL_STACK_SIZE));
+
+       setup_kernel();
+
+       asm("   movl    $0x23,%%eax;            \
+               movw    %%ax,%%ds;              \
+               movw    %%ax,%%es;              \
+               movw    %%ax,%%fs;              \
+               movw    %%ax,%%gs;              \
+               pushl   $0x23;                  \
+               pushl   %%ebx;                  \
+               pushl   $0x282;                 \
+               pushl   $0x1B;                  \
+               leal    root_task,%%eax;        \
+               pushl   %%eax;                  \
+               iret;"::"b"(KRNLADDR));
+       return 0;
+}
+
+#if 0
+void root_task()
+{
+       pid_t pid;
+       pid = fork();
+       if(pid < 0)
+       {
+               printf("failed create child\n");
+               while(1);
+       }
+       else if(pid == 0)
+       {
+               execv("/bin/sh", NULL);
+               while(1);
+       }
+       else
+       {
+               while(1)
+               {
+
+               }
+       }
+}
+#else
+void root_task()
+{
+       pid_t pid;
+/*
+       int fd = open("/boot/grub/grub.conf", O_RDONLY);
+       //int fd = open("/bin/hw", O_RDONLY);
+       printf("FD: %d\n", fd);
+       char    buf[1024];
+       int     filesz, i;
+       Stat    stat;
+       fstat(fd, &stat);
+       filesz = stat.st_size;
+       printf("file size: %d bytes\n", filesz);
+       read(fd, buf, filesz);
+       for(i=0; i<filesz; i++)
+               printf("%c", buf[i]);
+       execv("/bin/hw", NULL);
+       while(0)
+       {
+               printf("r");
+               int d=100000; while(d--);
+       }
+*/
+
+
+//#define      SHOW    
+
+       pid = fork();
+#ifdef SHOW
+       printf("PID: %d\n", pid);
+#endif
+       if(pid < 0)
+       {
+               printf("failed create child\n");
+               while(1);
+       }
+       else if(pid == 0)
+       {
+               pid_t ccid;
+               ccid = fork();
+
+#ifdef SHOW
+               printf("CCID: %d\n", ccid);
+#endif
+
+               if(ccid < 0)
+               {
+                       printf("child faild to create child\n");
+                       while(1);
+               }
+               else if(ccid == 0)
+               {
+                       execv("/bin/sh", NULL);
+                       while(1)
+                       {
+#ifdef SHOW
+                               printf("a");
+#endif
+                               delay(100);
+                       }
+               }
+               else
+               {
+                       while(1)
+                       {
+#ifdef SHOW
+                               printf("b");
+#endif
+                               delay(200);
+                       }
+               }
+       }
+       else
+       {
+               pid_t pcid;
+               pcid = fork();
+       
+#ifdef SHOW
+               printf("PCID: %d\n", pcid);
+#endif
+               if(pcid < 0)
+               {
+                       printf("parent faild to create child\n");
+                       while(1);
+               }
+               else if(pcid == 0)
+               {
+                       while(1)
+                       {
+#ifdef SHOW
+                               printf("c");
+#endif
+                               delay(300);
+                       }
+               }
+               else
+               {
+                       while(1)
+                       {
+#if 0
+                               int k;
+                               extern  void    ParseKbdInput(int k);
+                               k = read_kbd();
+                               ParseKbdInput(k);
+#else
+#ifdef SHOW
+                               printf("d");
+#endif
+                               delay(400);
+#endif
+                       }
+               }
+       }
+}
+#endif
diff --git a/kernel/innerint.c b/kernel/innerint.c
new file mode 100644 (file)
index 0000000..1463029
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:        innerint.c
+ * 
+ * Description:        none
+ * 
+ * 
+ *      Author:        Zhao Yanbai [zhaoyanbai@126.com]
+ * 
+ *     Version:        1.0
+ * Create Date: Mon Nov 10 15:58:46 2008
+ * Last Update: Tue Feb 10 22:39:24 2009
+ *     Version:        2.0
+ * Last Update: Fri Jul 10 11:55:39 2009
+ * 
+ *--------------------------------------------------------------------------
+ */
+
+#include<system.h>
+#include<sched.h>
+
+#define        DIE_MSG() do{\
+       printk("Unsupport Now...[%s]\n", __FUNCTION__);         \
+       printk("EFLAGS:%08x CS:%02x EIP:%08x ERRCODE:%x",       \
+       regs.eflags, regs.cs, regs.eip, regs.errcode);          \
+       while(1);                                               \
+}while(0);
+
+void doDivideError(PtRegs regs)
+{
+       DIE_MSG();
+}
+void doDebug(PtRegs regs)
+{
+       DIE_MSG();
+}
+void doNMI(PtRegs regs)
+{
+       DIE_MSG();
+}
+void doBreakPoint(PtRegs regs)
+{
+       DIE_MSG();
+}
+void doOverFlow(PtRegs regs)
+{
+       DIE_MSG();
+}
+void doBoundsCheck(PtRegs regs)
+{
+       DIE_MSG();
+}
+void doInvalidOpcode(PtRegs regs)
+{
+       DIE_MSG();
+}
+void doDeviceNotAvailable(PtRegs regs)
+{
+       DIE_MSG();
+}
+void doDoubleFault(PtRegs regs)
+{
+       DIE_MSG();
+}
+void doCoprocSegOverRun(PtRegs regs)
+{
+       DIE_MSG();
+}
+void doInvalidTss(PtRegs regs)
+{
+       DIE_MSG();
+}
+void doSegNotPresent(PtRegs regs)
+{
+       DIE_MSG();
+}
+void doStackFault(PtRegs regs)
+{
+       DIE_MSG();
+}
+void doGeneralProtection(PtRegs regs)
+{
+       DIE_MSG();
+}
+void doPageFault(PtRegs regs)
+{
+       //DIE_MSG();
+       void    *addr;
+       u32     errcode = regs.errcode;
+
+       asm("movl %%cr2,%%eax":"=a"(addr));
+
+/*
+       unsigned long cr3;
+       asm("movl %%cr3,%%eax":"=a"(cr3));
+       printk("%08x errcode: %08x cr2: %08x cr3: %08x\n",
+               current, errcode, addr, cr3);
+*/
+
+       if((errcode & (1UL<<PAGE_P)) == 0)
+       {
+               extern  void    do_no_page(void *);
+               do_no_page(addr);
+       }
+       else
+       {
+               extern  void    do_wp_page(void *);
+               do_wp_page(addr);
+       }
+}
+void doCoprocError(PtRegs regs)
+{
+       DIE_MSG();
+}
diff --git a/kernel/interrupts.S b/kernel/interrupts.S
new file mode 100644 (file)
index 0000000..679117c
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:        interrupts.S
+ * 
+ * Description:        none
+ * 
+ * 
+ *      Author:        Zhao Yanbai [zhaoyanbai@126.com]
+ * 
+ *     Version:        1.0
+ * Create Date: Thu Jul 16 18:54:08 2009
+ * Last Update: Wed Feb 10 23:10:56 2010
+ * 
+ *--------------------------------------------------------------------------
+ */
+#define        ASM
+#include<linkage.h>
+#include<system.h>
+
+#define        IRQ_SYMBL(a,b)  irq_0x##a##b_handler
+#define        IRQ_LIST(x)     \
+IRQ_SYMBL(x,0),                \
+IRQ_SYMBL(x,1),                \
+IRQ_SYMBL(x,2),                \
+IRQ_SYMBL(x,3),                \
+IRQ_SYMBL(x,4),                \
+IRQ_SYMBL(x,5),                \
+IRQ_SYMBL(x,6),                \
+IRQ_SYMBL(x,7),                \
+IRQ_SYMBL(x,8),                \
+IRQ_SYMBL(x,9),                \
+IRQ_SYMBL(x,A),                \
+IRQ_SYMBL(x,B),                \
+IRQ_SYMBL(x,C),                \
+IRQ_SYMBL(x,D),                \
+IRQ_SYMBL(x,E),                \
+IRQ_SYMBL(x,F)
+
+#define        DEF_IRQ(a,b)            \
+.align 0x04,0x90;              \
+.global        irq_0x##a##b##_handler; \
+irq_0x##a##b##_handler:                \
+pushl  $0x##a##b;              \
+jmp    _irq_handler;
+
+
+DEF_IRQ(0,0)
+DEF_IRQ(0,1)
+DEF_IRQ(0,2)
+DEF_IRQ(0,3)
+DEF_IRQ(0,4)
+DEF_IRQ(0,5)
+DEF_IRQ(0,6)
+DEF_IRQ(0,7)
+DEF_IRQ(0,8)
+DEF_IRQ(0,9)
+DEF_IRQ(0,A)
+DEF_IRQ(0,B)
+DEF_IRQ(0,C)
+DEF_IRQ(0,D)
+DEF_IRQ(0,E)
+DEF_IRQ(0,F)
+
+
+.global _irq_handler
+.extern irq_handler
+.extern        schedule
+_irq_handler:
+#if 1
+       /*
+        * 这些寄存器以及上面的中断号和中断自动压栈的寄存器
+        * 都存在中断栈中.
+        */
+       SAVE_REGS
+
+       movw    %ss,%ax
+       movw    %ax, %ds
+       movw    %ax, %es
+       movw    %ax, %fs
+       movw    %ax, %gs
+
+       movl    %esp, %eax
+       call    irq_handler
+
+       call    schedule
+
+       # movl  current, %esp
+               
+       RESTORE_REGS
+       
+       addl    $4,%esp /* 跳过中断号. */
+
+       iret
+#endif
+
+#if 0  /* 2010.02.22 */
+       /*
+        * 这些寄存器以及上面的中断号和中断自动压栈的寄存器
+        * 都存在中断栈中.
+        */
+       SAVE_REGS
+
+       movw    %ss,%ax
+       movw    %ax, %ds
+       movw    %ax, %es
+       movw    %ax, %fs
+       movw    %ax, %gs
+
+       movl    %esp, %eax
+       call    irq_handler
+
+
+       /* 向调度器传递栈帧的位置以便其保存现场. */
+       pushl   %esp
+       call    schedule
+
+       /*
+        * 利用task_struct 里的内容作为新进程的现场来恢复
+        * 所以用不着针对pushl %esp 写 addl $4,%esp了.
+        */
+       movl    current, %esp
+               
+       RESTORE_REGS
+       
+       addl    $4,%esp /* 跳过中断号. */
+
+       iret
+#endif
diff --git a/kernel/irq.c b/kernel/irq.c
new file mode 100644 (file)
index 0000000..cbc162b
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:        irq.c
+ * 
+ * Description:        none
+ * 
+ * 
+ *      Author:        Zhao Yanbai [zhaoyanbai@126.com]
+ * 
+ *     Version:        1.0
+ * Create Date: Thu Jul 16 18:06:22 2009
+ * Last Update: Thu Jul 16 18:06:22 2009
+ * 
+ *--------------------------------------------------------------------------
+ */
+
+#include<irq.h>
+#include<errno.h>
+#include<assert.h>
+
+IrqDesc        irq_desc[NR_IRQS];
+
+int    enable_no_irq_chip(unsigned int irq){return 0;}
+int    disable_no_irq_chip(unsigned int irq){return 0;}
+IrqChip        no_irq_chip =
+{
+       .name           = "none",
+       .enable         = enable_no_irq_chip,
+       .disable        = disable_no_irq_chip
+};
+IrqDesc        no_irq_desc =
+{
+       .chip   = &no_irq_chip,
+       .action = NULL,
+       .status = 0,
+       .depth  = 0
+};
+__attribute__ ((regparm(1))) void      irq_handler(pPtRegs regs)
+{
+
+       unsigned int irq = regs->irq;
+       pIrqDesc        p = irq_desc + irq;
+       pIrqAction      action = p->action;
+       p->chip->ack(irq);
+       while(action)
+       {
+               //action->handler(regs, irq);
+               action->handler(irq, regs, action->dev_id);
+               action = action->next;
+       }
+       p->chip->enable(irq);
+}
+
+
+/*
+int    request_irq(    unsigned int irq,
+                       void (*handler)(pPtRegs, unsigned int),
+                       const char *devname,
+                       void    *dev_id)
+*/
+int    request_irq(    unsigned int irq,
+                       void    (*handler)(unsigned int, pPtRegs, void *),
+                       const char *devname,
+                       void    *dev_id)
+{
+       pIrqAction      p;
+
+       if(irq >= NR_IRQS)
+               return -EINVAL;
+       if(handler == NULL)
+               return -EINVAL;
+
+       // 检查是否已经注册过处理函数了
+       p = irq_desc[irq].action;
+       while(p != NULL)
+       {
+               if(p->handler == handler)
+                       return 0;
+               p = p->next;
+       }
+
+       p = kmalloc(sizeof(IrqAction));
+       if(p == NULL)
+               return -ENOMEM;
+
+
+       p->dev_name             = devname;
+       p->dev_id               = dev_id;
+       p->handler              = handler;
+       p->next                 = NULL;
+       if(irq_desc[irq].action != NULL)
+       {
+               p->next = irq_desc[irq].action;
+               //printk("p->next:%x\n", p->next);
+       }
+       irq_desc[irq].action = p;
+       //printk("irq: %d action:%x\n", irq, p);
+       return 0;
+}
diff --git a/kernel/printk.c b/kernel/printk.c
new file mode 100644 (file)
index 0000000..aa43454
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:        printk.c
+ * 
+ * Description:        none
+ * 
+ * 
+ *      Author:        Zhao Yanbai [zhaoyanbai@126.com]
+ * 
+ *     Version:        1.0 Wed Jul 30 14:25:23 2008
+ *     Version: 1.1 Tue Feb 10 22:40:25 2009
+ *     Version:        2.0 Sun Mar 08 10:52:51 2009
+ *     Version:        3.0 Sat Jul 18 23:06:27 2009
+ * 
+ *--------------------------------------------------------------------------
+ */
+
+char pkbuf[1024];
+extern void    printString(const char *buf, unsigned char color);
+int printk(const char *fmtstr, ...)
+{
+       char *args = (char*)(((char*)&fmtstr)+4);
+       vsprintf(pkbuf, fmtstr, args);
+       printString(pkbuf,0x2);
+       return 0;
+}
+
diff --git a/kernel/processor.c b/kernel/processor.c
new file mode 100644 (file)
index 0000000..78ccf8c
--- /dev/null
@@ -0,0 +1,12 @@
+/*
+ * ------------------------------------------------------------------------
+ *   File Name: processor.c
+ *      Author: Zhao Yanbai
+ *              Thu Mar 27 23:44:12 2014
+ * Description: none
+ * ------------------------------------------------------------------------
+ */
+#include "processor.h"
+
+Desc   idt[NIDT];
+Desc   gdt[NGDT];
diff --git a/kernel/sched.c b/kernel/sched.c
new file mode 100644 (file)
index 0000000..4d1c230
--- /dev/null
@@ -0,0 +1,213 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:        sched.c
+ * 
+ * Description:        none
+ * 
+ * 
+ *      Author:        Zhao Yanbai [zhaoyanbai@126.com]
+ * 
+ *     Version:        1.0
+ * Create Date: Tue Feb 10 11:53:21 2009
+ * Last Update: Tue Feb 10 11:53:21 2009
+ * 
+ *--------------------------------------------------------------------------
+ */
+
+#include "sched.h"
+#include "assert.h"
+
+
+
+pTask          current;
+Task           RootTsk __attribute__((__aligned__(PAGE_SIZE)));
+
+task_struct* task[TASK_CNT];
+
+#define root_task task[0]
+#define first_task task[0]
+
+pid_t  get_next_pid()
+{
+       static pid_t    g_pid = ROOT_TSK_PID;
+
+       return g_pid++;
+}
+
+inline void    load_cr3(pTask  tsk)
+{
+       //printk("tsk %08x cr3: %08x\n",tsk, tsk->cr3);
+       asm("movl %%eax,%%cr3;"::"a"(tsk->cr3));
+       //int j=10000; while(j--);
+}
+
+void   init_tsk_cr3(pTask tsk)
+{
+       tsk->cr3 = pa2va(get_phys_pages(1));
+
+       if(tsk->cr3 == NULL)
+               panic("failed init tsk cr3");
+
+       memset(tsk->cr3, 0, PAGE_SIZE);
+       memcpy((void *)tsk->cr3, (void*)system.page_dir, PAGE_SIZE);
+       tsk->cr3 = (void *)va2pa(tsk->cr3);
+}
+
+void   init_root_tsk()
+{
+       int i;
+
+       root_task->pid  = get_next_pid();
+       root_task->ppid = 0;
+
+       for(i=0; i<NR_OPENS; i++)
+               root_task->fps[i] = 0;
+
+       /* 这个时候还没有进程开始 */
+       root_task->esp0 = tss.esp0;
+
+       init_tsk_cr3(root_task);
+       load_cr3(root_task);
+
+       current = root_task;
+/*
+       // 栈
+       void *stack = kmalloc(PAGE_SIZE);
+       if(stack == NULL)
+               panic("stack");
+       stack = va2pa(stack);
+
+       printk("Stack : %08x\n", stack);
+
+       u32 *pde = pa2va(current->cr3);
+       u32 *pte = (u32 *)kmalloc(PAGE_SIZE);
+       if(pte == NULL)
+               panic("root task stack pte");
+       pte[1023] = stack + 7;
+       printk("pte: %08x\n", pte);
+       pde[(KRNLADDR>>22)-1] = va2pa(pte) + 7;
+
+
+       printk("CR3:%08x\n", current->cr3);
+       asm("movl %%eax,%%cr3;"::"a"(current->cr3));
+*/
+}
+
+void   setup_tasks()
+{
+
+       /* 初始化第一个特殊的进程 */
+       init_root_tsk();
+#if 0
+       add_task(test_taskB);
+       add_task(test_taskA);
+#endif
+}
+
+
+task_struct *get_unused_task_pcb()
+{
+    unsigned int i;
+    for(i=0; i<TASK_CNT; ++i)
+    {
+
+    }
+}
+
+inline pTask get_next_tsk()
+{
+    static unsigned int inx = 0;
+    unsigned int i = 0;
+    task_struct *tsk = root_task;
+
+    for(i=0; i<TASK_CNT; ++i)
+    {
+        inx = (inx + i) % TASK_CNT;
+
+        task_struct *p = root_task + inx;
+
+        if(tsk->state == TASK_RUNNING)
+        {
+            tsk = p;
+            break;
+        }
+    }
+
+    return tsk;
+}
+
+#if 1
+inline void set_esp0(pTask tsk)
+{
+       tss.esp0 = tsk->esp0;
+}
+inline void    switch_to()
+{
+
+       //printk("current:%08x esp0:%08x\n", current, current->esp0);
+       load_cr3(current);
+       set_esp0(current);
+}
+inline void context_switch(pTask prev, pTask next)
+{
+#if 1
+       //pTask last;
+       unsigned long eax, ebx, ecx, edx, esi, edi;
+       //asm("xchg %bx, %bx");
+       asm volatile(
+       "pushfl;"
+       "pushl  %%ebp;"
+       "movl   %%esp,%[prev_esp];"
+       "movl   %[next_esp],%%esp;"
+       "movl   $1f,%[prev_eip];"
+       "pushl  %[next_eip];"
+       "jmp    switch_to;"
+       "1:"
+       "popl   %%ebp;"
+       "popfl;"
+       :       [prev_esp] "=m" (prev->esp),
+               [prev_eip] "=m" (prev->eip),
+               "=a" (prev),    "=b" (ebx),     "=c" (ecx),
+               "=d" (edx),     "=S" (esi),     "=D" (edi)
+       :       [next_esp] "m"  (next->esp),
+               [next_eip] "m"  (next->eip),
+               [prev]  "a" (prev),
+               [next]  "d" (next)
+       :       "memory"
+       );
+#endif
+}
+
+unsigned long  schedule()
+{
+       pTask   tsk, prev, next;
+
+       cli();  // For Safe.
+       tsk = current;
+       do
+       {
+               tsk = get_next_tsk(tsk);
+       }while(tsk->state == TASK_EXITING); /* 简单实现 */
+
+       if(current == tsk)
+               return;
+
+       //tsk = current;
+       //printk("tsk:%08x\t", tsk);
+       //current = tsk;
+       prev = current;
+       current = next = tsk;
+       context_switch(prev, next);
+}
+#endif
+
+
+inline void wake_up(pWaitQueue wq)
+{
+       
+}
+
+inline void sleep_on(pWaitQueue wq)
+{
+
+}
diff --git a/kernel/syscall.S b/kernel/syscall.S
new file mode 100644 (file)
index 0000000..25988f9
--- /dev/null
@@ -0,0 +1,148 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:        syscall.S
+ * 
+ * Description:        none
+ * 
+ * 
+ *      Author:        Zhao Yanbai [zhaoyanbai@126.com]
+ * 
+ *     Version:        1.0
+ * Create Date: Tue Feb 10 13:20:33 2009
+ *     Version: 2.0
+ * Last Update: Wed Feb 10 23:36:34 2010
+ * 
+ *--------------------------------------------------------------------------
+ */
+
+#define        ASM
+#include<system.h>
+#include<syscall.h>
+
+#define        TASK_SIZE 4096*2
+.code32
+#if 0
+.extern sysc_handler_table
+#endif
+.text
+.global        syscall_entry
+.global        ret_from_fork
+
+/*
+ *     0x40 -- %ss
+ *     0x3C -- %esp
+ *     0x38 -- %eflags
+ *     0x34 -- %cs
+ *     0x30 -- %eip
+ *     0x2C -- sysc_nr
+ *     0x28 -- %gs
+ *     0x24 -- %fs
+ *     0x20 -- %es
+ *     0x1C -- %ds
+ *     0x18 -- %eax
+ *     0x14 -- %ebp
+ *     0x10 -- %esi
+ *     0x0C -- %edi
+ *     0x08 -- %ecx
+ *     0x04 -- %edx
+ *     0x00 -- %ebx
+ */
+#if 1
+syscall_entry:
+       /* 此时%esp存的是current的地址(&current) */
+       movl    (%esp),%esp             /* 获得current的值 */
+       addl    $TASK_SIZE, %esp        /* 指向PCB的顶部 */
+
+       pushl   %ds                     /* %ss */
+       pushl   %ebp                    /* %esp */
+       pushfl                          /* %eflags */
+       pushl   $SELECTOR_USER_CS       /* %cs */
+       pushl   %gs:(,%ebp)             /* %eip */
+       pushl   %eax                    /* sysc_nr */
+       SAVE_REGS
+
+       pushl   %eax
+       movw    %ss,%ax
+       movw    %ax, %ds
+       movw    %ax, %es
+       movw    %ax, %gs
+       movw    %ax, %fs
+       popl    %eax
+
+       cmpl    $SYSC_NUM, %eax
+       jae     bad_syscnr
+
+       call    *sysc_handler_table(,%eax,4)
+
+ret_from_bad_syscnr:
+
+
+       movl    %eax, 0x18(%esp)        /* return value */
+
+       /*
+        * fork 后的新进程的返回值已经在栈上被设定为0了.
+        * ret_from_fork 就是新进程被换入执行的入口地址.
+        */
+ret_from_fork:
+
+       RESTORE_REGS
+       
+       movl    0x04(%esp), %edx        /* sysexit 参数 %eip */
+       movl    0x10(%esp), %ecx        /* sysexit 参数 %esp */
+
+       #xchg   %bx, %bx
+       sti             /* sysenter会自动清除IF.貌似sysexit不会自动置位 */
+       sysexit
+
+bad_syscnr:
+       call    sysc_bad_syscnr
+       jmp     ret_from_bad_syscnr
+#endif
+
+#if 0
+syscall_entry:
+       /* 此时%esp存的是current的地址(&current) */
+       movl    (%esp),%esp             /* 获得current的值 */
+       addl    $TASK_SIZE, %esp        /* 指向PCB的顶部 */
+
+       pushl   %ds                     /* %ss */
+       pushl   %ebp                    /* %esp */
+       pushfl                          /* %eflags */
+       pushl   $SELECTOR_USER_CS       /* %cs */
+       pushl   %gs:(,%ebp)             /* %eip */
+       pushl   %eax                    /* sysc_nr */
+       SAVE_REGS
+
+       pushl   %eax
+       movw    %ss,%ax
+       movw    %ax, %ds
+       movw    %ax, %es
+       movw    %ax, %gs
+       movw    %ax, %fs
+       popl    %eax
+
+       call    *sysc_handler_table(,%eax,4)
+
+       movl    %eax, 0x18(%esp)        /* return value */
+
+       RESTORE_REGS
+       
+       movl    0x04(%esp), %edx        /* sysexit 参数 %eip */
+       movl    0x10(%esp), %ecx        /* sysexit 参数 %esp */
+
+       sti             /* sysenter会自动清除IF.貌似sysexit不会自动置位 */
+       sysexit
+#endif
+
+#if 0
+.global sysc_handler_table
+.extern sysc_write
+.extern        sysc_read_kbd
+.extern        sysc_reboot
+.extern        sysc_fork
+sysc_handler_table:
+.long  sysc_write
+.long  sysc_read_kbd
+.long  sysc_reboot
+.long  sysc_fork
+#endif
diff --git a/kernel/syscall.c b/kernel/syscall.c
new file mode 100644 (file)
index 0000000..f658597
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:        syscall.c
+ * 
+ * Description:        none
+ * 
+ * 
+ *      Author:        Zhao Yanbai [zhaoyanbai@126.com]
+ * 
+ *     Version:        1.0
+ * Create Date: Fri Jan  2 19:49:20 2009
+ * Last Update: Fri Jan  2 19:49:20 2009
+ * 
+ *--------------------------------------------------------------------------
+ */
+#include "syscall.h"
+#include "system.h"
+#include "sched.h"
+#include "msr.h"
+
+extern void syscall_entry();
+extern void init_sysc_handler_table();
+
+unsigned long sysc_handler_table[SYSC_NUM];
+
+void   setup_sysc()
+{
+       wrmsr(MSR_SYSENTER_CS,  SELECTOR_KRNL_CS,       0);
+       wrmsr(MSR_SYSENTER_EIP, syscall_entry,          0);
+       wrmsr(MSR_SYSENTER_ESP, &current,               0);
+
+
+       init_sysc_handler_table();
+
+}
+
+
+int    sysc_none()
+{
+       int sysc_nr;
+       asm("":"=a"(sysc_nr));
+       printk("unsupport syscall:%d\n", sysc_nr);
+
+       return 0;
+}
+
+int sysc_pause()
+{
+
+    return 0;
+}
+
+void   init_sysc_handler_table()
+{
+       int i;
+
+       for(i=0; i<SYSC_NUM; i++)
+               sysc_handler_table[i] = (unsigned long) sysc_none;
+
+#define        _sysc_(nr, sym)                                                     \
+       do                                                                              \
+       {                                                                               \
+               extern int sym ();                                              \
+               sysc_handler_table[nr] = (unsigned long) sym;   \
+       }while(0);
+
+       /* 有没有一种宏定义可以把大写直接转成小写? */
+       _sysc_(SYSC_WRITE,          sysc_write);
+       _sysc_(SYSC_READ_KBD,   sysc_read_kbd);
+       _sysc_(SYSC_REBOOT,         sysc_reboot);
+       _sysc_(SYSC_FORK,           sysc_fork);
+       _sysc_(SYSC_EXEC,           sysc_exec);
+       _sysc_(SYSC_OPEN,           sysc_open);
+       _sysc_(SYSC_READ,           sysc_read);
+       _sysc_(SYSC_STAT,           sysc_stat);
+       _sysc_(SYSC_EXIT,           sysc_exit);
+       _sysc_(SYSC_PAUSE,          sysc_pause);
+       _sysc_(SYSC_TEST,           sysc_test);
+}
+int    sysc_bad_syscnr()
+{
+       int sysc_nr;
+       asm("":"=a"(sysc_nr));
+       printk("bad syscall nr:%d\n", sysc_nr);
+
+       return 0;
+}
diff --git a/kernel/system.c b/kernel/system.c
new file mode 100644 (file)
index 0000000..5de7d2a
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:        system.c
+ * 
+ *      Author:        Zhao Yanbai [zhaoyanbai@126.com]
+ *                     Sun Jan 24 13:57:46 2010
+ * 
+ * Description:        none
+ * 
+ *--------------------------------------------------------------------------
+ */
+
+
+#include<syscall.h>
+
+int    sysc_reboot(int mode)
+{
+
+       void do_reboot();
+       void do_poweroff();
+
+       switch(mode)
+       {
+       case 0:
+               do_reboot();
+               break;
+       case 1:
+               do_poweroff();
+               break;
+       }
+
+       return 0;
+}
+
+
+inline void panic(char *msg)
+{
+       printk("PANIC:\"%s\" file:%s function:%s line:%d\n",
+               msg, __FILE__, __FUNCTION__, __LINE__);
+       while(1);
+}
diff --git a/kernel/test.c b/kernel/test.c
new file mode 100644 (file)
index 0000000..2512968
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:        test.c
+ * 
+ *      Author:        Zhao Yanbai [zhaoyanbai@126.com]
+ *                     Tue Feb 23 17:47:43 2010
+ * 
+ * Description:        sysc_test
+ * 
+ *--------------------------------------------------------------------------
+ */
+#include<syscall.h>
+#include<printk.h>
+#include<sched.h>
+
+void dump_fd()
+{
+       int i;
+       for(i=0; i<NR_OPENS; i++)
+       {
+               pFile pf = current->fps[i];
+               if(pf == NULL) continue;
+               printk("fd[%d]: %08x\n", i, pf);
+
+
+               pInode inode = pf->inode;
+               printk("file_desc ino_nr: %04d inode:%08x\n",
+                       pf->ino_nr, inode);
+
+               printk("inode: size: %d\n", inode->i_size);
+       }
+}
+
+int sysc_test()
+{
+       dump_fd();
+
+       return 0;
+}
diff --git a/kernel/test_task.c b/kernel/test_task.c
new file mode 100644 (file)
index 0000000..f24cf5d
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:        test_task.c
+ * 
+ *      Author:        Zhao Yanbai [zhaoyanbai@126.com]
+ *                     Tue Feb  2 20:18:05 2010
+ * 
+ * Description:        none
+ * 
+ *--------------------------------------------------------------------------
+ */
+
+
+#include<stdio.h>
+#include<sched.h>
+#include<assert.h>
+#include<system.h>
+pTask  tTasks[NR_TASKS];
+
+#if 0
+void   SetuptTasks()
+{
+       int i;
+
+
+       for(i=0; i<NR_TASKS; i++)
+       {
+               tTasks[i] = NULL;
+       }
+
+       tTasks[0] = &RootTsk;
+       current = tTasks[0];
+}
+#endif
+void   add_task(void *fun)
+{
+#if 0
+       assert(fun != NULL);
+       pTask   tsk = NULL;
+       tsk = kmalloc(sizeof(Task));
+       if(tsk == NULL)
+               panic("shit happens");
+
+       printk("tsk:%08x\n", tsk);
+
+       tsk->pid        = get_next_pid();
+       tsk->ppid       = 0;
+       init_tsk_cr3(tsk);
+
+       pPtRegs r;
+       r = &tsk->regs;
+       memset((void *)r, 0, sizeof(PtRegs));
+       r->ds = r->es = r->fs = r->gs = SELECTOR_USER_DS;
+       r->eip          = (unsigned long)fun;
+       r->cs           = SELECTOR_USER_CS;
+       r->eflags       = 0x282;
+       r->esp          = (unsigned long)tsk;
+       r->ss           = SELECTOR_USER_SS;
+
+       add_tsk2list(tsk);
+#endif
+}
+
+#if 0
+void   add_task(void *fun)
+{
+       assert(fun != NULL);
+       pTask   tsk = NULL;
+       int i=0;
+       for(i=0; i<NR_TASKS; i++)
+       {
+               if(tTasks[i] == NULL)
+               {
+                       tsk = kmalloc(sizeof(Task));
+                       if(tsk == NULL)
+                               panic("shit happens");
+                       //tTasks[i] = tsk;
+                       break;
+               }
+       }
+
+       if(i == NR_TASKS)
+               panic("tasks full");
+
+       pPtRegs r;
+       r = &tsk->regs;//(pPtRegs)(TASK_SIZE + (unsigned long)tsk);
+       //printk("Add Tsk: tsk:%08x r:%08x ", tsk, r);
+       //r--;
+       //printk("r:%08x sizeof regs:%x ", r, sizeof(PtRegs));
+
+       memset((void *)r, 0, sizeof(PtRegs));
+       //printk("USER CS: %x\n", SELECTOR_USER_CS);
+       //printk("USER DS: %x\n", SELECTOR_USER_DS);
+       r->ds = r->es = r->fs = r->gs = SELECTOR_USER_DS;
+       r->eip          = (unsigned long)fun;
+       r->cs           = SELECTOR_USER_CS;
+       r->eflags       = 0x282;
+       r->esp          = (unsigned long)tsk;
+       r->ss           = SELECTOR_USER_SS;
+
+
+       tTasks[i] = tsk;
+}
+#endif
+
+void   delay(unsigned int d)
+{
+       unsigned int i;
+       int n = 10000;
+       for(i=0; i<d*n; i++)
+                       ;
+}
+
+#if 0
+void   test_taskA()
+{
+       while(1)
+       {
+               printf("A");
+               delay(400);
+       }
+}
+
+void   test_taskB()
+{
+       while(1)
+       {
+               printf("B");
+               delay(500);
+       }
+}
+#endif
diff --git a/kernel/wait.c b/kernel/wait.c
new file mode 100644 (file)
index 0000000..e9bda84
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:        wait.c
+ * 
+ *      Author:        Zhao Yanbai [zhaoyanbai@126.com]
+ *                     Mon Feb 22 20:45:22 2010
+ * 
+ * Description:        none
+ * 
+ *--------------------------------------------------------------------------
+ */
+#include<wait.h>
+
+void init_wait_queue(pWaitQueueHead wqh)
+{
+       INIT_LIST_HEAD(&wqh->wait);
+}
+
+void add_wait_queue(pWaitQueueHead wqh, pWaitQueue wq)
+{
+       list_add_tail(wq, &wqh->wait);
+}
+
+void del_wait_queue(pWaitQueueHead wqh, pWaitQueue old)
+{
+       //list_del_init();
+}
diff --git a/lib/Makefile b/lib/Makefile
new file mode 100644 (file)
index 0000000..2aaf358
--- /dev/null
@@ -0,0 +1,23 @@
+include ../kernel.mk
+CC = gcc
+CFLAGS = $(CF)
+
+CSOUCE_FILES = $(wildcard *.c)
+SSOUCE_FILES = $(wildcard *.S)
+OBJS  = $(patsubst %.c,%.o,$(CSOUCE_FILES))
+OBJS += $(patsubst %.S,%.S.o,$(SSOUCE_FILES))
+
+%.o : %.c ../include/*.h
+       $(CC) $(CFLAGS) $< -o $@
+%.S.o : %.S  ../include/*.h
+       $(CC) $(CFLAGS) $< -o $@
+
+
+all:$(OBJS)
+
+.PHONY:clean
+clean:
+       $(RM) $(OBJS)
+.PHONY:c
+c:
+       make clean
diff --git a/lib/assert.c b/lib/assert.c
new file mode 100644 (file)
index 0000000..ec3309a
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:        assert.c
+ * 
+ *      Author:        Zhao Yanbai [zhaoyanbai@126.com]
+ *                     Sat Jan 23 15:25:29 2010
+ * 
+ * Description:        none
+ * 
+ *--------------------------------------------------------------------------
+ */
+
+void assert_fail(char *exp, char *file, unsigned int line, char *func)
+{
+       printk("%s:%d: %s: Assertion \'%s\' failed.\n",
+               file, line, func, exp);
+
+       while(1);
+}
diff --git a/lib/errno.c b/lib/errno.c
new file mode 100644 (file)
index 0000000..9d0a4e4
--- /dev/null
@@ -0,0 +1,12 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:        errno.c
+ * 
+ *      Author:        Zhao Yanbai [zhaoyanbai@126.com]
+ *                     Tue Feb 23 01:49:49 2010
+ * 
+ * Description:        none
+ * 
+ *--------------------------------------------------------------------------
+ */
+int errno;
diff --git a/lib/exec.c b/lib/exec.c
new file mode 100644 (file)
index 0000000..b912564
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:        exec.c
+ * 
+ *      Author:        Zhao Yanbai [zhaoyanbai@126.com]
+ *                     Tue Feb 23 20:47:11 2010
+ * 
+ * Description:        none
+ * 
+ *--------------------------------------------------------------------------
+ */
+#include<syscall.h>
+
+int execv(const char *path, char *const argv[])
+{
+       return syscall2(SYSC_EXEC, path, argv);
+}
diff --git a/lib/exit.c b/lib/exit.c
new file mode 100644 (file)
index 0000000..8749935
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:        exit.c
+ * 
+ *      Author:        Zhao Yanbai [zhaoyanbai@126.com]
+ *                     Thu Mar  4 10:11:57 2010
+ * 
+ * Description:        none
+ * 
+ *--------------------------------------------------------------------------
+ */
+
+#include<syscall.h>
+int    exit(int status)
+{
+       syscall1(SYSC_EXIT, status);
+}
diff --git a/lib/fork.c b/lib/fork.c
new file mode 100644 (file)
index 0000000..36d9cd0
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:        fork.c
+ * 
+ *      Author:        Zhao Yanbai [zhaoyanbai@126.com]
+ *                     Sun Feb  7 13:30:24 2010
+ * 
+ * Description:        none
+ * 
+ *--------------------------------------------------------------------------
+ */
+
+#include<types.h>
+#include<syscall.h>
+#include<stdio.h>
+pid_t  fork()
+{
+#if 0
+       pid_t pid;
+       //asm("xchg %bx, %bx;");
+       //syscall0(SYSC_FORK);
+       //while(1);
+       //asm("xchg %bx, %bx;");
+       //asm("":"=a"(pid));
+       //printf("pid:%x\n", pid);
+       pid = syscall0(SYSC_FORK);
+       return pid;
+#endif
+       return (pid_t) syscall0(SYSC_FORK);
+}
diff --git a/lib/keyboard.c b/lib/keyboard.c
new file mode 100644 (file)
index 0000000..9364447
--- /dev/null
@@ -0,0 +1,229 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:        keyboard.h
+ * 
+ * Description:        none
+ * 
+ * 
+ *      Author:        Zhao Yanbai [zhaoyanbai@126.com]
+ * 
+ *     Version:        1.0
+ * Create Date: Thu Jul 16 18:39:57 2009
+ * Last Update: Thu Jul 16 18:39:57 2009
+ * 
+ *--------------------------------------------------------------------------
+ */
+#include<system.h>
+#include<syscall.h>
+#include<stdio.h>
+#include<io.h>
+#define        EXT_KEY         0x80000000      /* None Print Key */
+#define        L_SHIFT_DOWN    0x00000100
+#define        R_SHIFT_DOWN    0x00000200
+#define        L_CTRL_DOWN     0x00000400
+#define        R_CTRL_DOWN     0x00000800
+#define        L_ALT_DOWN      0x00001000
+#define        R_ALT_DOWN      0x00002000
+#define        L_SHIFT_UP      (~L_SHIFT_DOWN)
+#define        R_SHIFT_UP      (~R_SHIFT_DOWN)
+#define        L_CTRL_UP       (~L_CTRL_DOWN)
+#define        R_CTRL_UP       (~R_CTRL_DOWN)
+#define        L_ALT_UP        (~L_ALT_DOWN)
+#define        R_ALT_UP        (~R_ALT_DOWN)
+#define        SET_L_SHIFT_DOWN(key)   (key |= L_SHIFT_DOWN)
+#define        SET_R_SHIFT_DOWN(key)   (key |= R_SHIFT_DOWN)
+#define        SET_L_CTRL_DOWN(key)    (key |= L_CTRL_DOWN)
+#define        SET_R_CTRL_DOWN(key)    (key |= R_CTRL_DOWN)
+#define        SET_L_ALT_DOWN(key)     (key |= L_ALT_DOWN)
+#define        SET_R_ALT_DOWN(key)     (key |= R_ALT_DOWN)
+#define        SET_L_SHIFT_UP(key)     (key &= L_SHIFT_UP)
+#define        SET_R_SHIFT_UP(key)     (key &= R_SHIFT_UP)
+#define        SET_L_CTRL_UP(key)      (key &= L_CTRL_UP)
+#define        SET_R_CTRL_UP(key)      (key &= R_CTRL_UP)
+#define        SET_L_ALT_UP(key)       (key &= L_ALT_UP)
+#define        SET_R_ALT_UP(key)       (key &= R_ALT_UP)
+#define        IS_L_SHIFT_DOWN(key)    (key & L_SHIFT_DOWN)
+#define        IS_R_SHIFT_DOWN(key)    (key & R_SHIFT_DOWN)
+#define        IS_L_CTRL_DOWN(key)     (key & L_CTRL_DOWN)
+#define        IS_R_CTRL_DOWN(key)     (key & R_CTRL_DOWN)
+#define        IS_L_ALT_DOWN(key)      (key & L_ALT_DOWN)
+#define        IS_R_ALT_DOWN(key)      (key & R_ALT_DOWN)
+
+const unsigned char kbdCharTable[]={0,0,
+'1','2','3','4','5','6','7','8','9','0','-','=','\b',0,
+'q','w','e','r','t','y','u','i','o','p','[',']','\n',0,
+'a','s','d','f','g','h','j','k','l',';','\'','`',0,'\\',
+'z','x','c','v','b','n','m',',','.','/',0,0,0,' ',
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+};
+const unsigned char kbdShiftCharTable[]={0,0,
+'!','@','#','$','%','^','&','*','(',')','_','+','\b',0,
+'Q','W','E','R','T','Y','U','I','O','P','{','}','\n',0,
+'A','S','D','F','G','H','J','K','L',':','"','~',0,'|',
+'Z','X','C','V','B','N','M','<','>','?',0,0,0,' ',
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+};
+
+/* Make Code */
+#define        MC_BACKSPACE    0x0E
+#define        MC_CTRL         0x1D
+#define        MC_L_SHIFT      0x2A
+#define        MC_R_SHIFT      0x36
+#define        MC_ALT          0x38
+#define        MC_CAPSLOCK     0x3A
+#define        MC_DELETE       0x53
+#define        BC_BACKSPACE    (0x80 | MC_BACKSPACE)
+#define        BC_CTRL         (0x80 | MC_CTRL)
+#define        BC_L_SHIFT      (0x80 | MC_L_SHIFT)
+#define        BC_R_SHIFT      (0x80 | MC_R_SHIFT)
+#define        BC_ALT          (0x80 | MC_ALT)
+#define        BC_DELETE       (0x80 | MC_DELETE)
+#define        BC_CAPSLOCK     (0x80 | MC_CAPSLOCK)
+
+static unsigned char E0Flag = 0;
+
+unsigned char read_kbd()
+{
+       char    k;
+       int ret = -1;
+
+       while(ret == -1)
+       {
+               syscall0(SYSC_READ_KBD);
+               asm("":"=a"(ret));
+       }
+
+       k = (unsigned char) ret;
+
+
+       return k;
+}
+/*
+ * 貌似现在CapsLock不工作了
+ */
+unsigned int _parse_kbd(int ScanCode)
+{
+       //int ScanCode;
+       static unsigned int key;
+       //ScanCode = read_kbd();
+
+       if(ScanCode == 0xE0)
+       {
+               E0Flag = 1;
+               return -1;
+       }
+
+       if(ScanCode & 0x80)     // Make Or Break Code ?
+               goto    BreakCode;
+#if 0  
+       // Ctrl + Alt + Del
+       if( IS_L_CTRL_DOWN(key) && IS_L_ALT_DOWN(key))
+       {
+               if(E0Flag == 1 && ScanCode == MC_DELETE)
+               {
+                       extern  void reboot();
+                       printf("Reboot System Now ...\n");
+                       int i = 100000;
+                       while(i--);
+                       reboot();
+               }
+               if(ScanCode ==  MC_BACKSPACE)
+               {
+                       extern  void poweroff();
+                       printf("Shutdown System Now ...\n");
+                       int i = 100000;
+                       while(i--);
+                       poweroff();
+               }
+       }
+#endif
+
+       switch(ScanCode)
+       {
+       case    MC_L_SHIFT:     SET_L_SHIFT_DOWN(key);  goto End;
+       case    MC_R_SHIFT:     SET_R_SHIFT_DOWN(key);  goto End;
+
+       case    MC_CTRL:
+               E0Flag?SET_R_CTRL_DOWN(key):SET_L_CTRL_DOWN(key);
+               goto End;
+       case    MC_ALT:
+
+               E0Flag?SET_R_ALT_DOWN(key):SET_L_ALT_DOWN(key);
+               goto End;
+       }
+               
+       goto    End;
+
+BreakCode:
+       switch(ScanCode)
+       {
+       case    BC_L_SHIFT:     SET_L_SHIFT_UP(key);    goto End;
+       case    BC_R_SHIFT:     SET_R_SHIFT_UP(key);    goto End;
+       case    BC_CTRL:
+               E0Flag?SET_R_CTRL_UP(key):SET_L_CTRL_UP(key);
+               goto End;
+       case    BC_ALT:
+               E0Flag?SET_R_ALT_UP(key):SET_L_ALT_UP(key);
+               goto End;
+       }
+
+End:
+
+       key &= 0xFFFFFF00;
+       key |= (((E0Flag)?0x00:ScanCode) & 0xFF);
+
+       E0Flag = 0;
+
+       return key;
+
+}
+
+
+
+char ParseKbdInput(int k)
+{
+       //unsigned int k;
+       unsigned int inx;
+       unsigned char chr;
+       static unsigned char CapsLock;
+
+       k = _parse_kbd(k);
+
+       k = k & 0xFF;
+
+       if(k == -1) return ;
+
+       inx = k & 0xFF;
+       chr = 0;
+
+       if(inx >= sizeof(kbdCharTable)) goto End;
+
+       // CapsLock ON OR OFF
+       if(inx == MC_CAPSLOCK)
+               CapsLock = (CapsLock)?0:1;
+
+
+       //if((!IS_L_SHIFT_DOWN(k) && !IS_R_SHIFT_DOWN(k) && CapsLock == 0)
+       //|| ((IS_L_SHIFT_DOWN(k) || IS_R_SHIFT_DOWN(k)) && CapsLock ==1))
+       if(!IS_L_SHIFT_DOWN(k) && !IS_R_SHIFT_DOWN(k))
+       {
+               chr = kbdCharTable[inx];
+               if(CapsLock ==1 && chr >= 'a' && chr <= 'z')
+                       chr -= 32;
+       }
+       else
+       {
+               chr = kbdShiftCharTable[inx];
+               if(CapsLock ==1 && chr >= 'A' && chr <= 'Z')
+                       chr += 32;
+       }
+
+End:
+       if(chr != 0)
+       {
+               printf("%c", chr);
+               return (char)chr;
+       }
+
+       return -1;
+}
diff --git a/lib/lib.c b/lib/lib.c
new file mode 100644 (file)
index 0000000..5e865e7
--- /dev/null
+++ b/lib/lib.c
@@ -0,0 +1,40 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:        lib.c
+ * 
+ *      Author:        Zhao Yanbai [zhaoyanbai@126.com]
+ *                     Wed Feb 17 18:58:13 2010
+ * 
+ * Description:        none
+ * 
+ *--------------------------------------------------------------------------
+ */
+#include<syscall.h>
+#include<system.h>
+
+int isdigit(char c)
+{
+       return ('0'<=c && c<='9');
+}
+
+int atoi(const char *s)
+{
+       int i=0;
+       while(isdigit(*s))
+       {
+               i *= 10;
+               i += (*s++ - '0');
+       }
+
+       return i;
+}
+
+void reboot()
+{
+       syscall1(SYSC_REBOOT,0);
+}
+
+void poweroff()
+{
+       syscall1(SYSC_REBOOT,1);
+}
diff --git a/lib/open.c b/lib/open.c
new file mode 100644 (file)
index 0000000..1b39d14
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:        open.c
+ * 
+ *      Author:        Zhao Yanbai [zhaoyanbai@126.com]
+ *                     Tue Feb 23 01:15:29 2010
+ * 
+ * Description:        none
+ * 
+ *--------------------------------------------------------------------------
+ */
+#include<syscall.h>
+int open(const char *path, int flags, ...)
+{
+       // 不支持第三个参数
+       return syscall3(SYSC_OPEN, path, flags, 0);
+}
diff --git a/lib/read.c b/lib/read.c
new file mode 100644 (file)
index 0000000..09a9aef
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:        read.c
+ * 
+ *      Author:        Zhao Yanbai [zhaoyanbai@126.com]
+ *                     Tue Feb 23 18:54:48 2010
+ * 
+ * Description:        none
+ * 
+ *--------------------------------------------------------------------------
+ */
+#include<types.h>
+#include<syscall.h>
+ssize_t read(int fd, void *buf, size_t count)
+{
+       return (ssize_t) syscall3(SYSC_READ, fd, buf, count);
+}
diff --git a/lib/stat.c b/lib/stat.c
new file mode 100644 (file)
index 0000000..938b200
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:        stat.c
+ * 
+ *      Author:        Zhao Yanbai [zhaoyanbai@126.com]
+ *                     Tue Feb 23 19:27:15 2010
+ * 
+ * Description:        none
+ * 
+ *--------------------------------------------------------------------------
+ */
+#include<types.h>
+#include<syscall.h>
+#include<stat.h>
+
+inline int _stat(int fd, struct stat *stat)
+{
+       return syscall2(SYSC_STAT, fd, stat);
+}
+int fstat(int fd, struct stat *buf)
+{
+       return _stat(fd, buf);
+}
diff --git a/lib/string.c b/lib/string.c
new file mode 100644 (file)
index 0000000..2e76bbf
--- /dev/null
@@ -0,0 +1,73 @@
+//=========================================================================
+// lib/string.c (C) Zhao Yanbai
+//     wed, 30 Jul 2008 15:22 +0800
+//=========================================================================
+
+#include"string.h"
+
+char *strcpy(char *dest, const char *src)
+{
+       char *p = dest;
+       while((*dest++ = *src++));
+       return p;
+}
+
+size_t strlen(const char *str)
+{
+       int i=0;
+       while(*str++) i++;
+       return i;
+}
+int    strcmp(const char *a, const char *b)
+{
+       int delta;
+       while (*a || *b)
+       {
+               delta = *a++ - *b++;
+               if(delta != 0)
+                       return delta;
+       }
+       return 0;
+}
+
+int    strncmp(const char *a, const char *b, size_t count)
+{
+       unsigned char c1, c2;
+       int delta;
+       while(count)
+       {
+               c1 = *a++;
+               c2 = *b++;
+
+               delta = c1-c2;
+               if(delta != 0)
+                       return delta;
+
+               if(c1 == 0)
+                       break;
+               
+               count--;
+       }
+
+       return 0;
+}
+
+char   *strcat(char *dest, const char *src)
+{
+       char *tmp = dest;
+       while(*dest) dest++;
+       while((*dest++ = *src++) != '\0');
+       return tmp;
+}
+void *memcpy(void *dest, const void *src, size_t size)
+{
+       char *d = (char *) dest;
+       char *s = (char *) src;
+       while(size-->0) {*d = *s;d++;s++;}
+       return dest;
+}
+
+void   memset(char *dest, char ch, size_t size)
+{
+       while(size--) *dest++ = ch;
+}
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
new file mode 100644 (file)
index 0000000..1f0004a
--- /dev/null
@@ -0,0 +1,170 @@
+//=========================================================================
+// vsprintf.c (C) Zhao Yanbai
+//     wed, 30 Jul 2008 14:47 +0800
+//     Add %012d %012x %12d %12x Support  Mon, 20 Jul 2009 19:30:34
+// ========================================================================
+#include"string.h"
+
+char   *itoa(char *s, int n);
+char   *itox(char *s, unsigned int n);
+
+enum {
+    ALIGN_RIGHT,
+    ALIGN_LEFT
+};
+
+int write_buf(char *buf, const char *str, char fillch, int charcnt, int align)
+{
+    int len = strlen(str);
+    int delta_char_cnt = charcnt - len;
+
+    int s_pos = 0;
+    int c_pos = len;
+
+    if(ALIGN_RIGHT == align)
+    {
+        s_pos = delta_char_cnt > 0 ? delta_char_cnt : 0;
+        c_pos = 0;
+    }
+
+    strcpy(buf + s_pos, str);
+
+    int i = 0;
+    for(i=0; i<delta_char_cnt; ++i)
+    {
+        buf[c_pos + i] = fillch;
+    }
+
+    return charcnt > len ? charcnt : len;
+}
+
+int vsprintf(char *buf, const char *fmt, char *args)
+{
+       char *p = buf;
+       int char_cnt;
+       char tmp[64];
+
+       while(*fmt)
+       {
+               if( *fmt != '%' )
+               {
+                       *p++ = *fmt++;
+                       continue;
+               }
+
+               fmt++;
+
+        int align = ALIGN_RIGHT;
+        if(*(fmt) == '-')
+        {
+            align = ALIGN_LEFT;
+            ++fmt;
+        }
+        
+
+        char char_fill = ' ';
+               if(*(fmt) == '0' || *(fmt) == ' ')
+        {
+            char_fill = *(fmt);
+            ++fmt;
+        }
+
+               char_cnt = 0;
+               while(*(fmt) >= '0' && *(fmt) <= '9')
+               {
+                       char_cnt += *(fmt) - '0';
+                       char_cnt *= 10;
+                       ++fmt;
+               }
+
+        char_cnt /= 10;
+
+               switch(*fmt)
+               {
+               case 'c':
+                       *p++ = *args;
+                       break;
+               case 'd':
+                       itoa(tmp, *((int*)args));
+            p += write_buf(p, tmp, char_fill, char_cnt, align);           
+#if 0
+                       char_cnt -= strlen(tmp);
+                       if(char_cnt > 0)
+                       {
+                               while(char_cnt--)
+                               *p++ = char_fill;
+                       }
+                       strcpy(p, tmp);
+                       p += strlen(tmp);
+#endif
+                       break;
+               case 's':
+            p += write_buf(p, (const char *)*((unsigned int *) args), char_fill, char_cnt, align);           
+#if 0
+                       strcpy(p, (const char *)*((unsigned int *) args));
+                       p += strlen((const char *)*((unsigned int *) args));
+#endif
+                       break;
+               case 'x':
+                       itox(tmp, *((unsigned int *) args));
+            p += write_buf(p, tmp, char_fill, char_cnt, align);           
+#if 0
+                       char_cnt -= strlen(tmp);
+                       if(char_cnt > 0)
+                       {
+                               while(char_cnt--)
+                                *p++ = char_fill;
+                       }
+                       strcpy(p, tmp);
+                       p += strlen(tmp);
+#endif
+                       break;
+               default:
+                       break;
+               }
+               args += 4;
+               fmt++;
+       }
+       *p = 0;
+}
+
+char   *itoa(char *s, int n)
+{
+       int i;
+       char tmp[64];
+       if( n & 0x80000000 )
+       {
+               n       = ~n + 1;
+               *s++    = '-';
+       }
+       i=0;
+       do
+       {
+               tmp[i++]        = (n % 10) + '0';
+               n               /= 10;
+       }while(n);
+       while(i) *s++=tmp[--i];
+       *s = 0;
+       
+}
+
+char   *itox(char *s, unsigned int n)
+{
+       char *p = s;
+       char ch,i,flag = 0;
+       
+       //*p++  = '0';  *p++    = 'x';
+
+       if(n==0){*p++='0';*p=0;return s;}
+       for(i=28; i>=0; i-=4)
+       {
+               ch      = (n>>i) & 0x0F;
+               if(ch >= 0)     ch += '0';
+               if(ch > '9')    ch += 7;
+               if(ch != '0')   flag = 1;
+               if(ch != '0' || flag == 1)
+                       *p++ = ch;
+       }
+       *p = 0;
+       return s;
+}
diff --git a/lib/write.c b/lib/write.c
new file mode 100644 (file)
index 0000000..89859d4
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:        write.c
+ * 
+ * Description:        none
+ * 
+ * 
+ *      Author:        Zhao Yanbai [zhaoyanbai@126.com]
+ * 
+ *     Version:        1.0
+ * Create Date: Mon Mar  9 02:00:09 2009
+ * Last Update: Mon Mar  9 02:00:09 2009
+ * 
+ *--------------------------------------------------------------------------
+ */
+
+#include<syscall.h>
+
+int write(int fd, const char *buf, unsigned long size)
+{
+       //asm(""::"c"(size),"d"(buf),"b"(fd));
+       //sysenter(0);
+       //syscall3(0, fd, buf, size);
+       //asm("nop;nop;nop;");
+
+       syscall3(SYSC_WRITE, fd, buf, size);
+
+       return size;
+}
diff --git a/mm/Makefile b/mm/Makefile
new file mode 100644 (file)
index 0000000..2aaf358
--- /dev/null
@@ -0,0 +1,23 @@
+include ../kernel.mk
+CC = gcc
+CFLAGS = $(CF)
+
+CSOUCE_FILES = $(wildcard *.c)
+SSOUCE_FILES = $(wildcard *.S)
+OBJS  = $(patsubst %.c,%.o,$(CSOUCE_FILES))
+OBJS += $(patsubst %.S,%.S.o,$(SSOUCE_FILES))
+
+%.o : %.c ../include/*.h
+       $(CC) $(CFLAGS) $< -o $@
+%.S.o : %.S  ../include/*.h
+       $(CC) $(CFLAGS) $< -o $@
+
+
+all:$(OBJS)
+
+.PHONY:clean
+clean:
+       $(RM) $(OBJS)
+.PHONY:c
+c:
+       make clean
diff --git a/mm/kmalloc.c b/mm/kmalloc.c
new file mode 100644 (file)
index 0000000..7e1f9ac
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:        kmalloc.c
+ * 
+ *      Author:        Zhao Yanbai [zhaoyanbai@126.com]
+ *                     Sat Jan 30 12:15:51 2010
+ * 
+ * Description:        现在的版本实现得非常简单,简陋。不能分配大于32*4K的内存
+ *             另外小于32*4K的都按32*4K分配
+ *             以后再来重写这里吧
+ *--------------------------------------------------------------------------
+ */
+#include<page.h>
+#include<types.h>
+#include<assert.h>
+#include<system.h>
+
+static get_order(size_t size)
+{
+       //printk("size:%08x ", size);
+       size = ALIGN(size, PAGE_SIZE);
+       //printk(" %08x\n", size);
+       int i;
+       int n = size>>PAGE_SHIFT;
+       for(i=0; i<MAX_ORDER; i++)
+       {
+               if(n<=(1UL<<i))
+                       break;
+       }
+
+       //printk("i:%d\n", i);
+       return i;
+}
+void   *kmalloc(size_t size)
+{
+       assert(0<size && size<=32*PAGE_SIZE);
+       int     order = get_order(size);
+       void    *p;
+       pPage page = alloc_pages(order);
+
+       if(page == NULL)
+               return NULL;
+
+       //printk("kmalloc:%08x %08x ", page->mapNR, page->mapNR<<PAGE_SHIFT);
+       p = (void*)pa2va(page->mapNR<<PAGE_SHIFT);
+       
+       //printk("kmalloc: %08x\n", p);
+
+       return p;
+}
+
+
+void   kfree(void *p)
+{
+       assert(p != NULL);
+
+       pPage page = system.page_map;
+       //printk("kfree:%08x %08x %08x ", p, va2pa(p));
+       page += ((unsigned long)va2pa(p)>>PAGE_SHIFT);
+       //printk("%08x\n", page->mapNR);
+       free_pages(page);
+}
diff --git a/mm/mm.c b/mm/mm.c
new file mode 100644 (file)
index 0000000..c169b2f
--- /dev/null
+++ b/mm/mm.c
@@ -0,0 +1,441 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:        mm.c
+ * 
+ * Description:        none
+ * 
+ * 
+ *      Author:        Zhao Yanbai [zhaoyanbai@126.com]
+ * 
+ *     Version:        1.0
+ * Create Date: Wed Mar  4 21:08:47 2009
+ * Last Update: Wed Mar  4 21:08:47 2009
+ * 
+ *--------------------------------------------------------------------------
+ */
+#include<printk.h>
+#include<system.h>
+#include<page.h>
+#include<types.h>
+#include<bits.h>
+#include<mm.h>
+#include<boot/bootparam.h>
+
+
+extern char kernel_begin, kernel_end;
+extern char etext,edata,end;
+
+static void e820_print_type(unsigned long type)
+{
+    switch (type) {
+    case E820_RAM:
+        printk("usable");
+        break;
+    case E820_RESERVED:
+        printk("reserved");
+        break;
+    case E820_ACPI:
+        printk("ACPI data");
+        break;
+    case E820_NVS:
+        printk("ACPI NVS");
+        break;
+    case E820_UNUSABLE:
+        printk("unusable");
+        break;
+    default:
+        printk("type %x", type);
+        break;
+    }    
+}
+
+
+void e820_print_map()
+{
+    unsigned int i=0;
+
+    for(i=0; i<boot_params.e820map.map_cnt; ++i)
+    {
+        struct e820_entry *p = boot_params.e820map.map + i;
+
+               printk("[%02d] 0x%08x - 0x%08x size %- 10d %8dKB %5dMB ", i, p->addr, p->addr + p->size, p->size, p->size>>10, p->size>>20);
+
+        e820_print_type(p->type);
+
+               printk("\n");
+    }
+}
+
+
+typedef struct bootmem_data {
+    unsigned long min_pfn;
+    unsigned long max_pfn;
+
+    unsigned long last_offset;   // offset to pfn2pa(this->min_pfn);
+    unsigned long last_hint_inx; // last hit index in bitmap
+
+    void *bitmap;   
+    unsigned long mapsize;
+} bootmem_data_t;
+
+bootmem_data_t bootmem_data;
+#define pfn2inx(pfn) ((pfn) - bootmem_data.min_pfn)
+#define inx2pfn(inx) ((inx) + bootmem_data.min_pfn)
+
+void e820_init_bootmem_data()
+{
+    unsigned int i=0;
+
+    memset(&bootmem_data, 0, sizeof(bootmem_data));
+    bootmem_data.min_pfn    = ~0UL;
+
+    unsigned long bgn_pfn;
+    unsigned long end_pfn;
+
+    for(i=0; i<boot_params.e820map.map_cnt; ++i)
+    {
+        struct e820_entry *p = boot_params.e820map.map + i;
+
+        if(p->type != E820_RAM)
+            continue;
+
+        bgn_pfn = pa2pfn(p->addr);
+        end_pfn = pa2pfn(p->addr + p->size);
+
+        if(bootmem_data.min_pfn > bgn_pfn)
+            bootmem_data.min_pfn = bgn_pfn;
+
+        if(bootmem_data.max_pfn < end_pfn)
+            bootmem_data.max_pfn = end_pfn;
+    }
+
+    // limit min_pfn
+    unsigned long kernel_begin_pfn = va2pfn(&kernel_begin);
+    if(bootmem_data.min_pfn < kernel_begin_pfn)
+    {
+        bootmem_data.min_pfn = kernel_begin_pfn;
+    }
+
+    // limit max_pfn
+    unsigned long max_support_pfn = pa2pfn(MAX_SUPT_PHYMM_SIZE);
+    if(bootmem_data.max_pfn > max_support_pfn)
+    {
+        bootmem_data.max_pfn = max_support_pfn;
+    }
+
+    if(bootmem_data.min_pfn >= bootmem_data.max_pfn)
+    {
+        printk("can not go on playing...\n");
+        while(1);
+    }
+}
+
+void register_bootmem_pages()
+{
+    unsigned int i=0;
+    unsigned int j=0;
+
+    for(i=0; i<boot_params.e820map.map_cnt; ++i)
+    {
+        struct e820_entry *p = boot_params.e820map.map + i;
+
+        if(p->type != E820_RAM)
+            continue;
+
+        unsigned long bgn_pfn = PFN_UP(p->addr);
+        unsigned long end_pfn = PFN_DW(p->addr + p->size);
+
+        bgn_pfn = bgn_pfn > bootmem_data.min_pfn ? bgn_pfn : bootmem_data.min_pfn;
+        end_pfn = end_pfn < bootmem_data.max_pfn ? end_pfn : bootmem_data.max_pfn;
+
+        if(bgn_pfn >= end_pfn)
+        {
+            continue;
+        }
+
+        unsigned long bgn_inx = pfn2inx(bgn_pfn);
+        unsigned long end_inx = pfn2inx(end_pfn);
+
+        for(j=bgn_inx; j<end_inx; ++j)
+        {
+            test_and_clear_bit(j, bootmem_data.bitmap);
+        }
+    } 
+
+}
+
+void reserve_bootmem(unsigned long bgn_inx, unsigned long end_inx)
+{
+    printk("reserve %d %d\n", bgn_inx, end_inx);
+
+    int i=0;
+    for(i=bgn_inx; i<end_inx; ++i)
+    {
+        test_and_set_bit(i, bootmem_data.bitmap);
+    }
+}
+
+void reserve_kernel_pages()
+{
+    reserve_bootmem(pfn2inx(PFN_DW(va2pa(&kernel_begin))), pfn2inx(PFN_UP(va2pa(&kernel_end))));
+}
+
+void reserve_bootmem_pages()
+{
+    unsigned long bgn_pfn = PFN_DW(va2pa(bootmem_data.bitmap));
+
+    unsigned long end_pfn = bgn_pfn;
+
+    end_pfn += PFN_UP(bootmem_data.mapsize);
+
+    reserve_bootmem(pfn2inx(bgn_pfn), pfn2inx(end_pfn));
+}
+
+void init_bootmem_allocator()
+{
+    int mapsize = (bootmem_data.max_pfn - bootmem_data.min_pfn + 7) / 8;
+
+    bootmem_data.bitmap = &kernel_end;
+    bootmem_data.mapsize= mapsize;
+
+    memset(bootmem_data.bitmap, 0xFF, mapsize);
+
+    register_bootmem_pages();
+
+    reserve_kernel_pages();
+
+    reserve_bootmem_pages();
+}
+
+void init_bootmem()
+{
+    e820_print_map();
+    e820_init_bootmem_data();
+    init_bootmem_allocator();
+    
+    printk("alloc 10 bytes align 8    addr %08x\n", alloc_bootmem(10, 8));
+    printk("alloc 40961 bytes align 4096 addr %08x\n", alloc_bootmem(40961, 4096));
+    printk("alloc 5  bytes align 4    addr %08x\n", alloc_bootmem(5, 4));
+    printk("alloc 10 bytes align 1024 addr %08x\n", alloc_bootmem(10, 1024));
+    printk("alloc 123bytes align 2    addr %08x\n", alloc_bootmem(123, 2));
+    printk("alloc 123bytes align 2    addr %08x\n", alloc_bootmem(123, 2));
+}
+
+unsigned long align_bootmem_index(unsigned long inx, unsigned long align)
+{
+    unsigned long min_pfn = bootmem_data.min_pfn;
+    unsigned long aln_pfn = ALIGN(min_pfn + inx, align);
+
+    return aln_pfn - min_pfn;
+}
+
+unsigned long align_bootmem_offset(unsigned long offset,  unsigned long align)
+{
+    unsigned long base = pfn2pa(bootmem_data.min_pfn);
+
+    return ALIGN(base + offset, align) - base;
+}
+
+void *alloc_bootmem(unsigned long size, unsigned long align)
+{
+    bootmem_data_t *pbd = &bootmem_data;
+
+    assert(size != 0);
+    assert((align & (align-1)) == 0); // must be power of 2
+    
+    unsigned long fallback = 0;
+    unsigned long bgn_inx, end_inx, step;
+
+    step = align >> PAGE_SHIFT;
+    step = step > 0 ? step : 1;
+
+    bgn_inx = ALIGN(pbd->min_pfn, step) - pbd->min_pfn;
+    end_inx = pbd->max_pfn - pbd->min_pfn;
+
+    // 优先从上次分配结束的地方开始分配
+    if(pbd->last_hint_inx > bgn_inx)
+    {
+        fallback = bgn_inx + 1;
+        bgn_inx = align_bootmem_index(pbd->last_hint_inx, step);
+    }
+
+    while(1)
+    {
+        int merge;
+        void *region;
+        unsigned long i, search_end_inx;
+        unsigned long start_off, end_off;
+
+find_block:
+
+        bgn_inx = find_next_zero_bit(pbd->bitmap, end_inx - bgn_inx, bgn_inx);
+        bgn_inx = align_bootmem_index(bgn_inx, step);
+
+        search_end_inx = bgn_inx + PFN_UP(size);
+
+        if(bgn_inx >= end_inx || search_end_inx > end_inx)
+            break;
+
+        for(i=bgn_inx; i<search_end_inx; ++i)
+        {
+            if(constant_test_bit(i, pbd->bitmap) != 0) {    // space not enough
+                bgn_inx = align_bootmem_index(i, step);
+                if(bgn_inx == i)
+                    bgn_inx += step;
+
+                goto find_block;
+            }
+        }
+
+        // 如果上次分配截止地址不是页对齐,且是本页的上一页.就尝试利用这段空间.
+        if(pbd->last_offset & (PAGE_SIZE - 1) && PFN_DW(pbd->last_offset) + 1 == bgn_inx)
+            start_off = align_bootmem_offset(pbd->last_offset, align);
+        else
+            start_off = pfn2pa(bgn_inx);
+
+        merge = PFN_DW(start_off) < bgn_inx;
+        end_off = start_off + size;
+
+        pbd->last_offset = end_off;
+        pbd->last_hint_inx = PFN_UP(end_off);
+
+        reserve_bootmem(PFN_DW(start_off) + merge, PFN_UP(end_off));
+        
+        region = pa2va(pfn2pa(pbd->min_pfn) + start_off);
+
+        memset(region, 0, size);
+
+        return region;
+    }
+
+    if(fallback)
+    {
+        bgn_inx = align_bootmem_index(fallback-1, step);
+        fallback = 0;
+        goto find_block;
+    }
+
+    return 0;
+}
+
+void init_mm()
+{
+
+
+}
+
+
+
+
+
+
+FreeArea freeArea[MAX_ORDER];
+#if 0
+unsigned long mb_mm_lower, mb_mm_upper;
+unsigned long mb_mmap_addr, mb_mmap_size;
+unsigned long mmStart, mmEnd;
+unsigned long totalPages;
+FreeArea freeArea[MAX_ORDER];
+
+void printBitMap(FreeArea fa)
+{
+       int i;
+       printk("# ");
+       for(i=0; i<fa.mapSize; i++)
+               printk("%x ", fa.map[i]);
+       printk("++++ %d ++++", freeArea[i].count);
+       printk(" #\n");
+}
+void setup_mm()
+{
+       u32 mm_size = system.mm_size;
+       if(mm_size > 1UL<<30)
+               mm_size = 1UL<<30;
+
+       printk("mm_size: %x\n", mm_size);
+
+/*
+       pmmapItem mmap;
+       unsigned long maxAddr;
+
+       mmStart = (va2pa(&end) + (PAGE_SIZE-1)) & PAGE_MASK;
+       //mmEnd = (mb_mm_upper) & PAGE_MASK;
+
+       mmap = (pmmapItem)mb_mmap_addr;
+       maxAddr = 0;
+       int n = 1;
+       printk("Boot Loader Provided Physical RAM Map:\n");
+       while((unsigned long)mmap < (mb_mmap_addr + mb_mmap_size))
+       {
+               printk("[%02d] 0x%08x%08x - 0x%08x%08x ",
+               n++,//mmap->size,
+
+               mmap->base_addr_high,
+               mmap->base_addr_low,
+               mmap->length_high,
+               mmap->length_low);
+
+               switch(mmap->type)
+               {
+               case E820_RAM:
+                       printk("RAM");
+                       if(maxAddr<(mmap->base_addr_low+mmap->length_low))
+                       {
+                               maxAddr = 
+                               mmap->base_addr_low + mmap->length_low;
+                       }
+                       break;
+               case E820_RESERVED:
+                       printk("Reserved");
+                       break;
+               case E820_ACPI:
+                       printk("ACPI Data");
+                       break;
+               case E820_NVS:
+                       printk("ACPI NVS");
+                       break;
+               default:
+                       printk("Unknown %x\n", mmap->type);
+                       break;
+               }
+               printk("\n");
+
+               mmap = (pmmapItem) ((unsigned long) mmap
+                       + mmap->size + sizeof(mmap->size));
+       }
+
+       
+       //if(maxAddr < mmEnd)   
+       mmEnd = maxAddr & PAGE_MASK;
+       if(mmEnd > MAX_SUPT_PHY_MEM_SIZE)
+               mmEnd = MAX_SUPT_PHY_MEM_SIZE;
+       totalPages = mmEnd >> PAGE_SHIFT;
+
+
+       // bit map
+       int i;
+       static char *bitmap_start,*bitmap_end;
+       bitmap_start = (char *)mmStart;
+
+
+
+       // 
+       unsigned long bitmap_size = (mmEnd + 7) / 8;
+       bitmap_size =  (bitmap_size + (sizeof(long) - 1UL))
+                   &~ (sizeof(long) - 1UL);
+       //while(1);
+       //memset(bitmap_start, 0xFF, bitmap_size);
+
+#if 0
+       printk( "bitmap_start: %x "
+               "mmStart: %x "
+               "mmEnd: %x "
+               "bitmap_size: %x\n",
+               bitmap_start,
+               mmStart,
+               mmEnd,
+               bitmap_size);
+#endif
+*/
+}
+#endif
diff --git a/mm/page.c b/mm/page.c
new file mode 100644 (file)
index 0000000..e73c0a7
--- /dev/null
+++ b/mm/page.c
@@ -0,0 +1,393 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:        page.c
+ * 
+ *      Author:        Zhao Yanbai [zhaoyanbai@126.com]
+ *                     Sun Jan 24 15:14:24 2010
+ * 
+ * Description:        none
+ * 
+ *--------------------------------------------------------------------------
+ */
+
+#include<page.h>
+#include<bits.h>
+#include<types.h>
+#include<sched.h>
+#include<assert.h>
+#include<printk.h>
+#include<init.h>
+
+#define INIT_PAGE_TABLE_CNT 2
+
+char __initdata init_pgd[PAGE_SIZE]                     __attribute__((__aligned__(PAGE_SIZE)));
+char __initdata init_pgt[PAGE_SIZE*INIT_PAGE_TABLE_CNT] __attribute__((__aligned__(PAGE_SIZE)));
+
+
+void init_paging()
+{
+    system.page_dir = (u32 *) init_pgd;
+
+       int i;
+       unsigned long kernel_pde_base = KRNLADDR>>22;
+       for(i=0; i<kernel_pde_base; ++i)
+    {
+               system.page_dir[i] = 0;
+    }
+
+    for(i=kernel_pde_base + INIT_PAGE_TABLE_CNT; i<1024; ++i)
+    {
+        
+    }
+}
+
+
+#define        get_page_from_list(pList) list_entry(pList, Page, list)
+#define        add_page2list(page, order) \
+               list_add(&page->list, &freeArea[order].freeList)
+
+#if 1
+void   do_no_page(void *addr)
+{
+       //printk("%s ", __FUNCTION__);
+       u32     *pde = (u32*)pa2va(current->cr3);
+       u32     *pte;
+       void    *page = get_phys_pages(1);
+       if(page == NULL)
+               panic("failed alloc page");
+
+       int npde = ((u32)addr)>>22;
+       int npte = (((u32)addr)>>12) & 0x3FF;
+
+       if((pde[npde] & 0xFFFFF000)== 0)
+       {
+               //printk("*a*\n");
+               pte = (u32 *) pa2va(get_phys_pages(1));
+               memset((void*)pte, 0, PAGE_SIZE);
+               if(pte == NULL)
+                       panic("failed alloc pte");
+
+               pte[npte] = (u32) page | 7;
+               pde[npde] = va2pa(pte) | 7;
+       }
+       else
+       {
+               //printk("*b* : %08x\n", page);
+               //printk("*b* : %08x %08x\n", pde[npde], page);
+               pte = (u32*)(pde[npde] & 0xFFFFF000);
+               pte = pa2va(pte);
+               pte[npte] = (u32) page | 7;
+       }
+       load_cr3(current);
+#if 0
+       u32     *pde = (u32*)pa2va(current->cr3);
+       u32     *pte;
+       void    *page = (void*)va2pa(kmalloc(PAGE_SIZE));
+       if(page == NULL)
+               panic("failed alloc page");
+
+       int npde = ((u32)addr)>>22;
+       int npte = (((u32)addr)>>12) & 0x3FF;
+
+       if(pde[npde] == 0)
+       {
+               printk("*a*");
+               pte = (u32 *) kmalloc(PAGE_SIZE);
+               memset((void*)pte, 0, PAGE_SIZE);
+               if(pte == NULL)
+                       panic("failed alloc pte");
+
+               pte[npte] = (u32) page | 7;
+               pde[npde] = va2pa(pte) | 7;
+       }
+       else
+       {
+               printk("*b*");
+               pte = pde[npde] & 0xFFFFF000;
+               pte = pa2va(pte);
+               pte[npte] = (u32) page | 7;
+       }
+#endif
+}
+
+
+void do_wp_page(void *addr)
+{
+       int npde = ((u32)addr)>>22;
+       int npte = (((u32)addr)>>12) & 0x3FF;
+
+
+       u32 *pd = (u32 *)pa2va(current->cr3);
+       u32 *pt = NULL;
+
+
+       pt = pa2va(pd[npde] & 0xFFFFF000);
+
+       void *dst, *src;
+
+       src = (void*)pt[npte];
+
+       if(pgmap[((u32)src)>>PAGE_SHIFT].count > 0)
+       {
+               pgmap[((u32)src)>>PAGE_SHIFT].count--;
+
+               src = (void *)pa2va(((u32)src) & 0xFFFFF000);
+
+               dst = get_phys_pages(1);
+               if(dst == NULL)
+                       panic("out of memory");
+               dst = pa2va(dst);
+
+               memcpy(dst, src, PAGE_SIZE);    
+
+               dst = (void *)va2pa(dst);
+               pt[npte] = (u32)dst | 7;
+       }
+       else
+       {
+               pt[npte] |= 7;
+       }
+
+       load_cr3(current);
+}
+
+inline pPage __alloc_pages(unsigned int order, unsigned int alloc_order)
+{
+       assert(0 <= order && order<MAX_ORDER);
+       assert(!list_is_empty(&freeArea[order].freeList));
+       assert(alloc_order <= order);
+
+       pListHead pl = freeArea[order].freeList.next;
+       list_del_init(pl);
+       pPage   page = get_page_from_list(pl);
+
+       if(order == alloc_order)
+       {
+               page->order = alloc_order;
+               page->count = 0;
+               assert((page->mapNR%(1UL<<(order))) == 0);
+               return page;
+       }
+
+       assert(order >= 1);
+
+       // 把这个页分成两半挂到小一级的队列上
+       add_page2list(page, order-1);
+#if 0
+       if(page->mapNR == 0)
+       {
+               printk("[>1<%08x %d %d]\n", page, order, alloc_order);
+               while(1);
+       }
+#endif
+       assert((page->mapNR%(1UL<<(order-1))) == 0);
+       page += (1 << (order-1));
+       assert((page->mapNR%(1UL<<(order-1))) == 0);
+#if 0
+       if(page->mapNR == 0)
+       {
+               printk("[>2<%08x %d %d]\n", page, order, alloc_order);
+               while(1);
+       }
+#endif
+       add_page2list(page, order-1);
+
+       //int j=2000000;while(j--);
+       return __alloc_pages(order-1, alloc_order);
+}
+
+pPage  alloc_pages(unsigned int order)
+{
+       if(order<0 || order>=MAX_ORDER)
+               return NULL;
+
+       int i;
+       for(i=order; i<MAX_ORDER; i++)
+       {
+               if(list_is_empty(&freeArea[i].freeList))
+                       continue;
+
+               return  __alloc_pages(i, order);
+       }
+       return NULL;
+}
+
+
+pPage  get_buddy_page(pPage page, unsigned int order)
+{
+       assert(0<=order && order<MAX_ORDER);
+       assert(page != NULL);
+
+       //printk("mapnr: %d order:%d %d\n", page->mapNR, order, 1UL<<order);
+       assert((page->mapNR%(1UL<<order)) == 0);
+
+       int off = 1<<(order+0);
+       int div = 1<<(order+1);
+       int nr = page->mapNR;
+
+       pListHead pos, tmp;
+       pPage p;
+
+       nr += ((nr+off)/div == nr/div) ? off : -off;
+
+       list_for_each_safe(pos, tmp, &freeArea[order].freeList)
+       {
+               p = get_page_from_list(pos);
+               if(p->mapNR == nr)
+               {
+                       list_del_init(&p->list);
+                       p->order = order;
+                       return p;
+               }
+       }
+
+
+       return NULL;
+}
+
+void   free_pages(pPage page)
+{
+       assert(page != NULL);
+       unsigned int order = page->order;
+       assert(0<=order && order<MAX_ORDER);
+
+
+       // buddy page
+       //printk("[%d %d]", page->mapNR, page->order);
+       assert((page->mapNR % (1UL<<order)) == 0);
+       pPage bpage = get_buddy_page(page, order);
+       //printk("<%d %d>", bpage->mapNR, bpage->order);
+       
+
+       if(bpage == NULL || order == MAX_ORDER-1)
+       {
+               add_page2list(page, order);
+       }
+       else
+       {
+               //list_del_init(&bpage->list);
+               page = (page->mapNR > bpage->mapNR) ? bpage : page;
+               page->order += 1;
+               assert((page->mapNR%(1UL<<page->order)) == 0);
+#if 0
+               if((page->mapNR%(1UL<<page->order)) != 0)
+               {
+                       printk("*%d %d*", page->mapNR, 1UL<<page->order);
+                       panic("bug");
+               }
+#endif
+               free_pages(page);
+       }
+}
+
+#else
+
+inline pPage __alloc_pages(unsigned int order, unsigned int alloc_order)
+{
+       assert(0 <= order && order<MAX_ORDER);
+       assert(!list_is_empty(&freeArea[order].freeList));
+       assert(alloc_order <= order);
+
+       pListHead pl = freeArea[order].freeList.next;
+       list_del_init(pl);
+       pPage   pg = list_entry(pl, Page, list);
+       change_bit(pg->mapNR>>(order+1), (unsigned long *)freeArea[order].map);
+
+       if(order == alloc_order)
+       {
+               return pg;
+       }
+
+       // 把这个页分成两半挂到小一级的队列上
+       assert(order >= 1);
+       list_add(&pg->list, &freeArea[order-1].freeList);
+       pg += (1 << (order-1));
+       list_add(&pg->list, &freeArea[order-1].freeList);
+
+       return __alloc_pages(order-1, alloc_order);
+}
+
+pPage alloc_pages(unsigned int order)
+{
+       if(order >= MAX_ORDER)
+               return NULL;
+
+       int i;
+       for(i=order; i<MAX_ORDER; i++)
+       {
+               if(list_is_empty(&freeArea[i].freeList))
+                       continue;
+
+               return __alloc_pages(i, order);
+       }
+
+       return NULL;
+}
+
+
+void free_pages(pPage page, unsigned int order)
+{
+       assert(0<=order &&  order<MAX_ORDER);
+       assert(page != NULL);
+
+
+       
+       int nr = page->mapNR>>(order+1);
+       //printk("#########%d %d\n",page->mapNR, variable_test_bit( nr, (unsigned long *)freeArea[order].map));
+       if(order == MAX_ORDER -1
+       || !variable_test_bit( nr, (unsigned long *)freeArea[order].map))
+       {
+               change_bit( nr, (unsigned long *)freeArea[order].map);
+               list_add(&page->list, &freeArea[order].freeList);
+       }
+       else
+       {
+               
+               pListHead pos, tmp;
+
+               int offset = 1<<order;
+               nr = page->mapNR;
+               printk("------------%d %d ", offset, nr);
+               nr += (((nr+offset)>>(order)) == (nr>>(order)))
+                        ? offset : -offset;
+               printk("%d\n", nr);
+               list_for_each_safe(pos, tmp, &freeArea[order].freeList)
+               {
+                       printk("[%d] ",list_entry(pos, Page, list)->mapNR);
+                       if(list_entry(pos, Page, list)->mapNR == nr)
+                               break;
+               }
+
+               assert(pos != &freeArea[order].freeList);
+               list_del_init(pos);
+
+               nr = page->mapNR>>(order+2);
+               change_bit( nr, (unsigned long *)freeArea[order+1].map);
+               pPage bpage = get_page_from_list(pos);
+               page = (page->mapNR > bpage->mapNR)? bpage: page;
+               list_add(&page->list, &freeArea[order+1].freeList);
+       }
+}
+#endif
+
+void disp_free_area()
+{
+       int i;
+       for(i=0; i<MAX_ORDER; i++)
+       {
+               pListHead pos,tmp;
+               int count = 0;
+
+               list_for_each_safe(pos, tmp, &freeArea[i].freeList)
+               {
+                       count++;
+                       //printk("%d ", list_entry(pos, Page, list)->mapNR);
+                       //printk("%08x %08x %08x %08x\n",pos, pos->prev, tmp,
+                       //              &(freeArea[i].freeList));
+               }
+               printk("[%d %d]",i, count);
+       }
+       printk("\n");
+       int j=100000;
+       //while(j--);
+}
diff --git a/pci/Makefile b/pci/Makefile
new file mode 100644 (file)
index 0000000..2aaf358
--- /dev/null
@@ -0,0 +1,23 @@
+include ../kernel.mk
+CC = gcc
+CFLAGS = $(CF)
+
+CSOUCE_FILES = $(wildcard *.c)
+SSOUCE_FILES = $(wildcard *.S)
+OBJS  = $(patsubst %.c,%.o,$(CSOUCE_FILES))
+OBJS += $(patsubst %.S,%.S.o,$(SSOUCE_FILES))
+
+%.o : %.c ../include/*.h
+       $(CC) $(CFLAGS) $< -o $@
+%.S.o : %.S  ../include/*.h
+       $(CC) $(CFLAGS) $< -o $@
+
+
+all:$(OBJS)
+
+.PHONY:clean
+clean:
+       $(RM) $(OBJS)
+.PHONY:c
+c:
+       make clean
diff --git a/pci/setuppci.c b/pci/setuppci.c
new file mode 100644 (file)
index 0000000..5a5ade3
--- /dev/null
@@ -0,0 +1,155 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:        setuppci.c
+ * 
+ * Description:        none
+ * 
+ * 
+ *      Author:        Zhao Yanbai [zhaoyanbai@126.com]
+ * 
+ *     Version:        1.0
+ * Create Date: Sun Mar  8 21:33:13 2009
+ * Last Update: Sun Mar  8 21:33:13 2009
+ * 
+ *--------------------------------------------------------------------------
+ */
+#include<io.h>
+#include<pci.h>
+#include<types.h>
+#include<system.h>
+#include<printk.h>
+
+void ScanPCIBus(int bus);
+int ProbePCIBus();
+
+static int pci_read_config_byte(int cmd)
+{
+       outl(PCI_CONFIG_CMD(cmd), PCI_ADDR);
+       return inb(PCI_DATA + (PCI_GET_CMD_REG(cmd) & 3));
+}
+
+static int pci_read_config_word(int cmd)
+{
+       outl(PCI_CONFIG_CMD(cmd), PCI_ADDR);
+       return inw(PCI_DATA + (PCI_GET_CMD_REG(cmd) & 2));
+}
+
+static int pci_read_config_long(int cmd)
+{
+       outl(PCI_CONFIG_CMD(cmd), PCI_ADDR);
+       return inl(PCI_DATA);
+}
+
+
+void   setup_pci()
+{
+       if(!ProbePCIBus())
+               return ;
+
+       ScanPCIBus(0);
+}
+
+void ScanPCIBus(int bus)
+{
+       u8 dev, devfn;
+       u32 cmd;
+       u32 retval;
+       printk("Scanning PCI Bus.\n");
+       
+       for(dev=0; dev<32; dev++)
+               for(devfn =0; devfn<8; devfn++)
+               {
+                       cmd = PCI_CMD(bus, dev, devfn, PCI_VENDORID);
+                       retval = pci_read_config_word(cmd);
+                       if(retval == 0xFFFF)
+                               continue;
+                       //Vendor
+                       printk("%x ", retval);
+
+                       //Device
+                       cmd = PCI_CMD(bus, dev, devfn, PCI_DEVICEID);
+                       retval = pci_read_config_word(cmd);
+                       printk("%x ", retval);
+               
+                       // Class Device
+                       cmd = PCI_CMD(bus, dev, devfn, PCI_CLASSPROG);
+                       retval = pci_read_config_byte(cmd);
+                       printk("%x ", retval);
+
+                       cmd = PCI_CMD(bus, dev, devfn, PCI_CLASSDEVICE);
+                       retval = pci_read_config_word(cmd);
+                       printk("%x ", retval);
+                       
+
+                       //Interrupt Line
+                       cmd = PCI_CMD(bus, dev, devfn, PCI_INTRLINE);
+                       retval = pci_read_config_byte(cmd);
+                       printk("%x ", retval);
+
+                       //Interrupt Pin
+                       cmd = PCI_CMD(bus, dev, devfn, PCI_INTRPIN);
+                       retval = pci_read_config_byte(cmd);
+                       printk("%x ", retval);
+
+                       cmd = PCI_CMD(bus, dev, devfn, PCI_HDRTYPE);
+                       retval = pci_read_config_byte(cmd);
+                       printk("%x ", retval);
+                       retval &= PCI_HDRTYPE_MASK;
+                       printk("%x", retval);
+                       
+                       switch(retval)
+                       {
+                       case PCI_HDRTYPE_NORMAL:
+                               printk("Normal Device\n");
+                               break;
+                       case PCI_HDRTYPE_BRIDGE:
+                               printk("Aha PCI-PCI Bridge\n");
+                               break;
+                       case PCI_HDRTYPE_CARDBUS:
+                               printk("Wow PCI-CardBus\n");
+                               break;
+                       default:
+                               printk("Not Support!\n");
+                               break;
+                       }
+               }
+}
+
+int ProbePCIBus()
+{
+       int retval;
+       int cmd;
+       int dev,devfn;
+       char errmsg[]="Can not find PCI bus on your computer";
+
+       // Check if The IO Address was Used...
+       cmd = PCI_CMD(0,0,0,0);
+       retval = pci_read_config_long(cmd);
+       if( retval == 0xFFFFFFFF || retval == 0x00000000
+       ||  retval == 0x0000FFFF || retval == 0xFFFF0000)
+       {
+               printk("%s\n",errmsg);
+               return 0;
+       }
+
+       // Maybe it's just an ISA Device
+       // So We Must Check if It is PCI...
+       for(dev=0; dev<32; dev++)
+               for(devfn=0; devfn<8; devfn++)
+               {
+                       cmd = PCI_CMD(0, dev, devfn, PCI_CLASSDEVICE);
+                       retval = pci_read_config_word(cmd);
+                       if(retval == PCI_CLASS_BRIDGE_HOST
+                       || retval == PCI_CLASS_DISPLAY_VGA)
+                               return 1;
+                       cmd = PCI_CMD(0, dev, devfn, PCI_VENDORID);
+                       retval = pci_read_config_word(cmd);
+                       if(retval == PCI_VENDORID_INTEL
+                       || retval == PCI_VENDORID_COMPAQ)
+                               return 1;
+               }
+
+
+       printk("%s\n",errmsg);
+       return 0;
+}
diff --git a/scripts/bochscompile b/scripts/bochscompile
new file mode 100644 (file)
index 0000000..b3fc98a
--- /dev/null
@@ -0,0 +1 @@
+./configure --with-x11 --with-wx --with-svga --enable-cpu-level=6 --enable-smp --enable-configurable-msrs --enable-a20-pin --enable-idle-hack --enable-pnic --enable-e1000 --enable-fast-function-calls --enable-debugger --enable-readline --enable-disasm --enable-show-ips --enable-logging --enable-usb --enable-usb-ohci --enable-usb-xhci --enable-ne2000 --enable-sb16
diff --git a/scripts/grub.cfg b/scripts/grub.cfg
new file mode 100644 (file)
index 0000000..6db5b49
--- /dev/null
@@ -0,0 +1,12 @@
+set default="0"
+
+set timeout=1
+
+insmod msdospart
+insmod ext2
+
+root=(hd0,msdos1)
+
+menuentry 'Kernel'  --class os {
+    multiboot /boot/Kernel root=(hd0,0) debug=1
+}
diff --git a/scripts/init.sh b/scripts/init.sh
new file mode 100755 (executable)
index 0000000..01cb172
--- /dev/null
@@ -0,0 +1,71 @@
+#!/bin/bash
+set -x
+
+HDIMG=out.img
+TMP=build/tmp
+MNT=$TMP/mnt
+
+dd if=/dev/zero of=$HDIMG bs=512 count=49152
+
+lodev=`losetup -f --show $HDIMG`
+
+sleep 1
+
+parted ${lodev} mklabel msdos
+
+sleep 1
+
+parted ${lodev} mkpart primary ext2 200k 100% -a minimal
+
+sleep 1
+
+parted ${lodev} set 1 boot on
+
+sleep 1
+
+partx -a ${lodev}
+
+sleep 1
+
+ls -l ${lodev}*
+
+PART=${lodev}p1
+
+sleep 1
+
+mkfs.ext2 $PART
+
+sleep 1
+
+mkdir -p $MNT
+
+mount $PART $MNT
+
+sleep 1
+
+echo "(hd0) ${lodev}" > ${TMP}/device.map
+
+grub2-install --target=i386-pc              \
+              --grub-mkdevicemap=${TMP}/device.map                                  \
+              --modules="biosdisk part_msdos ext2 configfile normal multiboot"      \
+              --root-directory=$MNT \
+              ${lodev}
+
+cp grub.cfg ${MNT}/boot/grub2/
+cp ../KERNEL.BIN ${MNT}/boot/Kernel
+
+mkdir -p ${MNT}/bin/
+cp ../bin/hw ${MNT}/bin/
+cp ../bin/sh ${MNT}/bin/
+
+sleep 1
+
+umount $MNT
+
+sleep 1
+
+partx -d ${lodev}
+
+sleep 1
+
+losetup -d ${lodev}
diff --git a/scripts/link.ld b/scripts/link.ld
new file mode 100644 (file)
index 0000000..0f7f1e7
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:        link.ld
+ * 
+ * Description: Link All Object Files to KERNEL ...
+ * 
+ * 
+ *      Author:        Zhao Yanbai [zhaoyanbai@126.com]
+ * 
+ *     Version:        1.1
+ * Create Date: Mon Mar  2 12:21:03 2009
+ * Last Update: Mon Mar  2 12:21:03 2009
+ * 
+ *--------------------------------------------------------------------------
+ */
+
+OUTPUT_FORMAT("elf32-i386")
+ENTRY(_start)
+kernel_loaded_physic_addr = 0x100000;
+kernel_virtual_addr_start = 0xC0000000;
+kernel_begin = kernel_virtual_addr_start + kernel_loaded_physic_addr;
+SECTIONS
+{
+       . = kernel_begin;
+       .text : AT(phys_addr) ALIGN(0x1000)
+       {
+               code = .;
+        phys_addr = . - kernel_virtual_addr_start;
+        *(.multiboot_header)
+               *(.text)
+       }
+       etext = .;
+       .data : AT(phys_addr) ALIGN(0x1000) 
+       {
+               data = .;
+        phys_addr = . - kernel_virtual_addr_start;
+               *(.data)
+       }
+       edata = .;
+       .bss : AT(phys_addr)  ALIGN(0x1000)
+       {
+               bss = .;
+        phys_addr = . - kernel_virtual_addr_start;
+               *(.bss);
+       }
+
+    ebss = .;
+
+    .init.data : AT(phys_addr) ALIGN(0x1000)
+    {
+        initdata = .;
+        phys_addr = . - kernel_virtual_addr_start;
+        *(.init.data);
+    }
+
+
+       end = .;
+       _end = .;
+       kernel_end = (end + 0x1000 - 1) & ~ (0x1000 -1);
+}
diff --git a/scripts/mnthd.sh b/scripts/mnthd.sh
new file mode 100755 (executable)
index 0000000..e553746
--- /dev/null
@@ -0,0 +1,26 @@
+#!/bin/bash
+set -x
+
+HDIMG=../HD.IMG
+lodev=`losetup -f --show $HDIMG`
+
+partx -a ${lodev}
+
+PART=${lodev}p1
+
+mount $PART /mnt/
+
+while true; do
+       read -p "Unmount?[y/n]" yn
+       case $yn in
+               [Yy]* ) break;;
+               [Nn]* ) continue;;
+               * ) echo "Please answer yes or no.";;
+       esac
+done
+
+umount /mnt/
+
+partx -d ${lodev}p1
+
+losetup -d ${lodev}
diff --git a/setup/Makefile b/setup/Makefile
new file mode 100644 (file)
index 0000000..2aaf358
--- /dev/null
@@ -0,0 +1,23 @@
+include ../kernel.mk
+CC = gcc
+CFLAGS = $(CF)
+
+CSOUCE_FILES = $(wildcard *.c)
+SSOUCE_FILES = $(wildcard *.S)
+OBJS  = $(patsubst %.c,%.o,$(CSOUCE_FILES))
+OBJS += $(patsubst %.S,%.S.o,$(SSOUCE_FILES))
+
+%.o : %.c ../include/*.h
+       $(CC) $(CFLAGS) $< -o $@
+%.S.o : %.S  ../include/*.h
+       $(CC) $(CFLAGS) $< -o $@
+
+
+all:$(OBJS)
+
+.PHONY:clean
+clean:
+       $(RM) $(OBJS)
+.PHONY:c
+c:
+       make clean
diff --git a/setup/cpuid.c b/setup/cpuid.c
new file mode 100644 (file)
index 0000000..ede5e89
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:        cpuid.c
+ * 
+ * Description:        none
+ * 
+ * 
+ *      Author:        Zhao Yanbai [zhaoyanbai@126.com]
+ * 
+ *     Version:        1.0
+ * Create Date: Sat Feb 28 14:43:35 2009
+ * Last Update: Sat Feb 28 14:43:35 2009
+ * 
+ *--------------------------------------------------------------------------
+ */
+#include<bits.h>
+
+#define        TEST_FEATURE(val,bit,fea)\
+do{\
+       if( ISSET_BIT(val,bit) )\
+               /*printk(" %s",fea)*/;\
+}while(0);
+
+typedef struct reg{ unsigned long eax,ebx,ecx,edx; }Reg,*pReg;
+Reg    cpuid(unsigned long op)
+{
+       Reg     r;
+       asm("cpuid;"
+       :"=a"(r.eax),
+        "=b"(r.ebx),
+        "=c"(r.ecx),
+        "=d"(r.edx)
+       :"a"(op)
+       );
+
+       return  r;
+}
+
+void   detect_cpu()
+{
+
+       Reg     r;
+       unsigned short int cpu_sn[6];   //serial number
+       int     i;
+
+       /**********************Get CPU Name********************************/
+       char    cpu_name[13];
+
+       //printk("Detecting CPU...   ");
+
+       r=cpuid(0);
+       memcpy(cpu_name + 0, &r.ebx, 4);
+       memcpy(cpu_name + 4, &r.edx, 4);
+       memcpy(cpu_name + 8, &r.ecx, 4);
+       cpu_name[12] = 0;
+       printk("%s ",cpu_name);
+
+       /**********************Get Processor Brand String******************/
+       char    pbs[50];                //processor brand string
+       r = cpuid(0x80000002);
+       memcpy(pbs + 0 , &r.eax, 4);
+       memcpy(pbs + 4 , &r.ebx, 4);
+       memcpy(pbs + 8 , &r.ecx, 4);
+       memcpy(pbs + 12, &r.edx, 4);
+       r=cpuid(0x80000003);
+       memcpy(pbs + 16 , &r.eax, 4);
+       memcpy(pbs + 20 , &r.ebx, 4);
+       memcpy(pbs + 24 , &r.ecx, 4);
+       memcpy(pbs + 28 , &r.edx, 4);
+       r=cpuid(0x80000004);
+       memcpy(pbs + 32 , &r.eax, 4);
+       memcpy(pbs + 36 , &r.ebx, 4);
+       memcpy(pbs + 40 , &r.ecx, 4);
+       memcpy(pbs + 44 , &r.edx, 4);
+       //printk("Model Name: %s\n",pbs);
+       printk("%s", pbs);
+
+       /**********************Get Number of Processors********************/
+       int     pn;//number of logical processors in one physical processor
+       r=cpuid(1);
+       pn      = ((r.ebx & 0x00FF0000) >> 16);
+
+       /**********************Get the CPU's Feature***********************/
+       int     fv = r.edx;
+       TEST_FEATURE(fv, 1, "fpu")
+       TEST_FEATURE(fv, 2, "vme")
+       TEST_FEATURE(fv, 3, "de")
+       TEST_FEATURE(fv, 4, "pse")
+       TEST_FEATURE(fv, 5, "msr")
+       TEST_FEATURE(fv, 6, "pae")
+       TEST_FEATURE(fv, 7, "mce")
+       TEST_FEATURE(fv, 8, "cxs")
+       TEST_FEATURE(fv, 9, "apic")
+       //TEST_FEATURE(fv, 10, "Reserved")
+       //TEST_FEATURE(fv, 11, "SYSENTER/SYSEXIT")
+       TEST_FEATURE(fv, 12, "mttr")
+       TEST_FEATURE(fv, 13, "pge")     
+       TEST_FEATURE(fv, 14, "mca")
+       TEST_FEATURE(fv, 15, "cmov")
+       TEST_FEATURE(fv, 16, "pat")
+       TEST_FEATURE(fv, 17, "pse-36")
+       TEST_FEATURE(fv, 18, "psn")
+       TEST_FEATURE(fv, 19, "clflush")
+       //TEST_FEATURE(fv, 20, "Reserved")
+       TEST_FEATURE(fv, 21, "dts")
+       TEST_FEATURE(fv, 22, "acpi")
+       TEST_FEATURE(fv, 23, "mmx")
+       TEST_FEATURE(fv, 24, "fxsr")
+       TEST_FEATURE(fv, 25, "sse")
+       TEST_FEATURE(fv, 26, "sse2")
+       //TEST_FEATURE(fv, 27, "Reserved")
+       TEST_FEATURE(fv, 28, "ht")
+       TEST_FEATURE(fv, 29, "tm")
+       //TEST_FEATURE(fv, 30, "Reserved")
+       TEST_FEATURE(fv, 31, "pbe")
+
+       printk(" x %d Cores\n",pn);
+
+       if(!((1UL<<11) & fv))
+       {
+               printk("Your CPU Do Not Support SYSENTER/SYSEXIT\n");
+               while(1);
+       }
+       
+}
diff --git a/setup/logo.c b/setup/logo.c
new file mode 100644 (file)
index 0000000..b9a2e79
--- /dev/null
@@ -0,0 +1,45 @@
+#include<string.h>
+extern const char *version;
+extern void printString(const char *s, unsigned char color);
+void show_logo()
+{
+#if 1
+int i;
+#define        VER_SIZE        81
+char ver[VER_SIZE];
+memset(ver, ' ', VER_SIZE);
+ver[VER_SIZE-1] = 0;
+//printString(ver, 0x70);
+#if 0
+printString(
+"                     ** **       *******   **    ** **                          "
+"                    *** **       ********  **    ** ***                         "
+"                   **** **       **     ** **    ** ****                        "
+"                  ** ** **       *******   ******** ** **                       "
+"                 **  ** **       ******    ******** **  **                      "
+"                ******* **       **        **    ** *******                     "
+"               **    ** ******** **        **    ** **    **                    "
+"              **     ** ******** **        **    ** **     **                   "
+, 0x9F);
+#endif
+
+memset(ver, ' ', VER_SIZE);
+strcpy(ver, version);
+for(i=0; i<VER_SIZE; i++)
+       if(ver[i] == '\0')
+       {
+               ver[i] = ' ';
+               break;
+       }
+ver[VER_SIZE-1] = 0;
+printString(ver, 0x70);
+#endif
+#if 0
+for(i=1; i<80*1*2; i+=2)
+       *((unsigned char *)(0xB8000+i)) = 0x00;
+for(i=1+80*1*2; i<80*9*2; i+=2)
+       *((unsigned char *)(0xB8000+i)) = 0x1F;
+for(i=1+80*9*2; i<80*10*2; i+=2)
+       *((unsigned char *)(0xB8000+i)) = 0x7F;
+#endif
+}
diff --git a/setup/setup.c b/setup/setup.c
new file mode 100644 (file)
index 0000000..3507ec6
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:        setup.c
+ * 
+ * Description:        none
+ * 
+ * 
+ *      Author:        Zhao Yanbai [zhaoyanbai@126.com]
+ * 
+ *     Version:        1.0
+ * Create Date: Wed Mar  4 20:34:36 2009
+ * Last Update: Wed Mar  4 20:34:36 2009
+ * 
+ *--------------------------------------------------------------------------
+ */
+#include<bits.h>
+#include<printk.h>
+#include<system.h>
+
+extern void    setup_gdt();
+extern void    setup_idt();
+extern void    setup_gate();
+extern void    detect_cpu();
+extern void    setup_sysc();
+extern void    setup_pci();
+extern void    set_tss();
+extern void    show_logo();
+//extern void  setup_tTasks();
+extern void    setup_tasks();
+extern void    setup_root_dev();
+extern void    setup_hd();
+extern void    setup_fs();
+extern void    setup_ext2();
+
+extern unsigned long mb_mm_lower, mb_mm_upper;
+extern unsigned long mb_mmap_addr, mb_mmap_size;
+
+extern void reboot();
+
+
+void setup_kernel()
+{
+       extern char _start, _end;
+
+       printk("kernel:\t%08x - %08x\n", &_start,
+                                        &_end);
+
+       setup_gdt();
+       setup_idt();
+       setup_gate();
+
+       detect_cpu();
+
+       //setup_tTasks();
+       init_mm();
+
+       setup_irqs();
+       set_tss();
+       setup_sysc();
+       setup_pci();
+
+
+    while(1); // TODO MODIFY CODE BELOW
+
+       setup_tasks();
+
+       setup_root_dev();
+       setup_hd();
+       setup_fs();
+       setup_ext2();
+
+       show_logo();
+}
+
diff --git a/setup/system.c b/setup/system.c
new file mode 100644 (file)
index 0000000..e9a3f2e
--- /dev/null
@@ -0,0 +1,205 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:        system.c
+ * 
+ * Description:        none
+ * 
+ * 
+ *      Author:        Zhao Yanbai [zhaoyanbai@126.com]
+ * 
+ *     Version:        1.0
+ * Create Date: Wed Mar  4 21:34:47 2009
+ * Last Update: Wed Mar  4 21:34:47 2009
+ * 
+ *--------------------------------------------------------------------------
+ */
+
+#include<system.h>
+#include<string.h>
+#include<processor.h>
+#include<page.h>
+#include<irq.h>
+#include<sched.h>
+#include<assert.h>
+#include<i8259.h>
+#include<fs.h>
+
+void   setup_gdt()
+{
+       pDesc   pdesc;
+       //change to new gdt.
+       sgdt();
+       memcpy(gdt, (void *)*((unsigned long*)(gdtr+2)),
+                               *((unsigned short *)gdtr));
+       *((unsigned short *)gdtr)       = NGDT*sizeof(Desc);
+       *((unsigned long  *)(gdtr+2))   = (unsigned long)gdt;
+       lgdt();
+       memcpy(gdt+INDEX_UCODE, gdt+INDEX_KCODE, sizeof(Desc));
+       memcpy(gdt+INDEX_UDATA, gdt+INDEX_KDATA, sizeof(Desc));
+       pdesc = gdt+INDEX_UCODE;
+       pdesc->seg.DPL = 3;
+       pdesc = gdt+INDEX_UDATA;
+       pdesc->seg.DPL = 3;
+}
+
+void   setup_idt()
+{
+       //init idt.
+       *((unsigned short *)idtr)       = NIDT*sizeof(Gate);
+       *((unsigned long  *)(idtr+2))   = (unsigned long)idt;
+       lidt();
+}
+void no_irq_handler()
+{
+       printk("no_irq_handler");
+       while(1);
+}
+
+void   setup_gate()
+{      int i;
+#define        set_sys_int(vect, type, DPL, handler)           \
+do{                                                    \
+       extern  void    handler ();                     \
+       set_idt_gate(vect, (u32)handler, type, DPL);    \
+}while(0)
+
+#define        PL_KRNL PRIVILEGE_KRNL
+#define        PL_USER PRIVILEGE_USER
+#if 1
+       set_sys_int(0x00, TRAP_GATE, PL_KRNL, DivideError);
+       set_sys_int(0x01, TRAP_GATE, PL_KRNL, Debug);
+       set_sys_int(0x02, INTR_GATE, PL_KRNL, NMI);     
+       set_sys_int(0x03, TRAP_GATE, PL_USER, BreakPoint);      
+       set_sys_int(0x04, TRAP_GATE, PL_USER, OverFlow);        
+       set_sys_int(0x05, TRAP_GATE, PL_USER, BoundsCheck);     
+       set_sys_int(0x06, TRAP_GATE, PL_KRNL, InvalidOpcode);   
+       set_sys_int(0x07, TRAP_GATE, PL_KRNL, DeviceNotAvailable);      
+       set_sys_int(0x08, TRAP_GATE, PL_KRNL, DoubleFault);     
+       set_sys_int(0x09, TRAP_GATE, PL_KRNL, CoprocSegOverRun);        
+       set_sys_int(0x0A, TRAP_GATE, PL_KRNL, InvalidTss);      
+       set_sys_int(0x0B, TRAP_GATE, PL_KRNL, SegNotPresent);   
+       set_sys_int(0x0C, TRAP_GATE, PL_KRNL, StackFault);      
+       set_sys_int(0x0D, TRAP_GATE, PL_KRNL, GeneralProtection);       
+       set_sys_int(0x0E, TRAP_GATE, PL_KRNL, PageFault);       
+       set_sys_int(0x10, TRAP_GATE, PL_KRNL, CoprocError);
+
+       for(i=0x20; i<256; i++)
+               set_sys_int(i, INTR_GATE, PL_KRNL, no_irq_handler);
+
+       set_sys_int(0x20, INTR_GATE, PL_KRNL, irq_0x00_handler);
+       set_sys_int(0x21, INTR_GATE, PL_KRNL, irq_0x01_handler);        
+       set_sys_int(0x22, INTR_GATE, PL_KRNL, irq_0x02_handler);        
+       set_sys_int(0x23, INTR_GATE, PL_KRNL, irq_0x03_handler);        
+       set_sys_int(0x24, INTR_GATE, PL_KRNL, irq_0x04_handler);        
+       set_sys_int(0x25, INTR_GATE, PL_KRNL, irq_0x05_handler);        
+       set_sys_int(0x26, INTR_GATE, PL_KRNL, irq_0x06_handler);        
+       set_sys_int(0x27, INTR_GATE, PL_KRNL, irq_0x07_handler);        
+       set_sys_int(0x28, INTR_GATE, PL_KRNL, irq_0x08_handler);        
+       set_sys_int(0x29, INTR_GATE, PL_KRNL, irq_0x09_handler);        
+       set_sys_int(0x2A, INTR_GATE, PL_KRNL, irq_0x0A_handler);        
+       set_sys_int(0x2B, INTR_GATE, PL_KRNL, irq_0x0B_handler);        
+       set_sys_int(0x2C, INTR_GATE, PL_KRNL, irq_0x0C_handler);        
+       set_sys_int(0x2D, INTR_GATE, PL_KRNL, irq_0x0D_handler);        
+       set_sys_int(0x2E, INTR_GATE, PL_KRNL, irq_0x0E_handler);        
+       set_sys_int(0x2F, INTR_GATE, PL_KRNL, irq_0x0F_handler);        
+#endif
+}
+
+void   setup_irqs()
+{
+       extern  void init_i8259();
+       init_i8259();
+
+       int i;
+       for(i=0; i<NR_IRQS; i++)
+       {
+               irq_desc[i] = no_irq_desc;
+
+               if(i<16)
+                       irq_desc[i].chip = &i8259_chip;
+       }
+
+       //extern        void kbd_handler(pPtRegs, unsigned int);
+       //extern        void clk_handler(pPtRegs, unsigned int);
+       //extern        void hd_handler(pPtRegs, unsigned int);
+       void    kbd_handler(unsigned int irq, pPtRegs regs, void *dev_id);
+       void    clk_handler(unsigned int irq, pPtRegs regs, void *dev_id);
+       void    hd_handler(unsigned int irq, pPtRegs regs, void *dev_id);
+       request_irq(0x00, clk_handler,  "Intel 8254",   "Clock Chip");
+       request_irq(0x01, kbd_handler,  "Intel 8042",   "PS/2 Keyboard");
+       request_irq(0x0E, hd_handler,   "IDE",          "IDE");
+       enable_irq(0x00);
+       enable_irq(0x01);
+       enable_irq(0x0E);
+       
+
+/*
+       pIRQAction      pKbdAction, pClkAction;
+
+
+       pKbdAction      = (pIRQAction) kmalloc(sizeof(IRQAction));
+       pClkAction      = (pIRQAction) kmalloc(sizeof(IRQAction));
+
+
+       assert(pKbdAction != NULL);
+       assert(pClkAction != NULL);
+
+       pClkAction->handler     = clk_handler;
+       pClkAction->next        = NULL;
+       pKbdAction->handler     = kbd_handler;
+       pKbdAction->next        = NULL;
+
+       printk("**********%08x %08x", pKbdAction, pClkAction);
+
+       irq_desc[0x0].chip = &i8259_chip;
+       irq_desc[0x0].chip->enable(0x0);
+       irq_desc[0x0].action = pClkAction;
+
+       irq_desc[0x1].chip = &i8259_chip;
+       irq_desc[0x1].chip->enable(0x1);
+       irq_desc[0x1].action = pKbdAction;
+*/
+
+}
+
+
+void   set_tss()
+{
+       pTSS p = &tss;
+       memset((void *)p, sizeof(TSS), 0);
+       p->esp0         = TASK_SIZE + (unsigned long)&RootTsk;
+       p->ss0          = SELECTOR_KRNL_DS;
+       p->ss           = SELECTOR_KRNL_DS;
+       p->gs           = SELECTOR_KRNL_DS;
+       p->fs           = SELECTOR_KRNL_DS;
+       p->es           = SELECTOR_KRNL_DS;
+       p->ds           = SELECTOR_KRNL_DS;
+       p->cs           = SELECTOR_KRNL_CS;
+       p->eflags       = 0x1200;
+       p->iomap_base   = sizeof(TSS);
+       set_tss_gate(INDEX_TSS, (u32)p);
+       //printk("TSS:%08x\n", p);
+       asm("ltr %%ax"::"a"((INDEX_TSS<<3)+3));
+}
+
+void setup_root_dev()
+{
+       unsigned char dev;
+       dev = (unsigned char)(system.boot_device >> 24);
+       //if(dev != 0x80)
+       //      panic("OS must boot from the first hard disk");
+
+       printk("root device: %08x\n", system.root_dev);
+#if 0
+
+       /* 
+        * 硬盘的次设备号
+        * 0: 整个硬盘
+        * 1-4: 主分区
+        * 5~N: 逻辑分区(N<2^16-5)
+        * 目录只支持从第一个硬盘引导.
+        */
+       int     minor = ((system.boot_device>>16) & 0xFF) + 1;
+       system.root_dev = MAKE_DEV(DEV_MAJOR_HD, minor);
+#endif
+}
diff --git a/setup/version.c b/setup/version.c
new file mode 100644 (file)
index 0000000..0129260
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ *--------------------------------------------------------------------------
+ *   File Name:        version.c
+ * 
+ * Description:        none
+ * 
+ * 
+ *      Author:        Zhao Yanbai [zhaoyanbai@126.com]
+ * 
+ *     Version:        1.0
+ * Create Date: Sat Mar  7 10:47:41 2009
+ * Last Update: Sat Mar  7 10:47:41 2009
+ * 
+ *--------------------------------------------------------------------------
+ */
+#define        VERSION "0.2.5 Final"
+#define        BUIDER  "Zhao Yanbai"
+const char *version = 
+       "Kernel "
+       VERSION
+       " Build on "__DATE__ " " __TIME__
+       " by "
+       BUIDER;