diff --git a/API.md b/API.md index 2dc4230..6cb10fa 100644 --- a/API.md +++ b/API.md @@ -9,6 +9,18 @@ All fonctions in the "libsys" library. ------ +`u32 exit(u32 resultcode);` + +*Description:End a task for user or kernel domain* + +* syscall id : **5** +* arguments : **1** +* * argument 1 : **u32 resultcode** *Code result of the execution* +* results : **u32** +* dump of register cpu: **no** + +------ + `u32 getticks(void);` *Description:Return the internal value of the timer* @@ -20,6 +32,17 @@ All fonctions in the "libsys" library. ------ +`u8 waitkey(void);` + +*Description:Wait for user to press a key and return the ascii code pressed* + +* syscall id : **1** +* arguments : **0** +* results : **u8** +* dump of register cpu: **no** + +------ + `u32 testapi(u32 arg1, u32 arg2, u32 arg3);` *Description:Simple function to test if SYSCALL API is correctly running* @@ -32,29 +55,6 @@ All fonctions in the "libsys" library. * results : **u32** * dump of register cpu: **yes** ------- - -`u8 waitkey(void);` - -*Description:Wait for user to press a key and return the ascii code pressed* - -* syscall id : **1** -* arguments : **0** -* results : **u8** -* dump of register cpu: **no** - ------- - -`u32 exit(u32 resultcode);` - -*Description:End a task for user or kernel domain* - -* syscall id : **5** -* arguments : **1** -* * argument 1 : **u32 resultcode** *Code result of the execution* -* results : **u32** -* dump of register cpu: **no** - ### LIBVIDEO diff --git a/README.md b/README.md index 7e30652..4dd8407 100644 --- a/README.md +++ b/README.md @@ -228,8 +228,10 @@ Pour l'instant quelques commandes seulement sont disponibles: #### En cours -* correction de bogues - stabilisation du projet +* correction de bogues - libération des ressources après destruction processus, * liste d'API automatiquement mise à jour avec intégration de librairies & header, +* gestion du système de fichier CRAMFS, +* lancement du noyau par kernel et non par multiboot afin de bénéficier de initrd, #### A faire @@ -247,6 +249,7 @@ Pour l'instant quelques commandes seulement sont disponibles: Des fichiers sources utilisés par COS2000 sont sous d'autres licences, parmis ceux-ci figurent : * `include/queues.h` sous licence Berkeley Software Distribution License +* `tools/*` sous licence GPL V2.0, fichiers issus du noyau Linux #### Historique du projet * Version 2.2fr - C en mode protégé Reprise du projet diff --git a/include/memory.h b/include/memory.h index 96c7717..cb7c673 100644 --- a/include/memory.h +++ b/include/memory.h @@ -100,6 +100,7 @@ typedef TAILQ_HEAD(page_s, page) page_t; typedef TAILQ_HEAD(vrange_s, vrange) vrange_t; + void virtual_pd_show(pd *dst); void panic(u8 * string); void memset(void *dst, u8 val, u32 count, u32 size); void memcpy(void *src, void *dst, u32 count, u32 size); diff --git a/include/multiboot.h b/include/multiboot.h deleted file mode 100644 index 959c631..0000000 --- a/include/multiboot.h +++ /dev/null @@ -1,13 +0,0 @@ -/*******************************************************************************/ -/* COS2000 - Compatible Operating System - LGPL v3 - Hordé Nicolas */ -/* */ -#include "types.h" -#include "multiboot2.h" - -u32 getgrubinfo(u8 type); -u8 *getgrubinfo_cmdline(void); -u32 getgrubinfo_ram(void); -struct multiboot_tag_mmap *getgrubinfo_mem(void); -struct multiboot_tag_framebuffer *getgrubinfo_fb(void); -void getgrubinfo_all(void); -void initmultiboot(const u32 addr); diff --git a/include/multiboot2.h b/include/multiboot2.h deleted file mode 100644 index c81f77a..0000000 --- a/include/multiboot2.h +++ /dev/null @@ -1,391 +0,0 @@ -/*******************************************************************************/ -/* COS2000 - Compatible Operating System - LGPL v3 - Hordé Nicolas */ -/* */ -#ifndef MULTIBOOT -# define MULTIBOOT - - /* How many bytes from the start of the file we search for the header. */ -# define MULTIBOOT_SEARCH 32768 -# define MULTIBOOT_HEADER_ALIGN 8 - - /* The magic field should contain this. */ -# define MULTIBOOT2_HEADER_MAGIC 0xe85250d6 - - /* This should be in %eax. */ -# define MULTIBOOT2_BOOTLOADER_MAGIC 0x36d76289 - - /* Alignment of multiboot modules. */ -# define MULTIBOOT_MOD_ALIGN 0x00001000 - - /* Alignment of the multiboot info structure. */ -# define MULTIBOOT_INFO_ALIGN 0x00000008 - - /* Flags set in the 'flags' member of the multiboot header. */ - -# define MULTIBOOT_TAG_ALIGN 8 -# define MULTIBOOT_TAG_TYPE_END 0 -# define MULTIBOOT_TAG_TYPE_CMDLINE 1 -# define MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME 2 -# define MULTIBOOT_TAG_TYPE_MODULE 3 -# define MULTIBOOT_TAG_TYPE_BASIC_MEMINFO 4 -# define MULTIBOOT_TAG_TYPE_BOOTDEV 5 -# define MULTIBOOT_TAG_TYPE_MMAP 6 -# define MULTIBOOT_TAG_TYPE_VBE 7 -# define MULTIBOOT_TAG_TYPE_FRAMEBUFFER 8 -# define MULTIBOOT_TAG_TYPE_ELF_SECTIONS 9 -# define MULTIBOOT_TAG_TYPE_APM 10 -# define MULTIBOOT_TAG_TYPE_EFI32 11 -# define MULTIBOOT_TAG_TYPE_EFI64 12 -# define MULTIBOOT_TAG_TYPE_SMBIOS 13 -# define MULTIBOOT_TAG_TYPE_ACPI_OLD 14 -# define MULTIBOOT_TAG_TYPE_ACPI_NEW 15 -# define MULTIBOOT_TAG_TYPE_NETWORK 16 -# define MULTIBOOT_TAG_TYPE_EFI_MMAP 17 -# define MULTIBOOT_TAG_TYPE_EFI_BS 18 -# define MULTIBOOT_TAG_TYPE_EFI32_IH 19 -# define MULTIBOOT_TAG_TYPE_EFI64_IH 20 -# define MULTIBOOT_TAG_TYPE_LOAD_BASE_ADDR 21 - -# define MULTIBOOT_HEADER_TAG_END 0 -# define MULTIBOOT_HEADER_TAG_INFORMATION_REQUEST 1 -# define MULTIBOOT_HEADER_TAG_ADDRESS 2 -# define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS 3 -# define MULTIBOOT_HEADER_TAG_CONSOLE_FLAGS 4 -# define MULTIBOOT_HEADER_TAG_FRAMEBUFFER 5 -# define MULTIBOOT_HEADER_TAG_MODULE_ALIGN 6 -# define MULTIBOOT_HEADER_TAG_EFI_BS 7 -# define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS_EFI32 8 -# define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS_EFI64 9 -# define MULTIBOOT_HEADER_TAG_RELOCATABLE 10 - -# define MULTIBOOT_ARCHITECTURE_I386 0 -# define MULTIBOOT_ARCHITECTURE_MIPS32 4 -# define MULTIBOOT_HEADER_TAG_OPTIONAL 1 - -# define MULTIBOOT_LOAD_PREFERENCE_NONE 0 -# define MULTIBOOT_LOAD_PREFERENCE_LOW 1 -# define MULTIBOOT_LOAD_PREFERENCE_HIGH 2 - -# define MULTIBOOT_CONSOLE_FLAGS_CONSOLE_REQUIRED 1 -# define MULTIBOOT_CONSOLE_FLAGS_EGA_TEXT_SUPPORTED 2 - -#include "types.h" -struct multiboot_header -{ - /* Must be MULTIBOOT_MAGIC - see above. */ - u32 magic; - - /* ISA */ - u32 architecture; - - /* Total header length. */ - u32 header_length; - - /* The above fields plus this one must equal 0 mod 2^32. */ - u32 checksum; -}; - -struct multiboot_header_tag -{ - u16 type; - u16 flags; - u32 size; -}; - -struct multiboot_header_tag_information_request -{ - u16 type; - u16 flags; - u32 size; - u32 requests[0]; -}; - -struct multiboot_header_tag_address -{ - u16 type; - u16 flags; - u32 size; - u32 header_addr; - u32 load_addr; - u32 load_end_addr; - u32 bss_end_addr; -}; - -struct multiboot_header_tag_entry_address -{ - u16 type; - u16 flags; - u32 size; - u32 entry_addr; -}; - -struct multiboot_header_tag_console_flags -{ - u16 type; - u16 flags; - u32 size; - u32 console_flags; -}; - -struct multiboot_header_tag_framebuffer -{ - u16 type; - u16 flags; - u32 size; - u32 width; - u32 height; - u32 depth; -}; - -struct multiboot_header_tag_module_align -{ - u16 type; - u16 flags; - u32 size; -}; - -struct multiboot_header_tag_relocatable -{ - u16 type; - u16 flags; - u32 size; - u32 min_addr; - u32 max_addr; - u32 align; - u32 preference; -}; - -struct multiboot_color -{ - u8 red; - u8 green; - u8 blue; -}; - -struct multiboot_mmap_entry -{ - u64 addr; - u64 len; -# define MULTIBOOT_MEMORY_AVAILABLE 1 -# define MULTIBOOT_MEMORY_RESERVED 2 -# define MULTIBOOT_MEMORY_ACPI_RECLAIMABLE 3 -# define MULTIBOOT_MEMORY_NVS 4 -# define MULTIBOOT_MEMORY_BADRAM 5 - u32 type; - u32 zero; -}; -typedef struct multiboot_mmap_entry multiboot_memory_map_t; - -struct multiboot_tag -{ - u32 type; - u32 size; -}; - -struct multiboot_tag_string -{ - u32 type; - u32 size; - u8 string[0]; -}; - -struct multiboot_tag_module -{ - u32 type; - u32 size; - u32 mod_start; - u32 mod_end; - u8 cmdline[0]; -}; - -struct multiboot_tag_basic_meminfo -{ - u32 type; - u32 size; - u32 mem_lower; - u32 mem_upper; -}; - -struct multiboot_tag_bootdev -{ - u32 type; - u32 size; - u32 biosdev; - u32 slice; - u32 part; -}; - -struct multiboot_tag_mmap -{ - u32 type; - u32 size; - u32 entry_size; - u32 entry_version; - struct multiboot_mmap_entry entries[0]; -}; - -struct multiboot_vbe_info_block -{ - u8 external_specification[512]; -}; - -struct multiboot_vbe_mode_info_block -{ - u8 external_specification[256]; -}; - -struct multiboot_tag_vbe -{ - u32 type; - u32 size; - - u16 vbe_mode; - u16 vbe_interface_seg; - u16 vbe_interface_off; - u16 vbe_interface_len; - - struct multiboot_vbe_info_block vbe_control_info; - struct multiboot_vbe_mode_info_block vbe_mode_info; -}; - -struct multiboot_tag_framebuffer_common -{ - u32 type; - u32 size; - - u64 framebuffer_addr; - u32 framebuffer_pitch; - u32 framebuffer_width; - u32 framebuffer_height; - u8 framebuffer_bpp; -# define MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED 0 -# define MULTIBOOT_FRAMEBUFFER_TYPE_RGB 1 -# define MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT 2 - u8 framebuffer_type; - u16 reserved; -}; - -struct multiboot_tag_framebuffer -{ - struct multiboot_tag_framebuffer_common common; - - union - { - struct - { - u16 framebuffer_palette_num_colors; - struct multiboot_color framebuffer_palette[0]; - }; - struct - { - u8 framebuffer_red_field_position; - u8 framebuffer_red_mask_size; - u8 framebuffer_green_field_position; - u8 framebuffer_green_mask_size; - u8 framebuffer_blue_field_position; - u8 framebuffer_blue_mask_size; - }; - }; -}; - -struct multiboot_tag_elf_sections -{ - u32 type; - u32 size; - u32 num; - u32 entsize; - u32 shndx; - u8 sections[0]; -}; - -struct multiboot_tag_apm -{ - u32 type; - u32 size; - u16 version; - u16 cseg; - u32 offset; - u16 cseg_16; - u16 dseg; - u16 flags; - u16 cseg_len; - u16 cseg_16_len; - u16 dseg_len; -}; - -struct multiboot_tag_efi32 -{ - u32 type; - u32 size; - u32 pointer; -}; - -struct multiboot_tag_efi64 -{ - u32 type; - u32 size; - u64 pointer; -}; - -struct multiboot_tag_smbios -{ - u32 type; - u32 size; - u8 major; - u8 minor; - u8 reserved[6]; - u8 tables[0]; -}; - -struct multiboot_tag_old_acpi -{ - u32 type; - u32 size; - u8 rsdp[0]; -}; - -struct multiboot_tag_new_acpi -{ - u32 type; - u32 size; - u8 rsdp[0]; -}; - -struct multiboot_tag_network -{ - u32 type; - u32 size; - u8 dhcpack[0]; -}; - -struct multiboot_tag_efi_mmap -{ - u32 type; - u32 size; - u32 descr_size; - u32 descr_vers; - u8 efi_mmap[0]; -}; - -struct multiboot_tag_efi32_ih -{ - u32 type; - u32 size; - u32 pointer; -}; - -struct multiboot_tag_efi64_ih -{ - u32 type; - u32 size; - u64 pointer; -}; - -struct multiboot_tag_load_base_addr -{ - u32 type; - u32 size; - u32 load_base_addr; -}; - -#endif diff --git a/lib/keyboard.c b/lib/keyboard.c index c6f5f0c..bf4c722 100644 --- a/lib/keyboard.c +++ b/lib/keyboard.c @@ -133,7 +133,7 @@ u8 *getstring(u8 * temp) "ARGS": [], "RETURN":"u8" } -END */ +END-SYSCALL */ u8 waitascii(void) { diff --git a/lib/memory.c b/lib/memory.c index 574a09a..b584500 100644 --- a/lib/memory.c +++ b/lib/memory.c @@ -3,7 +3,6 @@ /* */ #include "types.h" #include "memory.h" -#include "multiboot2.h" #include "queue.h" #include "asm.h" @@ -155,7 +154,7 @@ void vfree(void *vaddr) u64 physical_getmemorysize() { - u64 maxaddr = 0; + /*u64 maxaddr = 0; struct multiboot_tag_mmap *tag = getgrubinfo_mem(); multiboot_memory_map_t *mmap; for (mmap = ((struct multiboot_tag_mmap *) tag)->entries; @@ -168,7 +167,7 @@ u64 physical_getmemorysize() maxaddr = mmap->addr + mmap->len; if (maxaddr >= MAXMEMSIZE) maxaddr = MAXMEMSIZE - 1; - return maxaddr; + return maxaddr;*/ } /*******************************************************************************/ @@ -261,7 +260,7 @@ u64 getmemoryfree(void) void physical_init(void) { - u64 page; + /*u64 page; for (page = 0; page < sizeof(bitmap); page++) bitmap[page] = 0xFF; struct multiboot_tag_mmap *tag = getgrubinfo_mem(); @@ -276,7 +275,7 @@ void physical_init(void) physical_range_free(mmap->addr, mmap->len); else physical_range_use(mmap->addr, mmap->len); - physical_range_use(0x0, KERNELSIZE); + physical_range_use(0x0, KERNELSIZE);*/ } /*******************************************************************************/ @@ -590,6 +589,23 @@ void virtual_pd_destroy(pd * dst) return 0; } +/*******************************************************************************/ +/* Affiche toutes les page du directory */ + +void virtual_pd_show(pd *dst) +{ + page *pg; + bool first=true; + TAILQ_FOREACH(pg, &dst->page_head, tailq) + { + if (!first) + print(","); + else + first=false; + printf("%Y",(u32)pg->vaddr); + } +} + /*******************************************************************************/ /* Initialise une pages virtuelles (size) pour le heap du noyau */ diff --git a/lib/multiboot.c b/lib/multiboot.c deleted file mode 100644 index d9b3156..0000000 --- a/lib/multiboot.c +++ /dev/null @@ -1,158 +0,0 @@ -/*******************************************************************************/ -/* COS2000 - Compatible Operating System - LGPL v3 - Hordé Nicolas */ -/* */ - -#include "multiboot2.h" - -static u32 infobloc; - -/*******************************************************************************/ -/* Initialise avec l'adresse du bloc multiboot2 */ - -void initmultiboot(const u32 addr) -{ - infobloc = addr; -} - -/*******************************************************************************/ -/* Renvoie les informations souhaitées multiboot2 */ - -u32 getgrubinfo(u8 type) -{ - struct multiboot_tag *tag; - unsigned size = *(unsigned *) infobloc; - for (tag = (struct multiboot_tag *) (infobloc + 8); - tag->type != MULTIBOOT_TAG_TYPE_END; - tag = - (struct multiboot_tag *) ((u8 *) tag + - ((tag->size + 7) & ~7))) - if (tag->type == type) - return tag; -} - -/*******************************************************************************/ -/* Renvoie la ligne de commande */ - -u8 *getgrubinfo_cmdline(void) -{ - struct multiboot_tag_string *tag = - getgrubinfo(MULTIBOOT_TAG_TYPE_CMDLINE); - return tag->string; -} - -/*******************************************************************************/ -/* Renvoie la quantité de mémoire */ - -u32 getgrubinfo_ram(void) -{ - struct multiboot_tag_basic_meminfo *tag = - getgrubinfo(MULTIBOOT_TAG_TYPE_BASIC_MEMINFO); - return tag->mem_upper; -} - -/*******************************************************************************/ -/* Renvoie le plan de la mémoire */ - -struct multiboot_tag_mmap *getgrubinfo_mem(void) -{ - struct multiboot_tag_mmap *tag = - getgrubinfo(MULTIBOOT_TAG_TYPE_MMAP); - return tag; -} - -/*******************************************************************************/ -/* Renvoie les information sur le framebuffer */ - -struct multiboot_tag_framebuffer *getgrubinfo_fb(void) -{ - struct multiboot_tag_framebuffer *tag = - getgrubinfo(MULTIBOOT_TAG_TYPE_FRAMEBUFFER); - return tag; -} - -/*******************************************************************************/ -/* Affiche les informations multiboot2 ;*/ - -void getgrubinfo_all(void) -{ - struct multiboot_tag *tag; - u32 size = *(unsigned *) infobloc; - if (infobloc & 7) - print("Attention : Bloc non aligne..."); - printf(" Taille :% 4u\r\n", (u32) size); - for (tag = (struct multiboot_tag *) (infobloc + 8); - tag->type != MULTIBOOT_TAG_TYPE_END; - tag = - (struct multiboot_tag *) ((u8 *) tag + - ((tag->size + 7) & ~7))) - { - printf("--- Tag % hu, Taille % hu\r\n", tag->type, - tag->size); - switch (tag->type) - { - case MULTIBOOT_TAG_TYPE_CMDLINE: - printf(" Ligne de lancement : %s\r\n", - ((struct multiboot_tag_string *) - tag)->string); - break; - case MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME: - printf(" Chargeur de boot : %s\r\n", - ((struct multiboot_tag_string *) - tag)->string); - break; - case MULTIBOOT_TAG_TYPE_MODULE: - printf(" Module %X-%X. Command line %s\r\n", ((struct multiboot_tag_module *) tag)->mod_start, ((struct multiboot_tag_module *) tag)->mod_end, ((struct multiboot_tag_module *) tag)->cmdline); - break; - case MULTIBOOT_TAG_TYPE_BASIC_MEMINFO: - printf(" Memoire basse : %H, memoire haute = %lH\r\n", ((struct multiboot_tag_basic_meminfo *) tag)->mem_lower << 10, ((u64) ((struct multiboot_tag_basic_meminfo *) tag)->mem_upper) << 10); - break; - case MULTIBOOT_TAG_TYPE_BOOTDEV: - printf(" Peripherique de demarrage : %Y,%u,%u\r\n\r\n", ((struct multiboot_tag_bootdev *) tag)->biosdev, ((struct multiboot_tag_bootdev *) tag)->slice, ((struct multiboot_tag_bootdev *) tag)->part); - break; - case MULTIBOOT_TAG_TYPE_MMAP: - { - multiboot_memory_map_t *mmap; - printf("*** Plan de memoire ***\r\n"); - for (mmap = - ((struct multiboot_tag_mmap *) - tag)->entries; - (u8 *) mmap < (u8 *) tag + tag->size; - mmap = - (multiboot_memory_map_t - *) ((unsigned long) mmap + - ((struct multiboot_tag_mmap *) - tag)->entry_size)) - printf(" adresse: %lY, taille:%lY, type:%Y\r\n", (u64) (mmap->addr), (u64) (mmap->len), (u32) (mmap->type)); - break; - } - case MULTIBOOT_TAG_TYPE_FRAMEBUFFER: - { - struct multiboot_tag_framebuffer *tagfb = - (struct multiboot_tag_framebuffer - *) tag; - printf(" Framebuffer, resolution %d*%d*%d adresse: %X, ", tagfb->common.framebuffer_width, tagfb->common.framebuffer_height, tagfb->common.framebuffer_bpp, tagfb->common.framebuffer_addr); - switch (tagfb->common.framebuffer_type) - { - case MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED: - printf("mode graphique indexé\r\n"); - break; - case MULTIBOOT_FRAMEBUFFER_TYPE_RGB: - printf("mode graphique RGB\r\n"); - break; - case MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT: - printf("mode texte EGA\r\n"); - break; - } - break; - } - case MULTIBOOT_TAG_TYPE_VBE: - { - struct multiboot_tag_vbe *tagvbe = - (struct multiboot_tag_framebuffer - *) tag; - printf(" VBE 2.0, mode %Y, adresse %hY:%hY-%hY\r\n", tagvbe->vbe_mode, tagvbe->vbe_interface_seg, tagvbe->vbe_interface_off, tagvbe->vbe_interface_len); - } - } - } -} -/*******************************************************************************/ diff --git a/lib/process.c b/lib/process.c index 034c515..8e374ef 100644 --- a/lib/process.c +++ b/lib/process.c @@ -72,7 +72,7 @@ u32 iself(u8 * src) ], "RETURN":"u32" } -END */ +END-SYSCALL */ void processexit(void) { @@ -273,6 +273,7 @@ void switchtask(tid_t tid) } if (((atask->dump.cs & 0xFFF8) !=SEL_KERNEL_CODE) && ((atask->dump.cs & 0xFFF8) !=SEL_USER_CODE)) cpuerror("SWITCH ERROR", &atask->dump, false); + //printf("%Y\r\n",atask->tid.pid); atask->dump.eflags = (atask->dump.eflags | 0x200) & 0xFFFFBFFF; createdump(atask->dump); if ((atask->dump.cs & 0xFFF8)==SEL_KERNEL_CODE) @@ -433,10 +434,12 @@ tid_t createtask(pid_t pid,u8 *entry, bool kerneltask) } else { + TAILQ_INSERT_TAIL(&aprocess->pdd->page_head, apage, tailq); new->kernel_stack.ss0 = SEL_KERNEL_STACK; new->kernel_stack.esp0 = (u32) apage->vaddr + PAGESIZE - 16; page *apage = virtual_page_getfree(); + TAILQ_INSERT_TAIL(&aprocess->pdd->page_head, apage, tailq); new->syscall_stack.ss0 = SEL_KERNEL_STACK; new->syscall_stack.esp0 = (u32) apage->vaddr + PAGESIZE - 16; @@ -517,11 +520,12 @@ void deleteprocess(pid_t pid) stopprocess(pid); process* aprocess=findprocess(pid); if (aprocess==NULL) return; - if (current.pid==pid) - current=maketid(1,1); task *next; TAILQ_FOREACH(next, &aprocess->task_head, tailq) deletetask(next->tid); + virtual_pd_destroy(aprocess->pdd); + if (current.pid==pid) + current=maketid(1,1); aprocess->status = PROCESS_STATUS_FREE; sti(); } diff --git a/lib/scheduler.c b/lib/scheduler.c index a55914c..8f5b993 100644 --- a/lib/scheduler.c +++ b/lib/scheduler.c @@ -28,7 +28,7 @@ static u32 time = 0; "ARGS": [], "RETURN":"u32" } -END */ +END-SYSCALL */ u32 gettimer(void) { diff --git a/lib/shell.c b/lib/shell.c index 6fdcc88..77474a1 100644 --- a/lib/shell.c +++ b/lib/shell.c @@ -11,7 +11,6 @@ #include "string.h" #include "gdt.h" #include "shell.h" -#include "multiboot2.h" #include "math.h" #include "debug.h" #include "VGA/ansi.c" @@ -100,11 +99,13 @@ static u8* taskstatus[] = {"PRET ","EXEC.","PAUSE"}; int ps() { - print("*** Processus en memoire\r\n| PID | Parent|Status|K|P.| Pages|\r\n"); + print("*** Processus en memoire\r\n| PID | Parent|Status|K|P.|Directo.|Pages...\r\n"); process* aprocess=findprocess((pid_t)1); while(true) { - printf("|%Y|%Y| %s|%c|%hh u|%Y|\r\n",(u32)aprocess->pid,(u32)aprocess->parent,processstatus[aprocess->status],(aprocess->iskernel?'X':' '),aprocess->priority,(u32)aprocess->pdd); + printf("|%Y|%Y| %s|%c|%hh u|%Y|",(u32)aprocess->pid,(u32)aprocess->parent,processstatus[aprocess->status],(aprocess->iskernel?'X':' '),aprocess->priority,(u32)aprocess->pdd); + if (aprocess->pdd!=NULL) virtual_pd_show(aprocess->pdd); + print("\r\n"); aprocess=getnextprocess(aprocess,PROCESS_STATUS_ALL); if (aprocess==NULL || aprocess->pid==(pid_t)1) break; } @@ -477,7 +478,6 @@ int err(u8 * commandline) /* Information sur le démarrage */ int showinfo() { - getgrubinfo_all(); return 0; } diff --git a/lib/syscall.c b/lib/syscall.c index b8406c3..93c44e6 100644 --- a/lib/syscall.c +++ b/lib/syscall.c @@ -47,7 +47,7 @@ void initsyscall(void) "RETURN":"u32", "DUMP":"yes" } -END */ +END-SYSCALL */ u32 testapi(u32 arg1, u32 arg2, u32 arg3, regs* dump) { @@ -62,20 +62,20 @@ __attribute__ ((noreturn)) void sysenter_handler(regs *dump) sti(); switch (dump->eax) { + case 5: + dump->eax=(u32) processexit(dump->ebx); + break; case 4: dump->eax=(u32) gettimer(); break; case 2: dump->eax=(u32) print(dump->ebx); break; - case 0: - dump->eax=(u32) testapi(dump->ebx, dump->esi, dump->edi, dump); - break; case 1: dump->eax=(u32) waitascii(); break; - case 5: - dump->eax=(u32) processexit(dump->ebx); + case 0: + dump->eax=(u32) testapi(dump->ebx, dump->esi, dump->edi, dump); break; default: diff --git a/lib/vesa.c b/lib/vesa.c index 60dd373..b507e91 100644 --- a/lib/vesa.c +++ b/lib/vesa.c @@ -6,7 +6,6 @@ #include "memory.h" #include "asm.h" #include "types.h" -#include "multiboot2.h" static videoinfos infos; @@ -19,11 +18,11 @@ static capabilities vesacapabilities[] = { void VESA_remap_memory(u32 vaddr) { - struct multiboot_tag_framebuffer *tagfb = getgrubinfo_fb(); +/* struct multiboot_tag_framebuffer *tagfb = getgrubinfo_fb(); u32 len = infos.pagesize * 2; u32 paddr = tagfb->common.framebuffer_addr; virtual_range_use_kernel(vaddr, paddr, len, PAGE_NOFLAG); - infos.baseaddress = vaddr; + infos.baseaddress = vaddr;*/ } /*******************************************************************************/ @@ -31,7 +30,7 @@ void VESA_remap_memory(u32 vaddr) u8 *VESA_detect_hardware(void) { - struct multiboot_tag_framebuffer *tagfb = getgrubinfo_fb(); +/* struct multiboot_tag_framebuffer *tagfb = getgrubinfo_fb(); switch (tagfb->common.framebuffer_type) { case MULTIBOOT_FRAMEBUFFER_TYPE_RGB: @@ -54,7 +53,7 @@ u8 *VESA_detect_hardware(void) case MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT: return NULL; break; - } + }*/ } /*******************************************************************************/ diff --git a/lib/video.c b/lib/video.c index 8d5b95f..67252da 100644 --- a/lib/video.c +++ b/lib/video.c @@ -1045,7 +1045,7 @@ void triangle(vertex2d * AA, vertex2d * BB, vertex2d * CC, u32 color) ], "RETURN":"u32" } -END */ +END-SYSCALL */ u32 print(u8 * string) { @@ -1082,6 +1082,11 @@ u32 storestr(u8 * src, u8 ** dest, u32 len) return len; } +/* EXPORT +{ +"LIBRARY":"libsys" +} +*/ #define maxbuffersize 4096 /*******************************************************************************/ @@ -1155,14 +1160,18 @@ u32 format(const u8 * string, va_list args, u32 maxsize, u8 strbase16[] = "0x\000"; u8 hexadecimal[] = "*0x\000"; u8 achar, temp; - u8 asize, charadd, unit, precisioni, precisionf; + u8 asize=2; + u8 charadd=0xFF; + u8 unit = 0; + u8 precisioni = 0; + u8 precisionf = 0; u8 buffer[maxbuffersize]; u8 *bufferend; u32 buffersize; u8 *str = string; u8 *strtemp; u32 i = 0, counter = 0; - u64 num; + u64 num = 0; bool flag = false, intok = false, decok = false; for (achar = *str; achar != '\000'; i++, achar = *(str + i)) @@ -1383,7 +1392,6 @@ u32 format(const u8 * string, va_list args, u32 maxsize, u64); if (charadd == 0xFF) charadd = ' '; - unit = 0; while (num > 1024 * 10) { num = num >> 10; @@ -1715,3 +1723,5 @@ u8 *sitoa(u64 num, u8 * str, u64 dim) strinvert(str); return pointer; } + +/* END-EXPORT */ diff --git a/makefile b/makefile index c816519..883ca08 100755 --- a/makefile +++ b/makefile @@ -1,4 +1,4 @@ -all: programs bits32 bits64 harddisk uefi +all: tools programs bits32 bits64 harddisk uefi sync bits32: ARCH=bits32 @@ -9,6 +9,11 @@ bits64: ARCH=bits64 bits64: lib/libs.o system/system.sys sync +tools: tools/build + +tools/build: + make -C tools + syscall: clean remakeapi all remakeapi: @@ -37,6 +42,7 @@ togit: make -C lib togit make -C final togit make -C programs togit + make -C tools togit git status sync @@ -45,6 +51,7 @@ clean: make -C lib clean make -C final clean make -C programs clean + make -C tools clean sync littleclean: @@ -58,6 +65,7 @@ indent: make -C system indent make -C lib indent make -C programs indent + make -C tools indent sync backup: clean diff --git a/makesyscall.py b/makesyscall.py index 3c07502..37e8e36 100644 --- a/makesyscall.py +++ b/makesyscall.py @@ -41,7 +41,7 @@ def get_duplicates(sorted_list): path = "./" files = os.listdir(path) -pattern = r'\/\* SYSCALL.*END \*\/' +pattern = r'\/\* SYSCALL.*END-SYSCALL \*\/' output_file = "syscalls.txt" if os.path.exists(output_file): os.remove(output_file) @@ -59,7 +59,7 @@ for root, dirs, files in os.walk(path): results = re.findall(pattern, content, re.MULTILINE| re.DOTALL) for result in results: print("Fichier :"+os.path.join(root, name)) - new=string.replace(string.replace(result,"/* SYSCALL ",""),"END */","") + new=string.replace(string.replace(result,"/* SYSCALL ",""),"END-SYSCALL */","") if fo.tell()>2: new=","+new; fo.write(new+"\r\n") diff --git a/programs/include/libsys.h b/programs/include/libsys.h index fb8f40e..9350f61 100644 --- a/programs/include/libsys.h +++ b/programs/include/libsys.h @@ -4,8 +4,8 @@ #include "types.h"; -u32 getticks(void); -u32 testapi(u32 arg1, u32 arg2, u32 arg3); -u8 waitkey(void); u32 exit(u32 resultcode); +u32 getticks(void); +u8 waitkey(void); +u32 testapi(u32 arg1, u32 arg2, u32 arg3); diff --git a/programs/lib/libsys.c b/programs/lib/libsys.c index 086681b..b6cd955 100644 --- a/programs/lib/libsys.c +++ b/programs/lib/libsys.c @@ -6,24 +6,24 @@ #include "syscall.h"; #include "types.h"; +u32 exit(u32 resultcode) +{ + return syscall1(5,(u32) resultcode); +} + u32 getticks(void) { return syscall0(4); } -u32 testapi(u32 arg1, u32 arg2, u32 arg3) -{ - return syscall3(0,(u32) arg1,(u32) arg2,(u32) arg3); -} - u8 waitkey(void) { return syscall0(1); } -u32 exit(u32 resultcode) +u32 testapi(u32 arg1, u32 arg2, u32 arg3) { - return syscall1(5,(u32) resultcode); + return syscall3(0,(u32) arg1,(u32) arg2,(u32) arg3); } diff --git a/syscalls.txt b/syscalls.txt index ff30c0c..b3acd00 100644 --- a/syscalls.txt +++ b/syscalls.txt @@ -1,5 +1,18 @@ [ { +"ID":5, +"LIBRARY":"libsys", +"NAME":"exit", +"INTERNALNAME":"processexit", +"DESCRIPTION":"End a task for user or kernel domain", +"ARGS": [ +{"TYPE":"u32","NAME":"resultcode","DESCRIPTION":"Code result of the execution"} +], +"RETURN":"u32" +} + +, +{ "ID":4, "NAME":"getticks", "LIBRARY":"libsys", @@ -22,6 +35,17 @@ "RETURN":"u32" } +, +{ +"ID":1, +"LIBRARY":"libsys", +"NAME":"waitkey", +"INTERNALNAME":"waitascii", +"DESCRIPTION":"Wait for user to press a key and return the ascii code pressed", +"ARGS": [], +"RETURN":"u8" +} + , { "ID":0, @@ -38,28 +62,4 @@ "DUMP":"yes" } -, -{ -"ID":1, -"LIBRARY":"libsys", -"NAME":"waitkey", -"INTERNALNAME":"waitascii", -"DESCRIPTION":"Wait for user to press a key and return the ascii code pressed", -"ARGS": [], -"RETURN":"u8" -} - -, -{ -"ID":5, -"LIBRARY":"libsys", -"NAME":"exit", -"INTERNALNAME":"processexit", -"DESCRIPTION":"End a task for user or kernel domain", -"ARGS": [ -{"TYPE":"u32","NAME":"resultcode","DESCRIPTION":"Code result of the execution"} -], -"RETURN":"u32" -} - ] \ No newline at end of file diff --git a/system/linker.lds b/system/linker.lds index e9fb414..c1143fc 100644 --- a/system/linker.lds +++ b/system/linker.lds @@ -1,5 +1,6 @@ OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") OUTPUT_ARCH(i386) +OUPUT(system.bin) ENTRY(start) diff --git a/system/makefile b/system/makefile index 7ac37e4..e4519e3 100755 --- a/system/makefile +++ b/system/makefile @@ -1,24 +1,32 @@ GCC=gcc -O0 -g -nostdinc -ffreestanding -fno-builtin -Wall -w -I ../include -m32 -fno-pie -no-pie -c -o +GCCREAL=gcc -O0 -g -nostdinc -ffreestanding -fno-builtin -Wall -w -I ../include -m16 -fomit-frame-pointer -fno-pic -mno-mmx -mno-sse -mstack-alignment=4 -mno-80387 -mno-fp-ret-in-387 -c -o ASM=gcc -nostdinc -ffreestanding -fno-builtin -m32 -c -fno-pie -no-pie -LINK=ld -m elf_i386 -T linker.lds -n -o +LINK=ld -m elf_i386 -n -o CONVERT=dos2unix INDENT=indent -nhnl -l75 -ppi3 -ts8 -bls -nbc -di8 -nbad -nbap -nsob -i8 -bl -bli0 -ncdw -nce -cli8 -cbi0 -npcs -cs -saf -sai -saw -nprs -lp -npsl REMOVE=rm -f CHANGEPERM=chmod 644 -all: system.sys +all: system.sys + +system.sys: setup.bin system.bin + tools/build setup.bin system.bin zoffset.h system.sys sync togit: clean indent -system.sys: multiboot.o system.o ../lib/libs.o - $(LINK) system.sys multiboot.o system.o ../lib/libs.o +system.bin: system.o ../lib/libs.o + $(LINK) -T linker.lds multiboot.o system.o ../lib/libs.o + +setup.bin: setup.o + $(LINK) $@ $^ + $(OBJDUMP) + +setup.o: + $(GCCREAL) $@ $^ system.o: - $(GCC) system.o system.c - -multiboot.o: - $(ASM) multiboot.S -DVESA=$(VESA) + $(GCC) $@ $^ clean: $(REMOVE) *.o diff --git a/system/multiboot.S b/system/multiboot.S deleted file mode 100644 index 0e85e65..0000000 --- a/system/multiboot.S +++ /dev/null @@ -1,88 +0,0 @@ -/*******************************************************************************/ -/* COS2000 - Compatible Operating System - LGPL v3 - Hordé Nicolas */ -/* */ - -#define MULTIBOOT_SEARCH 32768 -#define MULTIBOOT_HEADER_ALIGN 8 -#define MULTIBOOT2_HEADER_MAGIC 0xe85250d6 -#define MULTIBOOT2_BOOTLOADER_MAGIC 0x36d76289 -#define MULTIBOOT_MOD_ALIGN 0x00001000 -#define MULTIBOOT_INFO_ALIGN 0x00000008 -#define MULTIBOOT_TAG_ALIGN 8 -#define MULTIBOOT_TAG_TYPE_END 0 -#define MULTIBOOT_TAG_TYPE_CMDLINE 1 -#define MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME 2 -#define MULTIBOOT_TAG_TYPE_MODULE 3 -#define MULTIBOOT_TAG_TYPE_BASIC_MEMINFO 4 -#define MULTIBOOT_TAG_TYPE_BOOTDEV 5 -#define MULTIBOOT_TAG_TYPE_MMAP 6 -#define MULTIBOOT_TAG_TYPE_VBE 7 -#define MULTIBOOT_TAG_TYPE_FRAMEBUFFER 8 -#define MULTIBOOT_TAG_TYPE_ELF_SECTIONS 9 -#define MULTIBOOT_TAG_TYPE_APM 10 -#define MULTIBOOT_TAG_TYPE_EFI32 11 -#define MULTIBOOT_TAG_TYPE_EFI64 12 -#define MULTIBOOT_TAG_TYPE_SMBIOS 13 -#define MULTIBOOT_TAG_TYPE_ACPI_OLD 14 -#define MULTIBOOT_TAG_TYPE_ACPI_NEW 15 -#define MULTIBOOT_TAG_TYPE_NETWORK 16 -#define MULTIBOOT_TAG_TYPE_EFI_MMAP 17 -#define MULTIBOOT_TAG_TYPE_EFI_BS 18 -#define MULTIBOOT_TAG_TYPE_EFI32_IH 19 -#define MULTIBOOT_TAG_TYPE_EFI64_IH 20 -#define MULTIBOOT_TAG_TYPE_LOAD_BASE_ADDR 21 - -#define MULTIBOOT_HEADER_TAG_END 0 -#define MULTIBOOT_HEADER_TAG_INFORMATION_REQUEST 1 -#define MULTIBOOT_HEADER_TAG_ADDRESS 2 -#define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS 3 -#define MULTIBOOT_HEADER_TAG_CONSOLE_FLAGS 4 -#define MULTIBOOT_HEADER_TAG_FRAMEBUFFER 5 -#define MULTIBOOT_HEADER_TAG_MODULE_ALIGN 6 -#define MULTIBOOT_HEADER_TAG_EFI_BS 7 -#define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS_EFI32 8 -#define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS_EFI64 9 -#define MULTIBOOT_HEADER_TAG_RELOCATABLE 10 - -#define MULTIBOOT_ARCHITECTURE_I386 0 -#define MULTIBOOT_ARCHITECTURE_MIPS32 4 -#define MULTIBOOT_HEADER_TAG_OPTIONAL 1 - -#define MULTIBOOT_LOAD_PREFERENCE_NONE 0 -#define MULTIBOOT_LOAD_PREFERENCE_LOW 1 -#define MULTIBOOT_LOAD_PREFERENCE_HIGH 2 - -#define MULTIBOOT_CONSOLE_FLAGS_CONSOLE_REQUIRED 1 -#define MULTIBOOT_CONSOLE_FLAGS_EGA_TEXT_SUPPORTED 2 - -.section .multiboot, "a" -.align MULTIBOOT_HEADER_ALIGN -multiboot_header: -.long MULTIBOOT2_HEADER_MAGIC -.long MULTIBOOT_ARCHITECTURE_I386 -.long multiboot_header_end - multiboot_header -.long -(MULTIBOOT2_HEADER_MAGIC + MULTIBOOT_ARCHITECTURE_I386 + (multiboot_header_end - multiboot_header)) -#ifdef VESA -#warning VESA active -framebuffer_tag_start: -.align MULTIBOOT_HEADER_ALIGN -.short MULTIBOOT_HEADER_TAG_FRAMEBUFFER -.short MULTIBOOT_HEADER_TAG_OPTIONAL -.long framebuffer_tag_end - framebuffer_tag_start -.long 1024 -.long 768 -.long 32 -framebuffer_tag_end: -#endif -.align MULTIBOOT_HEADER_ALIGN -.short MULTIBOOT_HEADER_TAG_END -.short 0 -.long 8 -multiboot_header_end: -.section .text -.globl start -start: -pushl %ebx -pushl %eax -call main -hlt diff --git a/system/system.c b/system/system.c index 4bcd96a..ba38d80 100644 --- a/system/system.c +++ b/system/system.c @@ -46,11 +46,9 @@ void error() return; } -int main(u32 magic, u32 addr) +int main(u8* info) { cli(); - if (magic == MULTIBOOT2_BOOTLOADER_MAGIC) - initmultiboot(addr); initdriver(); registerdriver(&vgafonctions); registerdriver(&vesafonctions); diff --git a/templates/syscall.c b/templates/syscall.c index 6d2158f..dd76c92 100644 --- a/templates/syscall.c +++ b/templates/syscall.c @@ -47,7 +47,7 @@ void initsyscall(void) "RETURN":"u32", "DUMP":"yes" } -END */ +END-SYSCALL */ u32 testapi(u32 arg1, u32 arg2, u32 arg3, regs* dump) { diff --git a/tools/build.c b/tools/build.c new file mode 100644 index 0000000..a14601f --- /dev/null +++ b/tools/build.c @@ -0,0 +1,435 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 1991, 1992 Linus Torvalds + * Copyright (C) 1997 Martin Mares + * Copyright (C) 2007 H. Peter Anvin + */ + +/* + * This file builds a disk-image from three different files: + * + * - setup: 8086 machine code, sets up system parm + * - system: 80386 code for actual system + * - zoffset.h: header with ZO_* defines + * + * It does some checking that all files are of the correct type, and writes + * the result to the specified destination, removing headers and padding to + * the right amount. It also writes some system data to stdout. + */ + +/* + * Changes by tytso to allow root device specification + * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996 + * Cross compiling fixes by Gertjan van Wingerde, July 1996 + * Rewritten by Martin Mares, April 1997 + * Substantially overhauled by H. Peter Anvin, April 2007 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +typedef unsigned char u8; +typedef unsigned short u16; +typedef unsigned int u32; + +#define DEFAULT_MAJOR_ROOT 0 +#define DEFAULT_MINOR_ROOT 0 +#define DEFAULT_ROOT_DEV (DEFAULT_MAJOR_ROOT << 8 | DEFAULT_MINOR_ROOT) + +/* Minimal number of setup sectors */ +#define SETUP_SECT_MIN 5 +#define SETUP_SECT_MAX 64 + +/* This must be large enough to hold the entire setup */ +u8 buf[SETUP_SECT_MAX*512]; + +#define PECOFF_RELOC_RESERVE 0x20 + +unsigned long efi32_stub_entry; +unsigned long efi64_stub_entry; +unsigned long efi_pe_entry; +unsigned long startup_64; + +/*----------------------------------------------------------------------*/ + +static const u32 crctab32[] = { + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, + 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, + 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, + 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, + 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, + 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, + 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, + 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, + 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, + 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, + 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, + 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, + 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, + 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, + 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, + 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, + 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, + 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, + 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, + 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, + 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, + 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, + 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, + 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, + 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, + 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, + 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, + 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, + 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, + 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, + 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, + 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, + 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, + 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, + 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, + 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, + 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, + 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, + 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, + 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, + 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, + 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, + 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, + 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, + 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, + 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, + 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, + 0x2d02ef8d +}; + +static u32 partial_crc32_one(u8 c, u32 crc) +{ + return crctab32[(crc ^ c) & 0xff] ^ (crc >> 8); +} + +static u32 partial_crc32(const u8 *s, int len, u32 crc) +{ + while (len--) + crc = partial_crc32_one(*s++, crc); + return crc; +} + +static void die(const char * str, ...) +{ + va_list args; + va_start(args, str); + vfprintf(stderr, str, args); + fputc('\n', stderr); + exit(1); +} + +static void usage(void) +{ + die("Usage: build setup system zoffset.h image"); +} + +#ifdef CONFIG_EFI_STUB + +static void update_pecoff_section_header_fields(char *section_name, u32 vma, u32 size, u32 datasz, u32 offset) +{ + unsigned int pe_header; + unsigned short num_sections; + u8 *section; + + pe_header = get_unaligned_le32(&buf[0x3c]); + num_sections = get_unaligned_le16(&buf[pe_header + 6]); + +#ifdef CONFIG_X86_32 + section = &buf[pe_header + 0xa8]; +#else + section = &buf[pe_header + 0xb8]; +#endif + + while (num_sections > 0) { + if (strncmp((char*)section, section_name, 8) == 0) { + /* section header size field */ + put_unaligned_le32(size, section + 0x8); + + /* section header vma field */ + put_unaligned_le32(vma, section + 0xc); + + /* section header 'size of initialised data' field */ + put_unaligned_le32(datasz, section + 0x10); + + /* section header 'file offset' field */ + put_unaligned_le32(offset, section + 0x14); + + break; + } + section += 0x28; + num_sections--; + } +} + +static void update_pecoff_section_header(char *section_name, u32 offset, u32 size) +{ + update_pecoff_section_header_fields(section_name, offset, size, size, offset); +} + +static void update_pecoff_setup_and_reloc(unsigned int size) +{ + u32 setup_offset = 0x200; + u32 reloc_offset = size - PECOFF_RELOC_RESERVE; + u32 setup_size = reloc_offset - setup_offset; + + update_pecoff_section_header(".setup", setup_offset, setup_size); + update_pecoff_section_header(".reloc", reloc_offset, PECOFF_RELOC_RESERVE); + + /* + * Modify .reloc section contents with a single entry. The + * relocation is applied to offset 10 of the relocation section. + */ + put_unaligned_le32(reloc_offset + 10, &buf[reloc_offset]); + put_unaligned_le32(10, &buf[reloc_offset + 4]); +} + +static void update_pecoff_text(unsigned int text_start, unsigned int file_sz) +{ + unsigned int pe_header; + unsigned int text_sz = file_sz - text_start; + + pe_header = get_unaligned_le32(&buf[0x3c]); + + /* + * Size of code: Subtract the size of the first sector (512 bytes) + * which includes the header. + */ + put_unaligned_le32(file_sz - 512, &buf[pe_header + 0x1c]); + + /* + * Address of entry point for PE/COFF executable + */ + put_unaligned_le32(text_start + efi_pe_entry, &buf[pe_header + 0x28]); + + update_pecoff_section_header(".text", text_start, text_sz); +} + +static void update_pecoff_bss(unsigned int file_sz, unsigned int init_sz) +{ + unsigned int pe_header; + unsigned int bss_sz = init_sz - file_sz; + + pe_header = get_unaligned_le32(&buf[0x3c]); + + /* Size of uninitialized data */ + put_unaligned_le32(bss_sz, &buf[pe_header + 0x24]); + + /* Size of image */ + put_unaligned_le32(init_sz, &buf[pe_header + 0x50]); + + update_pecoff_section_header_fields(".bss", file_sz, bss_sz, 0, 0); +} + +static int reserve_pecoff_reloc_section(int c) +{ + /* Reserve 0x20 bytes for .reloc section */ + memset(buf+c, 0, PECOFF_RELOC_RESERVE); + return PECOFF_RELOC_RESERVE; +} + +static void efi_stub_defaults(void) +{ + /* Defaults for old kernel */ +#ifdef CONFIG_X86_32 + efi_pe_entry = 0x10; +#else + efi_pe_entry = 0x210; + startup_64 = 0x200; +#endif +} + +static void efi_stub_entry_update(void) +{ + unsigned long addr = efi32_stub_entry; + +#ifdef CONFIG_X86_64 + /* Yes, this is really how we defined it :( */ + addr = efi64_stub_entry - 0x200; +#endif + +#ifdef CONFIG_EFI_MIXED + if (efi32_stub_entry != addr) + die("32-bit and 64-bit EFI entry points do not match\n"); +#endif + put_unaligned_le32(addr, &buf[0x264]); +} + +#else + +static inline void update_pecoff_setup_and_reloc(unsigned int size) {} +static inline void update_pecoff_text(unsigned int text_start, + unsigned int file_sz) {} +static inline void update_pecoff_bss(unsigned int file_sz, + unsigned int init_sz) {} +static inline void efi_stub_defaults(void) {} +static inline void efi_stub_entry_update(void) {} + +static inline int reserve_pecoff_reloc_section(int c) +{ + return 0; +} +#endif /* CONFIG_EFI_STUB */ + + +/* + * Parse zoffset.h and find the entry points. We could just #include zoffset.h + * but that would mean tools/build would have to be rebuilt every time. It's + * not as if parsing it is hard... + */ +#define PARSE_ZOFS(p, sym) do { \ + if (!strncmp(p, "#define ZO_" #sym " ", 11+sizeof(#sym))) \ + sym = strtoul(p + 11 + sizeof(#sym), NULL, 16); \ +} while (0) + +static void parse_zoffset(char *fname) +{ + FILE *file; + char *p; + int c; + + file = fopen(fname, "r"); + if (!file) + die("Unable to open `%s': %m", fname); + c = fread(buf, 1, sizeof(buf) - 1, file); + if (ferror(file)) + die("read-error on `zoffset.h'"); + fclose(file); + buf[c] = 0; + + p = (char *)buf; + + while (p && *p) { + PARSE_ZOFS(p, efi32_stub_entry); + PARSE_ZOFS(p, efi64_stub_entry); + PARSE_ZOFS(p, efi_pe_entry); + PARSE_ZOFS(p, startup_64); + + p = strchr(p, '\n'); + while (p && (*p == '\r' || *p == '\n')) + p++; + } +} + +int main(int argc, char ** argv) +{ + unsigned int i, sz, setup_sectors, init_sz; + int c; + u32 sys_size; + struct stat sb; + FILE *file, *dest; + int fd; + void *kernel; + u32 crc = 0xffffffffUL; + + efi_stub_defaults(); + + if (argc != 5) + usage(); + parse_zoffset(argv[3]); + + dest = fopen(argv[4], "w"); + if (!dest) + die("Unable to write `%s': %m", argv[4]); + + /* Copy the setup code */ + file = fopen(argv[1], "r"); + if (!file) + die("Unable to open `%s': %m", argv[1]); + c = fread(buf, 1, sizeof(buf), file); + if (ferror(file)) + die("read-error on `setup'"); + if (c < 1024) + die("The setup must be at least 1024 bytes"); + if (get_unaligned_le16(&buf[510]) != 0xAA55) + die("Boot block hasn't got boot flag (0xAA55)"); + fclose(file); + + c += reserve_pecoff_reloc_section(c); + + /* Pad unused space with zeros */ + setup_sectors = (c + 511) / 512; + if (setup_sectors < SETUP_SECT_MIN) + setup_sectors = SETUP_SECT_MIN; + i = setup_sectors*512; + memset(buf+c, 0, i-c); + + update_pecoff_setup_and_reloc(i); + + /* Set the default root device */ + put_unaligned_le16(DEFAULT_ROOT_DEV, &buf[508]); + + printf("Setup is %d bytes (padded to %d bytes).\n", c, i); + + /* Open and stat the kernel file */ + fd = open(argv[2], O_RDONLY); + if (fd < 0) + die("Unable to open `%s': %m", argv[2]); + if (fstat(fd, &sb)) + die("Unable to stat `%s': %m", argv[2]); + sz = sb.st_size; + printf("System is %d kB\n", (sz+1023)/1024); + kernel = mmap(NULL, sz, PROT_READ, MAP_SHARED, fd, 0); + if (kernel == MAP_FAILED) + die("Unable to mmap '%s': %m", argv[2]); + /* Number of 16-byte paragraphs, including space for a 4-byte CRC */ + sys_size = (sz + 15 + 4) / 16; + + /* Patch the setup code with the appropriate size parameters */ + buf[0x1f1] = setup_sectors-1; + put_unaligned_le32(sys_size, &buf[0x1f4]); + + update_pecoff_text(setup_sectors * 512, i + (sys_size * 16)); + init_sz = get_unaligned_le32(&buf[0x260]); + update_pecoff_bss(i + (sys_size * 16), init_sz); + + efi_stub_entry_update(); + + crc = partial_crc32(buf, i, crc); + if (fwrite(buf, 1, i, dest) != i) + die("Writing setup failed"); + + /* Copy the kernel code */ + crc = partial_crc32(kernel, sz, crc); + if (fwrite(kernel, 1, sz, dest) != sz) + die("Writing kernel failed"); + + /* Add padding leaving 4 bytes for the checksum */ + while (sz++ < (sys_size*16) - 4) { + crc = partial_crc32_one('\0', crc); + if (fwrite("\0", 1, 1, dest) != 1) + die("Writing padding failed"); + } + + /* Write the CRC */ + printf("CRC %x\n", crc); + put_unaligned_le32(crc, buf); + if (fwrite(buf, 1, 4, dest) != 4) + die("Writing CRC failed"); + + /* Catch any delayed write failures */ + if (fclose(dest)) + die("Writing image failed"); + + close(fd); + + /* Everything is OK */ + return 0; +} diff --git a/tools/le_byteshift.h b/tools/le_byteshift.h new file mode 100644 index 0000000..dc8565f --- /dev/null +++ b/tools/le_byteshift.h @@ -0,0 +1,71 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _TOOLS_LE_BYTESHIFT_H +#define _TOOLS_LE_BYTESHIFT_H + +#include + +static inline uint16_t __get_unaligned_le16(const uint8_t *p) +{ + return p[0] | p[1] << 8; +} + +static inline uint32_t __get_unaligned_le32(const uint8_t *p) +{ + return p[0] | p[1] << 8 | p[2] << 16 | p[3] << 24; +} + +static inline uint64_t __get_unaligned_le64(const uint8_t *p) +{ + return (uint64_t)__get_unaligned_le32(p + 4) << 32 | + __get_unaligned_le32(p); +} + +static inline void __put_unaligned_le16(uint16_t val, uint8_t *p) +{ + *p++ = val; + *p++ = val >> 8; +} + +static inline void __put_unaligned_le32(uint32_t val, uint8_t *p) +{ + __put_unaligned_le16(val >> 16, p + 2); + __put_unaligned_le16(val, p); +} + +static inline void __put_unaligned_le64(uint64_t val, uint8_t *p) +{ + __put_unaligned_le32(val >> 32, p + 4); + __put_unaligned_le32(val, p); +} + +static inline uint16_t get_unaligned_le16(const void *p) +{ + return __get_unaligned_le16((const uint8_t *)p); +} + +static inline uint32_t get_unaligned_le32(const void *p) +{ + return __get_unaligned_le32((const uint8_t *)p); +} + +static inline uint64_t get_unaligned_le64(const void *p) +{ + return __get_unaligned_le64((const uint8_t *)p); +} + +static inline void put_unaligned_le16(uint16_t val, void *p) +{ + __put_unaligned_le16(val, p); +} + +static inline void put_unaligned_le32(uint32_t val, void *p) +{ + __put_unaligned_le32(val, p); +} + +static inline void put_unaligned_le64(uint64_t val, void *p) +{ + __put_unaligned_le64(val, p); +} + +#endif /* _TOOLS_LE_BYTESHIFT_H */ diff --git a/tools/makefile b/tools/makefile new file mode 100755 index 0000000..70832f5 --- /dev/null +++ b/tools/makefile @@ -0,0 +1,28 @@ +CC=gcc -I . -o +SRCS= $(wildcard *.c) +EXECS= $(SRCS:.c=) +CONVERT=dos2unix +INDENT=indent -nhnl -l75 -ppi3 -ts8 -bls -nbc -di8 -nbad -nbap -nsob -i8 -bl -bli0 -ncdw -nce -cli8 -cbi0 -npcs -cs -saf -sai -saw -nprs -lp -npsl +REMOVE=rm -f +CHANGELF=elfedit --output-osabi FenixOS +CHANGEPERM=chmod 644 + +all: $(EXECS) + sync + +togit: clean indent + +%: %.c + $(CC) $@ $< +clean: + $(REMOVE) *.o + $(REMOVE) *.c~ + find . -type f ! -name makefile -perm /u=x -maxdepth 1 -regex '.+/\.?[^\.]+' -exec $(REMOVE) {} \; + sync + +indent: + $(CHANGEPERM) *.c + $(CONVERT) *.c + $(INDENT) *.c + $(REMOVE) *.c~ + sync