Surface Laptop 2 修复 BLInitializeLibrary failed / 0xc0000001

适用于系统文件仍在,但EFI 引导区损坏导致无法启动、自动修复失败、bootrec 扫描不到 Windows 的情况。

以下步骤已被实际验证有效。


#️⃣1. 制作恢复 U 盘(Linux 环境)

① 下载微软恢复镜像

选择设备型号(如 Surface Laptop 2)
输入序列号
下载 ZIP(约 7.8GB)


② 在 Linux 中将 U 盘格式化为 FAT32(最重要步骤)

先确认你的 U 盘设备名称,例如:

lsblk

假设是 /dev/sda(⚠ 注意:千万不要选错)

格式化为 FAT32:

sudo umount /dev/sda*
sudo mkfs.fat -F 32 /dev/sda

③ 挂载 U 盘

sudo mkdir -p /mnt/usb
sudo mount /dev/sda /mnt/usb

④ 解压微软恢复镜像

unzip Surface_Recovery.zip -d surf

⑤ 将恢复文件复制到 U 盘(必须复制内容,而不是文件夹)

sudo cp -r surf/* /mnt/usb/

⑥ 卸载 U 盘

sudo umount /mnt/usb

#️⃣2. 从 U 盘启动进入恢复界面

  1. 插入 U 盘
  2. 长按 音量 –
  3. 按电源
  4. 松开电源但继续按住音量 –
  5. 进入 Windows 蓝色恢复界面

#️⃣3. 打开命令提示符

疑难解答 → 高级选项 → 命令提示符


#️⃣4. 可选:修复系统文件(推荐)

sfc /scannow /offbootdir=C:\ /offwindir=C:\Windows
dism /image:C:\ /cleanup-image /restorehealth

#️⃣5. 运行 bootrec(如果扫描到 0 个 Windows,继续下一步)

bootrec /fixmbr
bootrec /fixboot
bootsect /nt60 sys
bootrec /fixboot
bootrec /scanos

#️⃣6. 手动重建 EFI 引导分区(真正解决问题的步骤)

① 打开 diskpart

diskpart
list volume

记住EFI 分区编号:
通常是 100MB FAT32(如 Volume 1)


② 选择 EFI 分区并挂载为 Z:

sel volume 1
assign letter=Z
exit

③ 清空 EFI 目录并重建

cd /d Z:\
rmdir /S /Q Z:\EFI
mkdir Z:\EFI

④ 将 Windows 引导文件写入 EFI(最关键一步)

bcdboot C:\Windows /s Z: /f UEFI

看到:

启动文件创建成功

代表修复成功。


#️⃣7. 重启

exit

选择:

Continue → Continue to Windows

系统即可恢复正常启动。


🟦 总结(极简版流程)

# Linux 制作恢复盘
sudo umount /dev/sdX*
sudo mkfs.fat -F 32 /dev/sdX
sudo mount /dev/sdX /mnt/usb
unzip Recovery.zip -d surf
sudo cp -r surf/* /mnt/usb/
sudo umount /mnt/usb

# Windows 修复:
sfc /scannow /offbootdir=C:\ /offwindir=C:\Windows
dism /image:C:\ /cleanup-image /restorehealth
bootrec /fixmbr
bootrec /fixboot
bootsect /nt60 sys
bootrec /fixboot
bootrec /scanos

diskpart
list volume
sel volume 1
assign letter=Z
exit

cd /d Z:\
rmdir /S /Q Z:\EFI
mkdir Z:\EFI

bcdboot C:\Windows /s Z: /f UEFI

Microsoft 365 Business Premium: From License Activation to Teams Compliance and eDiscovery


A complete technical walkthrough of Microsoft 365 Business Premium,
covering Outlook mailboxes, Entra ID identity management, Teams message retention,
and Microsoft Purview eDiscovery for auditing and data governance.


1 Overview of Microsoft 365 Business Premium

License Components

  • Outlook Exchange Online (50 GB mailbox)
  • Teams for chat, calls, and meetings
  • OneDrive and SharePoint for cloud storage
  • Intune for device management
  • Entra ID (former Azure AD) for authentication and SSO
  • Purview for compliance and eDiscovery
  • Defender for Business for security protection

Each user license can activate Office apps on up to 5 PCs/Macs + 5 tablets + 5 phones.
All services update automatically after login with a valid subscription.


2 Outlook and Exchange Online Mailboxes

  • A Business Premium tenant automatically provisions an
    @yourtenant.onmicrosoft.com mailbox.
  • You can add a custom domain (e.g., @yourcompany.com) in
    Microsoft 365 Admin Center → Settings → Domains.
  • DNS records (MX, SPF, DKIM, DMARC) are handled automatically.

Mail data is stored in Exchange Online, enabling retention and eDiscovery.


3 Microsoft Entra ID (former Azure AD)

Purpose

  • Central identity provider for the tenant
  • User, group, and role management
  • SSO for internal and third-party apps
  • MFA and conditional access policies

Admin Portal


4 Teams Integration Architecture

Teams FeatureData LocationSearchable by eDiscovery
1:1 & group chatsExchange Online (hidden folder “TeamChat”)
Channel messagesSharePoint Team Site
File attachmentsOneDrive / SharePoint
Meeting recordingsStream or OneDrive
Calendar eventsExchange Calendar

Teams Admin Center provides usage reports:
message counts, meetings joined, call duration, and device types.


5 Microsoft Purview Compliance Portal

New unified entry point: https://compliance.microsoft.com

Included modules for Business Premium:

  • Audit – activity logs (90 days)
  • eDiscovery (Standard) – search and export content
  • Data Lifecycle Management – retention policies
  • Communication Compliance (basic rules)

6 Default Retention and Policy Extension

Data TypeDefault RetentionNotes
Teams chats≈ 30 days (if no policy)Deleted after expiration
Teams channel posts≈ 1 yearStored in SharePoint
Emails (Exchange)UnlimitedUntil user deletes
Files (OneDrive/SharePoint)UnlimitedUntil deleted
Audit logs90 daysExtend with E5 license

Create a Permanent Retention Policy

  1. Open Purview → Data Lifecycle Management → Microsoft 365 → Retention Policies
  2. Create policy → select Teams chats / channel messages
  3. Choose Keep Forever
  4. Apply to All Users → Save → Publish

After this, Teams messages remain permanently searchable and recoverable.


7 eDiscovery (Standard) Workflow

Step 1 Open Module

Purview → Solutions → eDiscovery → eDiscovery (Standard)

Step 2 Create a Case

Example name: Teams_Compliance_Audit

Step 3 Add Search

  • Locations: Teams Chats and Mailboxes
  • Keywords: e.g. ("resignation" OR "quit" OR "leave company")
  • Date range: optional
  • Run the search

Step 4 View and Export

Results show: sender, recipients, timestamp, and message snippet.
Select Preview to see context or Export to download a ZIP package.


8 Export Structure and HTML Preview

TeamsChatExport_20251112_XXXX/
├─ manifest.csv
├─ TeamsChat_1.html
└─ Metadata/
    ├─ MessageDetails.csv
    └─ Attachments/

Example HTML View

───────────────────────────────
User A  ( 2025-11-10 17:42 )
I haven’t mentioned the resignation yet.

User B  ( 2025-11-10 17:43 )
When will you bring it up?

User A  ( 2025-11-10 17:44 )
Probably end of the month, after handover.
───────────────────────────────

Each file includes message context, timestamps, and participants—
allowing a full reconstruction of conversation flow.


9 Permissions Required for eDiscovery

RoleCapabilities
Compliance AdministratorCreate and run Content Search, set policies
eDiscovery ManagerCreate cases, search Teams chats, export results
eDiscovery AdministratorManage all cases and exports
Global AdministratorHas all above permissions by default

Add roles via Purview → Permissions → Microsoft Purview solutions.

All features above are included in Business Premium—no extra license needed.
(Only eDiscovery Premium and Advanced Audit require E5 plans.)


10 Teams Privacy and Compliance Reality

ScenarioRetainedSearchableStorage Location
Private chat (1:1 / group)Exchange Online hidden folder
Channel postsSharePoint
Deleted messages (within policy)Retention snapshot
AttachmentsOneDrive / SharePoint

Even deleted messages remain discoverable until their retention period expires.

Conclusion for users:

Teams chat is not a private messenger.
All content belongs to the organization and may be retained or audited.


11 License Tier Comparison

FeatureBusiness PremiumE3 / E5
eDiscovery (Standard)
eDiscovery (Premium)
Audit log retention90 days1 year / 10 years
Communication ComplianceBasicAdvanced
DLP (Data Loss Prevention)BasicFull

12 Logical Architecture Summary

[User]
   ↓
[Teams Client]
   ↓
[Exchange Online / SharePoint / OneDrive]
   ↓
[Microsoft Purview Services]
   ├─ eDiscovery
   ├─ Audit
   ├─ Data Lifecycle Management
   ↓
[Compliance Admin Center]

13 Key Takeaways

  1. Business Premium integrates identity (Entra ID), collaboration (Teams), and compliance (Purview).
  2. Teams chat data is retained by default for 30 days unless a policy extends it.
  3. eDiscovery (Standard) can search and export full conversation context in HTML.
  4. Chat content is organizational data, not personal property.
  5. Administrators should set clear retention and privacy policies for all users.

Useful Portals

Install and Configure OpenAI Codex CLI on Ubuntu / WSL


🛠 Overview

This guide explains how to install the OpenAI Codex CLI on Ubuntu or Windows Subsystem for Linux (WSL), set up your API key, and switch authentication methods between apikey and chatgpt.


⚙️ Installation Steps

# Update packages
sudo apt update -y
sudo apt upgrade -y

# Install Node.js (using Node 22 as an example)
curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -
sudo apt install -y nodejs

# (Optional) Ensure git is installed
sudo apt install -y git

# Install the Codex CLI globally via npm
sudo npm install -g @openai/codex

# Set your OpenAI API key
export OPENAI_API_KEY="your_OpenAI_API_Key"

# To make this persistent across sessions:
echo 'export OPENAI_API_KEY="your_OpenAI_API_Key"' >> ~/.bashrc
source ~/.bashrc

# Verify installation
codex --version

🔄 Switching Authentication Methods

You can choose how Codex authenticates your account:

# Use direct API key authentication
codex --config preferred_auth_method='apikey'

# Or use ChatGPT-based login
codex --config preferred_auth_method='chatgpt'

🔑 Set API Key Manually

If needed, you can manually edit your authentication file:

vi ~/.codex/auth.json

Add or update your API key inside that file.


🪄 One-Line Quick Install (for Termux / Android)

pkg update -y && pkg upgrade -y && \
pkg install -y curl git && \
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/master/install.sh | bash && \
source ~/.bashrc && \
unset PREFIX && \
nvm install 20 && \
npm install -g @openai/codex && \
echo 'export OPENAI_API_KEY="your_OpenAI_API_Key"' >> ~/.bashrc && \
source ~/.bashrc

Use Local LLM:
Open your Codex configuration file: C:\Users\<username>\.codex\config.toml Replace or append the following: # Use Ollama as model provider model = "gpt-oss:20b" model_provider = "ollama"

like below:

# Use Ollama as model provider
model = "gpt-oss:20b"
model_provider = "ollama"

[model_providers.ollama]
name = "Ollama (local)"
base_url = "http://127.0.0.1:11434/v1"
# Ollama does not require API Key
wire_api = "chat"   # Codex uses Chat Completions API

Restart VS Code
After saving, restart VS Code (or reload the Codex extension) to apply the new settings.


📚 References

How to Add serena MCP Servers in Claude Code

Here are two common methods to configure them permanently — both survive restarts and will always auto-load when Claude Code launches.


Method 1: Command Line (Recommended)

Run the following command in your project directory:

claude mcp add serena -- uvx --from git+https://github.com/oraios/serena serena start-mcp-server --context ide-assistant --project $(pwd)
  • Automatically updates ~/.claude/settings.json
  • Adds the serena MCP server into the configuration
  • Will auto-connect each time Claude Code starts

Method 2: Manual Configuration File Edit

  1. Open ~/.claude/settings.json
  2. Add a new MCP server block, for example:
{
  "mcpServers": {
    "fujisoft-code-agent": {
      "command": "cmd.exe",
      "args": ["/c", "code-agent", "server"]
    },
    "serena": {
      "command": "uvx",
      "args": [
        "--from", "git+https://github.com/oraios/serena",
        "serena", "start-mcp-server",
        "--context", "ide-assistant",
        "--project", "/your/project/path"
      ]
    }
  }
}
  • You can add multiple MCP servers here
  • Save the file and restart Claude Code → the servers will auto-connect

Verify Your Configuration

To check your current MCP servers:

cat ~/.claude/settings.json

Or inside Claude Code:

/status

This will display the list of configured MCP servers and their status.


✅ Conclusion

  • Command Line Method → Quickest and easiest, auto-writes to config
  • Manual File Edit → More flexible, can add multiple servers at once
  • Result is the same → Both are persistent and survive restarts

Pro Tip:
On Windows, replace $(pwd) with %cd% when running the command.
Example:

claude mcp add serena -- uvx --from git+https://github.com/oraios/serena serena start-mcp-server --context ide-assistant --project %cd%

👉 With this setup, you can extend Claude Code with custom MCP servers like Serena and streamline your coding workflow!


🔹 Additional Knowledge: Execution Status & Management

After Adding Serena with --project

  • When you run: claude mcp add serena --project $(pwd)
    • Serena will only auto-start when you run Claude Code inside that project directory.
    • Other directories will not see Serena.

Manage and Modify MCP Servers

  1. List configured MCP servers: claude mcp list
  2. Remove Serena from config: claude mcp remove serena
  3. Re-add as a global configuration (visible everywhere): claude mcp add serena -- uvx --from git+https://github.com/oraios/serena serena start-mcp-server --context ide-assistant
  4. Add Serena to another project (project-level): cd /path/to/other/project claude mcp add serena -- uvx --from git+https://github.com/oraios/serena serena start-mcp-server --context ide-assistant --project $(pwd)

Config File Locations

  • Project-level config → created inside the project directory
  • Global config → stored in ~/.claude/settings.json

If you want to switch Serena from project-level to global:

  1. Remove the existing entry claude mcp remove serena
  2. Add it again without --project.

Deploying Ring Camera Recording with Docker: From Continuous Recording to Motion-triggered Capture


1. Goal

  • Enable local recording of Ring camera streams.
  • Phase 1: Continuous recording.
  • Phase 2: Motion-triggered recording (battery/storage friendly).

2. Environment

  • Host: Ubuntu/Debian server or VM
  • Docker / Docker Compose installed
  • Ring camera already linked in the Ring app
  • Testbed used: local VM (same steps apply to production).

3. Core Configuration Files

MQTT broker

mosquitto/mosquitto.conf

listener 1883
allow_anonymous true

Ring-MQTT

ring-mqtt/config.json

{
  "mqtt_url": "mqtt://mqtt",
  "mqtt_options": {
    "username": "xxx@mail.com",
    "password": "yyy"
  },
  "ring_token": ""
}

⚠️ Note: ring_token is obtained via WebUI (http://<host_ip>:55123/). Do not expose the actual value.

Docker Compose

docker-compose.yml

version: "3.8"

services:
  mqtt:
    image: eclipse-mosquitto
    container_name: mosquitto
    restart: unless-stopped
    ports:
      - "1883:1883"
    volumes:
      - ./mosquitto/mosquitto.conf:/mosquitto/config/mosquitto.conf

  ring-mqtt:
    image: tsightler/ring-mqtt
    container_name: ring-mqtt
    restart: unless-stopped
    depends_on:
      - mqtt
    ports:
      - "8554:8554"      # RTSP 流端口
      - "55123:55123"    # Web UI 端口
    volumes:
      - ./ring-mqtt:/data


4. Steps

  1. Start services: docker compose up -d
  2. Check Ring-MQTT logs: docker logs -f ring-mqtt → Access WebUI at http://<host_ip>:55123/ and generate your Ring token.
  3. Test recording manually: ffmpeg -i rtsp://localhost:8554/<DEVICE_ID>_live -t 30 test.mp4
  4. Verify recordings are saved under ./recordings/.

5. Common Issues & Fixes

  • Cannot connect RTSP → Ensure token generated & container restarted.
  • Recorder container fails → Use correct <DEVICE_ID>_live instead of camera name.
  • Files not saved → Check docker logs -f ring-recorder, confirm volume mounts.

6. Security Considerations

  • Always hide ring_token and <DEVICE_ID> in public configs.
  • Avoid continuous 24/7 recording if using battery-powered Ring devices.
  • Plan for storage growth if recording continuously.

7. Advanced Reference (Motion-triggered Recording)

By default, recording runs continuously, which can drain battery.
With MQTT events, we can start recording only when motion is detected.

Script Example

record_on_motion.sh

#!/bin/bash

DEVICE_ID="<DEVICE_ID>"       # Camera ID (hidden)
DURATION=90             # 每次录制时长(秒)
SAVE_PATH="./recordings"
LOG_FILE="./record_on_motion.log"

mkdir -p "$SAVE_PATH"

log() {
    MSG="[$(date +"%Y-%m-%d %H:%M:%S")] $1"
    echo "$MSG" | tee -a "$LOG_FILE"
}

# 持续订阅 motion 事件
mosquitto_sub -h localhost -t "ring/+/camera/$DEVICE_ID/motion/state" | while read state
do
    if [ "$state" == "ON" ]; then
        TIMESTAMP=$(date +"%Y-%m-%d_%H-%M-%S")
        FILE="$SAVE_PATH/Front_$TIMESTAMP.mp4"
        log "Motion detected, start recording: $FILE (duration $DURATION seconds)"

        ffmpeg -rtsp_transport tcp -i rtsp://localhost:8554/${DEVICE_ID}_live \
            -t $DURATION -c copy "$FILE" >>"$LOG_FILE" 2>&1

        log "Recording finished: $FILE"
    fi
done

⚠️ Replace <DEVICE_ID> with your Ring camera’s internal ID.

Usage

chmod +x record_on_motion.sh
./record_on_motion.sh

→ When motion is detected, a short recording is automatically created.

8. Directory Layout

~/dev/ring
├── docker-compose.yml
├── record_on_motion.sh
├── mosquitto
│   ├── data
│   ├── log
│   └── mosquitto.conf
├── recordings
└── ring-mqtt
    ├── config.json
    ├── go2rtc.yaml
    └── ring-state.json

9. Appendix: Port Explanations

MQTT → 1883

  • Purpose: Message broker for events (motion, doorbell).
  • Who connects: record_on_motion.sh, Home Assistant, automation systems.

WebUI → 55123

  • Purpose: Token generation interface for Ring authentication.
  • Who connects: You (via browser, one-time login).

RTSP → 8554

  • Purpose: Provides camera video stream as RTSP.
  • Who connects: ffmpeg, VLC, recording service.

Quick Reference Table

PortProtocol/ServiceFunctionWho Uses It
1883MQTT brokerTransmit event messagesMotion script, Home Assistant, automations
55123WebUI (HTTP)Generate/manage Ring tokenYou (browser login)
8554RTSP video streamProvide live video streamffmpeg, VLC, recording service

Install Nextcloud on Ubuntu 25.04 (with HTTPS and Common Issues Fixed)


1. Update the System

sudo apt update && sudo apt upgrade -y

2. Install Apache, MariaDB, PHP and Extensions

sudo apt install -y apache2 mariadb-server libapache2-mod-php \
php php-mysql php-gd php-curl php-xml php-zip php-mbstring php-bz2 \
php-intl php-gmp php-imagick unzip wget -y

3. Create Database and User

sudo mysql -u root

Inside MariaDB:

CREATE DATABASE nextcloud;
CREATE USER 'nextclouduser'@'localhost' IDENTIFIED BY 'yourPassword';
GRANT ALL PRIVILEGES ON nextcloud.* TO 'nextclouduser'@'localhost';
FLUSH PRIVILEGES;
EXIT;

4. Download and Install Nextcloud

cd /tmp
wget https://download.nextcloud.com/server/releases/latest.zip
unzip latest.zip
sudo mv nextcloud /var/www/
sudo chown -R www-data:www-data /var/www/nextcloud

5. Configure Apache

5.1 HTTP → HTTPS Redirect (Port 80)

This avoids the issue where Apache’s default page shows up or ZeroTier IP access fails.
Create a global redirect config:

sudo tee /etc/apache2/sites-available/nextcloud-http.conf >/dev/null <<'EOF'
<VirtualHost *:80>
    RewriteEngine On
    RewriteCond %{HTTPS} !=on
    RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
</VirtualHost>
EOF

sudo a2enmod rewrite
sudo a2ensite nextcloud-http.conf

5.2 HTTPS VirtualHost

sudo nano /etc/apache2/sites-available/nextcloud-ssl.conf

Example content (replace with your real IP/domain):

<VirtualHost *:443>
    ServerName 192.168.xx.xx
    ServerAlias 192.168.yy.yy

    DocumentRoot /var/www/nextcloud
    <Directory /var/www/nextcloud>
        Require all granted
        AllowOverride All
        Options FollowSymLinks MultiViews
    </Directory>

    SSLEngine on
    SSLCertificateFile /etc/ssl/nextcloud/nextcloud-selfsigned.crt
    SSLCertificateKeyFile /etc/ssl/nextcloud/nextcloud-selfsigned.key

    ErrorLog ${APACHE_LOG_DIR}/nextcloud_ssl_error.log
    CustomLog ${APACHE_LOG_DIR}/nextcloud_ssl_access.log combined
</VirtualHost>

6. Generate a Self-Signed SSL Certificate

sudo mkdir -p /etc/ssl/nextcloud
cd /etc/ssl/nextcloud

sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
  -keyout nextcloud-selfsigned.key \
  -out nextcloud-selfsigned.crt

Tip: For Common Name (CN) enter the IP or domain you plan to use.
If you need to support multiple IPs (LAN + ZeroTier), generate a SAN certificate.


7. Enable Modules and Sites

sudo a2enmod ssl headers env dir mime
sudo a2ensite nextcloud-ssl.conf
sudo systemctl reload apache2

8. Configure Firewall (if UFW is enabled)

sudo ufw allow 80
sudo ufw allow 443

9. Finish Nextcloud Setup

9.1 Access the Installer

Open in browser:

https://192.168.xx.xx
https://192.168.yy.yy   (ZeroTier IP)

Both should now work.


9.2 Fill in Setup Details

  • Admin username & password
  • Data folder (recommended: /var/nextcloud-data, not a VMware hgfs share)
  • Database user: nextclouduser
  • Database password: the strong password you set earlier
  • Database name: nextcloud

9.3 Fix Data Directory Permissions

If on a native Linux disk:

sudo mkdir -p /var/nextcloud-data
sudo chown -R www-data:www-data /var/nextcloud-data
sudo chmod -R 770 /var/nextcloud-data

If on VMware hgfs/Windows share, chmod won’t work → add to config.php:

'check_data_directory_permissions' => false,

9.4 Configure Trusted Domains

Edit:

sudo nano /var/www/nextcloud/config/config.php

Add your LAN and ZeroTier IPs:

'trusted_domains' =>
  array (
    0 => 'localhost',
    1 => '192.168.xx.xx',
    2 => '192.168.yy.yy',
  ),

This prevents the “Access through untrusted domain” error.


10. Client Notes

In the Nextcloud mobile app:

  • Yes → delete file on server and all synced devices.
  • Remove locally → only delete the local copy, file remains on the server.

📌 Key Takeaways

  • Default Apache page issue → solved by disabling 000-default.conf or global 80→443 redirect.
  • ZeroTier IP access issue → solved by adding ServerAlias and global redirect.
  • Data directory permission issue → solved by correct 770 on native disk or disabling check in config.
  • Untrusted domain error → solved by adding all used IPs/domains into trusted_domains.
  • HTTPS → self-signed is fine for testing; for production, use Let’s Encrypt.

VMware Ubuntu 25.04 Bridged Networking Setup Notes


During the setup of Ubuntu 25.04 on VMware Workstation, several common networking issues were encountered when configuring bridged networking.
This note documents the problems and their solutions in detail.


1. Initial Situation

  • After installation, the VM network defaults to NAT mode, with an IP in the 172.x.x.x range.
  • This allows Internet access, but all traffic goes through the host. The VM cannot be directly reached from other devices on the LAN.

2. Issue 1: Missing VMnet0 (Bridged Network)

  • Opening the Virtual Network Editor only showed:
    • VMnet1 (Host-only)
    • VMnet8 (NAT)
  • VMnet0 (bridged network) was missing.

Solution

  1. In the Virtual Network Editor, click Add Network (E).
  2. Select VMnet0 and set it to Bridged mode.
  3. In Bridged to (G):, avoid “Automatic” and instead manually bind VMnet0 to the physical adapter:
    • If the host uses Wi-Fi → choose the wireless adapter (Realtek / Intel Wireless).
    • If the host uses Ethernet → choose the wired Ethernet adapter.

3. Issue 2: VM Does Not Receive LAN IP

  • Even after enabling bridged networking, ip a still showed a NAT IP (172.17.x.x).
  • Cause: VMnet0 was not correctly bound to the physical NIC.

Solution

  1. In Virtual Network Editor, manually bind VMnet0 to the correct NIC (Wi-Fi or Ethernet).
  2. Inside the VM, request a new DHCP lease: sudo dhclient -4 ens33
  3. The VM should then receive a LAN IP, such as 192.168.1.63.

4. Issue 3: Other PCs Cannot Ping the VM

  • The VM can reach the Internet and ping other LAN devices.
  • But other LAN PCs cannot ping the VM.
  • Checking ARP tables shows the VM’s IP maps to the host’s Wi-Fi MAC, not the VM’s MAC.
  • This is a Wi-Fi bridging limitation: wireless NICs often do not allow VMs to use separate MAC addresses.

Solution Options

Option A: Use Wired Ethernet (most stable)

  • Plug in a LAN cable and bridge VMnet0 to the Ethernet adapter.
  • The VM becomes a fully independent LAN node, accessible from other devices.

Option B: Edit VMX Configuration

  • Edit the VM’s .vmx file and add: ethernet0.noPromisc = "FALSE" ethernet0.noForgedTransmit = "FALSE" ethernet0.noMACOverride = "FALSE"
  • Save and restart the VM.
  • ⚠️ Note: Not all Wi-Fi adapters support promiscuous mode. Success depends on hardware.

5. Verification Steps

  • Inside Ubuntu VM: ip a Confirm the VM has an IP in the same LAN subnet (e.g., 192.168.1.x).
  • Test Internet connectivity: ping -4 google.com
  • Test LAN access from another PC: ping <VM-IP> If reachable → bridged networking works.
    If unreachable → likely a Wi-Fi bridging limitation.

6. Summary

  • NAT mode: Internet access works, but LAN cannot reach the VM.
  • Bridged mode (VMnet0): The VM should act as a LAN node, but Wi-Fi bridging often fails.
  • Solutions:
    • Wired bridge (Ethernet) → most stable.
    • Wi-Fi + VMX config tweaks → may work, hardware dependent.

Getting Started with Seeed Studio XIAO ESP32S3 Sense: Camera Streaming


1. Setting Up the Development Environment

I recommend using PlatformIO (VS Code extension) instead of Arduino IDE. PlatformIO has native support for the XIAO ESP32S3 Sense, so you don’t need to fall back on “ESP32S3 Dev Module.”

  • Install VS Code
  • Install PlatformIO IDE extension
  • Create a new project, and select:
    • Board: Seeed Studio XIAO ESP32S3
    • Framework: Arduino

Your platformio.ini should look like this:

[env:seeed_xiao_esp32s3]
platform = espressif32
board = seeed_xiao_esp32s3
framework = arduino
monitor_speed = 115200


2. LED Blink Test

Always start simple. Run a blink sketch to confirm that the board and toolchain are working.

#include <Arduino.h>
#define LED_BUILTIN 21   // Yellow onboard LED

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
}

void loop() {
  digitalWrite(LED_BUILTIN, HIGH);
  delay(500);
  digitalWrite(LED_BUILTIN, LOW);
  delay(500);
}

If the yellow LED blinks, your setup is good to go.


3. Camera Initialization & Web Streaming

The XIAO ESP32S3 Sense comes with an OV2640 camera module. Below is a simplified snippet of the setup code (PlatformIO + Arduino framework):

#include "esp_camera.h"
#include <WiFi.h>
#include <WebServer.h>

#define XCLK_GPIO_NUM  10
#define SIOD_GPIO_NUM  40
#define SIOC_GPIO_NUM  39
#define Y9_GPIO_NUM    48
#define Y8_GPIO_NUM    11
#define Y7_GPIO_NUM    12
#define Y6_GPIO_NUM    14
#define Y5_GPIO_NUM    16
#define Y4_GPIO_NUM    18
#define Y3_GPIO_NUM    17
#define Y2_GPIO_NUM    15
#define VSYNC_GPIO_NUM 38
#define HREF_GPIO_NUM  47
#define PCLK_GPIO_NUM  13

const char *ssid = "YourWiFi";
const char *password = "Password";

WebServer server(80);

void startCameraServer() {
  server.on("/", HTTP_GET, []() {
    server.send(200, "text/html", "<h1>ESP32S3 Camera</h1><img src=\"/stream\">");
  });
  server.begin();
}

When successful, you’ll see an IP address in the Serial Monitor (e.g. 192.168.1.104).
Open http://192.168.1.104/stream in a browser to view the camera feed.


4. WiFi Connection & Debugging

A very common beginner issue is WiFi not connecting. Here are some tips:

  • ESP32 supports only 2.4GHz WiFi (no 5GHz support).
  • Keep your SSID and password simple (no unusual characters).
  • Use a WiFi scan to confirm available networks:
Serial.println("Scanning WiFi...");
int n = WiFi.scanNetworks();
for (int i = 0; i < n; i++) {
  Serial.printf("%d: %s (%d dBm)\n", i+1, WiFi.SSID(i).c_str(), WiFi.RSSI(i));
}
  • Print connection status codes while connecting:
    • 1 = WL_NO_SSID_AVAIL → AP not found
    • 3 = WL_CONNECTED → Connected successfully
    • 4 = WL_CONNECT_FAILED → Wrong password

5. Power Supply Pitfalls (The Biggest Trap!)

Here’s the #1 issue I ran into:

  • When powered via PC USB → everything worked, video stream was fine.
  • When powered via a cheap USB adapter or power bank → black screen, page not loading, or extreme lag.

Why? The ESP32S3 + Camera can draw 500–700mA at peak. Many USB adapters and thin cables can’t supply this reliably.

Fixes

  • Use a stable 5V / 2A USB power adapter
  • Use a short, thick USB cable (30–50 cm, rated for 2A current)
  • If you must use a weak power source, lower the camera load:
config.frame_size   = FRAMESIZE_QQVGA;   // 160x120
config.jpeg_quality = 20;                // High compression
config.xclk_freq_hz = 10000000;          // Lower clock speed
config.fb_count     = 1;                 // Single framebuffer

6. Common Issues & Solutions

  • Black screen → Power supply too weak / camera init failed
  • Page loads but extremely slow → WiFi unstable or CPU overloaded with JPEG compression
  • WiFi won’t connect → Check 2.4GHz availability, WPA2-PSK(AES) recommended
  • High latency → Either power issue or resolution too high

7. Suggested Beginner Workflow

  1. Verify development environment with LED Blink
  2. Test WiFi connectivity with a network scan
  3. Connect to WiFi and run basic camera streaming
  4. Solve power supply issues for stability
  5. Fine-tune resolution, frame rate, and JPEG quality for your use case

8. Changing PlatformIO Default Project Directory

By default, PlatformIO creates all new projects under:

~/Documents/PlatformIO/Projects/

On Linux, this path expands to something like:

/home/username/Documents/PlatformIO/Projects/

If you prefer to keep your projects in another location (for example, under ~/dev/platformio_projects), you can change this setting inside VS Code.

Steps:

  1. Open VS Code.
  2. Press Ctrl+Shift+P → type Preferences: Open User Settings (JSON).
  3. In the settings.json, add the following line: "platformio-ide.projectsDir": "/home/yourname/dev/platformio_projects"
  4. Save and restart VS Code.

From now on, all new PlatformIO projects will be created under your custom directory.


Getting Started with Seeed Studio XIAO ESP32S3 Sense + Arduino IDE (LED Blink Test)


If you’ve just received your Seeed Studio XIAO ESP32S3 Sense, this step-by-step guide will walk you through setting up the Arduino IDE, installing the correct board support, and running your first LED blink test.


1. Install Arduino IDE


2. Install ESP32 Board Support

  1. Open Arduino IDE → File → Preferences
  2. In Additional Board Manager URLs, add the following link:
https://espressif.github.io/arduino-esp32/package_esp32_index.json
  1. Click OK to save.
  2. Go to Tools → Board → Board Manager.
  3. Search for esp32, then install esp32 by Espressif Systems (latest version, currently 3.3.0).

⚠️ Important:
Do not use Arduino ESP32 Boards by Arduino. That package has incomplete support. Always use Espressif Systems (official).


3. Select the Correct Board

Navigate to:
Tools → Board → esp32 → ESP32S3 Dev Module

(Even though the XIAO ESP32S3 is not explicitly listed, selecting “ESP32S3 Dev Module” works perfectly.)


4. Select the Serial Port

Go to Tools → Port and choose your device, e.g.:

/dev/ttyACM0

If you don’t see it:

  • Try a different USB cable (must be a data cable, not a charge-only cable).
  • On Linux, you may need to add your user to the dialout group:
sudo usermod -a -G dialout $USER

Log out and log back in.


5. Test the LED (Blink Example)

Create a new sketch (.ino) and paste the following code:

#define LED_BUILTIN 21   // Onboard yellow LED on GPIO21

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
}

void loop() {
  digitalWrite(LED_BUILTIN, HIGH);  // turn LED on
  delay(500);
  digitalWrite(LED_BUILTIN, LOW);   // turn LED off
  delay(500);
}
  • Click Upload (→).
  • If the small yellow LED starts blinking, everything is working! 🎉

6. Troubleshooting

  • LED doesn’t blink
    • The power LED (always on) cannot be controlled. The correct controllable LED is the small yellow LED on GPIO21.
  • Compilation error: missing partition CSV
    • Ensure you selected ESP32S3 Dev Module.
  • No /dev/ttyACM0 port found
    • Check your USB cable (use a proper data cable).
    • Add user to dialout group (Linux).

✅ Conclusion

At this point, your XIAO ESP32S3 Sense is successfully set up with Arduino IDE. You can now control the onboard LED and are ready to explore more advanced features such as WiFi and the camera module.

AWS CLI Setup and Configuration on Windows


1. Install AWS CLI

Download and install the AWS CLI v2 for Windows:
👉 AWS CLI v2 MSI Installer (64-bit)

Verify installation:

aws --version

2. Create Access Keys

In the AWS Console:

  • Go to Security credentials
  • Under Access keys, click Create access key
  • Save both:
    • AWS_ACCESS_KEY_ID
    • AWS_SECRET_ACCESS_KEY (⚠️ only shown once)

3. Configure Credentials

Run in PowerShell:

aws configure

Enter:

AWS Access Key ID: <your_key_id>
AWS Secret Access Key: <your_secret_key>
Default region name: ap-northeast-1
Default output format: json

4. Verify Setup

aws sts get-caller-identity

Expected output:

{
  "UserId": "...",
  "Account": "123456789012",
  "Arn": "arn:aws:iam::123456789012:user/your-user"
}

✅ Done! You are now ready to use AWS CLI on Windows.
Example:

aws s3 ls

通过 WordPress.com 设计一个这样的站点
从这里开始