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