--- /dev/null
+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
--- /dev/null
+############################################################################
+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
--- /dev/null
+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?
--- /dev/null
+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
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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;
+}
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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
--- /dev/null
+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
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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 ;
+ }
+
+}
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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:
--- /dev/null
+#!/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}
--- /dev/null
+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
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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();
+}
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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();
+}
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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++;
+ }
+}
--- /dev/null
+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
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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);
+}
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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);
+}
+
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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;
+}
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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);
+}
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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;
+}
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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;
+}
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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
--- /dev/null
+/*
+ * ------------------------------------------------------------------------
+ * 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;
--- /dev/null
+/* 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 */
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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
--- /dev/null
+/*
+ * ------------------------------------------------------------------------
+ * File Name: init.h
+ * Author: Zhao Yanbai
+ * Sat Mar 29 15:47:03 2014
+ * Description: none
+ * ------------------------------------------------------------------------
+ */
+
+#pragma once
+
+
+#define __initdata __attribute__ ((__section__ (".init.data")))
+
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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
--- /dev/null
+/*
+ * ------------------------------------------------------------------------
+ * 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);
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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
--- /dev/null
+CF = -g -c -I. -Iinclude -I../include -fno-builtin
--- /dev/null
+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
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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);
+}
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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)
+
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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;
+}
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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;
+}
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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
+}
--- /dev/null
+#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
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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();
+}
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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;
+}
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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;
+}
+
--- /dev/null
+/*
+ * ------------------------------------------------------------------------
+ * 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];
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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)
+{
+
+}
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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的地址(¤t) */
+ 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的地址(¤t) */
+ 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
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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, ¤t, 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;
+}
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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);
+}
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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;
+}
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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();
+}
--- /dev/null
+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
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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);
+}
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * File Name: errno.c
+ *
+ * Author: Zhao Yanbai [zhaoyanbai@126.com]
+ * Tue Feb 23 01:49:49 2010
+ *
+ * Description: none
+ *
+ *--------------------------------------------------------------------------
+ */
+int errno;
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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);
+}
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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);
+}
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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);
+}
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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;
+}
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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);
+}
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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);
+}
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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);
+}
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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);
+}
--- /dev/null
+//=========================================================================
+// 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;
+}
--- /dev/null
+//=========================================================================
+// 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;
+}
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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;
+}
--- /dev/null
+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
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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);
+}
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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--);
+}
--- /dev/null
+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
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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;
+}
--- /dev/null
+./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
--- /dev/null
+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
+}
--- /dev/null
+#!/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}
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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);
+}
--- /dev/null
+#!/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}
--- /dev/null
+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
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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);
+ }
+
+}
--- /dev/null
+#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
+}
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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();
+}
+
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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
+}
--- /dev/null
+/*
+ *--------------------------------------------------------------------------
+ * 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;