| /tmp/sos-code-article7.5/drivers/zero.c (2005-04-27 20:17:13.000000000 +0200
) |
|
| ../sos-code-article7.5/drivers/zero.c (2005-06-06 20:47:20.000000000 +0200
) |
|
|
|
|
| zero_resource | zero_resource |
| = (struct zero_mapped_resource*) | = (struct zero_mapped_resource*) |
| sos_umem_vmm_get_mapped_resource_of_vr(vr)->custom_data; | sos_umem_vmm_get_mapped_resource_of_vr(vr)->custom_data; |
| | |
| SOS_ASSERT_FATAL(zero_resource->ref_cnt > 0); | SOS_ASSERT_FATAL(zero_resource->ref_cnt > 0); |
| zero_resource->ref_cnt --; | zero_resource->ref_cnt --; |
|
|
|
| struct zero_mapped_page *zmp; | struct zero_mapped_page *zmp; |
| list_collapse(zero_resource->list_mapped_pages, zmp) | list_collapse(zero_resource->list_mapped_pages, zmp) |
| { | { |
| /* No need to free the underlying physical pages, since they | /* Unreference the underlying physical page */ |
| should have been unmapped just before this unref is | sos_physmem_unref_physpage(zmp->ppage_paddr); |
| called */ | |
| } | } |
| | |
|
|
|
| SOS_PAGE_ALIGN_INF(uaddr), | SOS_PAGE_ALIGN_INF(uaddr), |
| TRUE, | TRUE, |
| vr_prot); | vr_prot); |
| | |
| return retval; | return retval; |
| } | } |
| } | } |
|
|
|
| ppage_paddr = sos_physmem_ref_physpage_new(FALSE); | ppage_paddr = sos_physmem_ref_physpage_new(FALSE); |
| if (! ppage_paddr) | if (! ppage_paddr) |
| return -SOS_ENOMEM; | return -SOS_ENOMEM; |
| | |
| SOS_PAGE_ALIGN_INF(uaddr), | SOS_PAGE_ALIGN_INF(uaddr), |
| TRUE, | TRUE, |
|
|
|
| zmp->ppage_paddr = ppage_paddr; | zmp->ppage_paddr = ppage_paddr; |
| | |
| list_add_head(mr->list_mapped_pages, zmp); | list_add_head(mr->list_mapped_pages, zmp); |
| | sos_physmem_ref_physpage_at(ppage_paddr); |
| return SOS_OK; | return SOS_OK; |
| } | } |
| | |
| | |
| /tmp/sos-code-article7.5/extra/bootsect.S (2005-04-27 20:17:13.000000000 +0200
) |
|
| ../sos-code-article7.5/extra/bootsect.S (2005-06-06 20:47:22.000000000 +0200
) |
|
|
|
|
| | |
| /* | /* |
| * @(#) $Id: bootsect.S,v 1.8 2004/11/20 16:00:11 d2 Exp $ | * @(#) $Id: bootsect.S,v 1.11 2005/04/28 21:55:35 d2 Exp $ |
| * Auteurs : Thomas Petazzoni & Fabrice Gautier & Emmanuel Marty | * Auteurs : Thomas Petazzoni & Fabrice Gautier & Emmanuel Marty |
| * Jerome Petazzoni & Bernard Cassagne & coffeeman | * Jerome Petazzoni & Bernard Cassagne & coffeeman |
| * David Decotigny | * David Decotigny (SOS integration for kernel size detection) |
| | * Christopher Goyet (RAM size determination through BIOS int 15H) |
| */ | */ |
| | |
|
|
|
| * valide | * valide |
| * - Le bootsect verifie que le processeur est du type 386+ | * - Le bootsect verifie que le processeur est du type 386+ |
| * - Il charge le noyau depuis la disquette en memoire a partir de | * - Il charge le noyau depuis la disquette en memoire a partir de |
| * 0x1000 (LOAD_ADRESS). Le noyau peut au max tenir sur | * 0x1000 (LOAD_ADRESS). La place dispo est donc 0x9f000 - 0x1000 , soit |
| * SECTORS_TO_LOAD secteurs | * 0x9E000, soit encore 1264 secteurs de 512 octets |
| * - Il recopie le noyau (situe en LOAD_ADRESS) vers son adresse | * - Il recopie le noyau (situe en LOAD_ADRESS) vers son adresse |
| * finale (FINAL_ADDRESS = 2Mo). La recopie se fait sur tout l'espace | * finale (FINAL_ADDRESS = 2Mo). La recopie se fait sur tout l'espace |
|
|
|
| /* Pour que gas genere du 16bits, afin que ca marche en realm */ | /* Pour que gas genere du 16bits, afin que ca marche en realm */ |
| .code16 | .code16 |
| | |
| #define SECTORS_TO_LOAD 128 /* 64 ko */ /* MAX=1264 */ | |
| | |
| * Parametres de la disquette. Comme c'est chiant de faire une | * Parametres de la disquette. Comme c'est chiant de faire une |
| * procedure de detection auto, et que ca prend de la place, on fait | * procedure de detection auto, et que ca prend de la place, on fait |
|
|
|
| copier le bootsecteur */ | copier le bootsecteur */ |
| #define LOAD_ADRESS 0x01000 /* 1er chargement du systeme */ | #define LOAD_ADRESS 0x01000 /* 1er chargement du systeme */ |
| #define LOAD_SEG (LOAD_ADRESS>>4) /* Segment du 1er chargement du */ | #define LOAD_SEG (LOAD_ADRESS>>4) /* Segment du 1er chargement du */ |
| #define MAX_KERN_LEN COPY_ADRESS-LOAD_ADRESS /* Taille noyau maxi */ | #define MAX_KERN_LEN (COPY_ADRESS-LOAD_ADRESS) /* Taille noyau maxi */ |
| | #define MAX_KERN_SECTS ((MAX_KERN_LEN + 511) / 512) /* Nbre de secteurs maxi */ |
| /* IMPORTANT : Cette valeur DOIT etre identique a l'adresse presente | /* IMPORTANT : Cette valeur DOIT etre identique a l'adresse presente |
| dans sos.lds ! */ | dans sos.lds ! */ |
|
|
|
| /* Efface l'ecran */ | /* Efface l'ecran */ |
| movb $0x0, %ah | movb $0x0, %ah |
| movb $0x3, %al | movb $0x3, %al |
| int $0x10 | int $0x10 |
| | |
| | /* Verifie que le noyau n'est pas trop gros a charger */ |
| | cmpw $MAX_KERN_SECTS, (load_size) |
| | jb sizeOk |
| | movw $toobig, %si |
| | call message |
| | call halt |
| | |
| | sizeOk: |
| | /* Recupere la taille de la RAM */ |
| | mov $0xE801, %ax |
| | int $0x15 |
| | movw %ax, (memsize1) |
| | movw %bx, (memsize2) |
| /* Affiche les messages d'attente */ | /* Affiche les messages d'attente */ |
| movw $loadkern, %si | movw $loadkern, %si |
|
|
|
| movl %eax, %ss | movl %eax, %ss |
| movl $(stack + BOOT_STACK_SIZE), %ebp | movl $(stack + BOOT_STACK_SIZE), %ebp |
| movl %ebp, %esp | movl %ebp, %esp |
| | |
| | /* passe les arguments a sos */ |
| | xor %eax, %eax |
| | xor %ebx, %ebx |
| | movw (COPY_ADRESS+(memsize2)), %ax /*eax = num de block de 64KB apres 16MB*/ |
| | movw (COPY_ADRESS+(memsize1)), %bx /*ebx = num de block de 1KB entre 1MB et 16MB*/ |
| | movl $0x40, %ecx /*ecx=64 */ |
| | mul %ecx |
| | add %ebx, %eax |
| | pushl %eax /* valeur de addr */ |
| | pushl $0x42244224 /* valeur de magic pour indiquer qu'on a pousse |
| | la taille de la RAM sur la pile */ |
| | pushl $0 /* normalement call fait un push eip, mais la on a un jmp*/ |
| | |
| /* Saut vers le noyau. La GDT est en place (flat mode), les | /* Saut vers le noyau. La GDT est en place (flat mode), les |
| * selecteurs aussi, a20 est ouverte, et les interruptions sont | * selecteurs aussi, a20 est ouverte, et les interruptions sont |
|
|
|
| | |
| /* quelques messages */ | /* quelques messages */ |
| | |
| loadkern: .string "-= S O S =- : The Simple Operating System \r\n" | loadkern: .string "This is SOS\r\n" |
| check: .string "Checking for a 386+ processor... " | toobig: .string "Image too big\r\n" |
| | check: .string "Checking 386+ processor... " |
| need386: .string " [FAILED]\r\n" | need386: .string " [FAILED]\r\n" |
| diskerror: .string "Disk Error\r\n" | diskerror: .string "Disk Error\r\n" |
| loading: .string "Loading... " | loading: .string "Loading... " |
| haltmsg: .string "System Halted\r\n" | haltmsg: .string "System Halted\r\n" |
| | |
| | /* Variables pour stocker la taille de la RAM (int 0x15) */ |
| | memsize1: .long 0 |
| | memsize2: .long 0 |
| | |
| /*** Les code/données du boot secteur se terminent ICI. le marqueur de | /*** Les code/données du boot secteur se terminent ICI. le marqueur de |
| * fin (aa55) est ajouté automatiquement par le script ld | * fin (aa55) est ajouté automatiquement par le script ld |
| * sos_bsect.lds ***/ | * sos_bsect.lds ***/ |
| | |
| /tmp/sos-code-article7.5/INSTALL (2005-04-27 20:17:12.000000000 +0200
) |
|
| ../sos-code-article7.5/INSTALL (2005-06-06 20:47:17.000000000 +0200
) |
|
|
|
|
| copy the file 'fd.img' to a floppy, and boot from it | copy the file 'fd.img' to a floppy, and boot from it |
| | |
| 2nd method | 2nd method |
| => see extra/README to compile with the boot sector we provide (up to | => see extra/README to compile with the boot sector we provide, |
| article 2 only), copy the file 'extra/sos_bsect.img' to a floppy, | copy the file 'extra/sos_bsect.img' to a floppy, and boot from |
| and boot from it | it |
| | |
| Inside a PC emulator (x86 and non-x86 hosts) | Inside a PC emulator (x86 and non-x86 hosts) |
|
|
|
| installed: 'apt-get install libsdl1.2-dev' on debian | installed: 'apt-get install libsdl1.2-dev' on debian |
| testing/unstable). | testing/unstable). |
| | |
| | |
| 1/ Grub is installed on the host (x86 hosts only) | 1/ Grub is installed on the host (x86 hosts only) |
| - - - - - - - - - - - - - - - - - - - - - - - - - | - - - - - - - - - - - - - - - - - - - - - - - - - |
| | |
|
|
|
| qemu: run 'qemu -fda fd.img' | qemu: run 'qemu -fda fd.img' |
| If grub hangs while loading the kernel, please go to method 2/ | If grub hangs while loading the kernel, please go to method 2/ |
| | |
| | |
| 2/ Grub is not installed (all hosts) | 2/ Grub is not installed (all hosts) |
| - - - - - - - - - - - - - - - - - - | - - - - - - - - - - - - - - - - - - |
| | |
|
|
|
| | |
| qemu: run 'qemu -fda fd.img' | qemu: run 'qemu -fda fd.img' |
| | |
| 3/ Bonus: boot with the bootsector we provide (all hosts, up to art. 2 ONLY !) | |
| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | 3/ Bonus: boot with the bootsector we provide (all hosts) |
| | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
| See extra/README to generate a floppy image with the boot sector we | See extra/README to generate a floppy image with the boot sector we |
| provide, and: | provide, and: |
|
|
|
| | |
| qemu: run 'qemu -fda extra/sos_qemu.img' | qemu: run 'qemu -fda extra/sos_qemu.img' |
| | |
| NOTE: After article 2, this way of booting is not supported: please | NOTE: This technique assumes that INT 15H is supported by the |
| use the method 2/ above. | machine's BIOS. This should be OK for the vast majority of targets |
| | (bochs, qemu, recent machines), but we do not guarantee it. In case |
| | of doubt, please use Grub. |
| | |
| NOTE : recommended versions of the tools | NOTE : recommended versions of the tools |
| ---------------------------------------- | ---------------------------------------- |
| - OS : Linux 2.6.11.7-d2-1 i686 | - OS : Linux 2.6.11.7 i686 |
| - gcc : gcc (GCC) 3.3.5 (Debian 1:3.3.5-8) | - gcc : gcc (GCC) 3.3.5 (Debian 1:3.3.5-12) |
| - GNU make : GNU Make 3.80 | - GNU make : GNU Make 3.80 |
| | |
| | |
| /tmp/sos-code-article7.5/Makefile (2005-04-27 20:17:12.000000000 +0200
) |
|
| ../sos-code-article7.5/Makefile (2005-06-06 20:47:16.000000000 +0200
) |
|
|
|
|
| | |
| CC=gcc | CC=gcc |
| LD=ld | LD=ld |
| | CP=cp |
| | STRIP=strip |
| CFLAGS = -Wall -nostdinc -ffreestanding -DKERNEL_SOS | CFLAGS = -Wall -nostdinc -ffreestanding -DKERNEL_SOS |
| LIBGCC := $(shell $(CC) -print-libgcc-file-name) # To benefit from FP/64bits artihm. | LIBGCC = $(shell $(CC) -print-libgcc-file-name) # To benefit from FP/64bits artihm. |
| OBJECTS = bootstrap/multiboot.o \ | OBJECTS = bootstrap/multiboot.o \ |
| hwcore/idt.o hwcore/gdt.o \ | hwcore/idt.o hwcore/gdt.o \ |
| hwcore/swintr.o hwcore/swintr_wrappers.o \ | hwcore/swintr.o hwcore/swintr_wrappers.o \ |
| hwcore/exception.o hwcore/exception_wrappers.o \ | hwcore/exception.o hwcore/exception_wrappers.o \ |
| hwcore/irq.o hwcore/irq_wrappers.o hwcore/i8259.o \ | hwcore/irq.o hwcore/irq_wrappers.o hwcore/i8259.o \ |
| hwcore/paging.o \ | hwcore/paging.o \ |
| hwcore/cpu_context.o hwcore/cpu_context_switch.o \ | hwcore/cpu_context.o hwcore/cpu_context_switch.o \ |
| hwcore/mm_context.o \ | hwcore/mm_context.o \ |
|
|
|
| userland/userprogs.kimg | userland/userprogs.kimg |
| | |
| KERNEL_OBJ = sos.elf | KERNEL_OBJ = sos.elf |
| | KERNEL_LOAD = sos.gz |
| MULTIBOOT_IMAGE = fd.img | MULTIBOOT_IMAGE = fd.img |
| PWD := $(shell pwd) | PWD := $(shell pwd) |
| | |
| # Main target | # Main target |
| all: $(MULTIBOOT_IMAGE) | all: $(MULTIBOOT_IMAGE) |
| | |
| $(MULTIBOOT_IMAGE): $(KERNEL_OBJ) | $(MULTIBOOT_IMAGE): $(KERNEL_LOAD) |
| | |
| | $(KERNEL_LOAD): $(KERNEL_OBJ) |
| | $(CP) $< $<.strip && $(STRIP) -sx $<.strip |
| | gzip < $<.strip > $@ |
| | |
| $(KERNEL_OBJ): $(OBJECTS) ./support/sos.lds | $(KERNEL_OBJ): $(OBJECTS) ./support/sos.lds |
| $(LD) $(LDFLAGS) -T ./support/sos.lds -o $@ $(OBJECTS) $(LIBGCC) | $(LD) $(LDFLAGS) -T ./support/sos.lds -o $@ $(OBJECTS) $(LIBGCC) |
| -nm -C $@ | cut -d ' ' -f 1,3 > sos.map | -nm -C $@ | cut -d ' ' -f 1,3 > sos.map |
|
|
|
| | |
| # Clean directory | # Clean directory |
| clean: | clean: |
| $(RM) *.img *.o mtoolsrc *~ menu.txt *.img *.elf *.bin *.map | $(RM) *.img *.o mtoolsrc *~ menu.txt *.img *.elf *.bin *.strip *.map |
| $(RM) *.log *.out bochs* | $(RM) *.log *.out bochs* sos.gz |
| $(RM) drivers/*.o drivers/*~ | $(RM) drivers/*.o drivers/*~ |
| $(RM) hwcore/*.o hwcore/*~ | $(RM) hwcore/*.o hwcore/*~ |
| | |
| /tmp/sos-code-article7.5/README (2005-04-27 20:17:12.000000000 +0200
) |
|
| ../sos-code-article7.5/README (2005-06-06 20:47:18.000000000 +0200
) |
|
|
|
|
| i586-gnu) is available. Can be tested on real i486/pentium | i586-gnu) is available. Can be tested on real i486/pentium |
| hardware, or on any host that can run an i486/pentium PC emulator | hardware, or on any host that can run an i486/pentium PC emulator |
| (bochs or qemu) | (bochs or qemu) |
| - kernel loaded by grub, or by a sample bootsector (up to article 2 | - kernel loaded by grub or by a sample bootsector |
| ONLY) | |
| even inside the kernel: no identity-mapping of the physical memory | even inside the kernel: no identity-mapping of the physical memory |
| inside the kernel (allows to move virtual mappings of kernel pages | inside the kernel (allows to move virtual mappings of kernel pages |
|
|
|
| 'all' and 'clean' | 'all' and 'clean' |
| - bootstrap/ directory: code to load the kernel. Both the stuff | - bootstrap/ directory: code to load the kernel. Both the stuff |
| needed for a multiboot-compliant loader (eg grub) AND a bootsector | needed for a multiboot-compliant loader (eg grub) AND a bootsector |
| are provided. The bootsector may only be used up to article 2. | are provided. |
| systemwide header files, a set of common useful C routines | systemwide header files, a set of common useful C routines |
| ("nano-klibc"), and kernel subsystems (kernel memory management, | ("nano-klibc"), and kernel subsystems (kernel memory management, |
| | |
| /tmp/sos-code-article7.5/sos/errno.h (2005-04-27 20:17:16.000000000 +0200
) |
|
| ../sos-code-article7.5/sos/errno.h (2005-06-06 20:47:34.000000000 +0200
) |
|
|
|
|
| */ | */ |
| | |
| /* Positive values of the error codes */ | /* Positive values of the error codes */ |
| #define SOS_OK 0 /* No error */ | #define SOS_OK 0 /* No error */ |
| #define SOS_EINVAL 1 /* Invalid argument */ | #define SOS_EINVAL 1 /* Invalid argument */ |
| #define SOS_ENOSUP 2 /* Operation not supported */ | #define SOS_ENOSUP 2 /* Operation not supported */ |
| #define SOS_ENOMEM 3 /* No available memory */ | #define SOS_ENOMEM 3 /* No available memory */ |
| #define SOS_EBUSY 4 /* Object or device still in use */ | #define SOS_EBUSY 4 /* Object or device still in use */ |
| #define SOS_EINTR 5 /* Wait/Sleep has been interrupted */ | #define SOS_EINTR 5 /* Wait/Sleep has been interrupted */ |
| #define SOS_EPERM 6 /* Mutex/files ownership error */ | #define SOS_EPERM 6 /* Mutex/files ownership error */ |
| #define SOS_EFAULT 7 /* Unresolved virtual memory fault */ | #define SOS_EFAULT 7 /* Unresolved virtual memory fault */ |
| #define SOS_ENOENT 8 /* No such file or directory */ | #define SOS_ENOENT 8 /* No such file or directory */ |
| #define SOS_EFATAL 255 /* Internal fatal error */ | #define SOS_EFATAL 255 /* Internal fatal error */ |
| /* A negative value means that an error occured. For | /* A negative value means that an error occured. For |
| * example -SOS_EINVAL means that the error was "invalid | * example -SOS_EINVAL means that the error was "invalid |
| | |
| /tmp/sos-code-article7.5/sos/main.c (2005-04-27 20:17:17.000000000 +0200
) |
|
| ../sos-code-article7.5/sos/main.c (2005-06-06 20:47:35.000000000 +0200
) |
|
|
|
|
| USA. | USA. |
| */ | */ |
| | |
| | #include <sos/errno.h> |
| | |
| /* Include definitions of the multiboot standard */ | /* Include definitions of the multiboot standard */ |
| #include <bootstrap/multiboot.h> | #include <bootstrap/multiboot.h> |
| #include <hwcore/idt.h> | #include <hwcore/idt.h> |
|
|
|
| } | } |
| } | } |
| | |
| | |
| static void clk_it(int intid) | static void clk_it(int intid) |
| { | { |
|
|
|
| sos_process_unref(proc_init); | sos_process_unref(proc_init); |
| return -SOS_ENOENT; | return -SOS_ENOENT; |
| } | } |
| | |
| ustack = (SOS_PAGING_TOP_USER_ADDRESS - SOS_DEFAULT_USER_STACK_SIZE) + 1; | ustack = (SOS_PAGING_TOP_USER_ADDRESS - SOS_DEFAULT_USER_STACK_SIZE) + 1; |
| retval = sos_dev_zero_map(as_init, &ustack, SOS_DEFAULT_USER_STACK_SIZE, | retval = sos_dev_zero_map(as_init, &ustack, SOS_DEFAULT_USER_STACK_SIZE, |
|
|
|
| /* PRIVATE */ 0); | /* PRIVATE */ 0); |
| if (SOS_OK != retval) | if (SOS_OK != retval) |
| { | { |
| sos_bochs_printf("ici 2\n"); | |
| return -SOS_ENOMEM; | return -SOS_ENOMEM; |
| } | } |
|
|
|
| SOS_SCHED_PRIO_TS_LOWEST); | SOS_SCHED_PRIO_TS_LOWEST); |
| if (! new_thr) | if (! new_thr) |
| { | { |
| sos_bochs_printf("ici 3\n"); | |
| return -SOS_ENOMEM; | return -SOS_ENOMEM; |
| } | } |
|
|
|
| /* ====================================================================== | /* ====================================================================== |
| * The C entry point of our operating system | * The C entry point of our operating system |
| */ | */ |
| void sos_main(unsigned long magic, unsigned long addr) | void sos_main(unsigned long magic, unsigned long arg) |
| unsigned i; | unsigned i; |
| sos_paddr_t sos_kernel_core_base_paddr, sos_kernel_core_top_paddr; | sos_paddr_t sos_kernel_core_base_paddr, sos_kernel_core_top_paddr; |
| struct sos_time tick_resolution; | struct sos_time tick_resolution; |
| | |
| /* Grub sends us a structure, called multiboot_info_t with a lot of | /* Size of RAM above 1MB. Might be undefined ! */ |
| precious informations about the system, see the multiboot | unsigned long int upper_mem = 0; |
| documentation for more information. */ | |
| multiboot_info_t *mbi; | |
| mbi = (multiboot_info_t *) addr; | |
| /* Setup bochs and console, and clear the console */ | /* Setup bochs and console, and clear the console */ |
| sos_bochs_setup(); | sos_bochs_setup(); |
|
|
|
| | |
| /* Greetings from SOS */ | /* Greetings from SOS */ |
| if (magic == MULTIBOOT_BOOTLOADER_MAGIC) | if (magic == MULTIBOOT_BOOTLOADER_MAGIC) |
| /* Loaded with Grub */ | { |
| sos_x86_videomem_printf(1, 0, | /* Grub sends us a structure, called multiboot_info_t with a lot of |
| SOS_X86_VIDEO_FG_YELLOW | SOS_X86_VIDEO_BG_BLUE, | precious informations about the system, see the multiboot |
| "Welcome From GRUB to %s%c RAM is %dMB (upper mem = 0x%x kB)", | documentation for more information. */ |
| "SOS article 7.5", ',', | multiboot_info_t *mbi = (multiboot_info_t *) arg; |
| (unsigned)(mbi->mem_upper >> 10) + 1, | |
| (unsigned)mbi->mem_upper); | /* Multiboot says: "The value returned for upper memory is |
| | maximally the address of the first upper memory hole minus 1 |
| | megabyte.". It also adds: "It is not guaranteed to be this |
| | value." aka "YMMV" ;) */ |
| | upper_mem = mbi->mem_upper; |
| | sos_x86_videomem_printf(1, 0, |
| | SOS_X86_VIDEO_FG_YELLOW | SOS_X86_VIDEO_BG_BLUE, |
| | "Welcome From GRUB to %s%c RAM is %dMB (upper mem = 0x%x kB)", |
| | "SOS article 7.5", ',', |
| | (unsigned)(upper_mem >> 10) + 1, |
| | (unsigned)upper_mem); |
| | } |
| | else if (magic == 0x42244224) |
| | { |
| | /* Loaded with SOS bootsect */ |
| | upper_mem = arg; |
| | sos_x86_videomem_printf(1, 0, |
| | SOS_X86_VIDEO_FG_YELLOW | SOS_X86_VIDEO_BG_BLUE, |
| | "Welcome to %s%c RAM is %dMB (upper mem = 0x%x kB)", |
| | "SOS article 7.5", ',', |
| | (unsigned)(upper_mem >> 10) + 1, |
| | (unsigned)upper_mem); |
| | } |
| /* Not loaded with grub */ | /* Not loaded with grub, not from an enhanced bootsect */ |
| SOS_X86_VIDEO_FG_YELLOW | SOS_X86_VIDEO_BG_BLUE, | SOS_X86_VIDEO_FG_YELLOW | SOS_X86_VIDEO_BG_BLUE, |
| "Welcome to SOS article 7.5"); | "Welcome to SOS article 7.5"); |
|
|
|
| tick_resolution = (struct sos_time) { .sec=0, .nanosec=10000000UL }; | tick_resolution = (struct sos_time) { .sec=0, .nanosec=10000000UL }; |
| sos_time_subsysem_setup(& tick_resolution); | sos_time_subsysem_setup(& tick_resolution); |
| | |
| /* We need a multiboot-compliant boot loader to get the size of the RAM */ | /* We need to know the RAM size */ |
| if (magic != MULTIBOOT_BOOTLOADER_MAGIC) | if (upper_mem == 0) |
| sos_x86_videomem_putstring(20, 0, | sos_x86_videomem_putstring(20, 0, |
| SOS_X86_VIDEO_FG_LTRED | SOS_X86_VIDEO_FG_LTRED |
| | SOS_X86_VIDEO_BG_BLUE | | SOS_X86_VIDEO_BG_BLUE |
| | SOS_X86_VIDEO_FG_BLINKING, | | SOS_X86_VIDEO_FG_BLINKING, |
| "I'm not loaded with Grub !"); | "I don't know RAM size ! Load me with Grub..."); |
| for (;;) | for (;;) |
| continue; | continue; |
|
|
|
| * Setup physical memory management | * Setup physical memory management |
| */ | */ |
| | |
| /* Multiboot says: "The value returned for upper memory is maximally | SOS_ASSERT_FATAL(SOS_OK |
| the address of the first upper memory hole minus 1 megabyte.". It | == sos_physmem_subsystem_setup((upper_mem<<10) + (1<<20), |
| also adds: "It is not guaranteed to be this value." aka "YMMV" ;) */ | &sos_kernel_core_base_paddr, |
| sos_physmem_subsystem_setup((mbi->mem_upper<<10) + (1<<20), | &sos_kernel_core_top_paddr)); |
| & sos_kernel_core_base_paddr, | |
| & sos_kernel_core_top_paddr); | |
| /* | /* |
| * Switch to paged-memory mode | * Switch to paged-memory mode |
|
|
|
| interrupt call the scheduler */ | interrupt call the scheduler */ |
| asm volatile ("sti\n"); | asm volatile ("sti\n"); |
| | |
| | |
| /* Start the 'init' process, which in turns launches the other | /* Start the 'init' process, which in turns launches the other |
| programs */ | programs */ |
| start_init(); | start_init(); |
| | |
| * We can safely exit from this function now, for there is already | * We can safely exit from this function now, for there is already |
| * an idle Kernel thread ready to make the CPU busy working... | * an idle Kernel thread ready to make the CPU busy working... |
| | |
| /tmp/sos-code-article7.5/sos/sched.c (2005-04-27 20:17:17.000000000 +0200
) |
|
| ../sos-code-article7.5/sos/sched.c (2005-06-06 20:47:38.000000000 +0200
) |
|
|
|
|
| return SOS_OK; | return SOS_OK; |
| | |
| /* Reset the CPU time used in the quantuum */ | /* Reset the CPU time used in the quantuum */ |
| memset(& thr->running.user_time_spent_in_slice, 0x0, sizeof(struct sos_time)); | memset(& thr->user_time_spent_in_slice, 0x0, sizeof(struct sos_time)); |
| if (SOS_SCHED_PRIO_IS_RT(sos_thread_get_priority(thr))) | if (SOS_SCHED_PRIO_IS_RT(sos_thread_get_priority(thr))) |
| { | { |
|
|
|
| /* Current (user) thread expired its time quantuum ? A kernel | /* Current (user) thread expired its time quantuum ? A kernel |
| thread never expires because sos_sched_do_timer_tick() below | thread never expires because sos_sched_do_timer_tick() below |
| won't update its user_time_spent_in_slice */ | won't update its user_time_spent_in_slice */ |
| if (sos_time_cmp(& thr->running.user_time_spent_in_slice, | if (sos_time_cmp(& thr->user_time_spent_in_slice, |
| return TRUE; | return TRUE; |
| | |
|
|
|
| if (thread_expired_its_quantuum(current_thread)) | if (thread_expired_its_quantuum(current_thread)) |
| { | { |
| /* Reset the CPU time used in the quantuum */ | /* Reset the CPU time used in the quantuum */ |
| memset(& current_thread->running.user_time_spent_in_slice, | memset(& current_thread->user_time_spent_in_slice, |
| | |
| do_yield = TRUE; | do_yield = TRUE; |
|
|
|
| & tick_duration); | & tick_duration); |
| | |
| /* Update time spent is current timeslice ONLY for a user thread */ | /* Update time spent is current timeslice ONLY for a user thread */ |
| sos_time_inc(& interrupted_thread->running.user_time_spent_in_slice, | sos_time_inc(& interrupted_thread->user_time_spent_in_slice, |
| } | } |
| else | else |
| | |