diff --git a/loongArch.md b/loongArch.md new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/loongrCore/Cargo.lock b/loongrCore/Cargo.lock index 01d0b7b846a50fb455569b44f02efb364da74c3c..686343b2a6e6f34ba2ce8c465b134149949250d3 100644 --- a/loongrCore/Cargo.lock +++ b/loongrCore/Cargo.lock @@ -8,6 +8,18 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "bit_field" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcb6dd1c2376d2e096796e234a70e17e94cc2d5d54ff8ce42b28cef1d0d359a4" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + [[package]] name = "lazy_static" version = "1.4.0" @@ -33,8 +45,15 @@ version = "0.1.0" dependencies = [ "lazy_static", "spin 0.9.3", + "uart_16550", ] +[[package]] +name = "rustversion" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2cc38e8fa666e2de3c4aba7edeb5ffc5246c1c2ed0e3d17e560aeeba736b23f" + [[package]] name = "scopeguard" version = "1.1.0" @@ -55,3 +74,32 @@ checksum = "c530c2b0d0bf8b69304b39fe2001993e267461948b890cd037d8ad4293fa1a0d" dependencies = [ "lock_api", ] + +[[package]] +name = "uart_16550" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b074eb9300ad949edd74c529c0e8d451625af71bb948e6b65fe69f72dc1363d9" +dependencies = [ + "bitflags", + "rustversion", + "x86_64", +] + +[[package]] +name = "volatile" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3ca98349dda8a60ae74e04fd90c7fb4d6a4fbe01e6d3be095478aa0b76f6c0c" + +[[package]] +name = "x86_64" +version = "0.14.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "958cd5cb28e720db2f59ee9dc4235b5f82a183d079fb0e6caf43ad074cfdc66a" +dependencies = [ + "bit_field", + "bitflags", + "rustversion", + "volatile", +] diff --git a/loongrCore/Cargo.toml b/loongrCore/Cargo.toml index 045a1b35f60d78bdbf163190caa2590a43f4a92e..f86bd96a905e95fada10bd481ab3a8790fdfbcae 100644 --- a/loongrCore/Cargo.toml +++ b/loongrCore/Cargo.toml @@ -7,6 +7,7 @@ edition = "2021" [dependencies] spin = "0.9.2" +uart_16550 = "0.2.16" [dependencies.lazy_static] version = "1.4.0" diff --git a/loongrCore/qemu-loongarch-runenv/run_loongarch.sh b/loongrCore/qemu-loongarch-runenv/run_loongarch.sh index d2d477f8610bf6049f8dc362f3295949111a54be..9c05e1a1585a5a0fb348e2b84fd09b0ff218ba60 100755 --- a/loongrCore/qemu-loongarch-runenv/run_loongarch.sh +++ b/loongrCore/qemu-loongarch-runenv/run_loongarch.sh @@ -28,7 +28,7 @@ MEM="1G" # 1-4 CPUS="1" #BIOS="./loongarch_bios_0310.bin" -BIOS="./loongarch_bios_0310_debug.bin" +BIOS="./loongarch_bios_0310.bin" KERNEL="./vmlinux" INITRD="busybox-rootfs.img" USE_GRAPHIC="no" diff --git a/loongrCore/src/boot.S b/loongrCore/src/boot.S index ecb3d2ae873ddabd45a46a3317ed47066f1451c4..592dbf537fcfc494d221dd15c857380749655abb 100644 --- a/loongrCore/src/boot.S +++ b/loongrCore/src/boot.S @@ -12,7 +12,6 @@ _start: csrwr $t0,0x181 #LOONGARCH_CSR_DMWIN1 1: la.global $t0, _bss_start - #st.d $zero, $t0,0 la.global $t1, _bss_end bgeu $t0, $t1, 3f #bge如果å‰è€…大于ç‰äºŽåŽè€…则跳转 2: diff --git a/loongrCore/src/config.rs b/loongrCore/src/config.rs index e2e598b120b5a5c404e40ca70e90546106dc64cc..14129f3d850fd3b2b9d68ae9c45fcc3d5fa95ba2 100644 --- a/loongrCore/src/config.rs +++ b/loongrCore/src/config.rs @@ -15,15 +15,3 @@ const LOONGARCH_CSR_DMWIN0: u32 = 0x180; const LOONGARCH_CSR_DMWIN1: u32 = 0x181; const LOONGARCH_CSR_DMWIN2: u32 = 0x182; const LOONGARCH_CSR_DMWIN3: u32 = 0x183; - -const DMW_PABITS:usize = 48; -const CSR_DMW0_PLV0:usize = 1 << 0; -const CSR_DMW0_VSEG:usize = 0x8000; -const CSR_DMW0_BASE:usize = CSR_DMW0_VSEG << DMW_PABITS; -const CSR_DMW0_INIT :usize= CSR_DMW0_BASE | CSR_DMW0_PLV0; - -const CSR_DMW1_PLV0:usize = 1 << 0; -const CSR_DMW1_MAT:usize = 1 << 4; -const CSR_DMW1_VSEG:usize = 0x9000; -const CSR_DMW1_BASE:usize = CSR_DMW0_VSEG << DMW_PABITS; -const CSR_DMW1_INIT :usize= CSR_DMW1_BASE|CSR_DMW1_MAT | CSR_DMW1_PLV0; \ No newline at end of file diff --git a/loongrCore/src/loong_arch/mod.rs b/loongrCore/src/loong_arch/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/loongrCore/src/main.rs b/loongrCore/src/main.rs index 662af00950e2ba6c585d31785cc0c606ccff8e06..7e6e9c09ba560fdc2083c03c27aaf03753ff49e4 100644 --- a/loongrCore/src/main.rs +++ b/loongrCore/src/main.rs @@ -10,21 +10,24 @@ mod uart; mod print; mod lang_items; mod test; +mod loong_arch; +use uart_16550::MmioSerialPort; use config::FLAG; use core::arch::{global_asm}; use crate::print::get_char; use test::color_output_test; +use crate::config::UART; +use crate::uart::Uart; global_asm!(include_str!("boot.S")); #[no_mangle] pub extern "C" fn main(){ INFO!("{}",FLAG); color_output_test(); - scanf(); + panic!(); } - fn scanf(){ const LF: u8 = 10; //æ¢è¡Œé”® const CR: u8 = 13; //回车键 diff --git a/manual.md b/manual.md new file mode 100644 index 0000000000000000000000000000000000000000..9fec9b9227265d92471e789f3a33344fd7c87d04 --- /dev/null +++ b/manual.md @@ -0,0 +1,158 @@ +# 实验手册 + +实验手册用于记录实验过程ä¸å¦ä¹ 的相关知识和é‡åˆ°çš„问题与解决方法 + +[TOC] + +## UEFI与BIOS + +BIOS(Basic Input/Output System),å³åŸºæœ¬è¾“入输出系统,亦称为ROM BIOSã€System BIOSã€PC BIOS,是在通电å¯åŠ¨é˜¶æ®µæ‰§è¡Œç¡¬ä»¶åˆå§‹åŒ–,以åŠä¸ºæ“作系统æä¾›è¿è¡Œæ—¶æœåŠ¡çš„å›ºä»¶ã€‚ä»¥å‰çš„BIOS主è¦ä½äºŽROM上,现在则主è¦ä½äºŽflashä¸ã€‚å…¶ä¸»è¦æ‰§è¡Œçš„任务有 + +- 自检程åºï¼Œç”¨äºŽæ£€æµ‹ç¡¬ä»¶ +- åˆå§‹åŒ–系统的处ç†å™¨æ ¸ã€å†…å˜ã€å¤–设ç‰åœ¨å†…çš„å„个部分 +- 基本的I/Oå¤„ç† +- å¤–è®¾é©±åŠ¨ç®¡ç† + +在计算机按下电æºé”®å¼€æœºåŽï¼Œcpu将会跳转到æŸä¸ªå›ºå®šçš„ä½ç½®ï¼Œå³BIOS所在的ä½ç½®ï¼Œç„¶åŽå¼€å§‹æ‰§è¡Œæ¤ä½ç½®çš„代ç 完æˆä¸Šè¿°åŠŸèƒ½ï¼Œåœ¨æ‰§è¡Œæ— è¯¯åŽï¼Œå°±ä¼šè·³è½¬åˆ°å¯ä»¥å¼•导æ“作系统å¯åŠ¨çš„Bootloader部分。 + +UEFI(Unified Extensible Firmware Interface)䏿–‡ç»Ÿä¸€å¯æ‰©å±•固件接å£ï¼ŒUEFI主è¦å®šä¹‰äº†æ“作系统和平å°å›ºä»¶ä¹‹é—´çš„æŽ¥å£ï¼ŒUEFIåªæ˜¯ä¸€ç§æ ‡å‡†ï¼Œå…·ä½“çš„å®žçŽ°ç”±å…¶ä»–å…¬å¸æˆ–å¼€æºç»„æˆæä¾›ã€‚UEFI与BIOS显著的区别就是UEFI是用模å—化,Cè¯è¨€é£Žæ ¼çš„傿•°å †æ ˆä¼ 递方å¼ï¼ŒåЍæ€é“¾æŽ¥çš„形弿ž„建的系统,较BIOSè€Œè¨€æ›´æ˜“äºŽå®žçŽ°ï¼Œå®¹é”™å’Œçº é”™ç‰¹æ€§æ›´å¼ºï¼Œç¼©çŸäº†ç³»ç»Ÿç ”å‘的时间。两者在完æˆçš„功能上是大åŒå°å¼‚的。 + +UEFIç³»ç»Ÿä»ŽåŠ ç”µåˆ°å…³æœºåˆ†ä¸º7个阶段 + +- SEC(安全验è¯) +- PEI(EIF剿œŸåˆå§‹åŒ–) +- DXE(驱动执行环境) +- BDS(å¯åŠ¨è®¾å¤‡é€‰æ‹©) +- TSL(æ“ä½œç³»ç»Ÿå‰æœŸåŠ è½½) +- RT(è¿è¡Œæ—¶) +- AL(系统ç¾é𾿢夿œŸ) + + + +## æ“作系统的å¯åŠ¨è¿‡ç¨‹ç¤ºæ„图 + +龙芯平å°ä¸Šçš„æ“ä½œç³»ç»Ÿå¯åŠ¨è¿‡ç¨‹ + + + + + +UEFI biosè£…è½½å†…æ ¸æ—¶ï¼Œä¼šæŠŠä»Žå†…æ ¸elf文件获å–的入å£ç‚¹åœ°å€ï¼ˆå¯ä»¥ç”¨readelf -h或者-l vmlinux看到)抹去高32ä½ä½¿ç”¨ã€‚比如vmlinuxé“¾æŽ¥çš„åœ°å€æ˜¯0x9000000001034804,实际bios跳转的地å€å°†æ˜¯0x1034804,代ç 装载的ä½ç½®ä¹Ÿæ˜¯ç‰©ç†å†…å˜0x1034804。BIOSè¿™ä¹ˆåšæ˜¯å› 为它逻辑上相当于用物ç†åœ°å€åŽ»è®¿é—®å†…å˜ï¼Œé«˜çš„虚拟地å€ç©ºé—´æ²¡æœ‰æ˜ å°„ä¸èƒ½ç›´æŽ¥ç”¨ã€‚ + +å†…æ ¸å¯åЍ入å£ä»£ç 需è¦åšä¸¤ä»¶äº‹ï¼š + +1. è®¾ç½®ä¸€ä¸ªç›´æŽ¥åœ°å€æ˜ 射窗å£ï¼ŒæŠŠå†…æ ¸ç”¨åˆ°çš„64åœ°å€æŠ¹åŽ»é«˜ä½æ˜ 射到物ç†å†…å˜ã€‚ç›®å‰linuxå†…æ ¸æ˜¯è®¾ç½®0x8000xxxx-xxxxxxxxå’Œ0x9000xxxx-xxxxxxxxåœ°å€æŠ¹åŽ»æœ€é«˜çš„8å’Œ9为其物ç†åœ°å€ï¼Œå‰è€…用于uncache访问(å³ä¸é€šè¿‡é«˜é€Ÿç¼“å˜åŽ»load/store),åŽè€…用于cache访问。 +2. åšä¸ªä»£ç 自跳转,使得åŽç»ä»£ç 执行的PC和链接用的虚拟地å€åŒ¹é…。BIOSåˆšè·³è½¬åˆ°å†…æ ¸æ—¶ï¼Œç”¨çš„åœ°å€æ˜¯æŠ¹åŽ»äº†é«˜32ä½çš„地å€ï¼ˆç›¸å½“于物ç†åœ°å€ï¼‰ï¼Œæ¥éª¤1使得链接时的高地å€å¯ä»¥è®¿é—®åˆ°åŒæ ·çš„物ç†å†…å˜ï¼Œè¿™é‡Œåˆ™æ¢å›žåˆ°åŽŸå§‹çš„è™šæ‹Ÿåœ°å€ã€‚ + +在linuxæºä»£ç ä¸å¯ä»¥å¾—到入å£ä»£ç 如下所示: + +```gas +SYM_CODE_START(kernel_entry) # kernel entry point + la.abs t0, 0f + jirl zero, t0, 0 +0: + la t0, __bss_start # clear .bss + st.d zero, t0, 0 + la t1, __bss_stop - LONGSIZE +1: + addi.d t0, t0, LONGSIZE + st.d zero, t0, 0 + bne t0, t1, 1b + + #è®¾ç½®ç›´æŽ¥åœ°å€æ˜ å°„çª—å£ + li.d t0, CSR_DMW0_INIT # UC, PLV0, 0x8000 xxxx xxxx xxxx + csrwr t0, LOONGARCH_CSR_DMWIN0 + li.d t0, CSR_DMW1_INIT # CA, PLV0, 0x9000 xxxx xxxx xxxx + csrwr t0, LOONGARCH_CSR_DMWIN1 + #å¼€å¯é¡µè¡¨ + li.w t0, 0xb0 # PLV=0, IE=0, PG=1 + csrwr t0, LOONGARCH_CSR_CRMD + li.w t0, 0x04 # PLV=0, PIE=1, PWE=0 + csrwr t0, LOONGARCH_CSR_PRMD + li.w t0, 0x00 # FPE=0, SXE=0, ASXE=0, BTE=0 + csrwr t0, LOONGARCH_CSR_EUEN + + #è®¾ç½®æ ˆç©ºé—´ + PTR_LI sp, (_THREAD_SIZE - 32 - PT_SIZE) + PTR_ADDU sp, sp, tp + set_saved_sp sp, t0, t1 + PTR_ADDIU sp, sp, -4 * SZREG # init stack pointer + + #è·³è½¬åˆ°å†…æ ¸å…¥å£ + bl start_kernel + +SYM_CODE_END(kernel_entry) +``` + +虽然得到了入å£ä»£ç ,但æ¤ä»£ç ä¸èƒ½ç›´æŽ¥copy到rust的实现ä¸ï¼Œå› 为上é¢çš„代ç ä¸åŒ…å«äº†è®¸å¤šå®å®šä¹‰ï¼Œè€Œä¸”这里å¯ä»¥ä½¿ç”¨çš„æŒ‡ä»¤åœ¨rustä¸ä¹Ÿå¹¶ä¸èƒ½ä½¿ç”¨ï¼Œå› æ¤æˆ‘们需è¦å°†å¾—åˆ°çš„å¯æ‰§è¡Œæ–‡ä»¶å汇编,得到原始的汇编代ç 。使用命令 + +``` +loongarch64-unknown-linux-gnu-objdump -d vmlinux > linux.S +``` + +通过查找linuxå†…æ ¸ä»£ç 相关文件,找到了CSR_DMW0_INIT的相关定义,其值为0x180ï¼Œä¹Ÿå³æ˜¯DMW0寄å˜å™¨çš„地å€ã€‚å› æ¤å¯ä»¥åœ¨æ±‡ç¼–代ç 䏿Ÿ¥æ‰¾0x180所在ä½ç½®ï¼Œå¾—åˆ°è®¾ç½®æ˜ å°„çª—å£çš„相关代ç : + +``` +#åˆå§‹åŒ–bss段 +90000000010347f4: 1c00d68c pcaddu12i $t0, 1716(0x6b4) +90000000010347f8: 02d7318c addi.d $t0, $t0, 1484(0x5cc) +90000000010347fc: 28c1e184 ld.d $a0, $t0, 120(0x78) +9000000001034800: 4c000020 jirl $zero, $ra, 0 +9000000001034804: 1402068c lu12i.w $t0, 4148(0x1034) +9000000001034808: 03a0618c ori $t0, $t0, 0x818 +900000000103480c: 1600000c lu32i.d $t0, 0 +9000000001034810: 0324018c lu52i.d $t0, $t0, -1792(0x900) +9000000001034814: 4c000180 jirl $zero, $t0, 0 +9000000001034818: 1c00c76c pcaddu12i $t0, 1595(0x63b) +900000000103481c: 02dfa18c addi.d $t0, $t0, 2024(0x7e8) +9000000001034820: 29c00180 st.d $zero, $t0, 0 +9000000001034824: 1c00e7ad pcaddu12i $t1, 1853(0x73d) +9000000001034828: 02fcf1ad addi.d $t1, $t1, -196(0xf3c) + +#bne if t0 < t1 则跳转 +#st.d å°† zero的内容写入内å˜ä¸ï¼Œå†…å˜åœ°å€ç”± t0+(0ç¬¦å·æ‰©å±•) +900000000103482c: 02c0218c addi.d $t0, $t0, 8(0x8) +9000000001034830: 29c00180 st.d $zero, $t0, 0 +9000000001034834: 5ffff98d bne $t0, $t1, -8(0x3fff8) + +#è®¾ç½®æ˜ å°„çª—å£ +9000000001034868: 0380040c ori $t0, $zero, 0x1 +900000000103486c: 0320018c lu52i.d $t0, $t0, -2048(0x800) +9000000001034870: 0406002c csrwr $t0, 0x180 +9000000001034874: 0380440c ori $t0, $zero, 0x11 +9000000001034878: 0324018c lu52i.d $t0, $t0, -1792(0x900) +900000000103487c: 0406042c csrwr $t0, 0x181 +``` + +综åˆä»¥ä¸Šä¿¡æ¯å¹¶æŸ¥æ‰¾ç›¸å…³èµ„料,我们é‡å†™å¾—åˆ°çš„å†…æ ¸å…¥å£ä»£ç 如下所示: + +``` +.section .text.init +.global _start + +_start: +0: + #è®¾ç½®æ˜ å°„çª—å£ + ori $t0, $zero,0x1 + lu52i.d $t0, $t0, -2048 #åŠ è½½ç«‹å³æ•° + csrwr $t0,0x180 #设置LOONGARCH_CSR_DMWIN0 #ç‰¹æƒæŒ‡ä»¤ç”¨äºŽäº¤æ¢ä¸¤ä¸ªå¯„å˜å™¨å†…容 + ori $t0, $zero,0x11 + lu52i.d $t0, $t0, -1792 + csrwr $t0,0x181 #LOONGARCH_CSR_DMWIN1 +1: + la.global $t0, _bss_start + la.global $t1, _bss_end + bgeu $t0, $t1, 3f #bge如果å‰è€…大于ç‰äºŽåŽè€…则跳转 +2: + st.d $zero, $t0,0 + addi.d $t0, $t0, 8 + bltu $t0, $t1, 2b +3: + la.global $sp, _stack # _stack 在linker.ld文件ä¸åˆ†é…ï¼Œè¿™é‡Œç”¨äºŽåˆ†é…æ ˆç©ºé—´ + bl main #跳转到mainå…¥å£å¼€å§‹æ‰§è¡Œ +``` + +在实验ä¸ï¼Œéœ€è¦ä½¿ç”¨ä¸²å£æ‰“å°ä¿¡æ¯ä»¥ä¾¿äºŽåŽæœŸå®žéªŒï¼Œåœ¨rCoreç¬¬ä¸€ç« ä¸ä½¿ç”¨çš„æ˜¯SBIæé«˜çš„è¿è¡Œæ—¶æœåŠ¡ï¼Œè¿™é‡Œç”±äºŽè°ƒç”¨UEFIæä¾›çš„æœåŠ¡æ¯”è¾ƒå›°éš¾ï¼Œå› æ¤æˆ‘们å°è¯•了使用uart_16550库æä¾›çš„æŽ¥å£ï¼Œä½†å‘现并ä¸èƒ½æ£å¸¸ä½¿ç”¨ï¼Œå› æ¤è¿™é‡Œå®žçŽ°äº†ä¸€ä¸ªç®€å•çš„uart模å—。在使用我们编写的串å£è¾“出åŽï¼Œå¯ä»¥æ£å¸¸æ˜¾ç¤ºå’Œè¾“å…¥ + + + diff --git a/sourcepicture/image-20220510212716244.png b/sourcepicture/image-20220510212716244.png new file mode 100644 index 0000000000000000000000000000000000000000..91042448c191640d911df499a0bd537b96361900 Binary files /dev/null and b/sourcepicture/image-20220510212716244.png differ diff --git a/sourcepicture/image-20220510221257744.png b/sourcepicture/image-20220510221257744.png new file mode 100644 index 0000000000000000000000000000000000000000..f9df81bf733a977a5d2af0a450ba2b81b64cd79c Binary files /dev/null and b/sourcepicture/image-20220510221257744.png differ