Mercurial > hg > Members > innparusu > xv6-rpi
changeset 52:1adde248a61f default tip
merge
author | anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 07 Jun 2019 17:30:15 +0900 |
parents | c05774dbd65f (diff) ccd59cd9ee45 (current diff) |
children | |
files | Dockerfile |
diffstat | 47 files changed, 3341 insertions(+), 420 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.hgignore Fri Jun 07 17:30:15 2019 +0900 @@ -0,0 +1,5 @@ +syntax: glob + +src/CMakeCache.txt +src/CMakeFiles/ +src/build/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.hgtags Fri Jun 07 17:30:15 2019 +0900 @@ -0,0 +1,1 @@ +87d6dc2cf0019912e6fc660dcaa6db6e00e7d094 no-cbc
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CMakeLists.txt Fri Jun 07 17:30:15 2019 +0900 @@ -0,0 +1,12 @@ +cmake_minimum_required(VERSION 3.3) + +# output compile log +set(CMAKE_VERBOSE_MAKEFILE 1) + +# set compiler +set(CMAKE_C_COMPILER $ENV{CBC_COMPILER}) + +# compile option +add_definitions("-Wall -g -O0") + +add_subdirectory(src)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Doc/cvc_xv6.mm Fri Jun 07 17:30:15 2019 +0900 @@ -0,0 +1,82 @@ +<map version="1.0.1"> +<!-- To view this file, download free mind mapping software FreeMind from http://freemind.sourceforge.net --> +<node CREATED="1551175900186" ID="ID_1543505841" MODIFIED="1551178157198" TEXT="cbc_xv6"> +<node CREATED="1551175940999" ID="ID_1168307211" MODIFIED="1551175966619" POSITION="right" TEXT="rewrite xv6 cbc"> +<node CREATED="1551175968191" ID="ID_1403236105" MODIFIED="1551176363951" TEXT="目的"> +<node CREATED="1551175984177" ID="ID_376992153" MODIFIED="1551175999729" TEXT="楽しそうだから"/> +<node CREATED="1551176000682" ID="ID_1852090178" MODIFIED="1551176204609" TEXT="provable operating system implimentation"/> +<node CREATED="1551176083263" ID="ID_916765352" MODIFIED="1551176158605" TEXT="GearsOS prototype"/> +<node CREATED="1551176213021" ID="ID_1111018273" MODIFIED="1551176292637" TEXT="hardware "/> +<node CREATED="1551176300809" ID="ID_86365793" MODIFIED="1551176350769" TEXT="effective interface"/> +</node> +<node CREATED="1551176361812" ID="ID_836890094" MODIFIED="1551176598071" TEXT="書き換えの方針"> +<node CREATED="1551176599911" ID="ID_1089103762" MODIFIED="1551176628199" TEXT="interface"> +<node CREATED="1551176707554" ID="ID_461523092" MODIFIED="1551176716422" TEXT="context"> +<node CREATED="1551176725928" ID="ID_1961623353" MODIFIED="1551176784259" TEXT="使用するCG,DGのすべての情報"/> +</node> +</node> +<node CREATED="1551176629367" ID="ID_1761134792" MODIFIED="1551176668507" TEXT="xv6の構造を保存しながら"/> +<node CREATED="1551176669792" ID="ID_361698037" MODIFIED="1551177025005" TEXT="kernelの状態はcontextに保持する"> +<node CREATED="1551177032279" ID="ID_1694243724" MODIFIED="1551177059576" TEXT="従来の実装はkernelの状態はkernelStack上にある"/> +<node CREATED="1551177071224" ID="ID_91309837" MODIFIED="1551177071224" TEXT=""/> +</node> +<node CREATED="1551177092678" ID="ID_398009673" MODIFIED="1551177117953" TEXT="cbcでの割り込み処理方法を確立する"/> +<node CREATED="1551177367633" ID="ID_1789983273" MODIFIED="1551177389377" TEXT="paging"/> +<node CREATED="1551177643268" ID="ID_16225531" MODIFIED="1551177672535" TEXT="CGはsingle thread"> +<node CREATED="1551177693474" ID="ID_45420596" MODIFIED="1551177724398" TEXT="DGへの書き込みはtransaction"/> +</node> +</node> +<node CREATED="1551177399550" ID="ID_285994758" MODIFIED="1551177416799" TEXT="xv6の構造"> +<node CREATED="1551177417759" ID="ID_93841800" MODIFIED="1551177433855" TEXT="system part"> +<node CREATED="1551177773054" ID="ID_1498815526" MODIFIED="1551177817968" TEXT="initialization"> +<node CREATED="1551177819616" ID="ID_662676004" MODIFIED="1551177830022" TEXT="page table"/> +<node CREATED="1551177831628" ID="ID_343435161" MODIFIED="1551177831628" TEXT=""/> +</node> +<node CREATED="1551177839146" ID="ID_1415447941" MODIFIED="1551177867626" TEXT="物理メモリ管理"> +<node CREATED="1551177867909" ID="ID_1335748263" MODIFIED="1551177867909" TEXT=""/> +</node> +<node CREATED="1551177885892" ID="ID_130513187" MODIFIED="1551177928702" TEXT="scheduler"/> +<node CREATED="1551177934053" ID="ID_1790682964" MODIFIED="1551177949416" TEXT="system call handre"/> +<node CREATED="1551177950598" ID="ID_1459485731" MODIFIED="1551177960632" TEXT="intarapt handre"/> +<node CREATED="1551177962076" ID="ID_1321823972" MODIFIED="1551177966620" TEXT="trap return"/> +<node CREATED="1551177968813" ID="ID_893294613" MODIFIED="1551178110280" TEXT="file system"> +<node CREATED="1551177974847" ID="ID_957111795" MODIFIED="1551177982344" TEXT="vfs"/> +</node> +<node CREATED="1551177989428" ID="ID_1693615101" MODIFIED="1551178006725" TEXT="device driver"> +<node CREATED="1551178006727" ID="ID_801323353" MODIFIED="1551178042525" TEXT="console"> +<node CREATED="1551178013955" ID="ID_1122171470" MODIFIED="1551178013955" TEXT=""/> +</node> +<node CREATED="1551178042884" ID="ID_1069505739" MODIFIED="1551178060879" TEXT="keybord"/> +<node CREATED="1551178061553" ID="ID_111165606" MODIFIED="1551178064268" TEXT="mouse"/> +<node CREATED="1551178065104" ID="ID_1663232555" MODIFIED="1551178075593" TEXT="grahics"/> +<node CREATED="1551178075909" ID="ID_200114717" MODIFIED="1551178094660" TEXT="disk"/> +<node CREATED="1551178095721" ID="ID_99906530" MODIFIED="1551178104803" TEXT="usb driver"/> +</node> +</node> +<node CREATED="1551177437581" ID="ID_26172412" MODIFIED="1551177442997" TEXT="usr part"> +<node CREATED="1551177459787" ID="ID_954938825" MODIFIED="1551177530203" TEXT=" 大きなCG,とDGとみなす"/> +<node CREATED="1551177531492" ID="ID_1658346576" MODIFIED="1551177566687" TEXT="GersOS向けに書く"/> +</node> +</node> +</node> +<node CREATED="1551178158685" ID="ID_679209856" MODIFIED="1551178170717" POSITION="left" TEXT="書き換えのスケジュール"> +<node CREATED="1551178178456" ID="ID_906410508" MODIFIED="1551178189374" TEXT="inter faceの導入"> +<node CREATED="1551178192675" ID="ID_1417590192" MODIFIED="1551178200670" TEXT="contextの導入"/> +</node> +<node CREATED="1551178232220" ID="ID_965556024" MODIFIED="1551178238793" TEXT="cmake"/> +<node CREATED="1551178239434" ID="ID_1533211516" MODIFIED="1551178262122" TEXT="基本的な書き換え方法の習得"/> +<node CREATED="1551178268281" ID="ID_1144258114" MODIFIED="1551178274850" TEXT="個別の書換の実行"/> +<node CREATED="1551178282907" ID="ID_1829748966" MODIFIED="1551178331696" TEXT="チェックポイント"> +<node CREATED="1551178297754" ID="ID_243715387" MODIFIED="1551178308433" TEXT="lsが動く"/> +</node> +<node CREATED="1551178312753" ID="ID_1972694781" MODIFIED="1551178325905" TEXT="usb driverの設計"/> +<node CREATED="1551178378786" ID="ID_1039081852" MODIFIED="1551178378786" TEXT=""/> +</node> +<node CREATED="1551178171432" ID="ID_623702460" MODIFIED="1551178467752" POSITION="left" TEXT="armxv6 sourceの統一"/> +<node CREATED="1551178487702" ID="ID_1465644850" MODIFIED="1551178498778" POSITION="left" TEXT="meta機能の使い方"> +<node CREATED="1551178518579" ID="ID_1090193181" MODIFIED="1551178545680" TEXT="source code の階層化"/> +<node CREATED="1551178550788" ID="ID_247708994" MODIFIED="1551178555263" TEXT="割り込み"/> +<node CREATED="1551178556367" ID="ID_1512315136" MODIFIED="1551178562278" TEXT="メモリ管理"/> +</node> +</node> +</map>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Todo Fri Jun 07 17:30:15 2019 +0900 @@ -0,0 +1,11 @@ +Fri Feb 16 16:38:49 JST 2018 + + * xv6arm をつくる Done + * cbclangの-arm Done + * CbC_gcc のarmくろすこんぱいら Done + * cbclang らいぶらりとインクルード Done + * gccbc ライブラリとインクルード Done + * できたxv6をKVMでうごかす Done + 実際にxv6の一部をCbCで書き直す Done + efi boot を書く +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cbclang/arm/setjmp.h Fri Jun 07 17:30:15 2019 +0900 @@ -0,0 +1,29 @@ + +typedef int __jmp_buf[64] __attribute__((__aligned__ (8))); +typedef int __sig_atomic_t; +typedef struct + { + unsigned long int __val[(1024 / (8 * sizeof (unsigned long int)))]; + } __sigset_t; +struct __jmp_buf_tag + { + __jmp_buf __jmpbuf; + int __mask_was_saved; + __sigset_t __saved_mask; + }; + +typedef struct __jmp_buf_tag jmp_buf[1]; +extern int setjmp (jmp_buf __env) __attribute__ ((__nothrow__)); + +extern int __sigsetjmp (struct __jmp_buf_tag __env[1], int __savemask) __attribute__ ((__nothrow__)); +extern int _setjmp (struct __jmp_buf_tag __env[1]) __attribute__ ((__nothrow__)); + +extern void longjmp (struct __jmp_buf_tag __env[1], int __val) + __attribute__ ((__nothrow__)) __attribute__ ((__noreturn__)); + +extern void _longjmp (struct __jmp_buf_tag __env[1], int __val) + __attribute__ ((__nothrow__)) __attribute__ ((__noreturn__)); +typedef struct __jmp_buf_tag sigjmp_buf[1]; +extern void siglongjmp (sigjmp_buf __env, int __val) + __attribute__ ((__nothrow__)) __attribute__ ((__noreturn__)); +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/edit_xv6arm7 Fri Jun 07 17:30:15 2019 +0900 @@ -0,0 +1,101 @@ +<domain type='kvm'> + <name>xv6arm7</name> + <uuid>80ddbab5-a467-4964-8eb1-0475512522ee</uuid> + <memory unit='KiB'>131072</memory> + <currentMemory unit='KiB'>131072</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='x86_64' machine='pc-i440fx-rhel7.4.0'>hvm</type> + <kernel>/mnt/dalmore-home/one/src/xv6-rpi/src/kernel.elf</kernel> + <boot dev='hd'/> + </os> + <features> + <acpi/> + <apic/> + <vmport state='off'/> + </features> + <cpu mode='custom' match='exact'> + <model fallback='allow'>Haswell-noTSX</model> + </cpu> + <clock offset='utc'> + <timer name='rtc' tickpolicy='catchup'/> + <timer name='pit' tickpolicy='delay'/> + <timer name='hpet' present='no'/> + </clock> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>restart</on_crash> + <pm> + <suspend-to-mem enabled='no'/> + <suspend-to-disk enabled='no'/> + </pm> + <devices> + <emulator>/usr/libexec/qemu-kvm</emulator> + <disk type='file' device='disk'> + <driver name='qemu' type='raw'/> + <source file='/mnt/dalmore-home/one/src/xv6-rpi/src/build/fs.img'/> + <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' target='0' unit='0'/> + </disk> + <controller type='usb' index='0' model='ich9-ehci1'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x7'/> + </controller> + <controller type='usb' index='0' model='ich9-uhci1'> + <master startport='0'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0' multifunction='on'/> + </controller> + <controller type='usb' index='0' model='ich9-uhci2'> + <master startport='2'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x1'/> + </controller> + <controller type='usb' index='0' model='ich9-uhci3'> + <master startport='4'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x2'/> + </controller> + <controller type='pci' index='0' model='pci-root'/> + <controller type='ide' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/> + </controller> + <controller type='virtio-serial' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/> + </controller> + <interface type='user'> + <mac address='52:54:00:42:94:60'/> + <model type='rtl8139'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> + </interface> + <serial type='pty'> + <target port='0'/> + </serial> + <console type='pty'> + <target type='serial' port='0'/> + </console> + <channel type='spicevmc'> + <target type='virtio' name='com.redhat.spice.0'/> + <address type='virtio-serial' controller='0' bus='0' port='1'/> + </channel> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + <graphics type='spice' autoport='yes'> + <listen type='address'/> + <image compression='off'/> + </graphics> + <sound model='ich6'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/> + </sound> + <video> + <model type='qxl' ram='65536' vram='65536' vgamem='16384' heads='1' primary='yes'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/> + </video> + <redirdev bus='usb' type='spicevmc'> + <address type='usb' bus='0' port='1'/> + </redirdev> + <redirdev bus='usb' type='spicevmc'> + <address type='usb' bus='0' port='2'/> + </redirdev> + <memballoon model='virtio'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'/> + </memballoon> + </devices> +</domain> +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kvm-armLinux.xml Fri Jun 07 17:30:15 2019 +0900 @@ -0,0 +1,53 @@ +<domain type='qemu' id='65'> + <name>arm1</name> + <uuid>8028f71a-1db8-40a4-94fa-5a4a42014273</uuid> + <memory unit='KiB'>131072</memory> + <currentMemory unit='KiB'>131072</currentMemory> + <vcpu placement='static'>1</vcpu> + <resource> + <partition>/machine</partition> + </resource> + <os> + <type arch='armv7l' machine='versatileab'>hvm</type> + <kernel>/var/lib/libvirt/images/zImage-versatile-2.6.24-rc7.armv5tel</kernel> + <cmdline>"root=0800"</cmdline> + <boot dev='hd'/> + </os> + <features> + <acpi/> + </features> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>restart</on_crash> + <devices> + <emulator>/bin/qemu-system-arm</emulator> + <disk type='file' device='disk'> + <driver name='qemu' type='raw'/> + <source file='/var/lib/libvirt/images/arm1.img'/> + <backingStore/> + <target dev='hdc' bus='scsi'/> + <alias name='scsi0-0-2'/> + <address type='drive' controller='0' bus='0' target='0' unit='2'/> + </disk> + <controller type='scsi' index='0'> + <alias name='scsi0'/> + </controller> + <input type='mouse' bus='ps2'> + <alias name='input0'/> + </input> + <graphics type='vnc' port='5900' autoport='yes' listen='0.0.0.0'> + <listen type='address' address='0.0.0.0'/> + </graphics> + <video> + <model type='cirrus' vram='16384' heads='1' primary='yes'/> + <alias name='video0'/> + </video> + </devices> + <seclabel type='none' model='none'/> + <seclabel type='dynamic' model='dac' relabel='yes'> + <label>+107:+107</label> + <imagelabel>+107:+107</imagelabel> + </seclabel> +</domain> +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kvm-armxv6.xml Fri Jun 07 17:30:15 2019 +0900 @@ -0,0 +1,49 @@ +<domain type='qemu' id='65'> + <name>arm1</name> + <memory unit='KiB'>121</memory> + <currentMemory unit='KiB'>131072</currentMemory> + <vcpu placement='static'>1</vcpu> + <resource> + <partition>/machine</partition> + </resource> + <os> + <type arch='armv7l' machine='versatileab'>hvm</type> + <kernel>/mnt/dalmore-home/one/src/xv6-rpi/src/kernel.elf</kernel> + </os> + <features> + <acpi/> + </features> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>restart</on_crash> + <devices> + <emulator>/bin/qemu-system-arm</emulator> + <disk type='file' device='disk'> + <driver name='qemu' type='raw'/> + <backingStore/> + <target dev='hdc' bus='scsi'/> + <alias name='scsi0-0-2'/> + <address type='drive' controller='0' bus='0' target='0' unit='2'/> + </disk> + <controller type='scsi' index='0'> + <alias name='scsi0'/> + </controller> + <input type='mouse' bus='ps2'> + <alias name='input0'/> + </input> + <graphics type='vnc' port='5900' autoport='yes' listen='0.0.0.0'> + <listen type='address' address='0.0.0.0'/> + </graphics> + <video> + <model type='cirrus' vram='16384' heads='1' primary='yes'/> + <alias name='video0'/> + </video> + </devices> + <seclabel type='none' model='none'/> + <seclabel type='dynamic' model='dac' relabel='yes'> + <label>+107:+107</label> + <imagelabel>+107:+107</imagelabel> + </seclabel> +</domain> +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/CMakeLists.txt Fri Jun 07 17:30:15 2019 +0900 @@ -0,0 +1,89 @@ +cmake_minimum_required(VERSION 3.8) +project(xv6cbc C ASM) + +set(USE_CUDA,0) +# -DUSE_CUDA +# add_definitions("-Wall -g -O") + +if (APPLE) + set(CMAKE_C_COMPILER $ENV{CBC_LANG_COMPILER}) + add_definitions("-Wall -g -arch arm -fno-pic -static -fno-builtin -fno-strict-aliasing -Wall -Werror -I. -g -O0 + -Wno-macro-redefined -Wno-gnu-designator -Wno-sometimes-uninitialized -Wno-tautological-compare + -I/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/usr/include + -Wno-nullability-completeness -Wno-expansion-to-defined") +else (APPLE) + set(CMAKE_C_COMPILER /mnt/dalmore-home/one/src/armgcc/cross/bin/arm-none-eabi-gcc) + add_definitions("-B/mnt/dalmore-home/one/src/armgcc/cross/bin/arm-none-eabi- + -DCBCXV6=1 -fno-pic -static -fno-builtin -fno-strict-aliasing -Wall -I. -g -O0") +endif (APPLE) + +# -DCMAKE_BUILD_TYPE=Debug +set(CMAKE_C_FLAGS_DEBUG "-O0") +set(CMAKE_EXE_LINKER_FLAGS "-L. -arch armv7 -T kernel.ld -o kernel.elf ") + +if (${USE_CUDA}) + include_directories("/usr/local/cuda/include") + set(NVCCFLAG "-std=c++11" "-g" "-O0" ) + if (UNIX AND NOT APPLE) # LINUX + set(CUDA_LINK_FLAGS "-L/usr/local/cuda/lib64 -lcuda -lcudart") + elseif (APPLE) + set(CUDA_LINK_FLAGS "-framework CUDA -lc++ -Wl,-search_paths_first -Wl,-headerpad_max_install_names /usr/local/cuda/lib/libcudart_static.a -Wl,-rpath,/usr/local/cuda/lib") + endif() + find_package(CUDA REQUIRED) + SET( CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${CUDA_LINK_FLAGS}" ) +endif() + +include_directories(".") + +macro( GearsCommand ) + set( _OPTIONS_ARGS ) + set( _ONE_VALUE_ARGS TARGET ) + set( _MULTI_VALUE_ARGS SOURCES ) + cmake_parse_arguments( _Gears "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN} ) + + set (_Gears_CBC_SOURCES) + set (_Gears_CSOURCES) + foreach(i ${_Gears_SOURCES}) + if (${i} MATCHES "\\.cbc") + string(REGEX REPLACE "(.*).cbc" "c/\\1.c" j ${i}) + add_custom_command ( + OUTPUT ${j} + DEPENDS ${i} + COMMAND "perl" "gearsTools/generate_stub.pl" "-o" ${j} ${i} + ) + list(APPEND _Gears_CBC_SOURCES ${j}) + elseif (${i} MATCHES "\\.cu") + string(REGEX REPLACE "(.*).cu" "c/\\1.ptx" j ${i}) + add_custom_command ( + OUTPUT ${j} + DEPENDS ${i} + COMMAND nvcc ${NVCCFLAG} -c -ptx -o ${j} ${i} + ) + list(APPEND _Gears_CBC_SOURCES ${j}) + else() + set(j ${i}) + list(APPEND _Gears_CSOURCES ${j}) + endif() + endforeach(i) + + add_custom_command ( + OUTPUT c/${_Gears_TARGET}-context.c + DEPENDS ${_Gears_CBC_SOURCES} + COMMAND "perl" "gearsTools/generate_context.pl" "-o" ${_Gears_TARGET} ${_Gears_CBC_SOURCES} + ) + add_executable(${_Gears_TARGET} ${_Gears_CBC_SOURCES} ${_Gears_CSOURCES} c/${_Gears_TARGET}-context.c) + target_link_libraries(${_Gears_TARGET} m pthread) +endmacro() + + +GearsCommand( + TARGET + kernel + SOURCES + lib/string.c arm.c asm.S bio.c buddy.c console.cbc exec.c file.c fs.c log.c main.c memide.c pipe.c proc.c spinlock.c + start.c swtch.S syscall.c sysfile.c sysproc.c trap_asm.S trap.c vm.c device/picirq.c device/timer.c device/uart.c + entry-osx.S +) + + +
--- a/src/Makefile Mon Dec 17 19:48:57 2018 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,75 +0,0 @@ -# specify path to QEMU, installed with MacPorts -QEMU = qemu-system-arm - -include makefile.inc - -# link the libgcc.a for __aeabi_idiv. ARM has no native support for div -LIBS = $(LIBGCC) - -OBJS = \ - lib/string.o \ - \ - arm.o\ - asm.o\ - bio.o\ - buddy.o\ - console.o\ - exec.o\ - file.o\ - fs.o\ - log.o\ - main.o\ - memide.o\ - pipe.o\ - proc.o\ - spinlock.o\ - start.o\ - swtch.o\ - syscall.o\ - sysfile.o\ - sysproc.o\ - trap_asm.o\ - trap.o\ - vm.o \ - \ - device/picirq.o \ - device/timer.o \ - device/uart.o - -KERN_OBJS = $(OBJS) entry.o -kernel.elf: $(addprefix build/,$(KERN_OBJS)) kernel.ld build/initcode build/fs.img - cp -f build/initcode initcode - cp -f build/fs.img fs.img - $(call LINK_BIN, kernel.ld, kernel.elf, \ - $(addprefix build/,$(KERN_OBJS)), \ - initcode fs.img) - $(OBJDUMP) -S kernel.elf > kernel.asm - $(OBJDUMP) -t kernel.elf | sed '1,/SYMBOL TABLE/d; s/ .* / /; /^$$/d' > kernel.sym - rm -f initcode fs.img - -qemu: kernel.elf - @clear - @echo "Press Ctrl-A and then X to terminate QEMU session\n" - $(QEMU) -M versatilepb -m 128 -cpu arm1176 -nographic -kernel kernel.elf - -INITCODE_OBJ = initcode.o -$(addprefix build/,$(INITCODE_OBJ)): initcode.S - $(call build-directory) - $(call AS_WITH, -nostdinc -I.) - -#initcode is linked into the kernel, it will be used to craft the first process -build/initcode: $(addprefix build/,$(INITCODE_OBJ)) - $(call LINK_INIT, -N -e start -Ttext 0) - $(call OBJCOPY_INIT) - $(OBJDUMP) -S $< > initcode.asm - -build/fs.img: - make -C tools - make -C usr - -clean: - rm -rf build - rm -f *.o *.d *.asm *.sym vectors.S bootblock entryother \ - initcode initcode.out kernel xv6.img fs.img kernel.elf memfs - make -C tools clean - make -C usr clean
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/Makefile.osx Fri Jun 07 17:30:15 2019 +0900 @@ -0,0 +1,75 @@ +# specify path to QEMU, installed with MacPorts +QEMU = qemu-system-arm + +include makefile-osx.inc + +# link the libgcc.a for __aeabi_idiv. ARM has no native support for div +LIBS = $(LIBGCC) + +OBJS = \ + lib/string.o \ + \ + arm.o\ + asm.o\ + bio.o\ + buddy.o\ + console.o\ + exec.o\ + file.o\ + fs.o\ + log.o\ + main.o\ + memide.o\ + pipe.o\ + proc.o\ + spinlock.o\ + start.o\ + swtch.o\ + syscall.o\ + sysfile.o\ + sysproc.o\ + trap_asm.o\ + trap.o\ + vm.o \ + \ + device/picirq.o \ + device/timer.o \ + device/uart.o + +KERN_OBJS = $(OBJS) entry-osx.o +kernel.elf: $(addprefix build/,$(KERN_OBJS)) kernel.ld build/initcode build/fs.img + cp -f build/initcode initcode + cp -f build/fs.img fs.img + $(call LINK_BIN, kernel.ld, kernel.elf, \ + $(addprefix build/,$(KERN_OBJS)), \ + initcode fs.img) + $(OBJDUMP) -S kernel.elf > kernel.asm + $(OBJDUMP) -t kernel.elf | sed '1,/SYMBOL TABLE/d; s/ .* / /; /^$$/d' > kernel.sym + rm -f initcode fs.img + +qemu: kernel.elf + @clear + @echo "Press Ctrl-A and then X to terminate QEMU session\n" + $(QEMU) -M versatilepb -m 128 -cpu arm1176 -nographic -kernel kernel.elf + +INITCODE_OBJ = initcode.o +$(addprefix build/,$(INITCODE_OBJ)): initcode.S + $(call build-directory) + $(call AS_WITH, -nostdinc -I.) + +#initcode is linked into the kernel, it will be used to craft the first process +build/initcode: $(addprefix build/,$(INITCODE_OBJ)) + $(call LINK_INIT, -e start ) + $(call OBJCOPY_INIT) + $(OBJDUMP) -S $< > initcode.asm + +build/fs.img: + make -C tools + make -C usr + +clean: + rm -rf build + rm -f *.o *.d *.asm *.sym vectors.S bootblock entryother \ + initcode initcode.out kernel xv6.img fs.img kernel.elf memfs + make -C tools clean + make -C usr clean
--- a/src/console.c Mon Dec 17 19:48:57 2018 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,294 +0,0 @@ -// Console input and output. -// Input is from the keyboard or serial port. -// Output is written to the screen and serial port. - -#include "types.h" -#include "defs.h" -#include "param.h" -#include "spinlock.h" -#include "fs.h" -#include "file.h" -#include "memlayout.h" -#include "mmu.h" -#include "proc.h" - -static void consputc (int); - -static int panicked = 0; - -static struct { - struct spinlock lock; - int locking; -} cons; - -static void printint (int xx, int base, int sign) -{ - static char digits[] = "0123456789abcdef"; - char buf[16]; - int i; - uint x; - - if (sign && (sign = xx < 0)) { - x = -xx; - } else { - x = xx; - } - - i = 0; - - do { - buf[i++] = digits[x % base]; - } while ((x /= base) != 0); - - if (sign) { - buf[i++] = '-'; - } - - while (--i >= 0) { - consputc(buf[i]); - } -} -//PAGEBREAK: 50 - -// Print to the console. only understands %d, %x, %p, %s. -void cprintf (char *fmt, ...) -{ - int i, c, locking; - uint *argp; - char *s; - - locking = cons.locking; - - if (locking) { - acquire(&cons.lock); - } - - if (fmt == 0) { - panic("null fmt"); - } - - argp = (uint*) (void*) (&fmt + 1); - - for (i = 0; (c = fmt[i] & 0xff) != 0; i++) { - if (c != '%') { - consputc(c); - continue; - } - - c = fmt[++i] & 0xff; - - if (c == 0) { - break; - } - - switch (c) { - case 'd': - printint(*argp++, 10, 1); - break; - - case 'x': - case 'p': - printint(*argp++, 16, 0); - break; - - case 's': - if ((s = (char*) *argp++) == 0) { - s = "(null)"; - } - - for (; *s; s++) { - consputc(*s); - } - break; - - case '%': - consputc('%'); - break; - - default: - // Print unknown % sequence to draw attention. - consputc('%'); - consputc(c); - break; - } - } - - if (locking) { - release(&cons.lock); - } -} - -void panic (char *s) -{ - cli(); - - cons.locking = 0; - - cprintf("cpu%d: panic: ", cpu->id); - - show_callstk(s); - panicked = 1; // freeze other CPU - - while (1) - ; -} - -//PAGEBREAK: 50 -#define BACKSPACE 0x100 -#define CRTPORT 0x3d4 - -void consputc (int c) -{ - if (panicked) { - cli(); - while (1) - ; - } - - if (c == BACKSPACE) { - uartputc('\b'); - uartputc(' '); - uartputc('\b'); - } else { - uartputc(c); - } - - // cgaputc(c); -} - -#define INPUT_BUF 512 -struct { - struct spinlock lock; - char buf[INPUT_BUF]; - uint r; // Read index - uint w; // Write index - uint e; // Edit index -} input; - -#define C(x) ((x)-'@') // Control-x -void consoleintr (int (*getc) (void)) -{ - int c; - - acquire(&input.lock); - - while ((c = getc()) >= 0) { - switch (c) { - case C('P'): // Process listing. - procdump(); - break; - - case C('U'): // Kill line. - while ((input.e != input.w) && (input.buf[(input.e - 1) % INPUT_BUF] != '\n')) { - input.e--; - consputc(BACKSPACE); - } - - break; - - case C('H'): - case '\x7f': // Backspace - if (input.e != input.w) { - input.e--; - consputc(BACKSPACE); - } - - break; - - default: - if ((c != 0) && (input.e - input.r < INPUT_BUF)) { - c = (c == '\r') ? '\n' : c; - - input.buf[input.e++ % INPUT_BUF] = c; - consputc(c); - - if (c == '\n' || c == C('D') || input.e == input.r + INPUT_BUF) { - input.w = input.e; - wakeup(&input.r); - } - } - - break; - } - } - - release(&input.lock); -} - -int consoleread (struct inode *ip, char *dst, int n) -{ - uint target; - int c; - - iunlock(ip); - - target = n; - acquire(&input.lock); - - while (n > 0) { - while (input.r == input.w) { - if (proc->killed) { - release(&input.lock); - ilock(ip); - return -1; - } - - sleep(&input.r, &input.lock); - } - - c = input.buf[input.r++ % INPUT_BUF]; - - if (c == C('D')) { // EOF - if (n < target) { - // Save ^D for next time, to make sure - // caller gets a 0-byte result. - input.r--; - } - - break; - } - - *dst++ = c; - --n; - - if (c == '\n') { - break; - } - } - - release(&input.lock); - ilock(ip); - - return target - n; -} - -int consolewrite (struct inode *ip, char *buf, int n) -{ - int i; - - iunlock(ip); - - acquire(&cons.lock); - - for (i = 0; i < n; i++) { - consputc(buf[i] & 0xff); - } - - release(&cons.lock); - - ilock(ip); - - return n; -} - -void consoleinit (void) -{ - initlock(&cons.lock, "console"); - initlock(&input.lock, "input"); - - devsw[CONSOLE].write = consolewrite; - devsw[CONSOLE].read = consoleread; - - cons.locking = 1; -} -
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/console.cbc Fri Jun 07 17:30:15 2019 +0900 @@ -0,0 +1,393 @@ +// Console input and output. +// Input is from the keyboard or serial port. +// Output is written to the screen and serial port. + +#include "types.h" +#include "defs.h" +#include "param.h" +#include "spinlock.h" +#include "fs.h" +#include "file.h" +#include "memlayout.h" +#include "mmu.h" +#include "proc.h" + +__code cbc_consoleread1 (); +__code cbc_consoleread2 (); + +static void consputc (int); + +static int panicked = 0; + +static struct { + struct spinlock lock; + int locking; +} cons; + +static void printint (int xx, int base, int sign) +{ + static char digits[] = "0123456789abcdef"; + char buf[16]; + int i; + uint x; + + if (sign && (sign = xx < 0)) { + x = -xx; + } else { + x = xx; + } + + i = 0; + + do { + buf[i++] = digits[x % base]; + } while ((x /= base) != 0); + + if (sign) { + buf[i++] = '-'; + } + + while (--i >= 0) { + consputc(buf[i]); + } +} +//PAGEBREAK: 50 + +// Print to the console. only understands %d, %x, %p, %s. +void cprintf (char *fmt, ...) +{ + int i, c, locking; + uint *argp; + char *s; + + locking = cons.locking; + + if (locking) { + acquire(&cons.lock); + } + + if (fmt == 0) { + panic("null fmt"); + } + + argp = (uint*) (void*) (&fmt + 1); + + for (i = 0; (c = fmt[i] & 0xff) != 0; i++) { + if (c != '%') { + consputc(c); + continue; + } + + c = fmt[++i] & 0xff; + + if (c == 0) { + break; + } + + switch (c) { + case 'd': + printint(*argp++, 10, 1); + break; + + case 'x': + case 'p': + printint(*argp++, 16, 0); + break; + + case 's': + if ((s = (char*) *argp++) == 0) { + s = "(null)"; + } + + for (; *s; s++) { + consputc(*s); + } + break; + + case '%': + consputc('%'); + break; + + default: + // Print unknown % sequence to draw attention. + consputc('%'); + consputc(c); + break; + } + } + + if (locking) { + release(&cons.lock); + } +} + +__code cbc_panic (char *s) +{ + cli(); + + cons.locking = 0; + + cprintf("cpu%d: panic: ", cpu->id); + + show_callstk(s); + panicked = 1; // freeze other CPU + + while (1) + ; +} + +void panic (char *s) +{ + cli(); + + cons.locking = 0; + + cprintf("cpu%d: panic: ", cpu->id); + + show_callstk(s); + panicked = 1; // freeze other CPU + + while (1) + ; +} + +//PAGEBREAK: 50 +#define BACKSPACE 0x100 +#define CRTPORT 0x3d4 + +void consputc (int c) +{ + if (panicked) { + cli(); + while (1) + ; + } + + if (c == BACKSPACE) { + uartputc('\b'); + uartputc(' '); + uartputc('\b'); + } else { + uartputc(c); + } + + // cgaputc(c); +} + +#define INPUT_BUF 512 +struct { + struct spinlock lock; + char buf[INPUT_BUF]; + uint r; // Read index + uint w; // Write index + uint e; // Edit index +} input; + +#define C(x) ((x)-'@') // Control-x +void consoleintr (int (*getc) (void)) +{ + int c; + + acquire(&input.lock); + + while ((c = getc()) >= 0) { + switch (c) { + case C('P'): // Process listing. + procdump(); + break; + + case C('U'): // Kill line. + while ((input.e != input.w) && (input.buf[(input.e - 1) % INPUT_BUF] != '\n')) { + input.e--; + consputc(BACKSPACE); + } + + break; + + case C('H'): + case '\x7f': // Backspace + if (input.e != input.w) { + input.e--; + consputc(BACKSPACE); + } + + break; + + default: + if ((c != 0) && (input.e - input.r < INPUT_BUF)) { + c = (c == '\r') ? '\n' : c; + + input.buf[input.e++ % INPUT_BUF] = c; + consputc(c); + + if (c == '\n' || c == C('D') || input.e == input.r + INPUT_BUF) { + input.w = input.e; + wakeup(&input.r); + } + } + + break; + } + } + + release(&input.lock); +} + +__code cbc_consoleread2 () +{ + struct inode *ip = proc->cbc_arg.cbc_console_arg.ip; + __code(*next)(int ret) = proc->cbc_arg.cbc_console_arg.next; + if (input.r == input.w) { + if (proc->killed) { + release(&input.lock); + ilock(ip); + goto next(-1); + } + goto cbc_sleep(&input.r, &input.lock, cbc_consoleread2); + } + goto cbc_consoleread1(); +} + +__code cbc_consoleread1 () +{ + int cont = 1; + int n = proc->cbc_arg.cbc_console_arg.n; + int target = proc->cbc_arg.cbc_console_arg.target; + char* dst = proc->cbc_arg.cbc_console_arg.dst; + struct inode *ip = proc->cbc_arg.cbc_console_arg.ip; + __code(*next)(int ret) = proc->cbc_arg.cbc_console_arg.next; + + int c = input.buf[input.r++ % INPUT_BUF]; + + if (c == C('D')) { // EOF + if (n < target) { + // Save ^D for next time, to make sure + // caller gets a 0-byte result. + input.r--; + } + cont = 0; + } + + *dst++ = c; + --n; + + if (c == '\n') { + cont = 0; + } + + if (cont == 1) { + if (n > 0) { + proc->cbc_arg.cbc_console_arg.n = n; + proc->cbc_arg.cbc_console_arg.target = target; + proc->cbc_arg.cbc_console_arg.dst = dst; + proc->cbc_arg.cbc_console_arg.ip = ip; + proc->cbc_arg.cbc_console_arg.next = next; + goto cbc_sleep(&input.r, &input.lock, cbc_consoleread2); + } + } + + release(&input.lock); + ilock(ip); + + goto next(target - n); +} + +__code cbc_consoleread (struct inode *ip, char *dst, int n, __code(*next)(int ret)) +{ + uint target; + + iunlock(ip); + + target = n; + acquire(&input.lock); + + if (n > 0) { + proc->cbc_arg.cbc_console_arg.n = n; + proc->cbc_arg.cbc_console_arg.target = target; + proc->cbc_arg.cbc_console_arg.dst = dst; + proc->cbc_arg.cbc_console_arg.ip = ip; + proc->cbc_arg.cbc_console_arg.next = next; + goto cbc_consoleread2(); + } + goto cbc_consoleread1(); +} + +int consoleread (struct inode *ip, char *dst, int n) +{ + uint target; + int c; + + iunlock(ip); + + target = n; + acquire(&input.lock); + + while (n > 0) { + while (input.r == input.w) { + if (proc->killed) { + release(&input.lock); + ilock(ip); + return -1; + } + + sleep(&input.r, &input.lock); + } + + c = input.buf[input.r++ % INPUT_BUF]; + + if (c == C('D')) { // EOF + if (n < target) { + // Save ^D for next time, to make sure + // caller gets a 0-byte result. + input.r--; + } + + break; + } + + *dst++ = c; + --n; + + if (c == '\n') { + break; + } + } + + release(&input.lock); + ilock(ip); + + return target - n; +} + +int consolewrite (struct inode *ip, char *buf, int n) +{ + int i; + + iunlock(ip); + + acquire(&cons.lock); + + for (i = 0; i < n; i++) { + consputc(buf[i] & 0xff); + } + + release(&cons.lock); + + ilock(ip); + + return n; +} + +void consoleinit (void) +{ + initlock(&cons.lock, "console"); + initlock(&input.lock, "input"); + + devsw[CONSOLE].write = consolewrite; + devsw[CONSOLE].read = consoleread; + //cbc_devsw[CONSOLE].write = cbc_consolewrite; + cbc_devsw[CONSOLE].read = cbc_consoleread; + + cons.locking = 1; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/context.h Fri Jun 07 17:30:15 2019 +0900 @@ -0,0 +1,457 @@ +/* Context definition for llrb example */ +#ifndef CONTEXT_H +#define CONTEXT_H +#ifdef CBCXV6 + +#else +#include <stdlib.h> +#include <pthread.h> +#endif +#ifdef USE_CUDAWorker +#include <cuda.h> +#include <driver_types.h> +#include <cuda_runtime.h> +#include "helper_cuda.h" +#endif + +#define ALLOCATE_SIZE 20000000 +#define NEW(type) (type*)(calloc(1, sizeof(type))) +#define NEWN(n, type) (type*)(calloc(n, sizeof(type))) + +#define ALLOC_DATA(context, dseg) ({\ + Meta* meta = (Meta*)context->heap;\ + meta->type = D_##dseg;\ + meta->size = sizeof(dseg);\ + meta->len = 1;\ + context->heap += sizeof(Meta);\ + context->data[D_##dseg] = context->heap; context->heap += sizeof(dseg); (dseg *)context->data[D_##dseg]; }) + +#define ALLOC_DATA_TYPE(context, dseg, t) ({\ + Meta* meta = (Meta*)context->heap;\ + meta->type = D_##t;\ + meta->size = sizeof(t);\ + meta->len = 1;\ + context->heap += sizeof(Meta);\ + context->data[D_##dseg] = context->heap; context->heap += sizeof(t); (t *)context->data[D_##dseg]; }) + +#define ALLOCATE(context, t) ({ \ + Meta* meta = (Meta*)context->heap;\ + context->heap += sizeof(Meta);\ + union Data* data = context->heap; \ + context->heap += sizeof(t); \ + meta->type = D_##t; \ + meta->size = sizeof(t); \ + meta->len = 1;\ + data; }) + +#define ALLOCATE_ARRAY(context, t, length) ({ \ + Meta* meta = (Meta*)context->heap;\ + context->heap += sizeof(Meta);\ + union Data* data = context->heap; \ + context->heap += sizeof(t)*length; \ + meta->type = D_##t; \ + meta->size = sizeof(t)*length; \ + meta->len = length; \ + data; }) + +#define ALLOCATE_PTR_ARRAY(context, dseg, length) ({\ + Meta* meta = (Meta*)context->heap;\ + context->heap += sizeof(Meta);\ + union Data* data = context->heap; \ + context->heap += sizeof(dseg *)*length; \ + meta->type = D_##dseg; \ + meta->size = sizeof(dseg *)*length; \ + meta->len = length; \ + data; }) + +#define ALLOCATE_DATA_GEAR(context, t) ({ \ + union Data* data = ALLOCATE(context, t); \ + Meta* meta = GET_META(data); \ + meta->wait = createSynchronizedQueue(context); \ + data; }) + +#define ALLOC(context, t) (&ALLOCATE(context, t)->t) + +#define GET_META(dseg) ((Meta*)(((void*)dseg) - sizeof(Meta))) +#define GET_TYPE(dseg) (GET_META(dseg)->type) +#define GET_SIZE(dseg) (GET_META(dseg)->size) +#define GET_LEN(dseg) (GET_META(dseg)->len) +#define GET_WAIT_LIST(dseg) (GET_META(dseg)->wait) + +#define Gearef(context, t) (&(context)->data[D_##t]->t) + +// (SingleLinkedStack *)context->data[D_Stack]->Stack.stack->Stack.stack + +#define GearImpl(context, intf, name) (Gearef(context, intf)->name->intf.name) + +#include "c/enumCode.h" + +enum Relational { + EQ, + GT, + LT, +}; + +#include "c/enumData.h" + +struct Context { + enum Code next; + struct Worker* worker; + struct TaskManager* taskManager; + int codeNum; + __code (**code) (struct Context*); + union Data **data; + void* heapStart; + void* heap; + long heapLimit; + int dataNum; + + // task parameter + int idgCount; //number of waiting dataGear + int idg; + int maxIdg; + int odg; + int maxOdg; + int gpu; // GPU task + struct Context* task; + struct Element* taskList; +#ifdef USE_CUDAWorker + int num_exec; + CUmodule module; + CUfunction function; +#endif + /* multi dimension parameter */ + int iterate; + struct Iterator* iterator; + enum Code before; +}; + +typedef int Int; +#ifndef USE_CUDAWorker +typedef unsigned long long CUdeviceptr; +#endif +union Data { + struct Meta { + enum DataType type; + long size; + long len; + struct Queue* wait; // tasks waiting this dataGear + } Meta; + struct Context Context; + struct Timer { + union Data* timer; + enum Code start; + enum Code end; + enum Code next; + } Timer; + struct TimerImpl { + double time; + } TimerImpl; + struct LoopCounter { + int i; + } LoopCounter; + struct TaskManager { + union Data* taskManager; + enum Code spawn; // start NEW context on the worker + enum Code spawnTasks; // start NEW tasks on the worker + enum Code shutdown; + enum Code incrementTaskCount; + enum Code decrementTaskCount; + enum Code next; + enum Code next1; + enum Code setWaitTask; + struct Context* task; + struct Element* taskList; + union Data* data; + } TaskManager; + struct TaskManagerImpl { + enum Code next; + int numWorker; + int sendCPUWorkerIndex; + int sendGPUWorkerIndex; + int taskCount; + pthread_mutex_t mutex; + struct Queue* activeQueue; + struct Worker** workers; + struct Element* taskList; + int loopCounter; + int cpu; + int gpu; + int io; + int maxCPU; + } TaskManagerImpl; + struct Worker { + union Data* worker; + enum Code taskReceive; + enum Code shutdown; + enum Code next; + struct Queue* tasks; + pthread_t thread; + struct TaskManager* taskManager; + struct Context* task; + } Worker; + struct CPUWorker { + pthread_mutex_t mutex; + pthread_cond_t cond; + struct Context* context; + int id; + int loopCounter; + } CPUWorker; +#ifdef USE_CUDAWorker + struct CUDAWorker { + CUdevice device; + CUcontext cuCtx; + struct Context* context; + int id; + int loopCounter; + int deviceNum; + struct Queue* tasks; + int runFlag; + enum Code next; + int numStream; + struct Executor* executor; + CUstream *stream; + } CUDAWorker; +#else + struct CUDAWorker { + } CUDAWorker; +#endif + struct Main { + enum Code code; + enum Code next; + struct Queue* args; + } Main; + // Queue Interface + struct Queue { + union Data* queue; + union Data* data; + enum Code whenEmpty; + enum Code clear; + enum Code put; + enum Code take; + enum Code isEmpty; + enum Code next; + } Queue; + struct SingleLinkedQueue { + struct Element* top; + struct Element* last; + } SingleLinkedQueue; + struct SynchronizedQueue { + struct Element* top; + struct Element* last; + struct Atomic* atomic; + } SynchronizedQueue; + // Stack Interface + struct Stack { + union Data* stack; + union Data* data; + union Data* data1; + enum Code whenEmpty; + enum Code clear; + enum Code push; + enum Code pop; + enum Code pop2; + enum Code isEmpty; + enum Code get; + enum Code get2; + enum Code next; + } Stack; + // Stack implementations + struct SingleLinkedStack { + struct Element* top; + } SingleLinkedStack; + struct ArrayStack { + int size; + int limit; + struct Element* array; + } ArrayStack; + // Stack implementation end + struct Element { + union Data* data; + struct Element* next; + } Element; + struct Array { + int prefix; + Int* array; + } Array; + struct Tree { + union Data* tree; + struct Node* node; + enum Code put; + enum Code get; + enum Code remove; + enum Code clear; + enum Code next; + } Tree; + struct RedBlackTree { + struct Node* root; + struct Node* current; // reading node of original tree + struct Node* previous; // parent of reading node of original tree + struct Node* newNode; // writing node of new tree + struct Node* parent; + struct Node* grandparent; + struct Stack* nodeStack; + enum Code findNodeNext; + int result; + } RedBlackTree; + struct RotateTree { + enum Code next; + struct RedBlackTree* traverse; + struct Tree* tree; + } RotateTree; + struct Node { + int key; // comparable data segment + union Data* value; + struct Node* left; + struct Node* right; + // need to balancing + enum Color { + Red, + Black, + // Red eq 0,Black eq 1. enum name convert intager. + } color; + } Node; + struct Atomic { + union Data* atomic; + union Data** ptr; + union Data* oldData; + union Data* newData; + enum Code checkAndSet; + enum Code next; + enum Code fail; + } Atomic; + struct AtomicReference { + } AtomicReference; + struct Semaphore { + union Data* semaphore; + enum Code p; + enum Code v; + enum Code next; + } Semaphore; + struct SemaphoreImpl { + int value; + struct Lock* lock; + struct Queue* waitThreadQueue; + } SemaphoreImpl; + struct Allocate { + enum Code next; + long size; + } Allocate; + struct Integer { + int value; + } Integer; + struct SortArray { + struct Integer *array; //Array arrayじゃできない? + int loopCounter; + int block; + int first; + int prefix; + } SortArray; + struct Iterator { + union Data* iterator; + struct Context* task; + int numGPU; + enum Code exec; + enum Code barrier; + enum Code whenWait; + enum Code next; + } Iterator; + struct MultiDimIterator { + int x; + int y; + int z; + int count; + int counterX; + int counterY; + int counterZ; + } MultiDimIterator; + struct MultiDim { + int x; + int y; + int z; + } MultiDim; + struct Executor { + union Data* executor; + struct Context* task; + enum Code read; + enum Code exec; + enum Code write; + enum Code next; + } Executor; +#ifdef USE_CUDAWorker + struct CUDAExecutor { + CUdeviceptr** kernelParams; + struct CUDABuffer* buffer; + int maxThreadPerBlock; + int maxThreadPerBlockX; + int maxThreadPerBlockY; + int maxThreadPerBlockZ; + struct Timer* timer; + } CUDAExecutor; + struct CUDABuffer { + int inputLen; + int outputLen; + union Data** inputData; + union Data** outputData; + } CUDABuffer; + CUdeviceptr CUdeviceptr; +#else + struct CUDAExecutor { + } CUDAExecutor; + struct CUDABuffer { + } CUDABuffer; + CUdeviceptr CUdeviceptr; +#endif + Int Int; + struct Memory { + union Data* adr; + int length; + union Data* body; + int hash; + } Memory; + struct Buffer { + union Data* buffer; + union Data* data; + enum Code put; + enum Code take; + enum Code next; + } Buffer; + struct BoundedBuffer { + struct Element* top; + struct Element* last; + struct Semaphore* fullCount; + struct Semaphore* emptyCount; + struct Semaphore* lock; + } BoundedBuffer; + struct Lock { + union Data* lock; + enum Code doLock; + enum Code doUnlock; + enum Code next; + } Lock; + struct LockImpl { + Int* lock; + struct Queue* waitThreadQueue; + struct Atomic* atomic; + struct Context* lockContext; + } LockImpl; + struct SpinLock { + volatile Int* lock; + struct Atomic* atomic; + struct Context* lockContext; + } SpinLock; +}; // union Data end this is necessary for context generator +typedef union Data Data; + +#include "c/typedefData.h" + +#include "c/extern.h" + +extern __code start_code(struct Context* context); +extern __code exit_code(struct Context* context); +extern __code meta(struct Context* context, enum Code next); +//extern __code par_meta(struct Context* context, enum Code spawns, enum Code next); +extern __code parGotoMeta(struct Context* context, enum Code next); +extern void initContext(struct Context* context); + +#endif
--- a/src/defs.h Mon Dec 17 19:48:57 2018 +0900 +++ b/src/defs.h Fri Jun 07 17:30:15 2019 +0900 @@ -59,6 +59,7 @@ void consoleinit(void); void cprintf(char*, ...); void consoleintr(int(*)(void)); +__code cbc_panic(char*) __attribute__((noreturn)); void panic(char*) __attribute__((noreturn)); // exec.c @@ -69,6 +70,7 @@ void fileclose(struct file*); struct file* filedup(struct file*); void fileinit(void); +__code cbc_fileread (struct file*, char*, int, __code (*)(int)); int fileread(struct file*, char*, int n); int filestat(struct file*, struct stat*); int filewrite(struct file*, char*, int n); @@ -88,6 +90,7 @@ int namecmp(const char*, const char*); struct inode* namei(char*); struct inode* nameiparent(char*, char*); +__code cbc_readi (struct inode*, char*, uint, uint, __code (*)(int)); int readi(struct inode*, char*, uint, uint); void stati(struct inode*, struct stat*); int writei(struct inode*, char*, uint, uint); @@ -118,6 +121,7 @@ int pipealloc(struct file**, struct file**); void pipeclose(struct pipe*, int); int piperead(struct pipe*, char*, int); +__code cbc_piperead(struct pipe*, char*, int, __code (*)(int)); int pipewrite(struct pipe*, char*, int); //PAGEBREAK: 16 @@ -131,9 +135,11 @@ void procdump(void); void scheduler(void) __attribute__((noreturn)); void sched(void); +__code cbc_sleep(void*, struct spinlock*, __code(*next1)()); void sleep(void*, struct spinlock*); void userinit(void); int wait(void); +__code cbc_wakeup(void*, __code(*next1)()); void wakeup(void*); void yield(void); @@ -161,6 +167,7 @@ int argstr(int, char**); int fetchint(uint, int*); int fetchstr(uint, char**); +__code cbc_ret(int); void syscall(void); // timer.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/entry-clang.S Fri Jun 07 17:30:15 2019 +0900 @@ -0,0 +1,34 @@ +#include "arm.h" +#include "memlayout.h" + +.text +.code 32 + +.global _start + +_start: + # clear the entry bss section, the svc stack, and kernel page table + LDR r1, =edata_entry + LDR r2, =end_entry + MOV r3, #0x00 + +1: + CMP r1, r2 +# STMLTIA r1!, {r3} + STMIALT r1!, {r3} + BLT 1b + + # initialize stack pointers for svc modes + MSR CPSR_cxsf, #(SVC_MODE|NO_INT) + LDR sp, =svc_stktop + + BL start + B . + +# during startup, kernel stack uses user address, now switch it to kernel addr +.global jump_stack +jump_stack: + MOV r0, sp + ADD r0, r0, #KERNBASE + MOV sp, r0 + MOV pc, lr
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/entry-osx.S Fri Jun 07 17:30:15 2019 +0900 @@ -0,0 +1,33 @@ +#include "arm.h" +#include "memlayout.h" + +.text +.code 32 + +.global _start + +_start: + # clear the entry bss section, the svc stack, and kernel page table + LDR r1, =edata_entry + LDR r2, =end_entry + MOV r3, #0x00 + +1: + CMP r1, r2 + STMIALT r1!, {r3} + BLT 1b + + # initialize stack pointers for svc modes + MSR CPSR_cxsf, #(SVC_MODE|NO_INT) + LDR sp, =svc_stktop + + BL start + B . + +# during startup, kernel stack uses user address, now switch it to kernel addr +.global jump_stack +jump_stack: + MOV r0, sp + ADD r0, r0, #KERNBASE + MOV sp, r0 + MOV pc, lr
--- a/src/entry.S Mon Dec 17 19:48:57 2018 +0900 +++ b/src/entry.S Fri Jun 07 17:30:15 2019 +0900 @@ -15,6 +15,7 @@ 1: CMP r1, r2 STMLTIA r1!, {r3} +# STMIALT r1!, {r3} BLT 1b # initialize stack pointers for svc modes @@ -30,4 +31,4 @@ MOV r0, sp ADD r0, r0, #KERNBASE MOV sp, r0 - MOV pc, lr \ No newline at end of file + MOV pc, lr
--- a/src/exec.c Mon Dec 17 19:48:57 2018 +0900 +++ b/src/exec.c Fri Jun 07 17:30:15 2019 +0900 @@ -13,7 +13,7 @@ struct elfhdr elf; struct inode *ip; struct proghdr ph; - pde_t *pgdir; + pde_t *pgdir = 0; pde_t *oldpgdir; char *s; char *last; @@ -39,8 +39,6 @@ goto bad; } - pgdir = 0; - if ((pgdir = kpt_alloc()) == 0) { goto bad; }
--- a/src/file.c Mon Dec 17 19:48:57 2018 +0900 +++ b/src/file.c Fri Jun 07 17:30:15 2019 +0900 @@ -8,8 +8,11 @@ #include "fs.h" #include "file.h" #include "spinlock.h" +#include "proc.h" struct devsw devsw[NDEV]; +struct cbc_devsw cbc_devsw[NDEV]; + struct { struct spinlock lock; struct file file[NFILE]; @@ -98,6 +101,36 @@ return -1; } +__code cbc_fileread1 (int r) +{ + struct file *f = proc->cbc_arg.cbc_console_arg.f; + __code (*next)(int ret) = cbc_ret; + if (r > 0) + f->off += r; + iunlock(f->ip); + goto next(r); +} + +__code cbc_fileread (struct file *f, char *addr, int n, __code (*next)(int ret)) +{ + if (f->readable == 0) { + goto next(-1); + } + + if (f->type == FD_PIPE) { + goto cbc_piperead(f->pipe, addr, n, next); + goto next(-1); + } + + if (f->type == FD_INODE) { + ilock(f->ip); + proc->cbc_arg.cbc_console_arg.f = f; + goto cbc_readi(f->ip, addr, f->off, n, cbc_fileread1); + } + + goto cbc_panic("fileread"); +} + // Read from file f. int fileread (struct file *f, char *addr, int n) {
--- a/src/file.h Mon Dec 17 19:48:57 2018 +0900 +++ b/src/file.h Fri Jun 07 17:30:15 2019 +0900 @@ -33,6 +33,12 @@ int (*write)(struct inode*, char*, int); }; +struct cbc_devsw { + __code (*read) (struct inode*, char*, int, __code (*)(int)); + //__code (*write)(struct inode*, char*, int, __code (*)(int)); +}; + extern struct devsw devsw[]; +extern struct cbc_devsw cbc_devsw[]; #define CONSOLE 1
--- a/src/fs.c Mon Dec 17 19:48:57 2018 +0900 +++ b/src/fs.c Fri Jun 07 17:30:15 2019 +0900 @@ -453,6 +453,37 @@ st->size = ip->size; } +__code cbc_readi (struct inode *ip, char *dst, uint off, uint n, __code (*next)(int ret)) +{ + uint tot, m; + struct buf *bp; + + if (ip->type == T_DEV) { + if (ip->major < 0 || ip->major >= NDEV || !cbc_devsw[ip->major].read) { + goto next(-1); + } + + goto cbc_devsw[ip->major].read(ip, dst, n, next); + } + + if (off > ip->size || off + n < off) { + goto next(-1); + } + + if (off + n > ip->size) { + n = ip->size - off; + } + + for (tot = 0; tot < n; tot += m, off += m, dst += m) { + bp = bread(ip->dev, bmap(ip, off / BSIZE)); + m = min(n - tot, BSIZE - off%BSIZE); + memmove(dst, bp->data + off % BSIZE, m); + brelse(bp); + } + + goto next(n); +} + //PAGEBREAK! // Read data from inode. int readi (struct inode *ip, char *dst, uint off, uint n)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/gearsTools/generate_context.pl Fri Jun 07 17:30:15 2019 +0900 @@ -0,0 +1,228 @@ +#!/usr/bin/perl + +use Getopt::Std; +use strict; + +# +# generrate Gears OS context heaader and initializer from CbC sources +# +# CodeGear +# +# get stub information from # *.c +# __code taskManager_stub(struct Context* context) { +# +# generate CodeGear indexn in context.h +# C_taskManager, +# +# generate CodeGear stub reference in context.h +# extern __code taskManager_stub(struct Context*); +# +# generate CodeGear stub reference in $name-context.h for each module +# context->code[C_taskManager] = taskManager_stub; +# +# DataGear +# +# get DataGear information from context.h +# struct Worker { +# int id; +# struct Context* contexts; +# enum Code execute; +# enum Code taskSend; +# enum Code taskRecive; +# enum Code shutdown; +# struct Queue* tasks; +# } Worker; +# +# generate typedefs and DataGear index in context.h +# typedef struct Worker Worker; +# D_Worker, +# +# generate DataGear allocator in context.h +# ALLOC_DATA(context, Worker); +# + +my $ddir = "c"; + +our($opt_o,$opt_d,$opt_h); +getopts('o:d:h'); + +my $name = $opt_o?$opt_o:"gears"; + +if ($opt_d) { + $ddir = $opt_d; +} + +if ( ! -d $ddir) { + mkdir $ddir; +} + +if ($opt_h) { + print "$0 [-d distdir] [-h]\n"; + exit; +} + +my %codeGear; +my %dataGear; +my %constructor; + +# gather module Information for code table initialization +for (@ARGV) { + next if (/context.c/); + &getStubInfo($_); +} + +my (%mCodeGear) = (%codeGear); + +# anyway we gather all Gears Information +while (<*.c test/*.c>) { + next if (/context.c/); + &getStubInfo($_); +} + +&generateContext(); + +sub getStubInfo { + my ($filename) = @_; + open my $fd,"<",$filename or die("can't open $filename $!"); + while (<$fd>) { + if (/^__code (\w+)_stub\(struct *Context *\* *context\)/) { + $codeGear{$1} = $filename; + } elsif (/^(\w+)(\*)+ *create(\w+)\(([^]]*)\)/) { + my $interface = $1; + my $implementation = $3; + my $constructorArgs = $4; + $constructor{$implementation} = [$interface, $constructorArgs]; + } + } + + open my $cx,"<","context.h" or die("can't open context.h $!"); + my $inUnionData = 0; + while (<$cx>) { + if (! $inUnionData) { + if ( /^union Data/) { + $inUnionData = 1; + } + next; + } + last if (/union Data end/); + if (/struct (\w+) \{/) { + $dataGear{$1} = 'struct'; + } elsif (/^\s{4}(\w+) (\w+);/) { # primitive type + $dataGear{$1} = 'primitive'; + } + $dataGear{"Context"} = "struct"; + } +} + +sub generateContext { + $codeGear{"start_code"} = "$ddir/$name-context.c"; + $codeGear{"exit_code"} = "$ddir/$name-context.c"; + $mCodeGear{"start_code"} = "$ddir/$name-context.c"; + $mCodeGear{"exit_code"} = "$ddir/$name-context.c"; + open my $fd,">","$ddir/extern.h" or die("can't open $ddir/extern.h $!"); + for my $code ( sort keys %codeGear ) { + print $fd "extern __code ${code}_stub(struct Context*);\n"; + } + for my $impl ( sort keys %constructor ) { + my ($interface, $constructorArgs) = @{$constructor{$impl}}; + print $fd "extern ${interface}* create${impl}($constructorArgs);\n"; + } + print $fd "\n"; + + open my $fd,">","$ddir/enumCode.h" or die("can't open $ddir/enumCode.h $!"); + print $fd "enum Code {\n"; + for my $code ( sort keys %codeGear ) { + print $fd " C_${code},\n"; + } + print $fd "};\n"; + + my $code_init = ''; + for my $code ( sort keys %mCodeGear ) { + $code_init .= " context->code[C_${code}] = ${code}_stub;\n"; + } + + my $data_num = keys(%dataGear); + $data_num++; +my $context_c = << "EOFEOF"; +#ifndef CBCXV6 +#include <stdlib.h> +#endif + +#include "../context.h" + +void initContext(struct Context* context) { + context->heapLimit = sizeof(union Data)*ALLOCATE_SIZE; + context->code = (__code(**) (struct Context*)) NEWN(ALLOCATE_SIZE, void*); + context->data = NEWN(ALLOCATE_SIZE, union Data*); + context->heapStart = NEWN(context->heapLimit, char); + context->heap = context->heapStart; + // context->codeNum = Exit; + +$code_init + +#include "dataGearInit.c" + context->dataNum = $data_num; +} +EOFEOF + + open my $fd,">","$ddir/$name-context.c" or die("can't open $ddir/$name-context.c $!"); + print $fd $context_c; + +my $meta_call = <<"EOFEOF"; +__code meta(struct Context* context, enum Code next) { + // printf("meta %d\\n",next); + goto (context->code[next])(context); +} + +__code parGotoMeta(struct Context* context, enum Code next) { + context->task = NULL; + context->taskList = NULL; + goto (context->code[Gearef(context, TaskManager)->taskManager->TaskManager.spawnTasks])(context); +} + +__code start_code(struct Context* context) { + goto meta(context, context->next); +} + +__code start_code_stub(struct Context* context) { + goto start_code(context); +} + +__code exit_code(struct Context* context) { + free(context->code); + free(context->data); + free(context->heapStart); + goto exit(0); +} + +__code exit_code_stub(struct Context* context) { + goto exit_code(context); +} + +// end context_c +EOFEOF + +print $fd $meta_call; + +open my $fd,">","$ddir/enumData.h" or die("can't open $ddir/enumData.h $!"); +print $fd "enum DataType {\n"; +print $fd " D_Code,\n"; +for my $data ( sort keys %dataGear ) { + print $fd " D_${data},\n"; +} +print $fd "};\n\n"; + +open my $fd,">","$ddir/typedefData.h" or die("can't open $ddir/typedefData.h $!"); +for my $data ( sort keys %dataGear ) { + if ($dataGear{$data} eq 'struct') { + print $fd "typedef struct ${data} ${data};\n"; + } +} + +open my $fd,">","$ddir/dataGearInit.c" or die("can't open $ddir/dataGearInit.c $!"); +for my $data ( sort keys %dataGear ) { + print $fd " ALLOC_DATA(context, ${data});\n"; +} +} + +# end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/gearsTools/generate_stub.pl Fri Jun 07 17:30:15 2019 +0900 @@ -0,0 +1,636 @@ +#!/usr/bin/perl + +use strict; +use Getopt::Std; +use File::Path qw(make_path); + +# interface.h +# typedef struct Worker { +# int id; +# struct Context* contexts; +# enum Code execute; +# enum Code taskSend; +# enum Code taskRecive; +# enum Code shutdown; +# struct Queue* tasks; +# } Worker; + +our($opt_o,$opt_d,$opt_h); +getopts('o:d:h'); + +my $dir = "."; +if ($opt_d) { + $dir = $opt_d; + if (! -d $dir) { + make_path $dir; + } +} + +for my $fn (@ARGV) { + next if ($fn !~ /\.cbc$/); + &getDataGear($fn); + &generateDataGear($fn); +} + +my %var; +my %code; +my %dataGearVar; +my %outputVar; # output var initializer +my %outputArgs; # continuation's output variables +my %dataGear; +my %dataGearName; +my %generic; +my %dataGearVarType; +my %codeGear; +my $implementation; +my $interface; + +# interface definision +# +# typedef struct Stack<Type, Impl>{ +# Type* stack; +# Type* data; +# Type* data1; +# __code whenEmpty(...); +# __code clear(Impl* stack,__code next(...)); +# __code push(Impl* stack,Type* data, __code next(...)); +# __code pop(Impl* stack, __code next(Type*, ...)); +# __code pop2(Impl* stack, Type** data, Type** data1, __code next(Type**, Type**, ...)); +# __code isEmpty(Impl* stack, __code next(...), __code whenEmpty(...)); +# __code get(Impl* stack, Type** data, __code next(...)); +# __code get2(Impl* stack,..., __code next(...)); +# __code next(...); +# } Stack; +# +# calling example +# +# goto nodeStack->push((union Data*)node, stackTest3); +# +# generated meta level code +# +# Gearef(context, Stack)->stack = (union Data*)nodeStack; +# Gearef(context, Stack)->data = (union Data*)node; +# Gearef(context, Stack)->next = C_stackTest3; +# goto meta(context, nodeStack->push); + +sub getDataGear { + my ($filename) = @_; + my ($codeGearName, $name, $inTypedef); + open my $fd,"<",$filename or die("can't open $filename $!"); + while (<$fd>) { + if (! $inTypedef) { + if (/^typedef struct (\w+)\s*<(.*)>/) { + $inTypedef = 1; + $name = $1; + $dataGear{$name} = $_; + $var{$name} = {}; + $code{$name} = {}; + $generic{$name} = \split(/,/,$2); + } elsif (/^typedef struct (\w+)/) { + $inTypedef = 1; + $name = $1; + $dataGear{$name} = $_; + $var{$name} = {}; + $code{$name} = {}; + $generic{$name} = []; + } elsif (/^(\w+)(\*)+ create(\w+)\(/) { + if (defined $interface) { + die "duplicate interface $interface\n"; + } + $interface = $1; + $implementation = $3; + if ( -f "$interface.cbc") { + &getDataGear("$interface.cbc"); + } + } elsif(/^(.*)par goto (\w+)\((.*)\)/) { + my $codeGearName = $2; + if ($filename =~ /^(.*)\/(.*)/) { + $codeGearName = "$1/$codeGearName"; + } + if ( -f "$codeGearName.cbc") { + &getCodeGear("$codeGearName.cbc"); + } + } elsif(/^#interface "(.*)"/) { + # use interface + my $interfaceHeader = $1; + next if ($interfaceHeader =~ /context.h/); + if (-f $interfaceHeader) { + &getDataGear("$interfaceHeader"); + &getCodeGear("$interfaceHeader"); + } + } elsif (/^\_\_code (\w+)\((.*)\)(.*)/) { + my $codeGearName = $1; + if ($filename =~ /^(.*)\/(.*)/) { + $codeGearName = "$1/$codeGearName"; + } + if ( -f "$codeGearName.cbc") { + &getCodeGear("$codeGearName.cbc"); + } + } + next; + } + # gather type name and type + $dataGear{$name} .= $_; + if (/^\s*(.*)\s+(\w+);$/ ) { + my $ttype = $1; + my $tname = $2; + if ($ttype =~ /^(union|struct)?\s*(\w+)/) { + $ttype = $2; + } + $var{$name}->{$tname} = $ttype; + } + if (/^}/) { + $inTypedef = 0; + } + } + +} + +sub getCodeGear { + my ($filename) = @_; + open my $fd,"<",$filename or die("can't open $filename $!"); + my ($name,$impln); + while (<$fd>) { + if (/^(\w+)(\*)+ create(\w+)\(/) { + $name = $1; + $impln = $3; + } elsif(/^typedef struct (.*)<.*>\s*{/) { + $name = $1; + } + if (defined $name) { + if (/^\s*\_\_code (\w+)\((.*)\);/) { + my $args = $2; + my $method = $1; + $code{$name}->{$method} = []; + while($args) { + # replace comma + $args =~ s/(^\s*,\s*)//; + # continuation case + if ($args =~ s/^(\s)*\_\_code\s+(\w+)\(([^)]*)\)//) { + my $next = $2; + my @args = split(/,/,$3); + push(@{$code{$name}->{$method}},"\_\_code $next"); + } elsif ($args =~ s/^(struct|union)?\s*(\w+)(\**)\s+(\w+)//) { + my $structType = $1; + my $typeName = $2; + my $ptrType = $3; + my $varName = $4; + my $typeField = lcfirst($typeName); + push(@{$code{$name}->{$method}},"$typeName$ptrType $varName"); + } elsif ($args =~ s/(.*,)//) { + } else { + last; + } + } + } + } elsif (/^\_\_code (\w+)\((.*)\)(.*)/) { + my $codeGearName = $1; + my $args = $2; + my $inputCount = 0; + my $outputCount = 0; + my $inputIncFlag = 1; + while($args) { + if ($args =~ s/(^\s*,\s*)//) { + } + if ($args =~ s/^(\s)*\_\_code\s+(\w+)\((.*?)\)//) { + $codeGear{$codeGearName}->{"code"}->{$2} = "\_\_code"; + $inputIncFlag = 0; + my @outputs = split(/,/,$3); + for my $output (@outputs) { + if ($output =~ /\s*(struct|union)?\s*(\w+)(\*)?+\s(\w+)/) { + my $type = $2; + my $varName = $4; + $codeGear{$codeGearName}->{"var"}->{$varName} = "$type $outputCount"; + $outputCount++; + } + } + } elsif ($args =~ s/^(struct|union)?\s*(\w+)(\*)?+\s(\w+)// && $inputIncFlag) { + my $type = $2; + my $varName = $4; + $codeGear{$codeGearName}->{"var"}->{$varName} = "$type $inputCount"; + $inputCount++; + } elsif ($args =~ s/(.*,)//) { + } else { + last; + } + } + $codeGear{$codeGearName}->{"input"} = $inputCount; + $codeGear{$codeGearName}->{"output"} = $outputCount; + } + } +} + +sub generateStub { + my($fd,$prevCodeGearName,$dataGearName) = @_; + print $fd "__code ", $prevCodeGearName ,"_stub(struct Context* context) {\n"; + print $fd $dataGearName; + print $fd "\n} \n\n"; + return 1; +} + +sub generateStubArgs { + my($codeGearName, $varName, $typeName, $ptrType, $typeField, $interface,$output) = @_; + my $varname1 = $output?"O_$varName":$varName; + for my $n ( @{$dataGearVar{$codeGearName}} ) { + # we already have it + return 0 if ( $n eq $varname1); + } + push @{$dataGearVar{$codeGearName}}, $varname1; + push @{$dataGearVarType{$codeGearName}}, $typeName; + if ($typeName eq $implementation) { + # get implementation + $dataGearName{$codeGearName} .= "\t$typeName* $varName = ($typeName*)GearImpl(context, $interface, $varName);\n"; + } else { + # interface var + for my $ivar (keys %{$var{$interface}}) { + # input data gear field + if ($varName eq $ivar) { + if ($typeName eq $var{$interface}->{$ivar}) { + if ($output) { + $dataGearName{$codeGearName} .= "\t$typeName$ptrType* O_$varName = &Gearef(context, $interface)->$varName;\n"; + $outputVar{$codeGearName} .= "\t$typeName$ptrType $varName = *O_$varName;\n"; + return 1; + } + $dataGearName{$codeGearName} .= "\t$typeName$ptrType $varName = Gearef(context, $interface)->$varName;\n"; + return 1; + } + } + } + + # interface continuation + for my $cName (keys %{$code{$interface}}) { + if ($varName eq $cName) { + # continuation field + $dataGearName{$codeGearName} .= "\tenum Code $varName = Gearef(context, $interface)->$varName;\n"; + return 1; + } + } + + # par goto var + for my $var (keys %{$codeGear{$codeGearName}->{"var"}}) { + # input data gear field + if ($varName eq $var) { + my ($type, $count) = split(/\s/, $codeGear{$codeGearName}->{"var"}->{$var}); + if ($typeName eq $type) { + if ($output) { + $dataGearName{$codeGearName} .= "\t$typeName$ptrType* O_$varName = ($typeName $ptrType*)&context->data[context->odg + $count];\n"; + $outputVar{$codeGearName} .= "\t$typeName$ptrType $varName = *O_$varName;\n"; + return 1; + } + $dataGearName{$codeGearName} .= "\t$typeName$ptrType $varName = &context->data[context->idg + $count]->$typeName;\n"; + return 1; + } + } + } + + # par goto continuation + for my $cName (keys %{$codeGear{$codeGearName}->{"code"}}) { + if ($varName eq $cName) { + # continuation field + $dataGearName{$codeGearName} .= "\tenum Code $varName = context->next;\n"; + return 1; + } + } + + # par goto continuation + # global or local variable case + if ($typeName eq "Code") { + $dataGearName{$codeGearName} .= "\tenum $typeName$ptrType $varName = Gearef(context, $interface)->$varName;\n"; + return 1; + } + $dataGearName{$codeGearName} .= "\t$typeName$ptrType $varName = Gearef(context, $typeName);\n"; + return 1; + } +} + +sub generateDataGear { + my ($filename) = @_; + open my $in,"<",$filename or die("can't open $filename $!"); + + my $fn; + if ($opt_o) { + $fn = $opt_o; + } else { + my $fn1 = $filename; + $fn1 =~ s/\.cbc/.c/; + my $i = 1; + $fn = "$dir/$fn1"; + while ( -f $fn) { + $fn = "$dir/$fn1.$i"; + $i++; + } + } + if ( $fn =~ m=(.*)/[^/]+$= ) { + if (! -d $1) { + make_path $1; + } + } + open my $fd,">",$fn or die("can't write $fn $!"); + + my $prevCodeGearName; + my $inTypedef = 0; + my $inStub = 0; + my $hasParGoto = 0; + my $inMain = 0 ; + my %stub; + my $codeGearName; + my %localVarType; + + while (<$in>) { + if (! $inTypedef && ! $inStub && ! $inMain) { + if (/^typedef struct (\w+) \{/) { + $inTypedef = 1; + } elsif (/^int main\((.*)\) \{/) { + $inMain = 1; + } elsif(/^#interface "(.*)"/) { + my $interfaceHeader = $1; + # #interface not write + next unless ($interfaceHeader =~ /context.h/); + } elsif (/^\_\_code (\w+)\((.*)\)(.*)/) { + %localVarType = {}; + $codeGearName = $1; + my $args = $2; + my $tail = $3; + if ($codeGearName =~ /_stub$/) { + # don't touch already existing stub + $inStub = 1; + $stub{$codeGearName} = 1; + print $fd $_; + next; + } + if (defined $prevCodeGearName) { + # stub is generated just before next CodeGear + if (defined $stub{$prevCodeGearName."_stub"}) { + undef $prevCodeGearName; + } else { + &generateStub($fd,$prevCodeGearName,$dataGearName{$prevCodeGearName}); + $stub{$prevCodeGearName."_stub"} = 1; + } + } + # analyzing CodeGear argument + # these arguments are extract from current context's arugment DataGear Interface + # and passed to the CodeGear + # struct Implementaion needs special handling + # __code next(...) ---> enum Code next + $prevCodeGearName = $codeGearName; + $dataGearVar{$codeGearName} = []; + $outputVar{$codeGearName} = ""; + $outputArgs{$codeGearName} = {}; + my $newArgs = "struct Context *context,"; + if ($args=~/^struct Context\s*\*\s*context/) { + $newArgs = ""; + } + if (!$args){ + $newArgs = "struct Context *context"; + } + while($args) { + if ($args =~ s/(^\s*,\s*)//) { + $newArgs .= $1; + } + # continuation case + if ($args =~ s/^(\s)*\_\_code\s+(\w+)\(([^)]*)\)//) { + my $next = $2; + my @args = split(/,/,$3); + if (&generateStubArgs($codeGearName, $next, "Code", "", $next, $interface,0) ) { + $newArgs .= "enum Code $next"; + } + # analyze continuation arguments + # output arguments are defined in the Interface take the pointer of these + # output arguments are put into the Interface DataGear just before the goto + for my $arg (@args) { + $arg =~ s/^\s*//; + last if ($arg =~ /\.\.\./); + $arg =~ s/^(struct|union)?\s*(\w+)(\**)\s(\w+)//; + my $structType = $1; + my $typeName = $2; + my $ptrType = $3; + my $varName = $4; + my $typeField = lcfirst($typeName); + push(@{$outputArgs{$codeGearName}->{$next}}, $varName); + if (&generateStubArgs($codeGearName, $varName, $typeName, $ptrType, $typeField, $interface,1)) { + $newArgs .= ",$structType $typeName **O_$varName"; + } + } + } elsif ($args =~ s/^(struct|union)?\s*(\w+)(\**)\s(\w+)//) { + my $structType = $1; + my $typeName = $2; + my $ptrType = $3; + my $varName = $4; + my $typeField = lcfirst($typeName); + $newArgs .= $&; # assuming no duplicate + &generateStubArgs($codeGearName, $varName, $typeName, $ptrType, $typeField, $interface,0); + } elsif ($args =~ s/(.*,)//) { + $newArgs .= $1; + } else { + $newArgs .= $args; + last; + } + } + # generate goto statement from stub to the CodeGear in the buffer + $dataGearName{$codeGearName} .= "\tgoto $codeGearName(context"; + for my $arg ( @{$dataGearVar{$codeGearName}}) { + $dataGearName{$codeGearName} .= ", $arg"; + } + $dataGearName{$codeGearName} .= ");"; + # generate CodeGear header with new arguments + print $fd "__code $codeGearName($newArgs)$tail\n"; + if ($outputVar{$codeGearName} ne "") { + # output data var can be use before write + # it should be initialze by gearef + print $fd $outputVar{$codeGearName}; + } + next; + } elsif (/^(.*)goto (\w+)\-\>(\w+)\((.*)\);/) { + # handling goto statement + # convert it to the meta call form with two arugments, that is context and enum Code + my $prev = $1; + my $next = $2; + my $method = $3; + my $tmpArgs = $4; + $tmpArgs =~ s/\(.*\)/\(\)/; + my @args = split(/,/,$tmpArgs); + my @types = @{$dataGearVarType{$codeGearName}}; + my $ntype; + my $ftype; + for my $v (@{$dataGearVar{$codeGearName}}) { + my $t = shift @types; + if ($v eq $next || $v eq "O_$next") { + $ntype = $t; + $ftype = lcfirst($ntype); + } + } + if (!defined $ntype) { + $ntype = $localVarType{$next}; + $ftype = lcfirst($ntype); + } + print $fd "\tGearef(context, $ntype)->$ftype = (union Data*) $next;\n"; + # Put interface argument + my $prot = $code{$ntype}->{$method}; + my $i = 1; + for my $arg (@args) { + my $pType; + my $pName; + my $p = @$prot[$i]; + next if ($p eq $arg); + $p =~ s/^(.*)\s(\w+)//; + $pType = $1; + $pName = $2; + $arg =~ s/^(\s)*(\w+)/$2/; + if ($pType =~ s/\_\_code$//) { + if ($arg =~ /(\w+)\(.*\)/) { + print $fd "\tGearef(context, $ntype)->$pName = $1;\n"; + } else { + print $fd "\tGearef(context, $ntype)->$pName = C_$arg;\n"; + } + } elsif ($pType =~ /Data\**$/){ + print $fd "\tGearef(context, $ntype)->$pName = (union $pType) $arg;\n"; + } else { + print $fd "\tGearef(context, $ntype)->$pName = $arg;\n"; + } + $i++; + } + print $fd "${prev}context->before = C_$codeGearName;\n"; + print $fd "${prev}goto meta(context, $next->$method);\n"; + next; + } elsif(/^(.*)par goto (\w+)\((.*)\);/) { + # handling par goto statement + # convert it to the parallel + my $prev = $1; + my $codeGearName = $2; + my $args = $3; + my $inputCount = $codeGear{$codeGearName}->{'input'}; + my $outputCount = $codeGear{$codeGearName}->{'output'}; + my @iterateCounts; + # parse examples 'par goto(.., iterate(10), exit);' + if ($args =~ /iterate\((.*)?\),/) { + @iterateCounts = split(/,/,$1);; + $inputCount--; + } + # replace iterate keyword + $args =~ s/iterate\((.*)?\),//; + my @dataGears = split(/,\s*/, $args); + my $nextCodeGear = pop(@dataGears); + if (! $hasParGoto) { + $hasParGoto = 1; + print $fd "${prev}struct Element* element;\n"; + } + my $initTask = << "EOFEOF"; + ${prev}context->task = NEW(struct Context); + ${prev}initContext(context->task); + ${prev}context->task->next = C_$codeGearName; + ${prev}context->task->idgCount = $inputCount; + ${prev}context->task->idg = context->task->dataNum; + ${prev}context->task->maxIdg = context->task->idg + $inputCount; + ${prev}context->task->odg = context->task->maxIdg; + ${prev}context->task->maxOdg = context->task->odg + $outputCount; +EOFEOF + print $fd $initTask; + if (@iterateCounts) { + print $fd "${prev}context->task->iterate = 0;\n"; + my $len = @iterateCounts; + if ($len == 1) { + print $fd "${prev}context->task->iterator = createMultiDimIterator(context, $iterateCounts[0], 1, 1);\n"; + } elsif ($len == 2) { + print $fd "${prev}context->task->iterator = createMultiDimIterator(context, $iterateCounts[0], $iterateCounts[1], 1);\n"; + } elsif ($len == 3) { + print $fd "${prev}context->task->iterator = createMultiDimIterator(context, $iterateCounts[0], $iterateCounts[1], $iterateCounts[2]);\n"; + } + } + for my $dataGear (@dataGears) { + print $fd "${prev}GET_META($dataGear)->wait = createSynchronizedQueue(context);\n"; + } + for my $i (0..$inputCount-1) { + print $fd "${prev}context->task->data[context->task->idg+$i] = (union Data*)@dataGears[$i];\n"; + } + for my $i (0..$outputCount-1) { + print $fd "${prev}context->task->data[context->task->odg+$i] = (union Data*)@dataGears[$inputCount+$i];\n"; + } + my $putTask = << "EOFEOF"; + ${prev}element = &ALLOCATE(context, Element)->Element; + ${prev}element->data = (union Data*)context->task; + ${prev}element->next = context->taskList; + ${prev}context->taskList = element; +EOFEOF + print $fd $putTask; + next; + } elsif (/^(.*)goto (\w+)\((.*)\);/) { + # handling goto statement + # convert it to the meta call form with two arugments, that is context and enum Code + my $prev = $1; + my $next = $2; + my @args = split(/,/, $3); + my $v = 0; + for my $n ( @{$dataGearVar{$codeGearName}} ) { + # continuation arguments + $v = 1 if ( $n eq $next); + } + if ($v || defined $code{$interface}->{$next}) { + # write continuation's arguments into the interface arguments + # we may need a commit for a shared DataGear + for my $arg ( @{$outputArgs{$codeGearName}->{$next}} ) { + my $v = shift(@args); + print $fd "\t*O_$arg = $v;\n"; + } + if ($hasParGoto) { + print $fd "${prev}Gearef(context, TaskManager)->taskList = context->taskList;\n"; + print $fd "${prev}Gearef(context, TaskManager)->next1 = C_$next;\n"; + print $fd "${prev}goto meta(context, C_$next);\n"; + } else { + print $fd "${prev}context->before = C_$codeGearName;\n"; + print $fd "${prev}goto meta(context, $next);\n"; + } + next; + } + if ($hasParGoto) { + print $fd "${prev}Gearef(context, TaskManager)->taskList = context->taskList;\n"; + print $fd "${prev}Gearef(context, TaskManager)->next1 = C_$next;\n"; + print $fd "${prev}goto parGotoMeta(context, C_$next);\n"; + next; + } elsif ($next eq "meta") { + print $fd $_; + next; + } else { + print $fd "${prev}context->before = C_$codeGearName;\n"; + print $fd "${prev}goto meta(context, C_$next);\n"; + next; + } + } elsif(/^.*(struct|union)?\s(\w+)\*\s(\w+)\s?[=;]/) { + my $type = $2; + my $varName = $3; + $localVarType{$varName} = $type; + s/new\s+(\w+)\(\)/\&ALLOCATE(context, \1)->\1/g; # replacing new + } elsif(/^}/) { + $hasParGoto = 0; + } else { + s/new\s+(\w+)\(\)/\&ALLOCATE(context, \1)->\1/g; # replacing new + } + # gather type name and type + } elsif ($inMain) { + if (/^(.*)goto start_code\(main_context\);/) { + print $fd $_; + next; + } elsif (/^(.*)goto (\w+)\((.*)\);/) { + my $prev = $1; + my $next = $2; + print $fd "${prev}struct Context* main_context = NEW(struct Context);\n"; + print $fd "${prev}initContext(main_context);\n"; + print $fd "${prev}main_context->next = C_$next;\n"; + print $fd "${prev}goto start_code(main_context);\n"; + next; + } + } + if (/^}/) { + $inStub = 0; + $inTypedef = 0; + $inMain = 0; + } + print $fd $_; + } + if (defined $prevCodeGearName) { + if (!defined $stub{$prevCodeGearName."_stub"}) { + $stub{$prevCodeGearName."_stub"} = &generateStub($fd,$prevCodeGearName,$dataGearName{$codeGearName}); + } + } +} + +# end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/kernel-clang.ld Fri Jun 07 17:30:15 2019 +0900 @@ -0,0 +1,78 @@ +OUTPUT_FORMAT("elf32-littlearm") +OUTPUT_ARCH(arm) +ENTRY(_start) + +ENTRY_SVC_STACK_SIZE = 0x1000; + +SECTIONS +{ + /* the entry point, before enabling paging. The code to enable paing + needs to have the same virtual/physical address. entry.S and start.c + run in this initial setting.*/ + . = 0x10000; + .start_sec : { + build/entry-clang.o(.text) + build/start.o(.text .text.*) + + build/entry-clang.o(.rodata .rodata.*) + build/start.o(.rodata .rodata.*) + + build/entry-clang.o(.data .data.*) + build/start.o(.data .data.*) + + PROVIDE(edata_entry = .); + + build/entry-clang.o(.bss .bss.* COMMON) + build/start.o(.bss .bss.* COMMON) + + /*define a stack for the entry*/ + . = ALIGN(0x1000); + . += ENTRY_SVC_STACK_SIZE; + + PROVIDE (svc_stktop = .); + + /* define the kernel page table, must be 16K and 16K-aligned*/ + . = ALIGN(0x4000); + PROVIDE (_kernel_pgtbl = .); + . += 0x4000; + + /* we also need a user page table*/ + PROVIDE (_user_pgtbl = .); + . += 0x1000; + + PROVIDE(end_entry = .); + } + + /*the kernel executes at the higher 2GB address space, but loaded + at the lower memory (0x20000)*/ + . = 0x80020000; + + .text : AT(0x20000){ + *(.text .text.* .gnu.linkonce.t.*) + } + + PROVIDE(etext = .); /* Define the 'etext' symbol to this value */ + + .rodata : { + *(.rodata .rodata.* .gnu.linkonce.r.*) + } + + /* aligned the data to a (4K) page, so it can be assigned + different protection than the code*/ + . = ALIGN(0x1000); + + PROVIDE (data_start = .); + + .data : { + *(.data .data.*) + } + + PROVIDE (edata = .); + + .bss : { + *(.bss .bss.* COMMON) + } + + . = ALIGN(0x1000); + PROVIDE (end = .); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/makefile-armclang Fri Jun 07 17:30:15 2019 +0900 @@ -0,0 +1,96 @@ +# specify path to QEMU, installed with MacPorts +QEMU = qemu-system-arm + +CPU = armv8 +QEMUCPU = cortex-a15 +include makefile.inc +CC = /usr/local/cbclang/bin/clang +AS = arm-linux-gnu-as +LD = arm-linux-gnu-ld +OBJCOPY = arm-linux-gnu-objcopy +OBJDUMP = arm-linux-gnu-objdump + +# CFLAGS = -march=${CPU} -fno-pic -static -fno-builtin -fno-strict-aliasing -Wall -Werror -I. -g -O0 +CFLAGS = -target ${CPU}-linux-gnueabihf -march=${CPU} -fno-pic -static -fno-builtin -fno-strict-aliasing -Wall -I. -I ../cbclang/arm -g -O0 +LDFLAGS = --noinhibit-exec +# ASFLAGS = -march=${CPU} +ASFLAGS = -target ${CPU}-linux-gnueabihf + +LIBGCC = $(shell $(CC) $(CFLAGS) -print-libgcc-file-name) + +# link the libgcc.a for __aeabi_idiv. ARM has no native support for div +LIBS =/net/open/RaspberryPi/rasbian-img/usr/lib/gcc/arm-linux-gnueabihf/6/libgcc.a + + +OBJS = \ + lib/string.o \ + \ + arm.o\ + asm.o\ + bio.o\ + buddy.o\ + console.o\ + exec.o\ + file.o\ + fs.o\ + log.o\ + main.o\ + memide.o\ + pipe.o\ + proc.o\ + spinlock.o\ + start.o\ + swtch.o\ + syscall.o\ + sysfile.o\ + sysproc.o\ + trap_asm.o\ + trap.o\ + vm.o \ + \ + device/picirq.o \ + device/timer.o \ + device/uart.o + +KERN_OBJS = $(OBJS) entry-clang.o +kernel.elf: $(addprefix build/,$(KERN_OBJS)) kernel-clang.ld build/initcode build/fs.img + cp -f build/initcode initcode + cp -f build/fs.img fs.img + $(call LINK_BIN, kernel-clang.ld, kernel.elf, \ + $(addprefix build/,$(KERN_OBJS)), \ + initcode fs.img) + $(OBJDUMP) -S kernel.elf > kernel.asm + $(OBJDUMP) -t kernel.elf | sed '1,/SYMBOL TABLE/d; s/ .* / /; /^$$/d' > kernel.sym + rm -f initcode fs.img + +qemu: kernel.elf + @clear + @echo "Press Ctrl-A and then X to terminate QEMU session\n" + export QEMU_AUDIO_DRV=none ; $(QEMU) -M versatilepb -m 128 -cpu ${QEMUCPU} -nographic -soundhw hda -kernel kernel.elf + +qemu-debug : kernel.elf + @clear + @echo "Press Ctrl-A and then X to terminate QEMU session\n" + export QEMU_AUDIO_DRV=none ; $(QEMU) -M versatilepb -m 128 -cpu ${QEMUCPU} -nographic -singlestep -d exec,cpu,guest_errors -D qemu.log -kernel kernel.elf -s -S + +INITCODE_OBJ = initcode.o +$(addprefix build/,$(INITCODE_OBJ)): initcode.S + $(call build-directory) + $(call AS_WITH, -nostdinc -I.) + +#initcode is linked into the kernel, it will be used to craft the first process +build/initcode: $(addprefix build/,$(INITCODE_OBJ)) + $(call LINK_INIT, -N -e start -Ttext 0) + $(call OBJCOPY_INIT) + $(OBJDUMP) -S $< > initcode.asm + +build/fs.img: + make -C tools + make -C usr + +clean: + rm -rf build + rm -f *.o *.d *.asm *.sym vectors.S bootblock entryother \ + initcode initcode.out kernel xv6.img fs.img kernel.elf memfs + make -C tools clean + make -C usr clean
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/makefile-armgcc4.8.5 Fri Jun 07 17:30:15 2019 +0900 @@ -0,0 +1,96 @@ +# specify path to QEMU, installed with MacPorts +QEMU = qemu-system-arm + +include makefile.inc + +CC = arm-linux-gnu-gcc +AS = arm-linux-gnu-as +LD = arm-linux-gnu-ld +OBJCOPY = arm-linux-gnu-objcopy +OBJDUMP = arm-linux-gnu-objdump + +CFLAGS = -fno-pic -static -fno-builtin -fno-strict-aliasing -Wall -I. -g -O0 + +ASFLAGS = + +LIBGCC = $(shell $(CC) -print-libgcc-file-name) + +LINK_BIN = $(call quiet-command,$(LD) $(LDFLAGS) \ + -T $(1) -o $(2) $(3) $(LIBS) -b binary $(4), " LINK $(TARGET_DIR)$@") + +LINK_INIT = $(call quiet-command,$(LD) $(LDFLAGS) \ + $(1) -o $@.out $<, " LINK $(TARGET_DIR)$@") +OBJCOPY_INIT = $(call quiet-command,$(OBJCOPY) \ + -S -O binary --prefix-symbols="_binary_$@" $@.out $@, " OBJCOPY $(TARGET_DIR)$@") + + +# link the libgcc.a for __aeabi_idiv. ARM has no native support for div +LIBS = $(LIBGCC) + +OBJS = \ + lib/string.o \ + \ + arm.o\ + asm.o\ + bio.o\ + buddy.o\ + console.o\ + exec.o\ + file.o\ + fs.o\ + log.o\ + main.o\ + memide.o\ + pipe.o\ + proc.o\ + spinlock.o\ + start.o\ + swtch.o\ + syscall.o\ + sysfile.o\ + sysproc.o\ + trap_asm.o\ + trap.o\ + vm.o \ + \ + device/picirq.o \ + device/timer.o \ + device/uart.o + +KERN_OBJS = $(OBJS) entry.o +kernel.elf: $(addprefix build/,$(KERN_OBJS)) kernel.ld build/initcode build/fs.img + cp -f build/initcode initcode + cp -f build/fs.img fs.img + $(call LINK_BIN, kernel.ld, kernel.elf, \ + $(addprefix build/,$(KERN_OBJS)), \ + initcode fs.img) + $(OBJDUMP) -S kernel.elf > kernel.asm + $(OBJDUMP) -t kernel.elf | sed '1,/SYMBOL TABLE/d; s/ .* / /; /^$$/d' > kernel.sym + rm -f initcode fs.img + +qemu: kernel.elf + @clear + @echo "Press Ctrl-A and then X to terminate QEMU session\n" + $(QEMU) -M versatilepb -m 128 -cpu arm1176 -nographic -kernel kernel.elf + +INITCODE_OBJ = initcode.o +$(addprefix build/,$(INITCODE_OBJ)): initcode.S + $(call build-directory) + $(call AS_WITH, -nostdinc -I.) + +#initcode is linked into the kernel, it will be used to craft the first process +build/initcode: $(addprefix build/,$(INITCODE_OBJ)) + $(call LINK_INIT, -N -e start -Ttext 0) + $(call OBJCOPY_INIT) + $(OBJDUMP) -S $< > initcode.asm + +build/fs.img: + make -C tools + make -C usr + +clean: + rm -rf build + rm -f *.o *.d *.asm *.sym vectors.S bootblock entryother \ + initcode initcode.out kernel xv6.img fs.img kernel.elf memfs + make -C tools clean + make -C usr clean
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/makefile-armgccbc Fri Jun 07 17:30:15 2019 +0900 @@ -0,0 +1,100 @@ +# specify path to QEMU, installed with MacPorts +QEMU = qemu-system-arm + +include makefile.inc + +CC = /mnt/dalmore-home/one/src/armgcc/cross/bin/arm-none-eabi-gcc -B/mnt/dalmore-home/one/src/armgcc/cross/bin/arm-none-eabi- +#AS = arm-linux-gnu-gcc +AS = /mnt/dalmore-home/one/src/armgcc/cross/bin/arm-none-eabi-gcc +#LD = arm-linux-gnu-ld +LD = /mnt/dalmore-home/one/src/armgcc/cross/bin/arm-none-eabi-ld +#OBJCOPY = arm-linux-gnu-objcopy +OBJCOPY = /mnt/dalmore-home/one/src/armgcc/cross/bin/arm-none-eabi-objcopy +#OBJDUMP = arm-linux-gnu-objdump +OBJDUMP = /mnt/dalmore-home/one/src/armgcc/cross/bin/arm-none-eabi-objdump +CFLAGS = -fno-pic -static -fno-builtin -fno-strict-aliasing -Wall -I. -g -O0 + +ASFLAGS = + +LIBGCC = $(shell $(CC) -print-libgcc-file-name) + +LINK_BIN = $(call quiet-command,$(LD) $(LDFLAGS) \ + -T $(1) -o $(2) $(3) $(LIBS) -b binary $(4), " LINK $(TARGET_DIR)$@") + +LINK_INIT = $(call quiet-command,$(LD) $(LDFLAGS) \ + $(1) -o $@.out $<, " LINK $(TARGET_DIR)$@") +OBJCOPY_INIT = $(call quiet-command,$(OBJCOPY) \ + -S -O binary --prefix-symbols="_binary_$@" $@.out $@, " OBJCOPY $(TARGET_DIR)$@") +AS_WITH = $(call quiet-command,$(AS) $(ASFLAGS) \ + $(1) -c -o $@ $<," AS $(TARGET_DIR)$@") + +# link the libgcc.a for __aeabi_idiv. ARM has no native support for div +LIBS = $(LIBGCC) + +OBJS = \ + lib/string.o \ + \ + arm.o\ + asm.o\ + bio.o\ + buddy.o\ + console.o\ + exec.o\ + file.o\ + fs.o\ + log.o\ + main.o\ + memide.o\ + pipe.o\ + proc.o\ + spinlock.o\ + start.o\ + swtch.o\ + syscall.o\ + sysfile.o\ + sysproc.o\ + trap_asm.o\ + trap.o\ + vm.o \ + \ + device/picirq.o \ + device/timer.o \ + device/uart.o + +KERN_OBJS = $(OBJS) entry.o +kernel.elf: $(addprefix build/,$(KERN_OBJS)) kernel.ld build/initcode build/fs.img + cp -f build/initcode initcode + cp -f build/fs.img fs.img + $(call LINK_BIN, kernel.ld, kernel.elf, \ + $(addprefix build/,$(KERN_OBJS)), \ + initcode fs.img) + $(OBJDUMP) -S kernel.elf > kernel.asm + $(OBJDUMP) -t kernel.elf | sed '1,/SYMBOL TABLE/d; s/ .* / /; /^$$/d' > kernel.sym + rm -f initcode fs.img + +qemu: kernel.elf + @clear + @echo "Press Ctrl-A and then X to terminate QEMU session\n" + $(QEMU) -M versatilepb -m 128 -cpu arm1176 -nographic -kernel kernel.elf + +INITCODE_OBJ = initcode.o +$(addprefix build/,$(INITCODE_OBJ)): initcode.S + $(call build-directory) + $(call AS_WITH, -nostdinc -I.) + +#initcode is linked into the kernel, it will be used to craft the first process +build/initcode: $(addprefix build/,$(INITCODE_OBJ)) + $(call LINK_INIT, -N -e start -Ttext 0) + $(call OBJCOPY_INIT) + $(OBJDUMP) -S $< > initcode.asm + +build/fs.img: + make -C tools + make -C usr -f makfile-armgccbc + +clean: + rm -rf build + rm -f *.o *.d *.asm *.sym vectors.S bootblock entryother \ + initcode initcode.out kernel xv6.img fs.img kernel.elf memfs + make -C tools clean + make -C usr clean
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/makefile-osx.inc Fri Jun 07 17:30:15 2019 +0900 @@ -0,0 +1,48 @@ +# Cross-compiling (e.g., on Mac OS X, install arm-none-eabi-gcc with MacPorts) +CROSSCOMPILE := + +CC = $(CROSSCOMPILE)/Users/one/src/cbclang-arm/build/bin/clang +AS = $(CROSSCOMPILE)as +LD = $(CROSSCOMPILE)ld +OBJCOPY = $(CROSSCOMPILE)objcopy +OBJDUMP = $(CROSSCOMPILE)objdump + +CFLAGS = -arch arm -fno-pic -static -fno-builtin -fno-strict-aliasing -Wall -Werror -I. -g -O0 \ + -Wno-macro-redefined -Wno-gnu-designator -Wno-sometimes-uninitialized -Wno-tautological-compare \ + -I/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/usr/include +LDFLAGS = -L. -arch armv7 +ASFLAGS = -arch arm + +LIBGCC = $(shell $(CC) -print-libgcc-file-name) + +# host compiler +HOSTCC_preferred = clang +define get_hostcc + $(if $(shell which $(HOSTCC_preferred)),$(HOSTCC_preferred),"cc") +endef +HOSTCC := $(call get_hostcc) + +# general rules +quiet-command = $(if $(V),$1,$(if $(2),@echo $2 && $1, @$1)) + +LINK_BIN = $(call quiet-command,$(LD) $(LDFLAGS) \ + -T $(1) -o $(2) $(3) $(LIBS) -b binary $(4), " LINK $(TARGET_DIR)$@") + +LINK_INIT = $(call quiet-command,$(LD) $(LDFLAGS) \ + $(1) -o $@.out $<, " LINK $(TARGET_DIR)$@") +OBJCOPY_INIT = $(call quiet-command,$(OBJCOPY) \ + -S -O binary --prefix-symbols="_binary_$@" $@.out $@, " OBJCOPY $(TARGET_DIR)$@") + +build-directory = $(shell mkdir -p build build/device build/lib) + +build/%.o: %.c + $(call build-directory) + $(call quiet-command,$(CC) $(CFLAGS) \ + -c -o $@ $<," CC $(TARGET_DIR)$@") + +AS_WITH = $(call quiet-command,$(CC) $(ASFLAGS) \ + $(1) -c -o $@ $<," AS $(TARGET_DIR)$@") + +build/%.o: %.S + $(call build-directory) + $(call AS_WITH, )
--- a/src/makefile.inc Mon Dec 17 19:48:57 2018 +0900 +++ b/src/makefile.inc Fri Jun 07 17:30:15 2019 +0900 @@ -1,20 +1,26 @@ # Cross-compiling (e.g., on Mac OS X, install arm-none-eabi-gcc with MacPorts) -CROSSCOMPILE := arm-none-eabi- + +CROSSCOMPILE := arm-linux-gnu- -CC = $(CROSSCOMPILE)gcc +CPU = armv8 +#CC = /usr/local/cbclang/bin/clang AS = $(CROSSCOMPILE)as LD = $(CROSSCOMPILE)ld OBJCOPY = $(CROSSCOMPILE)objcopy OBJDUMP = $(CROSSCOMPILE)objdump -CFLAGS = -march=armv6 -fno-pic -static -fno-builtin -fno-strict-aliasing -Wall -Werror -I. -g -O0 +# CFLAGS = -march=${CPU} -fno-pic -static -fno-builtin -fno-strict-aliasing -Wall -Werror -I. -g -O0 +CFLAGS = -target ${CPU}-none-eabi -I /net/open/Linux/arm/gcc-arm-none-eabi-7-2017-q4-major/arm-none-eabi/include/ /net/open/Linux/arm/gcc-arm-none-eabi-7-2017-q4-major/lib/gcc/arm-none-eabi/7.2.1/include-fixed/ -fno-pic -static -fno-builtin -fno-strict-aliasing -Wall -I. -g -O0 LDFLAGS = -L. -ASFLAGS = -march=armv6 +# ASFLAGS = -march=${CPU} +ASFLAGS = -target ${CPU}-none-eabi -LIBGCC = $(shell $(CC) -print-libgcc-file-name) +#LIBGCC = $(shell $(gcc) -print-libgcc-file-name) +LIBGCC = /net/open/Linux/arm/gcc-arm-none-eabi-7-2017-q4-major/lib/gcc/arm-none-eabi/7.2.1/libgcc.a # host compiler -HOSTCC_preferred = gcc + HOSTCC_preferred = gcc +#HOSTCC_preferred = /usr/local/cbclang/bin/clang define get_hostcc $(if $(shell which $(HOSTCC_preferred)),$(HOSTCC_preferred),"cc") endef @@ -38,6 +44,11 @@ $(call quiet-command,$(CC) $(CFLAGS) \ -c -o $@ $<," CC $(TARGET_DIR)$@") +build/%.o: %.cbc + $(call build-directory) + $(call quiet-command,$(CC) $(CFLAGS) \ + -c -o $@ $<," CC $(TARGET_DIR)$@") + AS_WITH = $(call quiet-command,$(CC) $(ASFLAGS) \ $(1) -c -o $@ $<," AS $(TARGET_DIR)$@")
--- a/src/pipe.c Mon Dec 17 19:48:57 2018 +0900 +++ b/src/pipe.c Fri Jun 07 17:30:15 2019 +0900 @@ -116,6 +116,59 @@ return n; } +__code cbc_piperead3(){ + struct pipe *p = proc->cbc_arg.cbc_console_arg.p; + int i = proc->cbc_arg.cbc_console_arg.i; + __code(*next)(int ret) = proc->cbc_arg.cbc_console_arg.next; + release(&p->lock); + + goto next(i); +} + +__code cbc_piperead2(){ + int i = proc->cbc_arg.cbc_console_arg.i; + int n = proc->cbc_arg.cbc_console_arg.n; + struct pipe *p = proc->cbc_arg.cbc_console_arg.p; + char *addr = proc->cbc_arg.cbc_console_arg.addr; + if (i < n && !(p->nread == p->nwrite)) { + addr[i] = p->data[p->nread++ % PIPESIZE]; + i ++; + proc->cbc_arg.cbc_console_arg.i = i; + proc->cbc_arg.cbc_console_arg.p = p; + proc->cbc_arg.cbc_console_arg.addr = addr; + goto cbc_piperead2(); + } + proc->cbc_arg.cbc_console_arg.p = p; + goto cbc_wakeup(&p->nwrite, cbc_piperead3); //DOC: piperead-wakeup +} + +__code cbc_piperead1(){ + struct pipe *p = proc->cbc_arg.cbc_console_arg.p; + __code(*next)(int ret) = proc->cbc_arg.cbc_console_arg.next; + if (p->nread == p->nwrite && p->writeopen){ + if(proc->killed){ + release(&p->lock); + goto next(-1); + } + proc->cbc_arg.cbc_console_arg.p = p; + goto cbc_sleep(&p->nread, &p->lock, cbc_piperead1); + } + int i = 0; + proc->cbc_arg.cbc_console_arg.i = i; + proc->cbc_arg.cbc_console_arg.p = p; + goto cbc_piperead2(); +} + +__code cbc_piperead(struct pipe *p, char *addr, int n, __code (*next)(int ret)) +{ + acquire(&p->lock); + proc->cbc_arg.cbc_console_arg.n = n; + proc->cbc_arg.cbc_console_arg.p = p; + proc->cbc_arg.cbc_console_arg.addr = addr; + proc->cbc_arg.cbc_console_arg.next = next; + goto cbc_piperead1(); +} + int piperead(struct pipe *p, char *addr, int n) { int i;
--- a/src/proc.c Mon Dec 17 19:48:57 2018 +0900 +++ b/src/proc.c Fri Jun 07 17:30:15 2019 +0900 @@ -196,7 +196,8 @@ np->sz = proc->sz; np->parent = proc; - *np->tf = *proc->tf; + // *np->tf = *proc->tf; // This generate memcpy4 which is not in libgcc.a + memmove(np->tf, proc->tf, sizeof(*np->tf)); // Clear r0 so that fork returns 0 in the child. np->tf->r0 = 0; @@ -352,6 +353,34 @@ } } +__code cbc_sched(__code(*next)()) +{ + int intena; + + if(!holding(&ptable.lock)) { + panic("sched ptable.lock"); + } + + if(cpu->ncli != 1) { + panic("sched locks"); + } + + if(proc->state == RUNNING) { + panic("sched running"); + } + + if(int_enabled ()) { + panic("sched interruptible"); + } + + intena = cpu->intena; + swtch(&proc->context, cpu->scheduler); + cpu->intena = intena; + + goto next(); +} + + // Enter scheduler. Must hold only ptable.lock // and have changed proc->state. void sched(void) @@ -410,6 +439,44 @@ // Return to "caller", actually trapret (see allocproc). } +__code cbc_sleep1() +{ + struct spinlock *lk = proc->lk; + // Tidy up. + proc->chan = 0; + + // Reacquire original lock. + if(lk != &ptable.lock){ //DOC: sleeplock2 + release(&ptable.lock); + acquire(lk); + } + goto proc->cbc_next(); +} + +__code cbc_sleep(void *chan, struct spinlock *lk, __code(*next1)()) +{ + //show_callstk("sleep"); + + if(proc == 0) { + panic("sleep"); + } + + if(lk == 0) { + panic("sleep without lk"); + } + + if(lk != &ptable.lock){ //DOC: sleeplock0 + acquire(&ptable.lock); //DOC: sleeplock1 + release(lk); + } + proc->chan = chan; + proc->state = SLEEPING; + proc->lk = lk; + proc->cbc_next = next1; + + goto cbc_sched(cbc_sleep1); +} + // Atomically release lock and sleep on chan. // Reacquires lock when awakened. void sleep(void *chan, struct spinlock *lk) @@ -461,6 +528,27 @@ } } +__code cbc_wakeup1(void *chan) +{ + struct proc *p; + + for(p = ptable.proc; p < &ptable.proc[NPROC]; p++) { + if(p->state == SLEEPING && p->chan == chan) { + p->state = RUNNABLE; + } + } + + release(&ptable.lock); + goto proc->cbc_next(); +} + +__code cbc_wakeup(void *chan, __code(*next1)()) +{ + acquire(&ptable.lock); + proc->cbc_next = next1; + cbc_wakeup1(chan); +} + // Wake up all processes sleeping on chan. void wakeup(void *chan) { @@ -501,12 +589,12 @@ void procdump(void) { static char *states[] = { - [UNUSED] "unused", - [EMBRYO] "embryo", - [SLEEPING] "sleep ", - [RUNNABLE] "runble", - [RUNNING] "run ", - [ZOMBIE] "zombie" + [UNUSED] ="unused", + [EMBRYO] ="embryo", + [SLEEPING] ="sleep ", + [RUNNABLE] ="runble", + [RUNNING] ="run ", + [ZOMBIE] ="zombie" }; struct proc *p;
--- a/src/proc.h Mon Dec 17 19:48:57 2018 +0900 +++ b/src/proc.h Fri Jun 07 17:30:15 2019 +0900 @@ -1,3 +1,4 @@ +#include "typedefData.h" #ifndef PROC_INCLUDE_ #define PROC_INCLUDE_ @@ -67,6 +68,22 @@ struct file* ofile[NOFILE]; // Open files struct inode* cwd; // Current directory char name[16]; // Process name (debugging) + union cbc_arg { + struct cbc_console_arg { + int n; + int target; + char* dst; + struct inode *ip; + struct file *f; + int num; + struct pipe *p; + char *addr; + int i; + __code (*next)(int ret); + } cbc_console_arg; + } cbc_arg; + __code (*cbc_next)(); + struct spinlock *lk; }; // Process memory is laid out contiguously, low addresses first:
--- a/src/spinlock.c Mon Dec 17 19:48:57 2018 +0900 +++ b/src/spinlock.c Fri Jun 07 17:30:15 2019 +0900 @@ -46,7 +46,60 @@ #endif } +/* +void cbc_acquire(struct spinlock *lk, __code (*next)(int ret)) +{ + pushcli(); // disable interrupts to avoid deadlock. + lk->locked = 1; // set the lock status to make the kernel happy + +#if 0 + if(holding(lk)) + panic("acquire"); + + // The xchg is atomic. + // It also serializes, so that reads after acquire are not + // reordered before it. + while(xchg(&lk->locked, 1) != 0) + ; + + // Record info about lock acquisition for debugging. + lk->cpu = cpu; + getcallerpcs(get_fp(), lk->pcs); + +#endif + goto next(); +} +*/ + +/* // Release the lock. +void cbc_release(struct spinlock *lk, __code (*next)(int ret)) +{ +#if 0 + if(!holding(lk)) + panic("release"); + + lk->pcs[0] = 0; + lk->cpu = 0; + + // The xchg serializes, so that reads before release are + // not reordered after it. The 1996 PentiumPro manual (Volume 3, + // 7.2) says reads can be carried out speculatively and in + // any order, which implies we need to serialize here. + // But the 2007 Intel 64 Architecture Memory Ordering White + // Paper says that Intel 64 and IA-32 will not move a load + // after a store. So lock->locked = 0 would work here. + // The xchg being asm volatile ensures gcc emits it after + // the above assignments (and after the critical section). + xchg(&lk->locked, 0); +#endif + + lk->locked = 0; // set the lock state to keep the kernel happy + popcli(); + goto next(); +} +*/ + void release(struct spinlock *lk) { #if 0
--- a/src/syscall.c Mon Dec 17 19:48:57 2018 +0900 +++ b/src/syscall.c Fri Jun 07 17:30:15 2019 +0900 @@ -115,30 +115,48 @@ extern int sys_write(void); extern int sys_uptime(void); +extern __code cbc_read(__code(*)(int)); + static int (*syscalls[])(void) = { - [SYS_fork] sys_fork, - [SYS_exit] sys_exit, - [SYS_wait] sys_wait, - [SYS_pipe] sys_pipe, - [SYS_read] sys_read, - [SYS_kill] sys_kill, - [SYS_exec] sys_exec, - [SYS_fstat] sys_fstat, - [SYS_chdir] sys_chdir, - [SYS_dup] sys_dup, - [SYS_getpid] sys_getpid, - [SYS_sbrk] sys_sbrk, - [SYS_sleep] sys_sleep, - [SYS_uptime] sys_uptime, - [SYS_open] sys_open, - [SYS_write] sys_write, - [SYS_mknod] sys_mknod, - [SYS_unlink] sys_unlink, - [SYS_link] sys_link, - [SYS_mkdir] sys_mkdir, - [SYS_close] sys_close, + [SYS_fork] =sys_fork, + [SYS_exit] =sys_exit, + [SYS_wait] =sys_wait, + [SYS_pipe] =sys_pipe, + [SYS_read] =sys_read, + [SYS_kill] =sys_kill, + [SYS_exec] =sys_exec, + [SYS_fstat] =sys_fstat, + [SYS_chdir] =sys_chdir, + [SYS_dup] =sys_dup, + [SYS_getpid] =sys_getpid, + [SYS_sbrk] =sys_sbrk, + [SYS_sleep] =sys_sleep, + [SYS_uptime] =sys_uptime, + [SYS_open] =sys_open, + [SYS_write] =sys_write, + [SYS_mknod] =sys_mknod, + [SYS_unlink] =sys_unlink, + [SYS_link] =sys_link, + [SYS_mkdir] =sys_mkdir, + [SYS_close] =sys_close, }; +static __code (*cbccodes[])(__code (*)(int)) = { + [SYS_cbc_read] = cbc_read, +}; + +__code cbc_trap_return(){ + return; +} + +__code cbc_ret(int ret){ + int num = proc->cbc_arg.cbc_console_arg.num; + if (num != SYS_exec) { + proc->tf->r0 = ret; + } + goto cbc_trap_return(); +} + void syscall(void) { int num; @@ -146,9 +164,17 @@ num = proc->tf->r0; + if (num == 5) + num = 22; //cprintf ("syscall(%d) from %s(%d)\n", num, proc->name, proc->pid); - if((num > 0) && (num <= NELEM(syscalls)) && syscalls[num]) { + if((num >= NELEM(syscalls)) && (num <= NELEM(cbccodes)) && cbccodes[num]) { + proc->cbc_arg.cbc_console_arg.num = num; + goto (cbccodes[num])(cbc_ret); + } + + + if((num > 0) && (num < NELEM(syscalls)) && syscalls[num]) { ret = syscalls[num](); // in ARM, parameters to main (argc, argv) are passed in r0 and r1
--- a/src/syscall.h Mon Dec 17 19:48:57 2018 +0900 +++ b/src/syscall.h Fri Jun 07 17:30:15 2019 +0900 @@ -20,3 +20,5 @@ #define SYS_link 19 #define SYS_mkdir 20 #define SYS_close 21 + +#define SYS_cbc_read 22
--- a/src/sysfile.c Mon Dec 17 19:48:57 2018 +0900 +++ b/src/sysfile.c Fri Jun 07 17:30:15 2019 +0900 @@ -74,6 +74,17 @@ return fd; } +__code cbc_read(__code (*next)(int ret)){ + struct file *f; + int n; + char *p; + + if(argfd(0, 0, &f) < 0 || argint(2, &n) < 0 || argptr(1, &p, n) < 0) { + goto next(-1); + } + goto cbc_fileread(f, p, n, next); +} + int sys_read(void) { struct file *f;
--- a/src/tools/Makefile Mon Dec 17 19:48:57 2018 +0900 +++ b/src/tools/Makefile Fri Jun 07 17:30:15 2019 +0900 @@ -1,6 +1,6 @@ include ../makefile.inc -CFLAGS = -Werror -Wall +CFLAGS = -Wall CFLAGS += -iquote ../ all: mkfs
--- a/src/tools/mkfs.c Mon Dec 17 19:48:57 2018 +0900 +++ b/src/tools/mkfs.c Fri Jun 07 17:30:15 2019 +0900 @@ -10,8 +10,9 @@ #include "fs.h" #include "stat.h" #include "param.h" - +#ifndef static_assert #define static_assert(a, b) do { switch (0) case 0: case (a): ; } while (0) +#endif int nblocks = 985; int nlog = LOGSIZE;
--- a/src/trap.c Mon Dec 17 19:48:57 2018 +0900 +++ b/src/trap.c Fri Jun 07 17:30:15 2019 +0900 @@ -152,3 +152,5 @@ cprintf (" r12: 0x%x\n", tf->r12); cprintf (" pc: 0x%x\n", tf->pc); } +void raise() +{}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/typedefData.h Fri Jun 07 17:30:15 2019 +0900 @@ -0,0 +1,2 @@ +typedef struct cbc_console_arg cbc_console_arg; +typedef union cbc_arg cbc_arg;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/usr/makfile-armgccbc Fri Jun 07 17:30:15 2019 +0900 @@ -0,0 +1,70 @@ +include ../makefile.inc + +CC = /usr/local/arm-cbc/bin/arm-none-eabi-gcc -B/usr/local/arm-cbc/bin/arm-none-eabi- +AS = arm-linux-gnu-gcc +LD = arm-linux-gnu-ld +OBJCOPY = arm-linux-gnu-objcopy +OBJDUMP = arm-linux-gnu-objdump +CFLAGS = -fno-pic -static -fno-builtin -fno-strict-aliasing -Wall -I. -g -O0 + +ASFLAGS = + +LIBGCC = $(shell $(CC) -print-libgcc-file-name) + +LINK_BIN = $(call quiet-command,$(LD) $(LDFLAGS) \ + -T $(1) -o $(2) $(3) $(LIBS) -b binary $(4), " LINK $(TARGET_DIR)$@") + +LINK_INIT = $(call quiet-command,$(LD) $(LDFLAGS) \ + $(1) -o $@.out $<, " LINK $(TARGET_DIR)$@") +OBJCOPY_INIT = $(call quiet-command,$(OBJCOPY) \ + -S -O binary --prefix-symbols="_binary_$@" $@.out $@, " OBJCOPY $(TARGET_DIR)$@") +AS_WITH = $(call quiet-command,$(AS) $(ASFLAGS) \ + $(1) -c -o $@ $<," AS $(TARGET_DIR)$@") + +CFLAGS += -iquote ../ +ASFLAGS += -I ../ +ULIB = ulib.o usys.o printf.o umalloc.o + +MKFS = ../tools/mkfs +FS_IMAGE = ../build/fs.img + +UPROGS=\ + _cat\ + _echo\ + _grep\ + _init\ + _kill\ + _ln\ + _ls\ + _mkdir\ + _rm\ + _sh\ + _stressfs\ + _usertests\ + _wc\ + _zombie\ + _hello\ + _forktest\ + + +all: $(FS_IMAGE) + +_%: %.o $(ULIB) + $(LD) $(LDFLAGS) -N -e main -Ttext 0 -o $@ $^ -L ../ $(LIBGCC) + $(OBJDUMP) -S $@ > $*.asm + $(OBJDUMP) -t $@ | sed '1,/SYMBOL TABLE/d; s/ .* / /; /^$$/d' > $*.sym + +_forktest: forktest.o $(ULIB) + # forktest has less library code linked in - needs to be small + # in order to be able to max out the proc table. + $(LD) $(LDFLAGS) -N -e main -Ttext 0 -o _forktest forktest.o ulib.o usys.o + $(OBJDUMP) -S _forktest > forktest.asm + +$(FS_IMAGE): $(MKFS) $(UPROGS) + $(MKFS) $@ $(UPROGS) UNIX + $(OBJDUMP) -S usys.o > usys.asm + +clean: + rm -f *.o *.d *.asm *.sym $(FS_IMAGE) \ + .gdbinit \ + $(UPROGS)
--- a/src/usr/printf.c Mon Dec 17 19:48:57 2018 +0900 +++ b/src/usr/printf.c Fri Jun 07 17:30:15 2019 +0900 @@ -1,6 +1,7 @@ #include "types.h" #include "stat.h" #include "user.h" +#include <stdarg.h> static void putc(int fd, char c) @@ -41,10 +42,10 @@ { char *s; int c, i, state; - uint *ap; + va_list ap; state = 0; - ap = (uint*)(void*)&fmt + 1; + va_start(ap, fmt); for(i = 0; fmt[i]; i++){ c = fmt[i] & 0xff; if(state == 0){ @@ -55,14 +56,11 @@ } } else if(state == '%'){ if(c == 'd'){ - printint(fd, *ap, 10, 1); - ap++; + printint(fd, va_arg(ap,int), 10, 1); } else if(c == 'x' || c == 'p'){ - printint(fd, *ap, 16, 0); - ap++; + printint(fd, va_arg(ap,int), 16, 0); } else if(c == 's'){ - s = (char*)*ap; - ap++; + s = va_arg(ap,char*); if(s == 0) s = "(null)"; while(*s != 0){ @@ -70,8 +68,7 @@ s++; } } else if(c == 'c'){ - putc(fd, *ap); - ap++; + putc(fd, va_arg(ap,int)); } else if(c == '%'){ putc(fd, c); } else { @@ -82,4 +79,5 @@ state = 0; } } + va_end(ap); }
--- a/src/usr/ulib.c Mon Dec 17 19:48:57 2018 +0900 +++ b/src/usr/ulib.c Fri Jun 07 17:30:15 2019 +0900 @@ -129,3 +129,7 @@ *dst++ = *src++; return vdst; } + +void +raise() +{}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/xv6arm7.xml Fri Jun 07 17:30:15 2019 +0900 @@ -0,0 +1,84 @@ +<domain type='qemu'> + <name>xv6arm7</name> + <uuid>80ddbab5-a467-4964-8eb1-0475512522ee</uuid> + <memory unit='KiB'>131072</memory> + <currentMemory unit='KiB'>131072</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='armv7l' machine='versatilepb'>hvm</type> + <kernel>/mnt/dalmore-home/one/src/xv6-rpi/src/kernel.elf</kernel> + <boot dev='hd'/> + </os> + <clock offset='utc'> + <timer name='rtc' tickpolicy='catchup'/> + <timer name='pit' tickpolicy='delay'/> + <timer name='hpet' present='no'/> + </clock> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>restart</on_crash> + <devices> + <emulator>/bin/qemu-system-arm</emulator> + <disk type='file' device='disk'> + <driver name='qemu' type='raw'/> + <source file='/mnt/dalmore-home/one/src/xv6-rpi/src/build/fs.img'/> + <target dev='sda' bus='sd'/> + </disk> + <controller type='usb' index='0' model='ich9-ehci1'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x7'/> + </controller> + <controller type='usb' index='0' model='ich9-uhci1'> + <master startport='0'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0' multifunction='on'/> + </controller> + <controller type='usb' index='0' model='ich9-uhci2'> + <master startport='2'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x1'/> + </controller> + <controller type='usb' index='0' model='ich9-uhci3'> + <master startport='4'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x2'/> + </controller> + <controller type='pci' index='0' model='pci-root'/> + <controller type='virtio-serial' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/> + </controller> + <interface type='user'> + <mac address='52:54:00:42:94:60'/> + <model type='rtl8139'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> + </interface> + <serial type='pty'> + <target port='0'/> + </serial> + <console type='pty'> + <target type='serial' port='0'/> + </console> + <channel type='spicevmc'> + <target type='virtio' name='com.redhat.spice.0'/> + <address type='virtio-serial' controller='0' bus='0' port='1'/> + </channel> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + <graphics type='spice' autoport='yes'> + <listen type='address'/> + <image compression='off'/> + </graphics> + <sound model='ich6'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/> + </sound> + <video> + <model type='qxl' ram='65536' vram='65536' vgamem='16384' heads='1' primary='yes'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/> + </video> + <redirdev bus='usb' type='spicevmc'> + <address type='usb' bus='0' port='1'/> + </redirdev> + <redirdev bus='usb' type='spicevmc'> + <address type='usb' bus='0' port='2'/> + </redirdev> + <memballoon model='virtio'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'/> + </memballoon> + </devices> +</domain>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/xv6arm.xml Fri Jun 07 17:30:15 2019 +0900 @@ -0,0 +1,86 @@ +<!-- +WARNING: THIS IS AN AUTO-GENERATED FILE. CHANGES TO IT ARE LIKELY TO BE +OVERWRITTEN AND LOST. Changes to this xml configuration should be made using: + virsh edit xv6arm7 +or other application using the libvirt API. +--> + +<domain type='qemu'> + <name>xv6arm7</name> + <uuid>80ddbab5-a467-4964-8eb1-0475512522ee</uuid> + <memory unit='KiB'>131072</memory> + <currentMemory unit='KiB'>131072</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='armv7l' machine='versatilepb'>hvm</type> + <kernel>/mnt/dalmore-home/one/src/xv6-rpi/src/kernel.elf</kernel> + <boot dev='hd'/> + </os> + <cpu mode='custom' match='exact' check='none'> + <model fallback='allow'>arm1176</model> + </cpu> + <clock offset='utc'> + <timer name='rtc' tickpolicy='catchup'/> + <timer name='pit' tickpolicy='delay'/> + <timer name='hpet' present='no'/> + </clock> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>restart</on_crash> + <devices> + <emulator>/bin/qemu-system-arm</emulator> + <disk type='file' device='disk'> + <driver name='qemu' type='raw'/> + <source file='/mnt/dalmore-home/one/src/xv6-rpi/src/build/fs.img'/> + <target dev='sda' bus='sd'/> + </disk> + <controller type='usb' index='0' model='ich9-ehci1'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x7'/> + </controller> + <controller type='usb' index='0' model='ich9-uhci1'> + <master startport='0'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0' multifunction='on'/> + </controller> + <controller type='usb' index='0' model='ich9-uhci2'> + <master startport='2'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x1'/> + </controller> + <controller type='usb' index='0' model='ich9-uhci3'> + <master startport='4'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x2'/> + </controller> + <controller type='pci' index='0' model='pci-root'/> + <controller type='virtio-serial' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/> + </controller> + <interface type='user'> + <mac address='52:54:00:42:94:60'/> + <model type='rtl8139'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> + </interface> + <serial type='pty'> + <target port='0'/> + </serial> + <console type='pty'> + <target type='serial' port='0'/> + </console> + <channel type='spicevmc'> + <target type='virtio' name='com.redhat.spice.0'/> + <address type='virtio-serial' controller='0' bus='0' port='1'/> + </channel> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + <sound model='ich6'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/> + </sound> + <redirdev bus='usb' type='spicevmc'> + <address type='usb' bus='0' port='1'/> + </redirdev> + <redirdev bus='usb' type='spicevmc'> + <address type='usb' bus='0' port='2'/> + </redirdev> + <memballoon model='virtio'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'/> + </memballoon> + </devices> +</domain>